研究でRocketChipというRISC-Vの割とデファクトスタンダードな実装のCPUをいじっているのですが、エラーがよくわからなくて苦しんでいます。
https://github.com/chipsalliance/rocket-chip
このRocketChipは実行するとvcdの他にCPUの実行した命令や、その時のALUのRS1、RS2、プログラムカウンタを含むXX.outというファイルを出力してくれます。このログファイルは次のような感じです
using random seed 1658059470 This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. Listening on port 34039 C0: 27 [1] pc=[00010040] W[r 0=00000208][1] R[r 0=00000000] R[r 0=00000000] inst=[7c105073] DASM(7c105073) C0: 32 [1] pc=[00010044] W[r10=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[f1402573] DASM(f1402573) C0: 33 [1] pc=[00010048] W[r11=00010048][1] R[r 0=00000000] R[r 0=00000000] inst=[00000597] DASM(00000597) C0: 34 [1] pc=[0001004c] W[r11=00010080][1] R[r11=00010048] R[r 0=00000000] inst=[03858593] DASM(03858593) C0: 35 [1] pc=[00010050] W[r 0=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[30405073] DASM(30405073) C0: 40 [1] pc=[00010054] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[10500073] DASM(10500073) C0: 43 [0] pc=[00010058] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0000bff5] DASM(0000bff5) C0: 70 [1] pc=[00000800] W[r 0=00000804][1] R[r 0=00000000] R[r 0=00000000] inst=[00c0006f] DASM(00c0006f) C0: 72 [1] pc=[0000080c] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0ff0000f] DASM(0ff0000f)
この中のDASMという項目がアセンブラなのでどんなプログラムが走っているか知りたいですよね。なのでこの項目に逆アセンブラを適応していきましょう。今回はRISCVのtoolchainに含まれているspike-dasmを使います。このコマンドは行内に含まれるDASM(0x????????)という16進数の記述を見つけると逆アセンブルして置き換えてくれるみたいです。便利ですね。
catにパイプ付けてそのまま実行出来るかと思ったら、なんかうまく行かなかったので次のように実行してます。以下の内容でshellで実行してください。僕の環境だとspike-dasmは/opt/riscv/bin/spike-dasm にありました。
cat <span style="color: #d32f2f">XXX.out</span>| while read line do /path/to/spike-dasm ${line} done;
この結果が次のようになります。
This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. Listening on port 34039 C0: 27 [1] pc=[00010040] W[r 0=00000208][1] R[r 0=00000000] R[r 0=00000000] inst=[7c105073] csrwi unknown_7c1, 0 C0: 32 [1] pc=[00010044] W[r10=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[f1402573] csrr a0, mhartid C0: 33 [1] pc=[00010048] W[r11=00010048][1] R[r 0=00000000] R[r 0=00000000] inst=[00000597] auipc a1, 0x0 C0: 34 [1] pc=[0001004c] W[r11=00010080][1] R[r11=00010048] R[r 0=00000000] inst=[03858593] addi a1, a1, 56 C0: 35 [1] pc=[00010050] W[r 0=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[30405073] csrwi mie, 0 C0: 40 [1] pc=[00010054] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[10500073] wfi C0: 43 [0] pc=[00010058] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0000bff5] c.j pc - 4 C0: 70 [1] pc=[00000800] W[r 0=00000804][1] R[r 0=00000000] R[r 0=00000000] inst=[00c0006f] j pc + 0xc C0: 72 [1] pc=[0000080c] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0ff0000f] fence
はい、とりあえず何の命令が実行されているか確認出来ますね。これでデバッグがかなり楽になります。 いままで大体1024番地のデバッグ用のレジスタの挙動が意味不明で動かないことが多かったのでそのへんも分かったらまとめていきます。 じゃあさよなら