@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそ、すべては、SystemC v0.9公開から始まった
こんな状況になってので、verilator について、いろいろ調べてみています。
NNgenのソースコード解析しようとみて、サンプルコード見たら、Veriloggenで、Veriloggenを見ていたら、シミュレータに verilator があって、verilator を見てみたら、verilatorって、SystemCと繋げられるようになっていて、結果的に、verilator のソースコード解析している感じになっています。 https://t.co/NbHXoQtSZY
— Cloud TPU Driver APIのソースコード解析したよ (@Vengineer) November 23, 2019
verilatorのサイトは、こちら
このプレゼンテーション資料、によると、マルチスレッド対応している模様。
とある回路のベンチマークでは、マルチスレッド対応前のv3.926に対して、v4のシングルスレッドでまず30%アップし、マルチスレッドでは、4スレッドで1スレッドに対して1.9倍になったと。何故かマルチチップ構成のベンチマークになっていて、
$ numactl –C 0,2,4,6 sim_executable
にてコントロールすると、シングルスレッドに対して、2.5倍になったと。
フリーランチだー。。。
12スレッドでは、5.5倍、チップをまたがると一気に性能がさがっちゃうんの、1チップ内で完結するようにしないとダメということ。。。
おまけとして、Hotchip 31のTeslaの発表では、
01:09PM EDT - Used Verilator, 50x faster than commercial simulators
にあるように商用シミュレータに対して、50倍速かったと。。なんと。
C++/SystemCモデルと接続できるようになっていんですね。
知らなかったですよ。トップ階層でしか接続できないようですが。
SystemCとの接続は、ここ の 「Chapter 5. The SystemC Test Bench」にいろいろ書いてありました。サンプルコードは、ここ 。
#include <systemc.h>
// Include common routines
#include <verilated.h>// Include model header, generated from Verilating "top.v"
#include "Vtop.h"int sc_main(int argc, char* argv[]) {
// See a similar example walkthrough in the verilator manpage.// This is intended to be a minimal example. Before copying this to start a
// real project, it is better to start with a more complete example,
// e.g. examples/c_tracing.// Prevent unused variable warnings
if (0 && argc && argv) {}// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop("top");// Initialize SC model
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif// Simulate until $finish
while (!Verilated::gotFinish()) {
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif
}// Final model cleanup
top->final();// Fin
return 0;
}
sc_main関数の中でインスタンスを設定するだけでOKなんだね。
こちらの例題では、信号線ありのコード。
とりあえず、WSL に SystemC 2.3.4 と verilator v4.022 をインストールしました。
verilatorのビルド後、
$ make test
を実行したら、ここに書いてあるエラーが発生したので、SystemCをビルドするときに、-DCMAKE_CXX_STANDARD=14 を指定しました。
$ cmake .. -DCMAKE_CXX_STANDARD=14 -DCMAKE_INSTALL_PREFIX=/usr/local/systemc
このオプションでSystemCをビルドしたら、エラーが無くなり、最後までテストが通りました。
テストでは、test_regress ディレクトリと examples ディレクトリをすべて実行しているようです。
テストが通ったので、インストール
$ sudo make install
SystemCの例題、その1:
make_hello_sc ディレクトリにて、make コマンドを実行したら、
以下のようなコマンドが実行されました。最初の verilator コマンドにて、-sc オプションにて SystemC を利用できるようにして、make コマンドにて実行プログラム obj_dir/Vtop を生成し、その obj_dir/Vtop を実行しています。
$ make
-- Verilator hello-world simple example
-- VERILATE ----------------
verilator -sc --exe top.v sc_main.cpp
-- COMPILE -----------------
make -j 4 -C obj_dir -f Vtop.mk
make[1]: Entering directory '/mnt/c/Users/haray/home/src/verilator/examples/make_hello_sc/obj_dir'
make[1]: Nothing to be done for 'default'.
make[1]: Leaving directory '/mnt/c/Users/haray/home/src/verilator/examples/make_hello_sc/obj_dir'
-- RUN ---------------------
obj_dir/Vtop
そうすると、SystemCシミュレータが起動し、"Hello World!"を表示し、Verilog HDLの$finish システムタスクが実行され、終了しています。
SystemC 2.3.4_pub_rev_20190904-Accellera --- Nov 23 2019 14:49:38
Copyright (c) 1996-2019 by all Contributors,
ALL RIGHTS RESERVED
Hello World!
- top.v:10: Verilog $finish
-- DONE --------------------
Note: Once this example is understood, see examples/make_tracing_sc.
Note: Also see the EXAMPLE section in the verilator manpage/document.
Verilog HDLコードの以下の $display と $finish システムタスクが実行されたことになります。
module top;
initial begin
$display("Hello World!");
$finish;
end
endmodule
SystemCの例題、その2:
make_tracing_sc ディレクトリにて、make コマンドを実行したら、
以下のようなコマンドが実行されました。最初の verilator コマンドにて、-sc オプションにて SystemC を利用できるようにして、make コマンドにて実行プログラム obj_dir/Vtop を生成し、その obj_dir/Vtop を +trace オプションを指定して実行しています。
-- Verilator tracing example-- VERILATE ----------------
verilator -sc --exe -O2 -x-assign 0 -Wall --trace --assert --coverage -f input.vc top.v sc_main.cpp-- COMPILE ----------------=
make -j 4 -C obj_dir -f ../Makefile_obj
make[1]: Entering directory '/mnt/c/Users/haray/home/src/verilator/examples/make_tracing_sc/obj_dir'
make[1]: Nothing to be done for 'default'.
make[1]: Leaving directory '/mnt/c/Users/haray/home/src/verilator/examples/make_tracing_sc/obj_dir'-- RUN ---------------------
obj_dir/Vtop +traceSystemC 2.3.4_pub_rev_20190904-Accellera --- Nov 23 2019 14:49:38
Copyright (c) 1996-2019 by all Contributors,
ALL RIGHTS RESERVED
top.vにて、
[0] Model running...
を表示し、sub.v にて、
Enabling waves into logs/vlt_dump.vcd...
[43] fastclk is 5 times faster than clk*-* All Finished *-*
- sub.v:45: Verilog $finish
が表示されます。verilator コマンドのオプションとして、--coverage を指定したのでコードカバレッジを実施しています。logs/coverage.dat がカバレッジデータ。
-- COVERAGE ----------------
verilator_coverage --annotate logs/annotated logs/coverage.dat
Total coverage (6/20) 30.00%
See lines with '%00' in logs/annotated-- DONE --------------------
verilator コマンドのオプションとして、-trace を指定したので、波形のダンプを行い、下記のように波形ビューアーにて、logs/vlt_dump.vcd を見てねと。
To see waveforms, open vlt_dump.vcd in a waveform viewer
examples では、obj_dir に verilator によって生成されたC++/SystemCコードとC++コンパイラでコンパイルされたオブジェクトファイルやライブラリ、実行プログラム(Vtop__ALL.a)だけでなく、Makefile (Vtop.mk) もあります。波形ダンプをするためのオプション (-trace) を指定すると、verilated_vcd_c.x が、コードカバレッジを実施するためのオプション (-coverage) を指定すると、verilated_cov.x が生成される。
verilator は、Perlスクリプトで、実行プログラムは、verilator_bin/verilator_bin_dbg。verilator_coverageはPerlスクリプトで、中でverilator_coverage_bin_dbgを呼んでいる。
C++モデルでも同じようなことはできるけど、信号線の扱い(クロックとかリセット)が面倒なので、SystemCでやればいいんじゃないかな。