Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

verilator、結構凄いことになっていた

@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそすべては、SystemC v0.9公開から始まった

こんな状況になってので、verilator について、いろいろ調べてみています。

 verilatorのサイトは、こちら

www.veripool.org

ソースコードは、github に移行していました。

github.com

このプレゼンテーション資料、によると、マルチスレッド対応している模様。

とある回路のベンチマークでは、マルチスレッド対応前の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 +trace

SystemC 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でやればいいんじゃないかな。