Verilatorを使って簡単RTLシミュレーション

本記事は HDL Advent Calendar 2022 の 6日目の記事です。

ハードでロックな皆さまは自宅でもRTLシミュレーションしたいと思っているはずです。

前日の記事は Vivado Simulatorだったので、本日は Verilator記事になります。

本記事の要約

Verilator v5で、とてもお手軽になりました。

Verilatorの導入障壁

個人的には Verilatorの嫌な制限としてタイミング指定(#10;)の記述が出来ないことがありました。

テストベンチでクロック生成したい時にこんな感じで書けないんですよね。

  always begin
    #(50ns / 2);
    clk <= ~clk;
  end

なので、SystemC側でクロック生成したりしてました。(メンドクサイ)
またリセット解除なども非同期で行いたかったので、時間指定で制御したかったのです。

Verilator v5リリース

嬉しい改善だったので、早速試しました。
しかも、--binaryオプションでより手軽になってるじゃありませんか!

ということで、昔SystemCで作ってたやつを改造して SystemVerilogのみで作ってみました。(即席で作ったので細かいところは気にしないで頂けるとタスカリマス)

01_apb
├ ─ ─  Makefile
├ ─ ─  README.md
├ ─ ─  rtl
│    ├ ─ ─  clk_gate.sv
│    ├ ─ ─  dut_reg.sv
│    └ ─ ─  dut_top.sv
└ ─ ─  tb
    ├ ─ ─  apb_if.sv
    └ ─ ─  tb_top.sv
  • 実行
$ git clone https://github.com/Kocha/try_verilator.git
$ cd try_verilator/01_apb
$ make
# : 省略

./obj_dir/run.x
Start simulation.
Release resetn : 0.425 us
Set wakeup : 1.225 us
End simulation : 3.325 us
- tb/tb_top.sv:76: Verilog $finish

という感じで、動くかと思います。
波形を確認したい場合は waves.vcdファイルが生成されるはずで、
波形Viewerで確認してみてください。

まとめ

Verilator v5になり簡単なテストベンチを作って、すぐRTLシミュレーションができるようになったんじゃないかと思います。

まだまだ文法的にサポートしていないものもあります*1 が、全然使えると思います!

最後に
まだまだ HDL Advent Calendar 2022 空きがありますので是非参加してみてください。

*1:コメントにしてますので探してみてください

Verilator v5試す(timingとbinaryオプション)

2022/10/29に Verilator v5.002がリリースされたようです。

Revision Historyによると

・Require C++20 for the new –timing features. Upgrading to a C++20 or newer compiler is strongly recommended.
・Support the Active and NBA scheduling regions as defined by the SystemVerilog standard (IEEE 1800-2017 chapter 4). This means all generated clocks are now simulated correctly (#3278, #3384). [Geza Lore, Shunyao CAD]
・Support timing controls (delays, event controls in any location, wait statements) and forks. [Krzysztof Bieganski, Antmicro Ltd] This may require adding –timing or –no-timing. See docs for details.
・Introduce a new combinational logic optimizer (DFG), that can yield significant performance improvements on some designs. [Geza Lore, Shunyao CAD]
・Add –binary option as alias of –main –exe –build –timing (#3625). For designs where C++ was only used to make a simple no-I/O testbench, we recommend abandoning that C++, and instead letting Verilator build it with –binary (or –main).

ということで、Timing Controlがサポートされたということで早速試してみました。

Mac(Monterey 12.6)だと brew installでインストールされると思います。
私は元々入れていたので、brew update/upgradeを実行しました。

$ verilator --version
Verilator 5.002 2022-10-29 rev UNKNOWN.REV

実行コード&オプション自体はこちらを参考にしました。

module our;
  initial begin
    $display("Current time = %t", $realtime);
    $display("Hello World");
    #10;
    $display("Current time = %t", $realtime);
    $finish;
  end
endmodule
$ verilator --binary -j 0 -Wall our.v
$ ./obj_dir/Vour
Current time =                    0
Hello World
Current time =                   10
- our.v:7: Verilog $finish

おぉ!きちんと #10;が効いてますね。

ちなみに、--no-timingを付けるとエラーメッセージが出てきます。

$ verilator --no-timing --binary -j 0 -Wall our.v

%Warning-STMTDLY: our.v:5:5: Ignoring delay on this statement due to --no-timing
                           : ... In instance our
    5 |     #10;
      |     ^
                  ... For warning description see https://verilator.org/warn/STMTDLY?v=5.002
                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)

Vim 9.0からcolorschemeが変更になったので前に戻す方法

最近、Vim 9.0に更新しました。

起動したら、表示色が変わったのでビックリ。
help colorschemeを確認すると、記載がありました。

Vim 9.0 ではカラースキームのコレクションが更新され、さまざまな端末で動作するよ うになった。変更の1つは、Normal ハイライトグループを複数定義して、色が適切に表 示されるようにすることであった。古いバージョンを好む場合は、ここで見つけること ができる: https://github.com/vim/colorschemes/blob/master/legacy_colors/

ということで、意図的に変更されたようです。
前の色合いが好みであれば以下で変更できます。

# リポジトリを clone
$ git clone https://github.com/vim/colorschemes.git
# legacy_colors を colorsとして格納
$ cp -r colorschemes/legacy_colors $HOME/.vim/colors

Windowsの場合は %userprofile%\vimfiles\colorsとのことです。

Macで Xilinx/systemctlm-cosim-demo動かす(終わり)

を 個人PC(Mac)で動かそうとしてます。

環境

  • macOS Monterey 12.5
  • Clang 14.0.6

前提

以下がインストールされている状態です。

動機

構成

systemctlm-cosim-demo/docs/lmac-demos.md を見てみると必要な構成は以下の感じぽい

動かす

ここら辺を参考に。

  • 端末1:QEMU実行ターミナル
$ mkdir /tmp/cosim
$ ./qemu-system-aarch64 -M arm-generic-fdt -nographic \
-dtb ~/dts/LATEST/SINGLE_ARCH/zcu102-arm.cosim.dtb \
-device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 \
-machine-path /tmp/cosim \
-sync-quantum 1000000

qemu-system-aarch64: Failed to connect to '/tmp/cosim/qemu-rport-_amba@0_cosim@0': Connection refused
qemu-system-aarch64: info: QEMU waiting for connection on: disconnected:unix:/tmp/cosim/qemu-rport-_amba@0_cosim@0,server=on
  • 端末2:systemctlm-cosim-demy実行ターミナル
$ LD_LIBRARY_PATH=${SYSTEMC_LIBDIR} ./zynqmp_demo unix:/tmp/cosim/qemu-rport-_amba@0_cosim@0 1000000


        SystemC 2.3.3-Accellera --- Aug 16 2022 12:13:48
        Copyright (c) 1996-2018 by all Contributors,
        ALL RIGHTS RESERVED

Info: (I702) default timescale unit used for tracing: 1 ps (trace.vcd)
connect to /tmp/cosim/qemu-rport-_amba@0_cosim@0

となりました。
Linuxのブートファイルなども用意していないので、表示としてはそのままに
端末2のほうで「CTRL+C」などでキャンセルすると、端末1のほうも接続が切れました。

ということで、一旦動くことの確認は出来たかなと。

Macで Xilinx/systemctlm-cosim-demo動かす(その4)

を 個人PC(Mac)で動かそうとしてます。

環境

  • macOS Monterey 12.5
  • Clang 14.0.6

前提

以下がインストールされている状態です。

動機

構成

systemctlm-cosim-demo/docs/lmac-demos.md を見てみると必要な構成は以下の感じぽい

Xilinx/qemu

systemctlm-cosim-demo/docs/lmac-demos.md 記載を参考に

新たにインストールしたもの

$ brew install ninja
$ brew install libgcrypt 
$ git clone https://github.com/Xilinx/qemu.git
$ mkdir build-qemu
$ cd build-qemu
$ ../qemu/configure --target-list=aarch64-softmmu,microblazeel-softmmu,riscv64-softmmu
$ make
qemu/include/hw/misc/ipcores-rsa5-4k.h:30:10: fatal error: 'gcrypt.h' file not found
#include <gcrypt.h>
         ^~~~~~~~~~
1 error generated.

あれ?ヘッダーファイルが無い!?

$ clang -x c++ -v -E /dev/null

で見てみると、search startsに /usr/local/includeが入ってなかったので 環境変数に設定した。 (ついで、ライブラリパスも)

$ export C_INCLUDE_PATH=/usr/local/include
$ export CPLUS_INCLUDE_PATH=/usr/local/include
$ export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/lib

再度 makeし、ヘッダーファイルのエラーは解消

Undefined symbols for architecture x86_64:
  "_gcry_mpi_add", referenced from:
      _rsa_do_add in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_sub in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_mod_addr in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_montmul in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_exp in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_mul in hw_misc_ipcores-rsa5-4k.c.o
  :
  "_gcry_mpi_test_bit", referenced from:
      _gf_mul in hw_misc_ipcores-rsa5-4k.c.o
      _gf_lshift in hw_misc_ipcores-rsa5-4k.c.o
      _bin_xor in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_gf_mod in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_add in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_sub in hw_misc_ipcores-rsa5-4k.c.o
      _rsa_do_mod_addr in hw_misc_ipcores-rsa5-4k.c.o
      ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ライブラリ内には定義はされているぽい。

$ grep "_gcry_mpi_add" /usr/local/lib/*
# :
Binary file /usr/local/lib/libgcrypt.20.dylib matches
Binary file /usr/local/lib/libgcrypt.a matches
Binary file /usr/local/lib/libgcrypt.dylib matches

と存在していることは確か。

標準出力にコンパイル時の引数が表示されていたので、見てみると-lgcryptのライブラリが読み込まれてないことが判明。

とりあえず、configure時に追加するようにした。

$ ../qemu/configure --target-list=aarch64-softmmu,microblazeel-softmmu,riscv64-softmmu --extra-ldflags="-lgcrypt"
$ make

エラーなく実行ファイルができてそう。

$ ls qemu-system-*
qemu-system-aarch64               qemu-system-microblazeel          qemu-system-riscv64
qemu-system-aarch64-unsigned      qemu-system-microblazeel-unsigned qemu-system-riscv64-unsigned

これで、主要なビルドは終わった!...はず