VerilatorとSystemC雑談会
2022.05.02
@Vengineer
VerilatorとSystemCで
Software Driven Verification
ブログ (2007年~) : Vengineerの戯言

 http://blogs.yahoo.co.jp/verification_engineer



SlideShare : 

 https://www.slideshare.net/ssuser479fa3





Twitter (2009年~) :

@Vengineer

Software Driven Verifaction
● Software Driven Verification
○ UVM (Universal Verification Methodology) : SystemVerilog
● Verilator とは?
● SystemC とは?
● 現在の SystemC は?
● Verilator での Software Driven Verification
○ Verilator + SystemC
○ Verilator + SystemC + SystemVerilog DPI
● おわりに
● VerilatorでSystemCを使うには?
発表内容
Software Driven Verification
● ソフトウェア(プログラム)を使って、ハードウェア(RTL等)を検証する
DUT (Design under Test)
RTL等で記述
Model
Driver/Checker/Monitor
Test Program
Top Test Bench
SystemVerilogでは?
● UVM (Universal Verification Methodology) : UVM 2020-1.1
DUT (Design under Test)
SystemVerilog
Model
SystemVerilog
Test Program
SystemVerilog
Top Test Bench
(SystemVerilog)
現状、商用HDLシミュレータのみ利用可能
Verilator とは? (https://github.com/verilator)
Welcome to Verilator, the fastest Verilog/SystemVerilog simulator.
● Accepts synthesizable Verilog or SystemVerilog
● Performs lint code-quality checks
● Compiles into multithreaded C++, or SystemC
● Creates XML to front-end your own tools
テストベンチ側に、
● マルチスレッドな C++
● SystemC
が使える
SystemC とは?
1999年にOpen SystemC(OSCI)が創設され、1999年9月にv0.9が公開
- 米Synopsys, Inc.
- 米CoWare, Inc.
- ベルギーFrontier Design社
● 2005.6 v2.1 LRM & TLM 1.0
● 2005.12 IEEE 1666-2005 (v2.1ベース)
● 2008.6 TLM 2.0 (2008.6)
● 2009.7 TLM 2.0 LRM (2009.7)
● 2010.2 AMS Extensions (2010.2)
現在の SystemC は?
accellera で管理
● 2018.11 SystemC 2.3.3 (Includes TLM)
● 2020.4 SystemC AMS 2.3
IEEE Standards Association (IEEE-SA)
● IEEE Std. 1666-2011 SystemC (SystemC 2.2 + TLM 2.0.1)
● IEEE Std. 1666.1-2016 SystemC AMS (SystemC AMS 2.0)
github : https://github.com/accellera-official/systemc
● 2.3.3
Verilatorでは?
● DUTは、SystemVerilog の RTL記述のみ使える
DUT (Design under Test)
SystemVerilog RTL
Model
C++/SystemC
Test Program
C++/SystemC
Top Test Bench
(C++/SystemC)
Verilator + SystemC
● DUTは、SystemVerilog の RTL記述のみ使える
DUT (Design under Test)
SystemVerilog RTL
Model
SystemC
Test Program
C++
Top Test Bench
(SystemC)
Top Test Bench
(SystemC)
BFMとMemoryの接続は、ピン・レベル
● クロックは、sc_clock で生成
Verilator + SystemC
● DUT(Memory)にアクセスするケース
DUT (Memory)
SystemVerilog RTL
Bus Functional Model
SystemC
Test Program
SystemC
Top Test Bench
(SystemC)
● Read
● Write
module top // Memory だけど、Verilatorの慣習で top にしています
(
input logic clk,
input logic reset,
input logic [15:0] addr,
input logic cs,
input logic rw,
input logic [31:0] data_in,
output logic ready,
output logic [31:0] data_out
);
localparam ram_size = (17'h10000>>2);
logic [31:0] ram[ram_size];
enum {STATE_IDLE, STATE_RUN, STATE_DONE} state;
always_ff @(posedge clk) begin
if(reset == 1'b1)
state <= STATE_IDLE;
else if(cs == 1'b1 && state == STATE_IDLE)
state <= STATE_RUN;
else if(cs == 1'b1 && state == STATE_RUN)
state <= STATE_DONE;
else if(cs == 1'b0)
state <= STATE_IDLE;
end
DUT (Memory)
always_ff @(posedge clk) begin
if(reset == 1'b1) begin
data_out <= 32'h0000_0000;
ready <= 1'b0;
end
else if(state == STATE_RUN) begin
if(rw == 1'b1)
data_out <= ram[addr[15:2]];
else
ram[addr[15:2]] <= data_in;
ready <= 1'b1;
end
else begin
data_out <= 32'h0000_0000;
ready <= 1'b0;
end
end
endmodule
int sc_main(int argc, char* argv[]) {
if (false && argc && argv) {}
Verilated::debug(0);
Verilated::randReset(2);
Verilated::commandArgs(argc, argv);
ios::sync_with_stdio();
sc_clock clk{"clk", 10, SC_NS, 0.5, 5, SC_NS, true};
sc_signal<bool> reset;
sc_signal<bool> cs;
sc_signal<bool> rw;
sc_signal<uint32_t> addr;
sc_signal<uint32_t> data_in;
sc_signal<bool> ready;
sc_signal<uint32_t> data_out;
const std::unique_ptr<Vtop> top{new Vtop{"top"}};
top->clk(clk);
top->reset(reset);
top->cs(cs);
top->rw(rw);
Top Testbench (sc_main)
top->addr(addr);
top->data_in(data_in);
top->ready(ready);
top->data_out(data_out);
const std::unique_ptr<bfm> u_bfm{new bfm("bfm")};
u_bfm->clk(clk);
u_bfm->reset(reset);
u_bfm->cs(cs);
u_bfm->rw(rw);
u_bfm->addr(addr);
u_bfm->data_in(data_out);
u_bfm->ready(ready);
u_bfm->data_out(data_in);
sc_start();
top->final();
cout << "done, time = " << sc_time_stamp() << endl;
return 0;
}
SC_MODULE(bfm) {
public:
SC_CTOR(bfm) :
clk("clk"), reset("reset"), addr("addr"), cs("cs"),
rw("rw"), data_in("data_in"),
ready("ready"), data_out("data_out"),
reset_done(false)
{
SC_THREAD(reset_task);
sensitive << clk.pos();
SC_THREAD(main);
sensitive << clk.pos();
}
BFM (bfm)
sc_in<bool> clk;
sc_out<bool> reset;
sc_out<uint32_t> addr;
sc_out<bool> cs;
sc_out<bool> rw;
sc_out<uint32_t> data_out;
sc_in<bool> ready;
sc_in<uint32_t> data_in;
private:
bool reset_done;
BFM (bfm)
void reset_task(){
reset.write(true);
for(int i=0;i<4;i++)
wait();
reset.write(false);
wait();
cout << "done reset" << endl;
reset_done = true;
}
void main(){
cs.write(false);
rw.write(true);
addr.write(0x00);
data_out.write(0x00);
while(!reset_done)
wait();
test_main();
sc_stop();
  cout << "sc_stop(), time = "
<< sc_time_stamp() << endl;
}
BFM (bfm)
void test_main(){
cout << "start test_main" << endl;
write(0x200, 0x12345678);
uint32_t data = read(0x200);
if(data != 0x12345678)
cout << "<<ERR>>, compare error, data = 0x"
<< hex << data << endl;
cout << "finish test_main" << endl;
}
BFM (bfm)
uint32_t read(uint32_t addr_){
cs.write(true);
rw.write(true);
addr.write(addr_);
while(!ready.read()){
wait();
}
cs.write(false);
addr.write(0x0);
uint32_t data = data_in.read();
wait();
return data;
}
void write(uint32_t addr_, uint32_t data_){
cs.write(true);
rw.write(false);
addr.write(addr_);
data_out.write(data_);
while(!ready.read()){
wait();
}
cs.write(false);
addr.write(0x0);
data_out.write(0x0);
wait();
}
Verilator + SystemC
● Test Program を別ファイルにして、いろいろなテストができる
DUT (Memory)
SystemVerilog RTL
Bus Functional Model
SystemC
Test Program
SystemC
Top Test Bench
(SystemC)
● Read
● Write
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
void main(){
cs.write(false);
rw.write(true);
addr.write(0x00);
data_out.write(0x00);
while(!reset_done)
wait();
test_main();
sc_stop();
  cout << "sc_stop(), time = "
<< sc_time_stamp() << endl;
}
BFM (bfm) + Test Program (test1.cpp)
void test_main(){
cout << "start test_main" << endl;
write(0x200, 0x12345678);
uint32_t data = read(0x200);
if(data != 0x12345678)
cout << "<<ERR>>, compare error, data = 0x"
<< hex << data << endl;
cout << "finish test_main" << endl;
}
Verilator + SystemC + SystemVerilog DPI
● SystemVerilogのDPIを使うと、DUTの中に直接アクセスできる
DUT (Memory)
SystemVerilog RTL
Bus Functional Model
SystemC
Test Program
SystemC
Top Test Bench
(SystemC)
● Read
● Write
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
Test Program
SystemC
SystemVerilog DPI
Verilatorの薄い本
BOOTH : https://vengineer.booth.pm/ にて、
ソースコード解析職人の薄い本として、
● Verilatorの中を調べる、No.1 : 例題解析編
● Verilatorの中を調べる、No.2 : テストデータ解析編
● Verilatorの中を調べる、No.3 : SystemC編
をダウンロード販売しています。
● Software Driven Verification
○ UVM (Universal Verification Methodology) : SystemVerilog
● Verilator とは?
● SystemC とは?
● 現在の SystemC は?
● Verilator での Software Driven Verification
○ Verilator + SystemC
○ Verilator + SystemC + SystemVerilog DPI
● おわりに
● VerilatorでSystemCを使うには?
発表内容
VerilatorでSystemCを使うには?
先に、SystemC 2.3.3 をどこか (/usr/local/systemc/2.3.3) にインストール
後、SYSTEMC_INCLUDE環境変数に、/usr/local/systemc/2.3.3/include を
設定して、verilator をビルド
$ git clone -b v4.202 https://github.com/verilator/verilator.git
v4.202 にて、SystemC で FST (Fast Signal Trace) をサポート
$ cd verilator
$ export SYSTEMC_INCLUDE=/usr/local/systemc/2.3.3/include
$ autoconf
$ ./configure --prefix=/usr/local/verilator/v4.202
$ make -j
$ make install
ありがとうございました
@Vengineer
是非、
Software Driven Verification
をやってみてください

VerilatorとSystemCでSoftware Driven Verification

  • 1.
  • 2.
    ブログ (2007年~) :Vengineerの戯言
  http://blogs.yahoo.co.jp/verification_engineer
 
 SlideShare : 
  https://www.slideshare.net/ssuser479fa3
 
 
 Twitter (2009年~) :
 @Vengineer
 Software Driven Verifaction
  • 3.
    ● Software DrivenVerification ○ UVM (Universal Verification Methodology) : SystemVerilog ● Verilator とは? ● SystemC とは? ● 現在の SystemC は? ● Verilator での Software Driven Verification ○ Verilator + SystemC ○ Verilator + SystemC + SystemVerilog DPI ● おわりに ● VerilatorでSystemCを使うには? 発表内容
  • 4.
    Software Driven Verification ●ソフトウェア(プログラム)を使って、ハードウェア(RTL等)を検証する DUT (Design under Test) RTL等で記述 Model Driver/Checker/Monitor Test Program Top Test Bench
  • 5.
    SystemVerilogでは? ● UVM (UniversalVerification Methodology) : UVM 2020-1.1 DUT (Design under Test) SystemVerilog Model SystemVerilog Test Program SystemVerilog Top Test Bench (SystemVerilog) 現状、商用HDLシミュレータのみ利用可能
  • 6.
    Verilator とは? (https://github.com/verilator) Welcometo Verilator, the fastest Verilog/SystemVerilog simulator. ● Accepts synthesizable Verilog or SystemVerilog ● Performs lint code-quality checks ● Compiles into multithreaded C++, or SystemC ● Creates XML to front-end your own tools テストベンチ側に、 ● マルチスレッドな C++ ● SystemC が使える
  • 7.
    SystemC とは? 1999年にOpen SystemC(OSCI)が創設され、1999年9月にv0.9が公開 -米Synopsys, Inc. - 米CoWare, Inc. - ベルギーFrontier Design社 ● 2005.6 v2.1 LRM & TLM 1.0 ● 2005.12 IEEE 1666-2005 (v2.1ベース) ● 2008.6 TLM 2.0 (2008.6) ● 2009.7 TLM 2.0 LRM (2009.7) ● 2010.2 AMS Extensions (2010.2)
  • 8.
    現在の SystemC は? accelleraで管理 ● 2018.11 SystemC 2.3.3 (Includes TLM) ● 2020.4 SystemC AMS 2.3 IEEE Standards Association (IEEE-SA) ● IEEE Std. 1666-2011 SystemC (SystemC 2.2 + TLM 2.0.1) ● IEEE Std. 1666.1-2016 SystemC AMS (SystemC AMS 2.0) github : https://github.com/accellera-official/systemc ● 2.3.3
  • 9.
    Verilatorでは? ● DUTは、SystemVerilog のRTL記述のみ使える DUT (Design under Test) SystemVerilog RTL Model C++/SystemC Test Program C++/SystemC Top Test Bench (C++/SystemC)
  • 10.
    Verilator + SystemC ●DUTは、SystemVerilog の RTL記述のみ使える DUT (Design under Test) SystemVerilog RTL Model SystemC Test Program C++ Top Test Bench (SystemC)
  • 11.
  • 12.
    Verilator + SystemC ●DUT(Memory)にアクセスするケース DUT (Memory) SystemVerilog RTL Bus Functional Model SystemC Test Program SystemC Top Test Bench (SystemC) ● Read ● Write
  • 13.
    module top //Memory だけど、Verilatorの慣習で top にしています ( input logic clk, input logic reset, input logic [15:0] addr, input logic cs, input logic rw, input logic [31:0] data_in, output logic ready, output logic [31:0] data_out ); localparam ram_size = (17'h10000>>2); logic [31:0] ram[ram_size]; enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; always_ff @(posedge clk) begin if(reset == 1'b1) state <= STATE_IDLE; else if(cs == 1'b1 && state == STATE_IDLE) state <= STATE_RUN; else if(cs == 1'b1 && state == STATE_RUN) state <= STATE_DONE; else if(cs == 1'b0) state <= STATE_IDLE; end DUT (Memory) always_ff @(posedge clk) begin if(reset == 1'b1) begin data_out <= 32'h0000_0000; ready <= 1'b0; end else if(state == STATE_RUN) begin if(rw == 1'b1) data_out <= ram[addr[15:2]]; else ram[addr[15:2]] <= data_in; ready <= 1'b1; end else begin data_out <= 32'h0000_0000; ready <= 1'b0; end end endmodule
  • 14.
    int sc_main(int argc,char* argv[]) { if (false && argc && argv) {} Verilated::debug(0); Verilated::randReset(2); Verilated::commandArgs(argc, argv); ios::sync_with_stdio(); sc_clock clk{"clk", 10, SC_NS, 0.5, 5, SC_NS, true}; sc_signal<bool> reset; sc_signal<bool> cs; sc_signal<bool> rw; sc_signal<uint32_t> addr; sc_signal<uint32_t> data_in; sc_signal<bool> ready; sc_signal<uint32_t> data_out; const std::unique_ptr<Vtop> top{new Vtop{"top"}}; top->clk(clk); top->reset(reset); top->cs(cs); top->rw(rw); Top Testbench (sc_main) top->addr(addr); top->data_in(data_in); top->ready(ready); top->data_out(data_out); const std::unique_ptr<bfm> u_bfm{new bfm("bfm")}; u_bfm->clk(clk); u_bfm->reset(reset); u_bfm->cs(cs); u_bfm->rw(rw); u_bfm->addr(addr); u_bfm->data_in(data_out); u_bfm->ready(ready); u_bfm->data_out(data_in); sc_start(); top->final(); cout << "done, time = " << sc_time_stamp() << endl; return 0; }
  • 15.
    SC_MODULE(bfm) { public: SC_CTOR(bfm) : clk("clk"),reset("reset"), addr("addr"), cs("cs"), rw("rw"), data_in("data_in"), ready("ready"), data_out("data_out"), reset_done(false) { SC_THREAD(reset_task); sensitive << clk.pos(); SC_THREAD(main); sensitive << clk.pos(); } BFM (bfm) sc_in<bool> clk; sc_out<bool> reset; sc_out<uint32_t> addr; sc_out<bool> cs; sc_out<bool> rw; sc_out<uint32_t> data_out; sc_in<bool> ready; sc_in<uint32_t> data_in; private: bool reset_done;
  • 16.
    BFM (bfm) void reset_task(){ reset.write(true); for(inti=0;i<4;i++) wait(); reset.write(false); wait(); cout << "done reset" << endl; reset_done = true; }
  • 17.
    void main(){ cs.write(false); rw.write(true); addr.write(0x00); data_out.write(0x00); while(!reset_done) wait(); test_main(); sc_stop();   cout<< "sc_stop(), time = " << sc_time_stamp() << endl; } BFM (bfm) void test_main(){ cout << "start test_main" << endl; write(0x200, 0x12345678); uint32_t data = read(0x200); if(data != 0x12345678) cout << "<<ERR>>, compare error, data = 0x" << hex << data << endl; cout << "finish test_main" << endl; }
  • 18.
    BFM (bfm) uint32_t read(uint32_taddr_){ cs.write(true); rw.write(true); addr.write(addr_); while(!ready.read()){ wait(); } cs.write(false); addr.write(0x0); uint32_t data = data_in.read(); wait(); return data; } void write(uint32_t addr_, uint32_t data_){ cs.write(true); rw.write(false); addr.write(addr_); data_out.write(data_); while(!ready.read()){ wait(); } cs.write(false); addr.write(0x0); data_out.write(0x0); wait(); }
  • 19.
    Verilator + SystemC ●Test Program を別ファイルにして、いろいろなテストができる DUT (Memory) SystemVerilog RTL Bus Functional Model SystemC Test Program SystemC Top Test Bench (SystemC) ● Read ● Write Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC
  • 20.
    void main(){ cs.write(false); rw.write(true); addr.write(0x00); data_out.write(0x00); while(!reset_done) wait(); test_main(); sc_stop();   cout<< "sc_stop(), time = " << sc_time_stamp() << endl; } BFM (bfm) + Test Program (test1.cpp) void test_main(){ cout << "start test_main" << endl; write(0x200, 0x12345678); uint32_t data = read(0x200); if(data != 0x12345678) cout << "<<ERR>>, compare error, data = 0x" << hex << data << endl; cout << "finish test_main" << endl; }
  • 21.
    Verilator + SystemC+ SystemVerilog DPI ● SystemVerilogのDPIを使うと、DUTの中に直接アクセスできる DUT (Memory) SystemVerilog RTL Bus Functional Model SystemC Test Program SystemC Top Test Bench (SystemC) ● Read ● Write Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC Test Program SystemC SystemVerilog DPI
  • 22.
    Verilatorの薄い本 BOOTH : https://vengineer.booth.pm/ にて、 ソースコード解析職人の薄い本として、 ●Verilatorの中を調べる、No.1 : 例題解析編 ● Verilatorの中を調べる、No.2 : テストデータ解析編 ● Verilatorの中を調べる、No.3 : SystemC編 をダウンロード販売しています。
  • 23.
    ● Software DrivenVerification ○ UVM (Universal Verification Methodology) : SystemVerilog ● Verilator とは? ● SystemC とは? ● 現在の SystemC は? ● Verilator での Software Driven Verification ○ Verilator + SystemC ○ Verilator + SystemC + SystemVerilog DPI ● おわりに ● VerilatorでSystemCを使うには? 発表内容
  • 24.
    VerilatorでSystemCを使うには? 先に、SystemC 2.3.3 をどこか(/usr/local/systemc/2.3.3) にインストール 後、SYSTEMC_INCLUDE環境変数に、/usr/local/systemc/2.3.3/include を 設定して、verilator をビルド $ git clone -b v4.202 https://github.com/verilator/verilator.git v4.202 にて、SystemC で FST (Fast Signal Trace) をサポート $ cd verilator $ export SYSTEMC_INCLUDE=/usr/local/systemc/2.3.3/include $ autoconf $ ./configure --prefix=/usr/local/verilator/v4.202 $ make -j $ make install
  • 25.