見出し画像

RISC-V(RV32IM.v)をRTLシミュレーションしてみる

背景

前回では素数を計算するプログラムの動作確認までで挫折した。
ステップを踏みながらRV32IM(RISC-V)を動かしてみる

初心者へ解説

CPUは半導体で作られてます。

トランジスタ
→ゲート回路
→RTLモデル
→ロジックシミュレーション
→機械語
→アセンブラ
この記事ではRTLモデル以下の動作を(わざわざ)シミュレーションして計算結果を求めていきます。

コード

ファイルを置いておきます。

RISC-Vの設計データ

テストベンチ

アセンブラコード

1から10までの合計を計算していくプログラムを書きます。
実行結果はメモリアドレスmem[0x1f]に書き込むようにしました。
ChatGTP→手で修正

コード

.section .data
    # データセクションは必要ない場合もあるので、ここでは空です

.section .text
.global _start

_start:
    # Initialize registers
    li   x1, 1             # x1 に 1 をロード (カウンタの初期値)
    li   x2, 0             # x2 に 0 をロード (合計の初期値)
    li   x3, 10            # x3 に 10 をロード (上限値)
    add  x3, x3, 1
    
loop:
    add  x2, x2, x1        # 合計にカウンタを加算
    addi x1, x1, 1         # カウンタをインクリメント
    blt  x1, x3, loop      # カウンタが上限値未満ならループ

    # メモリアドレス0x1fに合計を書き込む
    lui  x4, 0x0000        # x4 に 0x0000 をロード (アドレスの上位ビット)
    addi x4, x4, 0x001f    # x4 に 0x001f を加算 (アドレス0x1fを指定)
    sw   x2, 0(x4)         # 合計をメモリに書き込む

    # 無限ループでプログラムを停止
loop_end:
    j loop_end             # 無限ループ

アセンブル・リンク

リンクにはldファイルを使用しないとだめなようです。
ldファイル
linker.ld

ENTRY(_start)
MEMORY
{
    ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
    RAM (rw) : ORIGIN = 0x00040000, LENGTH = 256K
}

SECTIONS
{
    . = 0x00000000;

    .text : {
        *(.text)
    } > ROM

    .data : {
        *(.data)
    } > RAM

    .bss : {
        *(.bss)
    } > RAM

    /DISCARD/ : { *(.comment) }
}

以下を実行(run_sim.sh)

riscv64-unknown-elf-as -march=rv64im -o program.o program.s
riscv64-unknown-elf-ld -T linker.ld -o program.elf program.o
riscv64-unknown-elf-objcopy -O verilog program.elf program.hex
iverilog -o tb_RV32IM.vvp tb_RV32IM.v RV32IM.v
vvp tb_RV32IM.vvp

実行結果

RISC-V % ./run_sim.sh
Memory Dump at time 1020:
mem[0] = 93
mem[1] = 00
mem[2] = 10
mem[3] = 00
mem[4] = 13
mem[5] = 01
mem[6] = 00
mem[7] = 00
mem[8] = 93
mem[9] = 01
mem[a] = a0
mem[b] = 00
mem[c] = 93
mem[d] = 81
mem[e] = 11
mem[f] = 00
mem[10] = 33
mem[11] = 01
mem[12] = 11
mem[13] = 00
mem[14] = 93
mem[15] = 80
mem[16] = 10
mem[17] = 00
mem[18] = e3
mem[19] = cc
mem[1a] = 30
mem[1b] = fe
mem[1c] = 37
mem[1d] = 02
mem[1e] = 00
mem[1f] = 37

mem[1f] = 37
0x37=55
(1+2+3+4+5+6+7+8+9+10=55)
合っているようです。

所感

次ぐらいに、素数を求める計算コードを動かしてみましょう。

メモリアクセスが危険なコードな気がするが・・・趣味ですから、
今日の趣味の時間は終わり

いいなと思ったら応援しよう!