Chisel、コンセプトとしてはいいのかもしれないが、マジで書きにくいなあ。 一度Scalaでシミュレーションすればよいのかもしれないが、Rocket CoreのScalaシミュレーションとかどうやるんだろう? RTLシミュレーションするのだとしても一度Verilogに変換してからシミュレーションするのですごく遅いし、今現在ではフリーのツールではverilatorでvcdしか出力できないので、すごく遅い。
今現在でできることと言えば、念入りにprintfデバッグをすることだ。Chiselの開発環境においてprintfデバッグとはどうやって行うのか、調べた。
まず、本家の説明はこのようになっている。
Printing in Chisel · freechipsproject/chisel3 Wiki · GitHub
こちらの説明では、Chiselで普通にprintfを埋め込むことができるようになっている。実際。自作のアクセラレータ上で、printfを埋め込むことができた。
上記のWikiの説明では、以下のようになっているが、
val myUInt = 33.U printf(p"myUInt = $myUInt") // myUInt = 33
どちらかというとこっちの方がしっくりくるなあ。
printf("MemTotalExample: Command Received. %x, %x\n", io.cmd.bits.rs1, io.cmd.bits.rs2)
という訳で、ガンガンprintf()を入れて自作アクセラレータのデバッグを行っているわけだが、まだ時間がかかりそうだ。。。
ちなみに、Verilogに変換されると、このprintf()は以下のようにVerilogのシミュレーション用に埋め込まれ、Verilatorの実行中にも出力することができる。
RocketCoreの構成はRoccExampleConfig
、シミュレーションは以下のようにして実行している。
make CONFIG=RoccExampleConfig ./emulator-rocketchip-RoccExampleConfig +verbose ~/riscv64/riscv64-unknown-elf/riscv64-unknown-elf/bin/pk ../../rocket-rocc-examples/build/test-accumulator 2> rocc.log
- emulator/generated-src/rocketchip.RoccExampleConfig.v
... end end end `ifndef SYNTHESIS `ifdef PRINTF_COND if (`PRINTF_COND) begin `endif if (_T_1526 & _T_1528) begin $fwrite(32'h80000002,"MemTotalExample: Command Received. %h, %h\n",io_cmd_bits_rs1,io_cmd_bits_rs2); end `ifdef PRINTF_COND end `endif `endif `ifndef SYNTHESIS `ifdef PRINTF_COND if (`PRINTF_COND) begin `endif if (io_mem_resp_valid & _T_1528) begin $fwrite(32'h80000002,"MemTotalExample: IO.MEM Received %h %h\n",io_mem_resp_bits_data,r_state); end `ifdef PRINTF_COND end `endif
すると、rocc.logにアクセラレータが呼び出されると以下のデバッグ分が表示される。
C 0: 4493955 [1] pc=[000001012c] W[r12=0000000000000064][1] R[r 0=0000000000000000] R[r 4=0000000000000003] inst=[06400613] DASM(06400613) C 0: 4493956 [1] pc=[0000010130] W[r10=000000008ffffac0][1] R[r11=000000008ffffac0] R[r12=0000000000000064] inst=[00c5f55b] DASM(00c5f55b) MemTotalExample: Command Received. 000000008ffffac0, 0000000000000064 C 0: 4493957 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=0000000000000064] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) C 0: 4493958 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) C 0: 4493959 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) ... C 0: 4493991 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) C 0: 4493992 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) MemTotalExample: IO.MEM Received 0000000000000000 1 C 0: 4493993 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) MemTotalExample: IO.MEM Received 0000000000000000 1 C 0: 4493994 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) C 0: 4493995 [0] pc=[0000010130] W[r 0=000000008ffffac0][0] R[r11=000000008ffffac0] R[r12=000000008ffffac0] inst=[00c5f55b] DASM(00c5f55b) ...
まあ便利と言えば便利だけど、Rocketの場合は特に、一回のシミュレーションで時間がかかりすぎる。 もうちょっと何とかならないかなあ。