しばらくブログの更新が滞っていました。。。。twitterを見てる方がいらっしゃいましたら、理由はお察しと思います。。 この一月くらいはひたすら本を書いていました↓。
ということで、宣伝を。 12/14に開催される第二回技術書同人誌博覧会が開催されます。
そこでChiselのこと書いた
- Chiselを始めたい人に読んで欲しい本
を頒布します!! 価格は多くの方に手に取っていただきたいので「1000円」としました。
ブースは「3F-せ04」です!
中身については以下の掲載ページをどうぞ。
このブログに載せながら、一年くらいで学んだChiselの知識をベースに 「最初に知っておきたかったなー」ということをまとめたつもりです。 紙面で取り上げたコード+αのサンプルコードも一緒に動かしながら、読み進められるようになってます。
Chiselを本格的に触ってみたいけど、情報が無くて手が出ていない方 いらっしゃいましたら、是非お手にとってもらえると嬉しいです!
ということで、久々のブログ本編。今日はBlackBox
を使って組み込むRTLにdefine
が含まれていて、Verilatorのシミュレーション実行時に
ハマったので、その解決方法についてまとめます。
BlackBoxで取り込むRTLにdefineが含まれる場合のシミュレーション
Verilog-HDLを使っている方には説明の必要はないと思うけど、以下のようなRTLをChiselのテスト機構+Verilatorでそのまま実行すると
define
が見つからずにエラーが起きる。
module BlackBoxDelay ( input logic clk, input logic rst_n, input logic [7:0] in, output logic [7:0] out ); always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin out <= `DELAY 'h0; end else begin out <= in; end end endmodule : BlackBoxDelay
発生するエラーは以下のようにDELAY
が見つからないというもの。
Total FIRRTL Compile Time: 363.3 ms %Error: /home/diningyo/prj/test_run_dir/BlackBoxWithDefine1791218147/ BlackBoxDelay.sv:12: Define or directive not defined: `DELAY
上記を簡単に解決するにはRTL中にそのdefine
の定義を足せば良いんだけど、それもなんだかなぁ??と思ったので
他に解決方法がないか探してみた。
ソースの調査
あるとしたらシミュレーション時に引数を渡す経路が有力なので、まずはVelilator自体のオプションを確認してみると、まあ当然のように 存在している。
+define+<var>=<value> Set preprocessor define
あとはこの設定がChisel側からできるか?ということでiotesters.Driver
の引数を確認してみました。
怪しいのはこの辺。
-ttc, --test-command <value> Change the command run as the backend. Quote this if it contains spaces -tmvf, --more-vcs-flags <value> Add specified commands to the VCS command line -tmvf, --more-vcs-c-flags <value> Add specified commands to the CFLAGS on the VCS command line -tvce, --vcs-command-edits <value> a file containing regex substitutions, one per line s/pattern/replacement/ -tmif, --more-ivl-flags <value> Add specified commands to the ivl command line
上記のオプション名をキーにソースを漁っていくと、以下が見つかった。
- VerilatorBackend.scala
val verilatorFlags = optionsManager.testerOptions.moreVcsFlags ++ { if (suppressVerilatorVCD) Seq() else Seq("--trace") } assert( verilogToVerilator( circuit.name, dir, cppHarnessFile, moreVerilatorFlags = verilatorFlags, moreVerilatorCFlags = optionsManager.testerOptions.moreVcsCFlags, editCommands = optionsManager.testerOptions.vcsCommandEdits ).! == 0 )
どうもmoreVcsFlags
がVerilatorでも使えそう。
試してみる
実際に簡単なソースを準備して試してみた。Chisel側のBlackBox
のラッパーは普通のものなので、省いてテスト実行用のメイン関数だけ掲載。
object TestBlackBoxWithDefine extends App { iotesters.Driver.execute(Array( "-tbn=verilator", "-tmvf=+define+DELAY=1" ), () => new BlackBoxWithDefine) { c => new PeekPokeTester(c) { poke(c.io.in, 1) expect(c.io.out, 0) step(1) expect(c.io.out, 1) } } }
このコードの"-tmvf=+define+DELAY=1"
が肝。実行結果は以下のように正常にシミュレーションが実行されPASSする。
sim start on diningyo-pc at Sat Dec 7 00:17:57 2019 inChannelName: 00018323.in outChannelName: 00018323.out cmdChannelName: 00018323.cmd STARTING test_run_dir/chapter5.TestBlackBoxWithDefine395391358/VBlackBoxWithDefine [info] [0.001] SEED 1575645475565 Enabling waves.. Exit Code: 0 [info] [0.007] RAN 1 CYCLES PASSED [success] Total time: 3 s, completed 2019/12/07 0:17:57
ということで、簡単ではあるがdefine
を含むBlackBox
をVerilatorでシミュレーションする際のdefine
の指定方法についてでした。
こんな感じのコードをそこそこの量、本にはいれてあります。重ねてだけど、興味あれば是非に!