FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

RISC-V のISS "Spike"のログフォーマットを拡張する方法

f:id:msyksphinz:20170201002310j:plain

RISC-VにはUC-Berkeleyの開発した命令セットシミュレータであるSpikeが存在する。

github.com

この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のどこが悪いのかデバッグして行こう(やっと本来の目的に戻ってきた…)