RISC-VにはUC-Berkeleyの開発した命令セットシミュレータであるSpikeが存在する。
このSpikeというシミュレータ、高速でLinuxもブートできる優れものなのだが、欠点はログがほとんど見れず、プログラムが誤作動を起こしても何が起きているのかさっぱり分からないことだった。
- 通常起動させると基本的にログを出さない
spike riscv-spike.elf
-l
オプションを付ける事により、標準出力にログを出すことが可能(ただしPC値と逆アセンブルコード)
spike -l riscv-spike.elf core 0: 0x0000000080000000 (0x00002fb7) lui t6, 0x2 core 0: 0x0000000080000004 (0x800f8f9b) addiw t6, t6, -2048 core 0: 0x0000000080000008 (0x300f9073) csrw mstatus, t6 core 0: 0x000000008000000c (0x0340006f) j pc + 0x34 core 0: 0x0000000080000040 (0x00000297) auipc t0, 0x0 core 0: 0x0000000080000044 (0x12428293) addi t0, t0, 292 core 0: 0x0000000080000048 (0x30529073) csrw mtvec, t0 core 0: 0x000000008000004c (0x00000093) li ra, 0 core 0: 0x0000000080000050 (0x00000113) li sp, 0 core 0: 0x0000000080000054 (0x00000193) li gp, 0 core 0: 0x0000000080000058 (0x00000213) li tp, 0 core 0: 0x000000008000005c (0x00000293) li t0, 0 core 0: 0x0000000080000060 (0x00000313) li t1, 0 core 0: 0x0000000080000064 (0x00000393) li t2, 0 core 0: 0x0000000080000068 (0x00000413) li s0, 0 core 0: 0x000000008000006c (0x00000493) li s1, 0 core 0: 0x0000000080000070 (0x00000513) li a0, 0 core 0: 0x0000000080000074 (0x00000593) li a1, 0 ...
これが無いと、例えば64ビットバイナリを流すときに-isa=RV64IMA
をつけるのを忘れたときに、何がおきているのか分からなかったりする。
ただし、これでもレジスタの書き込み値が表示されなかったりして、詳細なデバッグをしたい時に不便だったりする。
–enable-commitlog=yesビルドオプションにてシミュレーションログを拡張する
ソースコードを眺めていると、どうやら詳細なログを出すためのdefineが切ってあるのを発見した。
STEP_STEPPED } single_step; reg_t load_reservation; #ifdef RISCV_ENABLE_COMMITLOG commit_log_reg_t log_reg_write; reg_t last_inst_priv; #endif }; ...
これを有効にするのはどうしたらいいのか、いろいろ調査していくと、どうやらconfigure
実行時に--enable-commitlog=yes
を追加すれば有効になることが分かった。
riscv-toolsリポジトリ中のbuild-spike-only.sh
を改造して、--enable-commitlog=yes
ビルドオプションを追加しよう。
- riscv-tools/build-spike-only.sh
diff --git a/build-spike-only.sh b/build-spike-only.sh index ac3fda5..2673dc8 100755 --- a/build-spike-only.sh +++ b/build-spike-only.sh @@ -7,6 +7,6 @@ echo "Starting RISC-V Toolchain build process" build_project riscv-fesvr --prefix=$RISCV -build_project riscv-isa-sim --prefix=$RISCV --with-fesvr=$RISCV +build_project riscv-isa-sim --prefix=$RISCV --with-fesvr=$RISCV --enable-commitlog=yes echo -e "\\nRISC-V Toolchain installation completed!"
このオプション付きでSpikeをビルドし直し、実行してみると以下のようにレジスタ書き込みのログが拡張された。
core 0: 0x0000000000001000 (0x7ffff297) auipc t0, 0x7ffff 3 0x0000000000001000 (0x7ffff297) x 5 0x0000000080000000 core 0: 0x0000000000001004 (0x00028067) jr t0 3 0x0000000000001004 (0x00028067) core 0: 0x0000000080000000 (0x00002fb7) lui t6, 0x2 3 0x0000000080000000 (0x00002fb7) x31 0x0000000000002000 core 0: 0x0000000080000004 (0x800f8f9b) addiw t6, t6, -2048 3 0x0000000080000004 (0x800f8f9b) x31 0x0000000000001800 core 0: 0x0000000080000008 (0x300f9073) csrw mstatus, t6 3 0x0000000080000008 (0x300f9073) core 0: 0x000000008000000c (0x0340006f) j pc + 0x34 3 0x000000008000000c (0x0340006f) core 0: 0x0000000080000040 (0x00000297) auipc t0, 0x0 3 0x0000000080000040 (0x00000297) x 5 0x0000000080000040 core 0: 0x0000000080000044 (0x12428293) addi t0, t0, 292 3 0x0000000080000044 (0x12428293) x 5 0x0000000080000164 core 0: 0x0000000080000048 (0x30529073) csrw mtvec, t0 3 0x0000000080000048 (0x30529073) core 0: 0x000000008000004c (0x00000093) li ra, 0 3 0x000000008000004c (0x00000093) x 1 0x0000000000000000 core 0: 0x0000000080000050 (0x00000113) li sp, 0 3 0x0000000080000050 (0x00000113) x 2 0x0000000000000000 core 0: 0x0000000080000054 (0x00000193) li gp, 0 3 0x0000000080000054 (0x00000193) x 3 0x0000000000000000 core 0: 0x0000000080000058 (0x00000213) li tp, 0
ちょっと見にくいけれど、、、例えばauipc
命令がx5(=t0)に即値の書き込みを発生させていることがわかるようになった。
これで、詳細なレジスタ値の遷移が読み取れるようになった。自作ISSと比較して、今の自作ISSのどこが悪いのかデバッグして行こう(やっと本来の目的に戻ってきた…)