ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

define入りBlackBoxをChisel+Verilatorでシミュレーションする方法

スポンサーリンク

しばらくブログの更新が滞っていました。。。。twitterを見てる方がいらっしゃいましたら、理由はお察しと思います。。 この一月くらいはひたすら本を書いていました↓。

ということで、宣伝を。 12/14に開催される第二回技術書同人誌博覧会が開催されます。

gishohaku.dev

そこでChiselのこと書いた

  • Chiselを始めたい人に読んで欲しい本

を頒布します!! 価格は多くの方に手に取っていただきたいので「1000円」としました。

ブースは「3F-せ04」です!

f:id:diningyo-kpuku-jougeki:20191207002616p:plain
表紙

中身については以下の掲載ページをどうぞ。

gishohaku.dev

このブログに載せながら、一年くらいで学んだ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

上記のオプション名をキーにソースを漁っていくと、以下が見つかった。

        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の指定方法についてでした。 こんな感じのコードをそこそこの量、本にはいれてあります。重ねてだけど、興味あれば是非に!