├── LICENSE ├── Models.md ├── README.md ├── examples ├── .gitignore ├── bind │ └── bind.sv ├── inside_operator │ └── inside_operator.sv ├── interface │ └── interface.sv ├── module │ ├── module1.sv │ ├── module2.sv │ ├── module3.sv │ ├── module4.sv │ ├── module5.sv │ └── module6.sv ├── parameterized_mux │ └── parameterized_mux.sv ├── program │ ├── prog1.sv │ └── prog2.sv └── simple_logic │ ├── simple_logic1.sv │ ├── simple_logic2.sv │ ├── simple_logic3.sv │ ├── simple_logic4.sv │ └── simple_logic5.sv ├── verilator ├── common │ ├── Makefile_obj │ └── top.v ├── jtag │ ├── Makefile │ ├── Makefile_obj │ ├── README.md │ ├── input.vc │ ├── jtag.c │ ├── jtag.sv │ ├── sim_main.cpp │ └── top.sv ├── make_tracing_c_verilatortb │ ├── Makefile │ ├── Makefile_obj │ ├── input.vc │ ├── sim_main.cpp │ ├── sub.v │ ├── top.v │ ├── verilatortb.cpp │ └── verilatortb.hpp ├── sample_sc_0 │ ├── .gitignore │ ├── Makefile │ └── sc_main.cpp ├── sample_sc_1 │ ├── .gitignore │ ├── Makefile │ └── sc_main.cpp ├── sample_sc_2 │ ├── .gitignore │ ├── Makefile │ ├── sc_main.cpp │ └── top.v ├── sample_sc_3 │ ├── .#top.v │ ├── .gitignore │ ├── Makefile │ ├── Makefile_obj │ ├── sc_main.cpp │ └── top.v ├── sample_sc_4 │ ├── .gitignore │ ├── Makefile │ ├── log │ ├── sc_main.cpp │ └── top.v ├── sample_sc_bfm_0 │ ├── Makefile │ ├── Makefile.questa │ ├── Vtop.h │ ├── run.do │ ├── sc_main.cpp │ ├── sc_top.cpp │ ├── sc_top.h │ └── top.v ├── sample_sc_bfm_1 │ ├── .gitignore │ ├── Makefile │ ├── Makefile.questa │ ├── Makefile.questa~ │ ├── bfm.cpp │ ├── bfm.h │ ├── run_1.do │ ├── run_2.do │ ├── sc_main.cpp │ ├── sc_top.cpp │ ├── sc_top.h │ ├── test_1.cpp │ ├── test_2.cpp │ └── top.v ├── sample_sc_bfm_2 │ ├── .gitignore │ ├── Makefile │ ├── bfm.cpp │ ├── bfm.h │ ├── sc_main.cpp │ ├── test_1.cpp │ ├── test_2.cpp │ └── top.v ├── sample_sc_bfm_3 │ ├── .gitignore │ ├── Makefile │ ├── bfm.cpp │ ├── bfm.h │ ├── sc_main.cpp │ ├── test_1.cpp │ ├── test_2.cpp │ ├── test_3.cpp │ └── top.v └── sample_sc_bfm_4 │ ├── .gitignore │ ├── Makefile │ ├── Makefile.questa │ ├── Makefile.questa~ │ ├── Vtop.h │ ├── bfm.cpp │ ├── bfm.h │ ├── bfm_api.cpp │ ├── bfm_api.h │ ├── run_1.do │ ├── run_2.do │ ├── run_3.do │ ├── sc_main.cpp │ ├── sc_top.cpp │ ├── sc_top.h │ ├── test_1.cpp │ ├── test_2.cpp │ ├── test_3.cpp │ └── top.v └── xsim ├── sample_xsi_bfm_0 ├── bfm.cpp ├── bfm.h ├── run.sh ├── testbench.cpp ├── top.prj ├── top.v ├── xsi_loader.cpp ├── xsi_loader.h └── xsi_shared_lib.h ├── sample_xsi_bfm_1 ├── bfm.cpp ├── bfm.h ├── run.sh ├── test_1.cpp ├── test_2.cpp ├── testbench.cpp ├── top.prj ├── top.v ├── xsi_loader.cpp ├── xsi_loader.h └── xsi_shared_lib.h └── sample_xsi_bfm_4 ├── bfm.cpp ├── bfm.h ├── bfm_api.cpp ├── bfm_api.h ├── run.sh ├── test_1.cpp ├── test_2.cpp ├── testbench.cpp ├── top.prj ├── top.v ├── xsi_loader.cpp ├── xsi_loader.h └── xsi_shared_lib.h /Models.md: -------------------------------------------------------------------------------- 1 | # いろいろなモデル 2 | 3 | 4 | * https://github.com/taichi-ishitani/tnoc 5 | * SV で実装した NoC のルーターと AXI アダプター 6 | * UVM ベースの検証環境もあり 7 | * https://github.com/taichi-ishitani/tbcm 8 | * FIFO や MUX などよく使いそうな基本モジュール集 9 | * `parameter type` を使って、より SV っぽくしてます 10 | * https://github.com/taichi-ishitani/tvip-axi 11 | * AXI の VIP (モドキ) 12 | * UVM で実装 13 | * https://github.com/taichi-ishitani/tvip-apb 14 | * APB の VIP (モドキ) 15 | * UVM で実装 16 | * https://github.com/taichi-ishitani/tue 17 | * UVM で足りない部分や、バグ修正した拡張パッケージ 18 | * tvip-axi/tvip-apb のベース 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # みんなの SystemVerilog 2 | 3 | 今日(2020年10月17日)20時過ぎにちょこっと思い付いたのでgithubにアカウントを作り、このrepoを立ち上げました。 4 | 5 | このrepoの目的は、SystemVerilogのコードをガンガン溜め込むことです。 6 | 非常に簡単な論理回路(and, or, nand, nor, not, Flipflopなど)やメモリから状態遷移マシン、Bus Functional 7 | ModelなどSystemVerilogで書かれていれば何でもOKです。設計用の記述だけでなく、検証用の記述でもOKです。 8 | 9 | ## SystemVerilog の書籍 10 | 11 | 現在発行されているSystemVerilogに関する書籍 12 | 13 | * [SystemVerilog入門](https://www.kyoritsu-pub.co.jp/bookdetail/9784320124639)、入門書というか LRM (Language Reference Manual)代わり 14 | * [SystemVerilogによる検証の基礎](https://www.morikita.co.jp/books/book/3427)、上記「SystemVerilog入門」の著者によるSystemVerilogの検証に関するもの 15 | * [SystemVerilog設計スタートアップ](https://www.cqpub.co.jp/hanbai/books/36/36191.htm)、2008年5月15日に出版されたCQ出版が過去発行していたDesign Wave Managineに掲載された記事を項目ごとにまとめたもの 16 | 17 | ## SystemVerilog に関するサイト 18 | 19 | * [QiitaのSystemVerilog関連](https://qiita.com/search?q=SystemVerilog) 20 | * [All of SystemVerilog](https://sites.google.com/site/allofsystemverilog/)、@Vengineer が大昔いろいろと書いたもの 21 | * 半導体ネットで連載しました[無償ツールで実践する「ハード・ソフト協調検証」(全8回) (2009.12.6 - 2010.1.29)](https://sites.google.com/site/allofsystemverilog/Home/dpi-c)もあります 22 | 23 | ## いろいろなモデル 24 | 25 | * [Models](Models.md)にいろいろなモデルへのリンクがあります 26 | 27 | ## SystemVerilogが利用できるシミュレータ 28 | ### オープンソースソフトウェア 29 | * [iverilog](http://iverilog.icarus.com/) 30 | * iverilogは、Verilog HDLのシミュレータであるが、オプションを付けると SystemVerilog の一部の機能が使えるようです 31 | * -g2012 というオプションを付けると、SystemVerilog 2012 をサポートするらしい 32 | * [verilator](https://www.veripool.org/wiki/verilator) 33 | * verilator は、initial文をサポートしていません。その代わりに、C/C++/SystemCを使ってテストベンチ側を作ることができます 34 | 35 | ### FPGA開発環境で利用できるシミュレータ 36 | * [Xilinx Simulator](https://japan.xilinx.com/products/design-tools/vivado/simulator.html) 37 | * SystemVerilogの多くの機能をサポートしている(UVMもサポートしている) 38 | * DPI (Direct Programming Interface)は、export task をサポートしていないので C 側から SystemVerilog 側の task が呼べないのが辛いです 39 | * [Intel FPGA用ModelSim](https://www.intel.co.jp/content/www/jp/ja/software/programmable/quartus-prime/model-sim.html) 40 | * Mentor Graphics の ModelSim なので、Verilog HDL/VHDL/SystemVerilog をサポートしています 41 | * 無償バージョンではHDLの行数が制限や実行速度がかなり遅くなっています 42 | * Linux版は64ビットバージョンではなく、32ビットバージョンなのでLinux 側に32ビットのパッケージをインストールする必要があります 43 | 44 | ### お高いシミュレータ 45 | * Synopsys VCS 46 | * Cadence ISU/Xcelium 47 | * Mentor Graphics Questa 48 | * Aldec Riviera-PRO 49 | 50 | また、[EDA Playgroud](https://www.edaplayground.com/)に登録すると、いろいろなSimulatorが利用できます。 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | a.out 2 | 3 | -------------------------------------------------------------------------------- /examples/bind/bind.sv: -------------------------------------------------------------------------------- 1 | // bind 構文 2 | // 動作確認したシミュレータ 3 | // * Aldec Riviera Pro 4 | // * インスタンスを指定する場合の bind はバグを踏む模様 5 | // * Cadence Xcelium 6 | // * Mentor Questa 7 | // * Synopsys VCS 8 | module sub_0 #( 9 | parameter int W = 1 10 | )( 11 | input var i_clk, 12 | input var i_rst_n 13 | ); 14 | logic [W-1:0] v; 15 | 16 | always_ff @(posedge i_clk, negedge i_rst_n) begin 17 | if (!i_rst_n) v <= 0; 18 | else v <= v + 1; 19 | end 20 | endmodule 21 | 22 | module sub_1 #( 23 | parameter int W = 1 24 | )( 25 | input var i_clk, 26 | input var i_rst_n 27 | ); 28 | logic [W-1:0] v; 29 | 30 | always_ff @(posedge i_clk, negedge i_rst_n) begin 31 | if (!i_rst_n) v <= 0; 32 | else v <= v - 1; 33 | end 34 | endmodule 35 | 36 | module monitor #( 37 | parameter int W = 1 38 | )( 39 | input var [W-1:0] i_v 40 | ); 41 | always_comb begin 42 | $display("%t %m v = %0d", $time, i_v); 43 | end 44 | endmodule 45 | 46 | module top; 47 | timeunit 1ns/1ps; 48 | 49 | bit clk; 50 | initial begin 51 | clk = 0; 52 | forever #(500ps) begin 53 | clk ^= 1; 54 | end 55 | end 56 | 57 | bit rst_n; 58 | initial begin 59 | rst_n = 0; 60 | repeat (10) @(posedge clk); 61 | rst_n = 1; 62 | end 63 | 64 | sub_0 #(2) u_sub_0_0 (clk, rst_n); 65 | sub_0 #(4) u_sub_0_1 (clk, rst_n); 66 | sub_1 #(2) u_sub_1_0 (clk, rst_n); 67 | sub_1 #(4) u_sub_1_1 (clk, rst_n); 68 | 69 | // module 一括で bind 70 | bind sub_0 71 | monitor #(W) u_monitor (v); 72 | 73 | // instnace を指定して bind 74 | bind u_sub_1_0 75 | monitor #(W) u_monitor (v); 76 | 77 | initial begin 78 | repeat (32) @(posedge clk); 79 | $finish; 80 | end 81 | endmodule 82 | -------------------------------------------------------------------------------- /examples/inside_operator/inside_operator.sv: -------------------------------------------------------------------------------- 1 | // inside 演算子 2 | // 動作確認したシミュレータ 3 | // * Aldec Riviera Pro 4 | // * Cadence Xcelium 5 | // * Mentor Questa 6 | // * Synopsys VCS 7 | module top; 8 | logic [3:0] v; 9 | logic [3:0] result; 10 | 11 | initial begin 12 | for (int i = 0;i < 16;++i) begin 13 | v = i; 14 | result[0] = v inside {0, 1, 2, 3, 8, 9, 10, 11}; // 複数の比較値 15 | result[1] = v inside {4'b00??, 4'b10??}; // ワイルドカード 16 | result[2] = v inside {[0:3], [8:11]}; // 範囲比較 17 | result[3] = v inside {0, 1, 4'b001?, [8:11]}; // 合わせ技 18 | $display("v = %b result = %b", v, result); 19 | end 20 | $finish; 21 | end 22 | endmodule 23 | -------------------------------------------------------------------------------- /examples/interface/interface.sv: -------------------------------------------------------------------------------- 1 | // interface 使用例 2 | // 動作確認したシミュレータ 3 | // * Aldec Riviera Pro 4 | // * Cadence Xcelium 5 | // * Mentor Questa 6 | // * Synopsys VCS 7 | interface foo_if #(parameter int W = 1); 8 | typedef logic [W-1:0] foo_type; 9 | 10 | logic valid; 11 | logic ready; 12 | foo_type foo; 13 | 14 | function automatic logic ack(); 15 | return valid && ready; 16 | endfunction 17 | 18 | modport master ( 19 | output valid, 20 | input ready, 21 | output foo, 22 | import ack 23 | ); 24 | 25 | modport slave ( 26 | input valid, 27 | output ready, 28 | input foo, 29 | import ack 30 | ); 31 | 32 | modport monitor ( 33 | input valid, 34 | input ready, 35 | input foo, 36 | import ack 37 | ); 38 | endinterface 39 | 40 | module foo_master ( 41 | input var i_clk, 42 | input var i_rst_n, 43 | foo_if.master master_if 44 | ); 45 | typedef master_if.foo_type foo_type; 46 | 47 | logic valid; 48 | foo_type foo; 49 | 50 | always_comb begin 51 | master_if.valid = valid; 52 | master_if.foo = foo; 53 | end 54 | 55 | always_ff @(posedge i_clk, negedge i_rst_n) begin 56 | if (!i_rst_n) begin 57 | valid <= '0; 58 | foo <= '0; 59 | end 60 | else if ((!valid) || master_if.ack()) begin 61 | valid <= $urandom_range(0, 1); 62 | foo <= $urandom_range(0, (2**$bits(foo_type) - 1)); 63 | end 64 | end 65 | endmodule 66 | 67 | module foo_slave ( 68 | input var i_clk, 69 | input var i_rst_n, 70 | foo_if.slave slave_if 71 | ); 72 | logic ready; 73 | 74 | always_comb begin 75 | slave_if.ready = ready; 76 | end 77 | 78 | always_ff @(posedge i_clk, negedge i_rst_n) begin 79 | if (!i_rst_n) begin 80 | ready <= '0; 81 | end 82 | else begin 83 | ready <= $urandom_range(0, 1); 84 | end 85 | end 86 | endmodule 87 | 88 | module foo_monitor ( 89 | foo_if.monitor monitor_if 90 | ); 91 | timeunit 1ns; 92 | 93 | always_comb begin 94 | if (monitor_if.ack()) begin 95 | $display("%t foo: %b", $time, monitor_if.foo); 96 | end 97 | end 98 | endmodule 99 | 100 | module top; 101 | timeunit 1ns/1ps; 102 | 103 | logic clk; 104 | initial begin 105 | clk = 0; 106 | forever #(500ps) begin 107 | clk ^= 1; 108 | end 109 | end 110 | 111 | logic rst_n; 112 | initial begin 113 | rst_n = 0; 114 | repeat (10) @(posedge clk); 115 | rst_n = 1; 116 | end 117 | 118 | foo_if #(4) fooif(); 119 | 120 | foo_master u_master (clk, rst_n, fooif); 121 | foo_slave u_slave (clk, rst_n, fooif); 122 | foo_monitor u_monitor (fooif); 123 | 124 | initial begin 125 | repeat (10) begin 126 | do begin 127 | @(posedge clk); 128 | end while (!fooif.ack()); 129 | end 130 | $finish; 131 | end 132 | endmodule 133 | -------------------------------------------------------------------------------- /examples/module/module1.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module1.sv 2 | // $ ./a.out 3 | // 4 | 5 | module tb; 6 | 7 | reg a, b; 8 | wire c0, c1; 9 | 10 | test_module1 u0( a, b, c0 ); 11 | test_module1 u1( .a(a), .b(b), .c(c1) ); 12 | 13 | initial begin 14 | $monitor("%t : a(%b), b(%b) => c0(%b), c1(%b)", 15 | $time, a, b, c0, c1); 16 | 17 | a <= 0; 18 | b <= 0; 19 | #10; 20 | a <= 1; 21 | #10; 22 | a <= 0; 23 | b <= 1; 24 | #10; 25 | a <= 1; 26 | #10; 27 | $finish(2); 28 | end 29 | 30 | endmodule : tb 31 | 32 | module test_module1( 33 | a, b, c 34 | ); 35 | input wire a; 36 | input wire b; 37 | output wire c; 38 | 39 | assign c = a & b; 40 | 41 | endmodule : test_module1 42 | -------------------------------------------------------------------------------- /examples/module/module2.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module2.sv 2 | // $ ./a.out 3 | // 4 | 5 | module tb; 6 | 7 | logic a, b, c; 8 | 9 | test_module2 u0( .a, .b, .c ); 10 | 11 | initial begin 12 | $monitor("%t : a(%b), b(%b) => c(%b)", 13 | $time, a, b, c); 14 | 15 | a <= 0; 16 | b <= 0; 17 | #10; 18 | a <= 1; 19 | #10; 20 | a <= 0; 21 | b <= 1; 22 | #10; 23 | a <= 1; 24 | #10; 25 | $finish(2); 26 | end 27 | 28 | endmodule : tb 29 | 30 | module test_module2( 31 | input logic a, 32 | input logic b, 33 | output logic c 34 | ); 35 | 36 | assign c = a & b; 37 | 38 | endmodule : test_module2 39 | -------------------------------------------------------------------------------- /examples/module/module3.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module3.sv 2 | // $ ./a.out 3 | // 4 | 5 | module tb; 6 | 7 | logic a, b, c; 8 | 9 | test_module3 u0( .* ); 10 | 11 | initial begin 12 | $monitor("%t : a(%b), b(%b) => c(%b)", 13 | $time, a, b, c); 14 | 15 | a <= 0; 16 | b <= 0; 17 | #10; 18 | a <= 1; 19 | #10; 20 | a <= 0; 21 | b <= 1; 22 | #10; 23 | a <= 1; 24 | #10; 25 | $finish(2); 26 | end 27 | 28 | endmodule : tb 29 | 30 | module test_module3( 31 | input logic a, b, 32 | output logic c 33 | ); 34 | 35 | assign c = a & b; 36 | 37 | endmodule : test_module3 38 | -------------------------------------------------------------------------------- /examples/module/module4.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module4.sv 2 | // $ ./a.out 3 | // 4 | 5 | module tb; 6 | localparam N = 4; 7 | 8 | logic [N-1:0] a, b, c; 9 | 10 | test_module4 #(.N(N)) u0( .* ); 11 | 12 | initial begin 13 | $monitor("%t : a(%b), b(%b) => c(%b)", 14 | $time, a, b, c); 15 | 16 | a <= 0; 17 | b <= 0; 18 | #10; 19 | a <= {N{1'b1}}; 20 | #10; 21 | a <= 0; 22 | b <= {N{1'b1}}; 23 | #10; 24 | a <= {N{1'b1}}; 25 | #10; 26 | $finish(2); 27 | end 28 | 29 | endmodule : tb 30 | 31 | module test_module4 32 | #( 33 | parameter N = 1 34 | ) 35 | ( 36 | input logic [N-1:0] a, b, 37 | output logic [N-1:0] c 38 | ); 39 | 40 | assign c = a & b; 41 | 42 | endmodule : test_module4 43 | -------------------------------------------------------------------------------- /examples/module/module5.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module5.sv 2 | // $ ./a.out 3 | // 4 | 5 | package my_pkg; 6 | parameter N = 8; 7 | endpackage : my_pkg 8 | 9 | module tb; 10 | 11 | import my_pkg::*; 12 | 13 | logic [N-1:0] a, b, c; 14 | 15 | test_module5 #(.N(N)) u0( .* ); 16 | 17 | initial begin 18 | $monitor("%t : a(%b), b(%b) => c(%b)", 19 | $time, a, b, c); 20 | 21 | a <= 0; 22 | b <= 0; 23 | #10; 24 | a <= {N{1'b1}}; 25 | #10; 26 | a <= 0; 27 | b <= {N{1'b1}}; 28 | #10; 29 | a <= {N{1'b1}}; 30 | #10; 31 | $finish(2); 32 | end 33 | 34 | endmodule : tb 35 | 36 | module test_module5 37 | #( 38 | parameter N = 1 39 | ) 40 | ( 41 | input logic [N-1:0] a, b, 42 | output logic [N-1:0] c 43 | ); 44 | 45 | assign c = a & b; 46 | 47 | endmodule : test_module5 48 | -------------------------------------------------------------------------------- /examples/module/module6.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 test_module6.sv 2 | // $ ./a.out 3 | // 4 | 5 | package my_pkg; 6 | parameter N = 8; 7 | endpackage : my_pkg 8 | 9 | module tb ; 10 | 11 | import my_pkg::*; 12 | 13 | logic [N-1:0] a, b, c; 14 | 15 | test_module6 u0( .* ); 16 | 17 | initial begin 18 | $monitor("%t : a(%b), b(%b) => c(%b)", 19 | $time, a, b, c); 20 | 21 | a <= 0; 22 | b <= 0; 23 | #10; 24 | a <= {N{1'b1}}; 25 | #10; 26 | a <= 0; 27 | b <= {N{1'b1}}; 28 | #10; 29 | a <= {N{1'b1}}; 30 | #10; 31 | $finish(2); 32 | end 33 | 34 | endmodule : tb 35 | 36 | module test_module6 import my_pkg::*; 37 | ( 38 | input logic [N-1:0] a, b, 39 | output logic [N-1:0] c 40 | ); 41 | 42 | assign c = a & b; 43 | 44 | endmodule : test_module6 45 | -------------------------------------------------------------------------------- /examples/parameterized_mux/parameterized_mux.sv: -------------------------------------------------------------------------------- 1 | // データの型、要素数、実装方法をパラメータ化した MUX 記述 2 | // 動作確認したシミュレータ 3 | // * Cadence Xcelium 4 | // * Mentor Questa 5 | // * Synopsys VCS 6 | interface parameterized_mux #( 7 | parameter type DATA = logic, 8 | parameter int ENTRIES = 2, 9 | parameter bit ONEHOT = 1 10 | ); 11 | localparam int SELECT_WIDTH = (ONEHOT) ? ENTRIES : $clog2(ENTRIES); 12 | 13 | if (ONEHOT) begin : g 14 | function automatic DATA __mux( 15 | logic [ENTRIES-1:0] select, 16 | DATA [ENTRIES-1:0] data 17 | ); 18 | DATA out; 19 | 20 | for (int i = 0;i < $bits(DATA);++i) begin 21 | logic [ENTRIES-1:0] temp; 22 | 23 | for (int j = 0;j < ENTRIES;++j) begin 24 | temp[j] = select[j] & data[j][i]; 25 | end 26 | 27 | out[i] = |temp; 28 | end 29 | 30 | return out; 31 | endfunction 32 | end 33 | else begin : g 34 | function automatic DATA __mux( 35 | logic [$clog2(ENTRIES)-1:0] select, 36 | DATA [ENTRIES-1:0] data 37 | ); 38 | return data[select]; 39 | endfunction 40 | end 41 | 42 | function automatic DATA mux( 43 | logic [SELECT_WIDTH-1:0] select, 44 | DATA [ENTRIES-1:0] data 45 | ); 46 | return g.__mux(select, data); 47 | endfunction 48 | endinterface 49 | 50 | module top; 51 | logic [3:0][1:0] data; 52 | logic [3:0] onehot_select; 53 | logic [1:0] onehot_out; 54 | logic [1:0] binary_select; 55 | logic [1:0] binary_out; 56 | 57 | parameterized_mux #(logic [1:0], 4, 1) u_onehot_mux(); 58 | parameterized_mux #(logic [1:0], 4, 0) u_binary_mux(); 59 | 60 | initial begin 61 | data[0] = 3; 62 | data[1] = 2; 63 | data[2] = 1; 64 | data[3] = 0; 65 | 66 | for (int i = 0;i < 4;++i) begin 67 | onehot_select = 1 << i; 68 | onehot_out = u_onehot_mux.mux(onehot_select, data); 69 | $display("onehot_select: %b, onehot_out: %0d", onehot_select, onehot_out); 70 | end 71 | 72 | for (int i = 0;i < 4;++i) begin 73 | binary_select = i; 74 | binary_out = u_binary_mux.mux(binary_select, data); 75 | $display("binary_select: %b, binary_out: %0d", binary_select, binary_out); 76 | end 77 | 78 | $finish; 79 | end 80 | endmodule 81 | -------------------------------------------------------------------------------- /examples/program/prog1.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 prog1.sv 2 | // $ ./a.out 3 | // 4 | 5 | module tb ; 6 | 7 | parameter N = 4; 8 | 9 | logic [N-1:0] a, b, c; 10 | 11 | assign_and #( .N(N) ) u0( .* ); 12 | 13 | prog1 #( .N(N) ) u1( .* ); 14 | 15 | endmodule : tb 16 | 17 | program prog1 18 | #( 19 | parameter N = 1 20 | ) 21 | ( 22 | output logic [N-1:0] a, b, 23 | input logic [N-1:0] c 24 | ); 25 | 26 | initial begin 27 | $monitor("%t : a(%b), b(%b) => c(%b)", 28 | $time, a, b, c); 29 | 30 | a = 0; 31 | b = 0; 32 | #10; 33 | a = {N{1'b1}}; 34 | #10; 35 | a = 0; 36 | b = {N{1'b1}}; 37 | #10; 38 | a = {N{1'b1}}; 39 | #10; 40 | $finish(2); 41 | end 42 | 43 | final begin 44 | $display("finish final"); 45 | end 46 | 47 | endprogram : prog1 48 | 49 | module assign_and 50 | #( 51 | parameter N = 1 52 | ) 53 | ( 54 | input logic [N-1:0] a, b, 55 | output logic [N-1:0] c 56 | ); 57 | 58 | assign c = a & b; 59 | 60 | endmodule : assign_and 61 | -------------------------------------------------------------------------------- /examples/program/prog2.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 prog2.sv 2 | // $ ./a.out 3 | // 4 | 5 | interface and_port_if 6 | #( 7 | parameter N = 4 8 | ); 9 | logic [N-1:0] a, b, c; 10 | 11 | modport dut( 12 | input a, b, 13 | output c 14 | ); 15 | 16 | modport tb( 17 | output a, b, 18 | input c 19 | ); 20 | 21 | endinterface : and_port_if 22 | 23 | module tb ; 24 | 25 | parameter N = 4; 26 | 27 | and_port_if port(); 28 | 29 | assign_and #( .N(N) ) u0( .a(port.a), .b(port.b), .c(port.c) ); 30 | 31 | prog1 #( .N(N) ) u1( .a(port.a), .b(port.b), .c(port.c) ); 32 | 33 | endmodule : tb 34 | 35 | program prog1 36 | #( 37 | parameter N = 1 38 | ) 39 | ( 40 | output logic [N-1:0] a, b, 41 | input logic [N-1:0] c 42 | ); 43 | 44 | initial begin 45 | $monitor("%t : a(%b), b(%b) => c(%b)", 46 | $time, a, b, c); 47 | 48 | a = 0; 49 | b = 0; 50 | #10; 51 | a = {N{1'b1}}; 52 | #10; 53 | a = 0; 54 | b = {N{1'b1}}; 55 | #10; 56 | a = {N{1'b1}}; 57 | #10; 58 | $finish(2); 59 | end 60 | 61 | final begin 62 | $display("finish final"); 63 | end 64 | 65 | endprogram : prog1 66 | 67 | module assign_and 68 | #( 69 | parameter N = 1 70 | ) 71 | ( 72 | input logic [N-1:0] a, b, 73 | output logic [N-1:0] c 74 | ); 75 | 76 | assign c = a & b; 77 | 78 | endmodule : assign_and 79 | -------------------------------------------------------------------------------- /examples/simple_logic/simple_logic1.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 simple_logic1.sv 2 | // $ ./a.out 3 | // 4 | module simple_logic1; 5 | 6 | logic a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not; 7 | 8 | assign c_and = a & b; 9 | assign c_or = a | b; 10 | assign c_nand = ~(a & b); 11 | assign c_nor = ~(a | b); 12 | assign c_xor = a ^ b; 13 | assign c_xnor = ~(a ^ b); 14 | assign a_not = ~a; 15 | 16 | initial begin 17 | $monitor("%t : a(%b), b(%b) => c_and(%b), c_or(%b), c_nand(%b), c_nor(%b), c_xor(%b), c_xnor(%b), a_not(%b)", 18 | $time, a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not); 19 | 20 | a <= 0; 21 | b <= 0; 22 | #10; 23 | a <= 1; 24 | #10; 25 | a <= 0; 26 | b <= 1; 27 | #10; 28 | a <= 1; 29 | #10; 30 | $finish(2); 31 | end 32 | 33 | endmodule : simple_logic1 34 | -------------------------------------------------------------------------------- /examples/simple_logic/simple_logic2.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 simple_logic2.sv 2 | // $ ./a.out 3 | // 4 | module simple_logic2; 5 | 6 | logic a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not; 7 | 8 | always @(a or b) begin 9 | c_and = a & b; 10 | c_or = a | b; 11 | c_nand = ~(a & b); 12 | c_nor = ~(a | b); 13 | c_xor = a ^ b; 14 | c_xnor = ~(a ^ b); 15 | a_not = ~a; 16 | end 17 | 18 | initial begin 19 | $monitor("%t : a(%b), b(%b) => c_and(%b), c_or(%b), c_nand(%b), c_nor(%b), c_xor(%b), c_xnor(%b), a_not(%b)", 20 | $time, a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not); 21 | 22 | a <= 0; 23 | b <= 0; 24 | #10; 25 | a <= 1; 26 | #10; 27 | a <= 0; 28 | b <= 1; 29 | #10; 30 | a <= 1; 31 | #10; 32 | $finish(2); 33 | end 34 | 35 | endmodule : simple_logic2 36 | -------------------------------------------------------------------------------- /examples/simple_logic/simple_logic3.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 simple_logic3.sv 2 | // $ ./a.out 3 | // 4 | module simple_logic3; 5 | 6 | logic a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not; 7 | 8 | always @* begin 9 | c_and = a & b; 10 | c_or = a | b; 11 | c_nand = ~(a & b); 12 | c_nor = ~(a | b); 13 | c_xor = a ^ b; 14 | c_xnor = ~(a ^ b); 15 | a_not = ~a; 16 | end 17 | 18 | initial begin 19 | $monitor("%t : a(%b), b(%b) => c_and(%b), c_or(%b), c_nand(%b), c_nor(%b), c_xor(%b), c_xnor(%b), a_not(%b)", 20 | $time, a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not); 21 | 22 | a <= 0; 23 | b <= 0; 24 | #10; 25 | a <= 1; 26 | #10; 27 | a <= 0; 28 | b <= 1; 29 | #10; 30 | a <= 1; 31 | #10; 32 | $finish(2); 33 | end 34 | 35 | endmodule : simple_logic3 36 | -------------------------------------------------------------------------------- /examples/simple_logic/simple_logic4.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 simple_logic4.sv 2 | // $ ./a.out 3 | // 4 | module simple_logic4; 5 | 6 | logic a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not; 7 | 8 | always_comb begin 9 | c_and = a & b; 10 | c_or = a | b; 11 | c_nand = ~(a & b); 12 | c_nor = ~(a | b); 13 | c_xor = a ^ b; 14 | c_xnor = ~(a ^ b); 15 | a_not = ~a; 16 | end 17 | 18 | initial begin 19 | $monitor("%t : a(%b), b(%b) => c_and(%b), c_or(%b), c_nand(%b), c_nor(%b), c_xor(%b), c_xnor(%b), a_not(%b)", 20 | $time, a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not); 21 | 22 | a <= 0; 23 | b <= 0; 24 | #10; 25 | a <= 1; 26 | #10; 27 | a <= 0; 28 | b <= 1; 29 | #10; 30 | a <= 1; 31 | #10; 32 | $finish(2); 33 | end 34 | 35 | endmodule : simple_logic4 36 | -------------------------------------------------------------------------------- /examples/simple_logic/simple_logic5.sv: -------------------------------------------------------------------------------- 1 | // $ iverilog -g2012 simple_logic5.sv 2 | // $ ./a.out 3 | // 4 | module simple_logic5; 5 | 6 | logic a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not; 7 | 8 | always @(a, b) begin 9 | c_and = a & b; 10 | c_or = a | b; 11 | c_nand = ~(a & b); 12 | c_nor = ~(a | b); 13 | c_xor = a ^ b; 14 | c_xnor = ~(a ^ b); 15 | a_not = ~a; 16 | end 17 | 18 | initial begin 19 | $monitor("%t : a(%b), b(%b) => c_and(%b), c_or(%b), c_nand(%b), c_nor(%b), c_xor(%b), c_xnor(%b), a_not(%b)", 20 | $time, a, b, c_and, c_or, c_nand, c_nor, c_xor, c_xnor, a_not); 21 | 22 | a <= 0; 23 | b <= 0; 24 | #10; 25 | a <= 1; 26 | #10; 27 | a <= 0; 28 | b <= 1; 29 | #10; 30 | a <= 1; 31 | #10; 32 | $finish(2); 33 | end 34 | 35 | endmodule : simple_logic5 36 | -------------------------------------------------------------------------------- /verilator/common/Makefile_obj: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | ####################################################################### 3 | # 4 | # DESCRIPTION: Verilator Example: Makefile for inside object directory 5 | # 6 | # This is executed in the object directory, and called by ../Makefile 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ####################################################################### 13 | 14 | default: Vtop 15 | 16 | # Include the rules made by Verilator 17 | include Vtop.mk 18 | 19 | # Use OBJCACHE (ccache) if using gmake and its installed 20 | COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 21 | 22 | ####################################################################### 23 | # Compile flags 24 | 25 | # Override some default compile flags 26 | CPPFLAGS += -MMD -MP 27 | CPPFLAGS += -DVL_DEBUG=1 28 | # SystemC isn't too clean 29 | CPPFLAGS += -Wno-deprecated 30 | # Turn on some more flags (when configured appropriately) 31 | # For testing inside Verilator, "configure --enable-ccwarn" will do this 32 | # automatically; otherwise you may want this unconditionally enabled 33 | ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users 34 | USER_CPPFLAGS_WALL += -W -Werror -Wall 35 | endif 36 | 37 | # If you build your own rules from scratch, note you need to include 38 | # SystemC as follows (Vtop.mk file includes verilated.mk with these 39 | # already). 40 | # CPPFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -I, $(SYSTEMC_INCLUDE)) 41 | # LDFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -L, $(SYSTEMC_LIBDIR)) 42 | 43 | # See the benchmarking section of bin/verilator. 44 | # Support class optimizations. This includes the tracing and symbol table. 45 | # SystemC takes minutes to optimize, thus it is off by default. 46 | OPT_SLOW = 47 | # Fast path optimizations. Most time is spent in these classes. 48 | OPT_FAST = -Os -fstrict-aliasing 49 | #OPT_FAST = -O 50 | #OPT_FAST = 51 | 52 | ####################################################################### 53 | # Linking final exe -- presumes have a sim_main.cpp 54 | 55 | # Special compile rule 56 | sim_main.o: sim_main.cpp $(VM_PREFIX).h 57 | 58 | ###################################################################### 59 | ###################################################################### 60 | # Automatically understand dependencies 61 | 62 | DEPS := $(wildcard *.d) 63 | ifneq ($(DEPS),) 64 | include $(DEPS) 65 | endif 66 | -------------------------------------------------------------------------------- /verilator/common/top.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | // This is intended to be a complex example of several features, please also 9 | // see the simpler examples/make_hello_c. 10 | 11 | `timescale 100ps/1ps 12 | 13 | module top 14 | ( 15 | // Declare some signals so we can see how I/O works 16 | input logic clk, 17 | input logic reset_l, 18 | 19 | output logic [7:0] out_data, 20 | input logic load, 21 | input logic [7:0] in_data 22 | ); 23 | 24 | always_ff @(posedge clk) begin 25 | if(reset_l == 1'b0) 26 | out_data <= 8'h00; 27 | else if(load) begin 28 | out_data <= in_data; 29 | end 30 | else begin 31 | out_data <= out_data + 1'b1; 32 | end 33 | end 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /verilator/jtag/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | VERILATOR_COVERAGE = verilator_coverage 28 | else 29 | export VERILATOR_ROOT 30 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 31 | VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage 32 | endif 33 | 34 | VERILATOR_FLAGS = 35 | # Generate C++ in executable form 36 | VERILATOR_FLAGS += -cc --exe 37 | # Generate makefile dependencies (not shown as complicates the Makefile) 38 | #VERILATOR_FLAGS += -MMD 39 | # Optimize 40 | VERILATOR_FLAGS += -Os -x-assign 0 41 | # Warn abount lint issues; may not want this on less solid designs 42 | VERILATOR_FLAGS += -Wall 43 | # Make waveforms 44 | VERILATOR_FLAGS += --trace 45 | # Check SystemVerilog assertions 46 | VERILATOR_FLAGS += --assert 47 | # Generate coverage analysis 48 | VERILATOR_FLAGS += --coverage 49 | # Run Verilator in debug mode 50 | #VERILATOR_FLAGS += --debug 51 | # Add this trace to get a backtrace in gdb 52 | #VERILATOR_FLAGS += --gdbbt 53 | 54 | # Input files for Verilator 55 | VERILATOR_INPUT = -f input.vc top.sv jtag.c sim_main.cpp 56 | 57 | ###################################################################### 58 | default: run 59 | 60 | run: 61 | @echo 62 | @echo "-- Verilator tracing example" 63 | 64 | @echo 65 | @echo "-- VERILATE ----------------" 66 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 67 | 68 | @echo 69 | @echo "-- BUILD -------------------" 70 | # To compile, we can either 71 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 72 | # 2. Or, run the make rules Verilator does: 73 | # $(MAKE) -j -C obj_dir -f Vtop.mk 74 | # 3. Or, call a submakefile where we can override the rules ourselves: 75 | $(MAKE) -j -C obj_dir -f ../Makefile_obj 76 | 77 | @echo 78 | @echo "-- RUN ---------------------" 79 | @rm -rf logs 80 | @mkdir -p logs 81 | obj_dir/Vtop +trace 82 | 83 | @echo 84 | @echo "-- COVERAGE ----------------" 85 | @rm -rf logs/annotated 86 | $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat 87 | 88 | @echo 89 | @echo "-- DONE --------------------" 90 | @echo "To see waveforms, open vlt_dump.vcd in a waveform viewer" 91 | @echo 92 | 93 | 94 | ###################################################################### 95 | # Other targets 96 | 97 | show-config: 98 | $(VERILATOR) -V 99 | 100 | maintainer-copy:: 101 | clean mostlyclean distclean maintainer-clean:: 102 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 103 | -------------------------------------------------------------------------------- /verilator/jtag/Makefile_obj: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | ####################################################################### 3 | # 4 | # DESCRIPTION: Verilator Example: Makefile for inside object directory 5 | # 6 | # This is executed in the object directory, and called by ../Makefile 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ####################################################################### 13 | 14 | default: Vtop 15 | 16 | # Include the rules made by Verilator 17 | include Vtop.mk 18 | 19 | # Use OBJCACHE (ccache) if using gmake and its installed 20 | COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 21 | 22 | ####################################################################### 23 | # Compile flags 24 | 25 | # Override some default compile flags 26 | CPPFLAGS += -MMD -MP 27 | CPPFLAGS += -DVL_DEBUG=1 28 | # Turn on some more flags (when configured appropriately) 29 | # For testing inside Verilator, "configure --enable-ccwarn" will do this 30 | # automatically; otherwise you may want this unconditionally enabled 31 | ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users 32 | USER_CPPFLAGS_WALL += -W -Werror -Wall 33 | endif 34 | 35 | # See the benchmarking section of bin/verilator. 36 | # Support class optimizations. This includes the tracing and symbol table. 37 | # SystemC takes minutes to optimize, thus it is off by default. 38 | OPT_SLOW = 39 | # Fast path optimizations. Most time is spent in these classes. 40 | OPT_FAST = -Os -fstrict-aliasing 41 | #OPT_FAST = -O 42 | #OPT_FAST = 43 | 44 | ####################################################################### 45 | # Linking final exe -- presumes have a sim_main.cpp 46 | 47 | # Special compile rule 48 | sim_main.o: sim_main.cpp $(VM_PREFIX).h 49 | 50 | ###################################################################### 51 | ###################################################################### 52 | # Automatically understand dependencies 53 | 54 | DEPS := $(wildcard *.d) 55 | ifneq ($(DEPS),) 56 | include $(DEPS) 57 | endif 58 | -------------------------------------------------------------------------------- /verilator/jtag/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Verilator + JTAG C model 3 | 4 | PULP-Platform内の[JTAG DPI Module](https://github.com/pulp-platform/jtag_dpi)は、SystemVerilog DPIを使って、ソフトウェアとソケット通信をすることで、JTAGの通信ができるものです。 5 | 6 | Verilatorは、SystemVerilog DPIのimportはサポートしているものの、initial構文をサポートしていないのでこのままでは使えません。 7 | そこで、C側のコード(jtag_dpi.c)をちょこっと変更(ファイル名も、jtag.c に変更しました)し、Verilatorでも使えるようにしました。 8 | 9 | ソフトウェア側では、ポート番号 4567 に繋いで、uint8_tのデータ(TCLK=BIT[0], TRSTN=BIT[1], TDI=BIT[2], TMS==BIT[3])を送ることでHDL側にJTAGの信号を通知します。HDLからのTDOはソフトウェア側からの獲得要求があったときのみ通知します。このプロトコルについては、jtag.c の jtag_recv関数の内容を確認してください。 10 | 11 | -------------------------------------------------------------------------------- /verilator/jtag/input.vc: -------------------------------------------------------------------------------- 1 | // This file typically lists flags required by a large project, e.g. include directories 2 | +librescan +libext+.v+.sv+.vh+.svh -y . 3 | -------------------------------------------------------------------------------- /verilator/jtag/jtag.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int jp_check_con(); 12 | 13 | uint8_t jp_waiting; 14 | uint8_t count_comp; 15 | uint8_t jp_got_con; 16 | 17 | static int jp_comm_m; // The listening socket 18 | static int jp_comm; // The socket for communicating with jp 19 | 20 | int socket_port; 21 | 22 | void socket_open() { 23 | struct sockaddr_in addr; 24 | int ret; 25 | 26 | count_comp = 0; 27 | jp_waiting = 0; 28 | jp_got_con = 0; 29 | 30 | addr.sin_family = AF_INET; 31 | addr.sin_port = htons(socket_port); 32 | addr.sin_addr.s_addr = INADDR_ANY; 33 | memset(addr.sin_zero, '\0', sizeof(addr.sin_zero)); 34 | 35 | jp_comm_m = socket(PF_INET, SOCK_STREAM, 0); 36 | if(jp_comm_m < 0) 37 | { 38 | fprintf(stderr, "Unable to create comm socket: %s\n", strerror(errno)); 39 | return; 40 | } 41 | 42 | int yes = 1; 43 | if(setsockopt(jp_comm_m, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 44 | fprintf(stderr, "Unable to setsockopt on the socket: %s\n", strerror(errno)); 45 | return; 46 | } 47 | 48 | if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 49 | fprintf(stderr, "Unable to bind the socket: %s\n", strerror(errno)); 50 | return; 51 | } 52 | 53 | if(listen(jp_comm_m, 1) == -1) { 54 | fprintf(stderr, "Unable to listen: %s\n", strerror(errno)); 55 | return; 56 | } 57 | 58 | ret = fcntl(jp_comm_m, F_GETFL); 59 | ret |= O_NONBLOCK; 60 | fcntl(jp_comm_m, F_SETFL, ret); 61 | 62 | fprintf(stderr, "Listening on port %d\n", socket_port); 63 | } 64 | 65 | int jtag_recv(int* tck, int* trstn, int* tdi, int* tms, int tdo) { 66 | uint8_t dat; 67 | int ret; 68 | 69 | if(!jp_got_con) { 70 | if(!jp_check_con()) { 71 | return 0; 72 | } 73 | } 74 | 75 | ret = recv(jp_comm, &dat, 1, 0); 76 | 77 | // check connection abort 78 | if((ret == -1 && errno != EWOULDBLOCK) || (ret == 0)) { 79 | printf("JTAG Connection closed\n"); 80 | 81 | close(jp_comm); 82 | socket_open(); 83 | return 0; 84 | } 85 | 86 | // no available data 87 | if(ret == -1 && errno == EWOULDBLOCK) 88 | return 0; 89 | 90 | if(dat & 0x80) { 91 | switch(dat & 0x7f) { 92 | case 0: 93 | send(jp_comm, &tdo, 1, 0); 94 | return 0; 95 | case 1: 96 | // jp wants a time-out 97 | if(count_comp) { 98 | dat = 0xFF; // A value of 0xFF is expected, but not required 99 | send(jp_comm, &dat, 1, 0); 100 | } 101 | else { 102 | jp_waiting = 1; 103 | } 104 | return 0; 105 | } 106 | } 107 | 108 | *tck = (dat & 0x1) >> 0; 109 | *trstn = (dat & 0x2) >> 1; 110 | *tdi = (dat & 0x4) >> 2; 111 | *tms = (dat & 0x8) >> 3; 112 | 113 | dat |= 0x10; 114 | ret = send(jp_comm, &dat, 1, 0); 115 | 116 | return 1; 117 | } 118 | 119 | void jtag_timeout() { 120 | uint8_t dat = 0xFF; 121 | if(jp_waiting) { 122 | send(jp_comm, &dat, 1, 0); 123 | jp_waiting = 0; 124 | } 125 | 126 | count_comp = 1; 127 | } 128 | 129 | void jtag_init(const int port) { 130 | count_comp = 0; 131 | jp_waiting = 0; 132 | jp_got_con = 0; 133 | 134 | socket_port = port; 135 | 136 | socket_open(); 137 | } 138 | 139 | // Checks to see if we got a connection 140 | int jp_check_con() 141 | { 142 | int ret; 143 | 144 | if((jp_comm = accept(jp_comm_m, NULL, NULL)) == -1) { 145 | if(errno == EAGAIN) 146 | return 0; 147 | 148 | fprintf(stderr, "Unable to accept connection: %s\n", strerror(errno)); 149 | return 0; 150 | } 151 | 152 | 153 | // Set the comm socket to non-blocking. 154 | // Close the server socket, so that the port can be taken again 155 | // if the simulator is reset. 156 | ret = fcntl(jp_comm, F_GETFL); 157 | ret |= O_NONBLOCK; 158 | fcntl(jp_comm, F_SETFL, ret); 159 | close(jp_comm_m); 160 | 161 | printf("JTAG communication connected!\n"); 162 | jp_got_con = 1; 163 | return 1; 164 | } 165 | -------------------------------------------------------------------------------- /verilator/jtag/jtag.sv: -------------------------------------------------------------------------------- 1 | module jtag( 2 | 3 | input logic tms, 4 | input logic tck, 5 | input logic trstn, 6 | input logic tdi, 7 | output logic tdo 8 | 9 | ); 10 | 11 | assign tdo = tdi; 12 | 13 | endmodule : jtag -------------------------------------------------------------------------------- /verilator/jtag/sim_main.cpp: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2017 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | //====================================================================== 7 | 8 | // Include common routines 9 | #include 10 | 11 | // Include model header, generated from Verilating "top.v" 12 | #include "Vtop.h" 13 | 14 | vluint64_t main_time = 0; 15 | 16 | void jtag_init(const int port); 17 | int jtag_recv(int* tck, int* trstn, int* tdi, int* tms, int tdo); 18 | 19 | int main(int argc, char** argv, char** env) { 20 | 21 | const int TCP_PORT = 4567; 22 | 23 | // See a similar example walkthrough in the verilator manpage. 24 | 25 | // This is intended to be a minimal example. Before copying this to start a 26 | // real project, it is better to start with a more complete example, 27 | // e.g. examples/c_tracing. 28 | 29 | // Prevent unused variable warnings 30 | if (false && argc && argv && env) {} 31 | 32 | // Set debug level, 0 is off, 9 is highest presently used 33 | // May be overridden by commandArgs 34 | Verilated::debug(0); 35 | 36 | // Randomization reset policy 37 | // May be overridden by commandArgs 38 | Verilated::randReset(2); 39 | 40 | // Verilator must compute traced signals 41 | Verilated::traceEverOn(true); 42 | 43 | // Pass arguments so Verilated code can see them, e.g. $value$plusargs 44 | // This needs to be called before you create any model 45 | Verilated::commandArgs(argc, argv); 46 | 47 | // Create logs/ directory in case we have traces to put under it 48 | Verilated::mkdir("logs"); 49 | 50 | jtag_init(TCP_PORT); 51 | 52 | // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" 53 | Vtop* top = new Vtop; 54 | 55 | top->clk = 0; 56 | 57 | top->tck = 0; 58 | top->trstn = 0; 59 | top->tdi = 0; 60 | top->tms = 0; 61 | 62 | for(int n=0;n<10;n++){ 63 | main_time++; // Time passes... 64 | top->eval(); 65 | top->clk = !top->clk; 66 | } 67 | 68 | // Simulate until $finish 69 | while (!Verilated::gotFinish()) { 70 | int changed = 0; 71 | main_time++; // Time passes... 72 | 73 | // Toggle a fast (time/2 period) clock 74 | top->clk = !top->clk; 75 | 76 | // Toggle control signals on an edge that doesn't correspond 77 | // to where the controls are sampled; in this example we do 78 | // this only on a negedge of clk, because we know 79 | // reset is not sampled there. 80 | if (!top->clk) { 81 | int tck, trstn, tdi, tms, tdo; 82 | 83 | tdo = top->tdo; 84 | if(jtag_recv(&tck, &trstn, &tdi, &tms, tdo)){ 85 | top->tck = tck; 86 | top->trstn = trstn; 87 | top->tdi = tdi; 88 | top->tms = tms; 89 | changed = 1; 90 | } 91 | } 92 | 93 | // Evaluate model 94 | // (If you have multiple models being simulated in the same 95 | // timestep then instead of eval(), call eval_step() on each, then 96 | // eval_end_step() on each.) 97 | top->eval(); 98 | 99 | // Read outputs 100 | if(changed) 101 | VL_PRINTF("[%" VL_PRI64 "d] clk=%x, tck=%x trstn=%x, tms=%x, tdi=%x, tdo=%x\n", 102 | main_time, top->clk, top->tck, top->trstn, top->tms, top->tdi, top->tdo); 103 | } 104 | 105 | // Final model cleanup 106 | top->final(); 107 | 108 | // Destroy model 109 | delete top; 110 | 111 | // Fin 112 | exit(0); 113 | } 114 | -------------------------------------------------------------------------------- /verilator/jtag/top.sv: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | 5 | input logic tms, 6 | input logic tck, 7 | input logic trstn, 8 | input logic tdi, 9 | output logic tdo 10 | ); 11 | 12 | jtag u0( .* ); 13 | 14 | endmodule : top 15 | 16 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | VERILATOR_COVERAGE = verilator_coverage 28 | else 29 | export VERILATOR_ROOT 30 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 31 | VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage 32 | endif 33 | 34 | # Generate C++ in executable form 35 | VERILATOR_FLAGS += -cc --exe 36 | # Generate makefile dependencies (not shown as complicates the Makefile) 37 | #VERILATOR_FLAGS += -MMD 38 | # Optimize 39 | VERILATOR_FLAGS += -Os -x-assign 0 40 | # Warn abount lint issues; may not want this on less solid designs 41 | VERILATOR_FLAGS += -Wall 42 | # Make waveforms 43 | VERILATOR_FLAGS += --trace 44 | # Check SystemVerilog assertions 45 | VERILATOR_FLAGS += --assert 46 | # Generate coverage analysis 47 | VERILATOR_FLAGS += --coverage 48 | # Run Verilator in debug mode 49 | #VERILATOR_FLAGS += --debug 50 | # Add this trace to get a backtrace in gdb 51 | #VERILATOR_FLAGS += --gdbbt 52 | 53 | # Input files for Verilator 54 | VERILATOR_INPUT = -f input.vc top.v sim_main.cpp verilatortb.cpp 55 | 56 | ###################################################################### 57 | default: run 58 | 59 | run: 60 | @echo 61 | @echo "-- Verilator tracing example" 62 | 63 | @echo 64 | @echo "-- VERILATE ----------------" 65 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 66 | 67 | @echo 68 | @echo "-- BUILD -------------------" 69 | # To compile, we can either 70 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 71 | # 2. Or, run the make rules Verilator does: 72 | # $(MAKE) -j -C obj_dir -f Vtop.mk 73 | # 3. Or, call a submakefile where we can override the rules ourselves: 74 | $(MAKE) -j -C obj_dir -f ../Makefile_obj 75 | 76 | @echo 77 | @echo "-- RUN ---------------------" 78 | @rm -rf logs 79 | @mkdir -p logs 80 | obj_dir/Vtop +trace 81 | 82 | @echo 83 | @echo "-- COVERAGE ----------------" 84 | @rm -rf logs/annotated 85 | $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat 86 | 87 | @echo 88 | @echo "-- DONE --------------------" 89 | @echo "To see waveforms, open vlt_dump.vcd in a waveform viewer" 90 | @echo 91 | 92 | 93 | ###################################################################### 94 | # Other targets 95 | 96 | show-config: 97 | $(VERILATOR) -V 98 | 99 | maintainer-copy:: 100 | clean mostlyclean distclean maintainer-clean:: 101 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 102 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/Makefile_obj: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | ####################################################################### 3 | # 4 | # DESCRIPTION: Verilator Example: Makefile for inside object directory 5 | # 6 | # This is executed in the object directory, and called by ../Makefile 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ####################################################################### 13 | 14 | default: Vtop 15 | 16 | # Include the rules made by Verilator 17 | include Vtop.mk 18 | 19 | # Use OBJCACHE (ccache) if using gmake and its installed 20 | COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 21 | 22 | ####################################################################### 23 | # Compile flags 24 | 25 | # Turn on creating .d make dependency files 26 | CPPFLAGS += -MMD -MP 27 | 28 | # Compile in Verilator runtime debugging, so +verilator+debug works 29 | CPPFLAGS += -DVL_DEBUG=1 30 | 31 | # Turn on some more compiler lint flags (when configured appropriately) 32 | # For testing inside Verilator, "configure --enable-ccwarn" will do this 33 | # automatically; otherwise you may want this unconditionally enabled 34 | ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users 35 | USER_CPPFLAGS_WALL += -W -Werror -Wall 36 | endif 37 | 38 | # See the benchmarking section of bin/verilator. 39 | # Support class optimizations. This includes the tracing and symbol table. 40 | # SystemC takes minutes to optimize, thus it is off by default. 41 | OPT_SLOW = 42 | 43 | # Fast path optimizations. Most time is spent in these classes. 44 | OPT_FAST = -Os -fstrict-aliasing 45 | #OPT_FAST = -O 46 | #OPT_FAST = 47 | 48 | ###################################################################### 49 | ###################################################################### 50 | # Automatically understand dependencies 51 | 52 | DEPS := $(wildcard *.d) 53 | ifneq ($(DEPS),) 54 | include $(DEPS) 55 | endif 56 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/input.vc: -------------------------------------------------------------------------------- 1 | // This file typically lists flags required by a large project, e.g. include directories 2 | +librescan +libext+.v+.sv+.vh+.svh -y . 3 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/sim_main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "Vtop.h" 6 | #include "VerilatorTb.hpp" 7 | 8 | int main(int argc, char** argv, char** env) { 9 | 10 | if (false && argc && argv && env) {} 11 | 12 | const std::unique_ptr contextp{new VerilatedContext}; 13 | contextp->commandArgs(argc, argv); 14 | 15 | const std::unique_ptr top{new Vtop{contextp.get(), "TOP"}}; 16 | const std::unique_ptr tb{new VerilatorTb{top.get(), contextp.get()}}; 17 | 18 | 19 | top->clk = 0; 20 | top->reset_l = 0; 21 | top->in_small = 1; 22 | top->in_quad = 0x1234; 23 | top->in_wide[0] = 0x11111111; 24 | top->in_wide[1] = 0x22222222; 25 | top->in_wide[2] = 0x3; 26 | 27 | if(!tb->driveReset(top->clk, top->reset_l, 10)) { 28 | 29 | while (!tb->toggleClock(top->clk,1)) { 30 | 31 | if(!top->clk) 32 | top->in_quad += 0x12; 33 | 34 | VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x" 35 | " -> oquad=%" VL_PRI64 "x owide=%x_%08x_%08x\n", 36 | contextp->time(), top->clk, top->reset_l, top->in_quad, top->out_quad, 37 | top->out_wide[2], top->out_wide[1], top->out_wide[0]); 38 | } 39 | } 40 | 41 | top->final(); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/sub.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog Test module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | module sub 9 | ( 10 | input clk, 11 | input reset_l 12 | ); 13 | 14 | // Example counter/flop 15 | reg [31:0] count_c; 16 | always_ff @ (posedge clk) begin 17 | if (!reset_l) begin 18 | /*AUTORESET*/ 19 | // Beginning of autoreset for uninitialized flops 20 | count_c <= 32'h0; 21 | // End of automatics 22 | end 23 | else begin 24 | count_c <= count_c + 1; 25 | if (count_c >= 3) begin 26 | // This write is a magic value the Makefile uses to make sure the 27 | // test completes successfully. 28 | $write("*-* All Finished *-*\n"); 29 | $finish; 30 | end 31 | end 32 | end 33 | 34 | // An example assertion 35 | always_ff @ (posedge clk) begin 36 | AssertionExample: assert (!reset_l || count_c<100); 37 | end 38 | 39 | // And example coverage analysis 40 | cover property (@(posedge clk) count_c==3); 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/top.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | // This is intended to be a complex example of several features, please also 9 | // see the simpler examples/make_hello_c. 10 | 11 | module top 12 | ( 13 | // Declare some signals so we can see how I/O works 14 | input clk, 15 | input reset_l, 16 | 17 | output wire [1:0] out_small, 18 | output wire [39:0] out_quad, 19 | output wire [69:0] out_wide, 20 | input [1:0] in_small, 21 | input [39:0] in_quad, 22 | input [69:0] in_wide 23 | ); 24 | 25 | // Connect up the outputs, using some trivial logic 26 | assign out_small = ~reset_l ? '0 : (in_small + 2'b1); 27 | assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1); 28 | assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1); 29 | 30 | // And an example sub module. The submodule will print stuff. 31 | sub sub (/*AUTOINST*/ 32 | // Inputs 33 | .clk (clk), 34 | .reset_l (reset_l)); 35 | 36 | // Print some stuff as an example 37 | initial begin 38 | if ($test$plusargs("trace") != 0) begin 39 | $display("[%0t] Tracing to logs/vlt_dump.vcd...\n", $time); 40 | $dumpfile("logs/vlt_dump.vcd"); 41 | $dumpvars(); 42 | end 43 | $display("[%0t] Model running...\n", $time); 44 | end 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/verilatortb.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "verilatortb.hpp" 3 | 4 | VerilatorTb::VerilatorTb(Vtop *top_, VerilatedContext *contextp_) 5 | : top(top_), contextp(contextp_) 6 | { 7 | #if VM_TRACE 8 | Verilated::mkdir("logs"); 9 | #endif 10 | 11 | contextp->debug(0); 12 | contextp->randReset(2); 13 | #if VM_TRACE 14 | contextp->traceEverOn(true); 15 | #endif 16 | } 17 | 18 | VerilatorTb::~VerilatorTb() 19 | { 20 | #if VM_COVERAGE 21 | Verilated::mkdir("logs"); 22 | contextp->coveragep()->write("logs/coverage.dat"); 23 | #endif 24 | } 25 | 26 | bool VerilatorTb::toggleClock(vluint8_t &clk, int cnt) 27 | { 28 | for(int n=0 ; neval(); 32 | 33 | contextp->timeInc(1); 34 | 35 | if(contextp->gotFinish()) 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | bool VerilatorTb::driveReset(vluint8_t &clk, vluint8_t &rst_n, int count) 43 | { 44 | rst_n = 0; 45 | 46 | if( toggleClock(clk, count) ) { 47 | return true; 48 | } 49 | 50 | 51 | rst_n = 1; 52 | 53 | return false; 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /verilator/make_tracing_c_verilatortb/verilatortb.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef VERILATORTB_HPP 3 | #define VERILATORTB_HPP 4 | 5 | #include "verilated.h" 6 | 7 | #include "Vtop.h" 8 | #include "verilatortb.hpp" 9 | 10 | class VerilatorTb { 11 | 12 | public: 13 | 14 | VerilatorTb(Vtop *top_, VerilatedContext *contextp_); 15 | ~VerilatorTb(); 16 | bool toggleClock(vluint8_t &clk, int cnt); 17 | bool driveReset(vluint8_t &clk, vluint8_t &rst_n, int count); 18 | 19 | private: 20 | Vtop *top; 21 | VerilatedContext *contextp; 22 | }; 23 | 24 | #endif // VERILATORTB_HPP 25 | -------------------------------------------------------------------------------- /verilator/sample_sc_0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_0/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = ../common/top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | @echo 68 | @echo "-- Verilator tracing example" 69 | 70 | @echo 71 | @echo "-- VERILATE ----------------" 72 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 73 | 74 | @echo 75 | @echo "-- COMPILE -----------------" 76 | # To compile, we can either 77 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 78 | # 2. Or, run the make rules Verilator does: 79 | # $(MAKE) -j -C obj_dir -f Vtop.mk 80 | # 3. Or, call a submakefile where we can override the rules ourselves: 81 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 82 | 83 | @echo 84 | @echo "-- RUN ---------------------" 85 | obj_dir/Vtop 86 | @echo 87 | @echo "-- DONE --------------------" 88 | 89 | ###################################################################### 90 | # Other targets 91 | 92 | nosc: 93 | @echo 94 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 95 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 96 | @echo 97 | 98 | show-config: 99 | $(VERILATOR) -V 100 | 101 | maintainer-copy:: 102 | clean mostlyclean distclean maintainer-clean:: 103 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 104 | -------------------------------------------------------------------------------- /verilator/sample_sc_0/sc_main.cpp: -------------------------------------------------------------------------------- 1 | // For std::unique_ptr 2 | #include 3 | 4 | // SystemC global header 5 | #include 6 | 7 | // Include model header, generated from Verilating "top.v" 8 | #include "Vtop.h" 9 | 10 | SC_MODULE(driver) { 11 | public: 12 | 13 | SC_CTOR(driver) : 14 | clk("clk"), reset_l("reset_l"), out_data("out_data"), load("load"), in_data("in_data") 15 | { 16 | SC_THREAD(main); 17 | sensitive << clk.pos(); 18 | } 19 | 20 | sc_in clk; 21 | sc_in reset_l; 22 | sc_in out_data; 23 | sc_out load; 24 | sc_out in_data; 25 | sc_out done; 26 | 27 | private: 28 | void main(){ 29 | 30 | load = 0; 31 | in_data = 0; 32 | 33 | do { 34 | wait(); 35 | } while(!reset_l.read()); 36 | 37 | wait(); 38 | 39 | load = 1; 40 | in_data = 2; 41 | wait(); 42 | 43 | load = 0; 44 | 45 | while(1){ 46 | wait(); 47 | if(out_data == 0xff) 48 | break; 49 | } 50 | 51 | done = 1; 52 | } 53 | }; 54 | 55 | SC_MODULE(reset) { 56 | public: 57 | 58 | SC_CTOR(reset) : 59 | clk("clk"), reset_l("reset_l") 60 | { 61 | SC_THREAD(main); 62 | sensitive << clk.pos(); 63 | } 64 | 65 | sc_in clk; 66 | sc_out reset_l; 67 | 68 | private: 69 | void main(){ 70 | 71 | reset_l = 0; 72 | for(int i=0 ; i<3 ; i++) 73 | wait(); 74 | 75 | reset_l = 1; 76 | 77 | while(1){ 78 | wait(); 79 | 80 | } 81 | } 82 | }; 83 | 84 | int sc_main(int argc, char* argv[]) { 85 | 86 | if (false && argc && argv) {} 87 | 88 | Verilated::debug(0); 89 | Verilated::randReset(2); 90 | Verilated::commandArgs(argc, argv); 91 | 92 | ios::sync_with_stdio(); 93 | 94 | sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; 95 | 96 | sc_signal reset_l; 97 | sc_signal load; 98 | sc_signal in_data; 99 | sc_signal out_data; 100 | sc_signal done; 101 | 102 | const std::unique_ptr top{new Vtop{"top"}}; 103 | 104 | top->clk(clk); 105 | top->reset_l(reset_l); 106 | top->load(load); 107 | top->in_data(in_data); 108 | top->out_data(out_data); 109 | 110 | const std::unique_ptr rst{new reset("reset")}; 111 | 112 | rst->clk(clk); 113 | rst->reset_l(reset_l); 114 | 115 | const std::unique_ptr drv{new driver("driver")}; 116 | 117 | drv->clk(clk); 118 | drv->reset_l(reset_l); 119 | drv->load(load); 120 | drv->in_data(in_data); 121 | drv->out_data(out_data); 122 | drv->done(done); 123 | 124 | while (!Verilated::gotFinish()) { 125 | sc_start(1, SC_NS); 126 | if(done) 127 | break; 128 | } 129 | 130 | top->final(); 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /verilator/sample_sc_1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_1/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = ../common/top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | @echo 68 | @echo "-- Verilator tracing example" 69 | 70 | @echo 71 | @echo "-- VERILATE ----------------" 72 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 73 | 74 | @echo 75 | @echo "-- COMPILE -----------------" 76 | # To compile, we can either 77 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 78 | # 2. Or, run the make rules Verilator does: 79 | # $(MAKE) -j -C obj_dir -f Vtop.mk 80 | # 3. Or, call a submakefile where we can override the rules ourselves: 81 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 82 | 83 | @echo 84 | @echo "-- RUN ---------------------" 85 | obj_dir/Vtop 86 | @echo 87 | @echo "-- DONE --------------------" 88 | 89 | ###################################################################### 90 | # Other targets 91 | 92 | nosc: 93 | @echo 94 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 95 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 96 | @echo 97 | 98 | show-config: 99 | $(VERILATOR) -V 100 | 101 | maintainer-copy:: 102 | clean mostlyclean distclean maintainer-clean:: 103 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 104 | -------------------------------------------------------------------------------- /verilator/sample_sc_1/sc_main.cpp: -------------------------------------------------------------------------------- 1 | // For std::unique_ptr 2 | #include 3 | 4 | // SystemC global header 5 | #include 6 | 7 | // Include model header, generated from Verilating "top.v" 8 | #include "Vtop.h" 9 | 10 | SC_MODULE(driver) { 11 | public: 12 | 13 | SC_CTOR(driver) : 14 | clk("clk"), reset_l("reset_l"), out_data("out_data"), load("load"), in_data("in_data") 15 | { 16 | SC_THREAD(main); 17 | sensitive << clk.pos(); 18 | } 19 | 20 | sc_in clk; 21 | sc_in reset_l; 22 | sc_in out_data; 23 | sc_out load; 24 | sc_out in_data; 25 | 26 | private: 27 | void main(){ 28 | 29 | load = 0; 30 | in_data = 0; 31 | 32 | do { 33 | wait(); 34 | } while(!reset_l.read()); 35 | 36 | wait(); 37 | 38 | load = 1; 39 | in_data = 2; 40 | wait(); 41 | 42 | load = 0; 43 | 44 | while(1){ 45 | wait(); 46 | if(out_data == 0xff) 47 | break; 48 | } 49 | 50 | sc_stop(); 51 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 52 | } 53 | }; 54 | 55 | SC_MODULE(reset) { 56 | public: 57 | 58 | SC_CTOR(reset) : 59 | clk("clk"), reset_l("reset_l") 60 | { 61 | SC_THREAD(main); 62 | sensitive << clk.pos(); 63 | } 64 | 65 | sc_in clk; 66 | sc_out reset_l; 67 | 68 | private: 69 | void main(){ 70 | 71 | reset_l = 0; 72 | for(int i=0 ; i<3 ; i++) 73 | wait(); 74 | 75 | reset_l = 1; 76 | 77 | while(1){ 78 | wait(); 79 | 80 | } 81 | } 82 | }; 83 | 84 | int sc_main(int argc, char* argv[]) { 85 | 86 | if (false && argc && argv) {} 87 | 88 | Verilated::debug(0); 89 | Verilated::randReset(2); 90 | Verilated::commandArgs(argc, argv); 91 | 92 | ios::sync_with_stdio(); 93 | 94 | sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; 95 | 96 | sc_signal reset_l; 97 | sc_signal load; 98 | sc_signal in_data; 99 | sc_signal out_data; 100 | 101 | const std::unique_ptr top{new Vtop{"top"}}; 102 | 103 | top->clk(clk); 104 | top->reset_l(reset_l); 105 | top->load(load); 106 | top->in_data(in_data); 107 | top->out_data(out_data); 108 | 109 | const std::unique_ptr rst{new reset("reset")}; 110 | 111 | rst->clk(clk); 112 | rst->reset_l(reset_l); 113 | 114 | const std::unique_ptr drv{new driver("driver")}; 115 | 116 | drv->clk(clk); 117 | drv->reset_l(reset_l); 118 | drv->load(load); 119 | drv->in_data(in_data); 120 | drv->out_data(out_data); 121 | 122 | sc_start(); 123 | 124 | top->final(); 125 | 126 | cout << "done, time = " << sc_time_stamp() << endl; 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /verilator/sample_sc_2/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_2/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | @echo 68 | @echo "-- Verilator tracing example" 69 | 70 | @echo 71 | @echo "-- VERILATE ----------------" 72 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 73 | 74 | @echo 75 | @echo "-- COMPILE -----------------" 76 | # To compile, we can either 77 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 78 | # 2. Or, run the make rules Verilator does: 79 | # $(MAKE) -j -C obj_dir -f Vtop.mk 80 | # 3. Or, call a submakefile where we can override the rules ourselves: 81 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 82 | 83 | @echo 84 | @echo "-- RUN ---------------------" 85 | obj_dir/Vtop 86 | @echo 87 | @echo "-- DONE --------------------" 88 | 89 | ###################################################################### 90 | # Other targets 91 | 92 | nosc: 93 | @echo 94 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 95 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 96 | @echo 97 | 98 | show-config: 99 | $(VERILATOR) -V 100 | 101 | maintainer-copy:: 102 | clean mostlyclean distclean maintainer-clean:: 103 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 104 | -------------------------------------------------------------------------------- /verilator/sample_sc_2/sc_main.cpp: -------------------------------------------------------------------------------- 1 | // For std::unique_ptr 2 | #include 3 | 4 | // SystemC global header 5 | #include 6 | 7 | // Include model header, generated from Verilating "top.v" 8 | #include "Vtop.h" 9 | 10 | SC_MODULE(driver) { 11 | public: 12 | 13 | SC_CTOR(driver) : 14 | clk("clk"), reset_l("reset_l"), out_data("out_data"), load("load"), in_data("in_data") 15 | { 16 | SC_THREAD(main); 17 | sensitive << clk.pos(); 18 | } 19 | 20 | sc_in clk; 21 | sc_in reset_l; 22 | sc_in out_data; 23 | sc_out load; 24 | sc_out in_data; 25 | 26 | private: 27 | void main(){ 28 | 29 | load = 0; 30 | in_data = 0; 31 | 32 | do { 33 | wait(); 34 | } while(!reset_l.read()); 35 | 36 | wait(); 37 | 38 | load = 1; 39 | in_data = 2; 40 | wait(); 41 | 42 | load = 0; 43 | 44 | while(1){ 45 | wait(); 46 | if(out_data == 0xff) 47 | break; 48 | } 49 | 50 | sc_stop(); 51 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 52 | } 53 | }; 54 | 55 | SC_MODULE(reset) { 56 | public: 57 | 58 | SC_CTOR(reset) : 59 | clk("clk"), reset_l("reset_l") 60 | { 61 | SC_THREAD(main); 62 | sensitive << clk.pos(); 63 | } 64 | 65 | sc_in clk; 66 | sc_out reset_l; 67 | 68 | private: 69 | void main(){ 70 | 71 | reset_l = 0; 72 | for(int i=0 ; i<3 ; i++) 73 | wait(); 74 | 75 | reset_l = 1; 76 | 77 | while(1){ 78 | wait(); 79 | 80 | } 81 | } 82 | }; 83 | 84 | int sc_main(int argc, char* argv[]) { 85 | 86 | if (false && argc && argv) {} 87 | 88 | Verilated::debug(0); 89 | Verilated::randReset(2); 90 | Verilated::commandArgs(argc, argv); 91 | 92 | ios::sync_with_stdio(); 93 | 94 | sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; 95 | 96 | sc_signal reset_l; 97 | sc_signal load; 98 | sc_signal in_data; 99 | sc_signal out_data; 100 | 101 | const std::unique_ptr top{new Vtop{"top"}}; 102 | 103 | top->clk(clk); 104 | top->reset_l(reset_l); 105 | top->load(load); 106 | top->in_data(in_data); 107 | top->out_data(out_data); 108 | 109 | const std::unique_ptr rst{new reset("reset")}; 110 | 111 | rst->clk(clk); 112 | rst->reset_l(reset_l); 113 | 114 | const std::unique_ptr drv{new driver("driver")}; 115 | 116 | drv->clk(clk); 117 | drv->reset_l(reset_l); 118 | drv->load(load); 119 | drv->in_data(in_data); 120 | drv->out_data(out_data); 121 | 122 | sc_start(); 123 | 124 | top->final(); 125 | 126 | cout << "done, time = " << sc_time_stamp() << endl; 127 | return 0; 128 | } 129 | 130 | void sc_stop_for_hdl() 131 | { 132 | sc_stop(); 133 | } 134 | -------------------------------------------------------------------------------- /verilator/sample_sc_2/top.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | // This is intended to be a complex example of several features, please also 9 | // see the simpler examples/make_hello_c. 10 | 11 | `timescale 100ps/1ps 12 | 13 | module top 14 | ( 15 | // Declare some signals so we can see how I/O works 16 | input logic clk, 17 | input logic reset_l, 18 | 19 | output logic [7:0] out_data, 20 | input logic load, 21 | input logic [7:0] in_data 22 | ); 23 | 24 | import "DPI-C" function void sc_stop_for_hdl(); 25 | 26 | always_ff @(posedge clk) begin 27 | if(reset_l == 1'b0) 28 | out_data <= 8'h00; 29 | else if(load) begin 30 | out_data <= in_data; 31 | end 32 | else begin 33 | out_data <= out_data + 1'b1; 34 | end 35 | if(out_data == 8'hf0) begin 36 | $display("sc_stop_for_hdl at %m"); 37 | sc_stop_for_hdl(); 38 | end 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /verilator/sample_sc_3/.#top.v: -------------------------------------------------------------------------------- 1 | vengineer@LAPTOP-9KS38JCG.2726 -------------------------------------------------------------------------------- /verilator/sample_sc_3/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_3/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | #VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | #VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | @echo 68 | @echo "-- VERILATE ----------------" 69 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 70 | 71 | @echo 72 | @echo "-- COMPILE -----------------" 73 | # To compile, we can either 74 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 75 | # 2. Or, run the make rules Verilator does: 76 | # $(MAKE) -j -C obj_dir -f Vtop.mk 77 | # 3. Or, call a submakefile where we can override the rules ourselves: 78 | $(MAKE) -j -C obj_dir -f ../Makefile_obj 79 | 80 | @echo 81 | @echo "-- RUN ---------------------" 82 | obj_dir/Vtop 83 | @echo 84 | @echo "-- DONE --------------------" 85 | 86 | ###################################################################### 87 | # Other targets 88 | 89 | nosc: 90 | @echo 91 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 92 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 93 | @echo 94 | 95 | show-config: 96 | $(VERILATOR) -V 97 | 98 | maintainer-copy:: 99 | clean mostlyclean distclean maintainer-clean:: 100 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 101 | -------------------------------------------------------------------------------- /verilator/sample_sc_3/Makefile_obj: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | ####################################################################### 3 | # 4 | # DESCRIPTION: Verilator Example: Makefile for inside object directory 5 | # 6 | # This is executed in the object directory, and called by ../Makefile 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ####################################################################### 13 | 14 | default: Vtop 15 | 16 | # Include the rules made by Verilator 17 | include Vtop.mk 18 | 19 | # Use OBJCACHE (ccache) if using gmake and its installed 20 | COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 21 | 22 | ####################################################################### 23 | # Compile flags 24 | 25 | # Override some default compile flags 26 | CPPFLAGS += -MMD -MP 27 | CPPFLAGS += -DVL_DEBUG=1 28 | # SystemC isn't too clean 29 | CPPFLAGS += -Wno-deprecated 30 | # Turn on some more flags (when configured appropriately) 31 | # For testing inside Verilator, "configure --enable-ccwarn" will do this 32 | # automatically; otherwise you may want this unconditionally enabled 33 | ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users 34 | USER_CPPFLAGS_WALL += -W -Werror -Wall 35 | endif 36 | 37 | # If you build your own rules from scratch, note you need to include 38 | # SystemC as follows (Vtop.mk file includes verilated.mk with these 39 | # already). 40 | # CPPFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -I, $(SYSTEMC_INCLUDE)) 41 | # LDFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -L, $(SYSTEMC_LIBDIR)) 42 | 43 | # See the benchmarking section of bin/verilator. 44 | # Support class optimizations. This includes the tracing and symbol table. 45 | # SystemC takes minutes to optimize, thus it is off by default. 46 | OPT_SLOW = 47 | # Fast path optimizations. Most time is spent in these classes. 48 | OPT_FAST = -Os -fstrict-aliasing 49 | #OPT_FAST = -O 50 | #OPT_FAST = 51 | 52 | ####################################################################### 53 | # Linking final exe -- presumes have a sim_main.cpp 54 | 55 | # Special compile rule 56 | sim_main.o: sim_main.cpp $(VM_PREFIX).h 57 | 58 | ###################################################################### 59 | ###################################################################### 60 | # Automatically understand dependencies 61 | 62 | DEPS := $(wildcard *.d) 63 | ifneq ($(DEPS),) 64 | include $(DEPS) 65 | endif 66 | -------------------------------------------------------------------------------- /verilator/sample_sc_3/sc_main.cpp: -------------------------------------------------------------------------------- 1 | // For std::unique_ptr 2 | #include 3 | 4 | // SystemC global header 5 | #include 6 | 7 | // Include model header, generated from Verilating "top.v" 8 | #include "Vtop.h" 9 | 10 | SC_MODULE(driver) { 11 | public: 12 | 13 | SC_CTOR(driver) : 14 | clk("clk"), reset_l("reset_l"), out_data("out_data"), load("load"), in_data("in_data") 15 | { 16 | SC_THREAD(main); 17 | sensitive << clk.pos(); 18 | } 19 | 20 | sc_in clk; 21 | sc_out reset_l; 22 | sc_in out_data; 23 | sc_out load; 24 | sc_out in_data; 25 | 26 | private: 27 | void main(){ 28 | 29 | reset_l = 0; 30 | load = 0; 31 | in_data = 0; 32 | wait(); 33 | wait(); 34 | wait(); 35 | 36 | reset_l = 1; 37 | wait(); 38 | 39 | load = 1; 40 | in_data = 2; 41 | wait(); 42 | 43 | load = 0; 44 | 45 | while(1){ 46 | wait(); 47 | if(out_data == 0x10) 48 | break; 49 | } 50 | 51 | sc_stop(); 52 | } 53 | }; 54 | 55 | int sc_main(int argc, char* argv[]) { 56 | 57 | if (false && argc && argv) {} 58 | 59 | Verilated::debug(0); 60 | Verilated::randReset(2); 61 | Verilated::commandArgs(argc, argv); 62 | 63 | ios::sync_with_stdio(); 64 | 65 | sc_set_time_resolution(1, SC_PS); 66 | 67 | sc_clock clk{"clk", 10, SC_NS, 0.5, 1, SC_NS, true}; 68 | 69 | sc_signal reset_l; 70 | sc_signal load; 71 | sc_signal inc1, inc2; 72 | sc_signal in_data; 73 | sc_signal out_data; 74 | sc_signal out_data2; 75 | 76 | const std::unique_ptr top{new Vtop{"top"}}; 77 | const std::unique_ptr top2{new Vtop{"top2"}}; 78 | 79 | inc1 = 1; 80 | inc2 = 1; 81 | 82 | top->clk(clk); 83 | top->reset_l(reset_l); 84 | top->load(load); 85 | top->inc(inc1); 86 | top->in_data(in_data); 87 | top->out_data(out_data); 88 | 89 | top2->clk(clk); 90 | top2->reset_l(reset_l); 91 | top2->inc(inc2); 92 | top2->load(load); 93 | top2->in_data(out_data); 94 | top2->out_data(out_data2); 95 | 96 | const std::unique_ptr drv{new driver("driver")}; 97 | 98 | drv->clk(clk); 99 | drv->reset_l(reset_l); 100 | drv->load(load); 101 | drv->in_data(in_data); 102 | drv->out_data(out_data2); 103 | 104 | sc_start(); 105 | 106 | top->final(); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /verilator/sample_sc_3/top.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | // This is intended to be a complex example of several features, please also 9 | // see the simpler examples/make_hello_c. 10 | 11 | `timescale 100ps/1ps 12 | 13 | module top 14 | ( 15 | // Declare some signals so we can see how I/O works 16 | input logic clk, 17 | input logic reset_l, 18 | 19 | output logic [7:0] out_data, 20 | input logic load, 21 | input logic [7:0] inc, 22 | input logic [7:0] in_data 23 | ); 24 | 25 | always_ff @(posedge clk) begin 26 | if(reset_l == 1'b0) 27 | out_data <= 8'h00; 28 | else if(load) begin 29 | $display("%t : %m, in_data=%h", $time, in_data); 30 | out_data <= in_data; 31 | end 32 | else begin 33 | $display("%t : %m, out_data=%h", $time, out_data); 34 | out_data <= out_data + inc; 35 | end 36 | end 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /verilator/sample_sc_4/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_4/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = -CFLAGS -DVL_USER_STOP 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | @echo 68 | @echo "-- Verilator tracing example" 69 | 70 | @echo 71 | @echo "-- VERILATE ----------------" 72 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 73 | 74 | @echo 75 | @echo "-- COMPILE -----------------" 76 | # To compile, we can either 77 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 78 | # 2. Or, run the make rules Verilator does: 79 | # $(MAKE) -j -C obj_dir -f Vtop.mk 80 | # 3. Or, call a submakefile where we can override the rules ourselves: 81 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 82 | 83 | @echo 84 | @echo "-- RUN ---------------------" 85 | obj_dir/Vtop 86 | @echo 87 | @echo "-- DONE --------------------" 88 | 89 | ###################################################################### 90 | # Other targets 91 | 92 | nosc: 93 | @echo 94 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 95 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 96 | @echo 97 | 98 | show-config: 99 | $(VERILATOR) -V 100 | 101 | maintainer-copy:: 102 | clean mostlyclean distclean maintainer-clean:: 103 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 104 | -------------------------------------------------------------------------------- /verilator/sample_sc_4/log: -------------------------------------------------------------------------------- 1 | 2 | -- Verilator tracing example 3 | 4 | -- VERILATE ---------------- 5 | verilator -CFLAGS -DVL_USER_STOP -sc --exe -Os -x-assign 0 -Wall --trace --assert top.v sc_main.cpp 6 | 7 | -- COMPILE ----------------- 8 | make -j -C obj_dir -f ../../common/Makefile_obj 9 | make[1]: Entering directory '/mnt/c/Users/haray/home/verilator/All-of-SystemVerilog/verilator/sample_sc_4/obj_dir' 10 | g++ -I. -MMD -I/usr/local/verilator/v4.200/share/verilator/include -I/usr/local/verilator/v4.200/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=1 -DVM_TRACE=1 -DVM_TRACE_FST=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -DVL_USER_STOP -I/usr/local/systemc/2.3.3/include -std=gnu++14 -MMD -MP -DVL_DEBUG=1 -Wno-deprecated -Os -fstrict-aliasing -c -o sc_main.o ../sc_main.cpp 11 | /usr/bin/perl /usr/local/verilator/v4.200/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include Vtop.cpp Vtop__Trace.cpp Vtop__Slow.cpp Vtop__Syms.cpp Vtop__Trace__Slow.cpp > Vtop__ALL.cpp 12 | g++ -I. -MMD -I/usr/local/verilator/v4.200/share/verilator/include -I/usr/local/verilator/v4.200/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=1 -DVM_TRACE=1 -DVM_TRACE_FST=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -DVL_USER_STOP -I/usr/local/systemc/2.3.3/include -std=gnu++14 -MMD -MP -DVL_DEBUG=1 -Wno-deprecated -Os -fstrict-aliasing -c -o Vtop__ALL.o Vtop__ALL.cpp 13 | make[1]: *** [Vtop.mk:60: sc_main.o] Interrupt 14 | make[1]: *** [/usr/local/verilator/v4.200/share/verilator/include/verilated.mk:235: Vtop__ALL.o] Interrupt 15 | make: *** [Makefile:74: run] Interrupt 16 | -------------------------------------------------------------------------------- /verilator/sample_sc_4/sc_main.cpp: -------------------------------------------------------------------------------- 1 | // For std::unique_ptr 2 | #include 3 | 4 | // SystemC global header 5 | #include 6 | 7 | // Include model header, generated from Verilating "top.v" 8 | #include "Vtop.h" 9 | 10 | SC_MODULE(driver) { 11 | public: 12 | 13 | SC_CTOR(driver) : 14 | clk("clk"), reset_l("reset_l"), out_data("out_data"), load("load"), in_data("in_data") 15 | { 16 | SC_THREAD(main); 17 | sensitive << clk.pos(); 18 | } 19 | 20 | sc_in clk; 21 | sc_out reset_l; 22 | sc_in out_data; 23 | sc_out load; 24 | sc_out in_data; 25 | 26 | private: 27 | void main(){ 28 | 29 | reset_l = 0; 30 | load = 0; 31 | in_data = 0; 32 | wait(); 33 | wait(); 34 | wait(); 35 | 36 | reset_l = 1; 37 | wait(); 38 | 39 | load = 1; 40 | in_data = 2; 41 | wait(); 42 | 43 | load = 0; 44 | 45 | while(1){ 46 | wait(); 47 | if(out_data == 0xff) 48 | break; 49 | } 50 | 51 | sc_stop(); 52 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 53 | } 54 | }; 55 | 56 | int sc_main(int argc, char* argv[]) { 57 | 58 | if (false && argc && argv) {} 59 | 60 | Verilated::debug(0); 61 | Verilated::randReset(2); 62 | Verilated::commandArgs(argc, argv); 63 | 64 | ios::sync_with_stdio(); 65 | 66 | sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; 67 | 68 | sc_signal reset_l; 69 | sc_signal load; 70 | sc_signal in_data; 71 | sc_signal out_data; 72 | 73 | const std::unique_ptr top{new Vtop{"top"}}; 74 | 75 | top->clk(clk); 76 | top->reset_l(reset_l); 77 | top->load(load); 78 | top->in_data(in_data); 79 | top->out_data(out_data); 80 | 81 | const std::unique_ptr drv{new driver("driver")}; 82 | 83 | drv->clk(clk); 84 | drv->reset_l(reset_l); 85 | drv->load(load); 86 | drv->in_data(in_data); 87 | drv->out_data(out_data); 88 | 89 | sc_start(); 90 | 91 | top->final(); 92 | 93 | cout << "done, time = " << sc_time_stamp() << endl; 94 | return 0; 95 | } 96 | 97 | #ifdef VL_USER_STOP 98 | void vl_stop(const char *filename, int linenum, const char *hier) VL_MT_UNSAFE 99 | { 100 | sc_stop(); 101 | cout << "call vl_stop" << endl; 102 | } 103 | #endif 104 | 105 | -------------------------------------------------------------------------------- /verilator/sample_sc_4/top.v: -------------------------------------------------------------------------------- 1 | // DESCRIPTION: Verilator: Verilog example module 2 | // 3 | // This file ONLY is placed under the Creative Commons Public Domain, for 4 | // any use, without warranty, 2003 by Wilson Snyder. 5 | // SPDX-License-Identifier: CC0-1.0 6 | // ====================================================================== 7 | 8 | // This is intended to be a complex example of several features, please also 9 | // see the simpler examples/make_hello_c. 10 | 11 | `timescale 100ps/1ps 12 | 13 | module top 14 | ( 15 | // Declare some signals so we can see how I/O works 16 | input logic clk, 17 | input logic reset_l, 18 | 19 | output logic [7:0] out_data, 20 | input logic load, 21 | input logic [7:0] in_data 22 | ); 23 | 24 | always_ff @(posedge clk) begin 25 | if(reset_l == 1'b0) 26 | out_data <= 8'h00; 27 | else if(load) begin 28 | out_data <= in_data; 29 | end 30 | else begin 31 | out_data <= out_data + 1'b1; 32 | end 33 | if(out_data == 8'hf0) begin 34 | $stop(); 35 | end 36 | end 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = -CFLAGS -DVERILATOR 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | # Input files for Verilator 53 | VERILATOR_INPUT = top.v sc_main.cpp 54 | 55 | # Check if SC exists via a verilator call (empty if not) 56 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 57 | 58 | ###################################################################### 59 | 60 | ifneq ($(SYSTEMC_EXISTS),) 61 | default: run 62 | else 63 | default: nosc 64 | endif 65 | 66 | run: 67 | rm -rf Vtop.h 68 | @echo 69 | @echo "-- Verilator tracing example" 70 | 71 | @echo 72 | @echo "-- VERILATE ----------------" 73 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 74 | 75 | @echo 76 | @echo "-- COMPILE -----------------" 77 | # To compile, we can either 78 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 79 | # 2. Or, run the make rules Verilator does: 80 | # $(MAKE) -j -C obj_dir -f Vtop.mk 81 | # 3. Or, call a submakefile where we can override the rules ourselves: 82 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 83 | 84 | @echo 85 | @echo "-- RUN ---------------------" 86 | obj_dir/Vtop 87 | @echo 88 | @echo "-- DONE --------------------" 89 | 90 | ###################################################################### 91 | # Other targets 92 | 93 | nosc: 94 | @echo 95 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 96 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 97 | @echo 98 | 99 | show-config: 100 | $(VERILATOR) -V 101 | 102 | maintainer-copy:: 103 | clean mostlyclean distclean maintainer-clean:: 104 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 105 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/Makefile.questa: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | vsim -c -do run.do 4 | 5 | clean: 6 | rm -rf work transcript Vtop.h 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/Vtop.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCGENMOD_Vtop_ 2 | #define _SCGENMOD_Vtop_ 3 | 4 | #include "systemc.h" 5 | 6 | class Vtop : public sc_foreign_module 7 | { 8 | public: 9 | sc_in clk; 10 | sc_in reset; 11 | sc_in > addr; 12 | sc_in cs; 13 | sc_in rw; 14 | sc_in > data_in; 15 | sc_out ready; 16 | sc_out > data_out; 17 | 18 | 19 | Vtop(sc_module_name nm, const char* hdl_name, 20 | int num_generics, const char** generic_list) 21 | : sc_foreign_module(nm), 22 | clk("clk"), 23 | reset("reset"), 24 | addr("addr"), 25 | cs("cs"), 26 | rw("rw"), 27 | data_in("data_in"), 28 | ready("ready"), 29 | data_out("data_out") 30 | { 31 | elaborate_foreign_module(hdl_name, num_generics, generic_list); 32 | } 33 | ~Vtop() 34 | {} 35 | 36 | }; 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/run.do: -------------------------------------------------------------------------------- 1 | vlog -sv top.v 2 | scgenmod -bool -sc_uint Vtop > Vtop.h 3 | sccom -g sc_top.cpp 4 | sccom -link 5 | vsim -c sc_top -do "run -all" 6 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/sc_main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "sc_top.h" 3 | 4 | int sc_main(int argc, char* argv[]) { 5 | 6 | if (false && argc && argv) {} 7 | 8 | Verilated::debug(0); 9 | Verilated::randReset(2); 10 | Verilated::commandArgs(argc, argv); 11 | 12 | ios::sync_with_stdio(); 13 | 14 | const std::unique_ptr u_sc_top{new sc_top{"sc_top"}}; 15 | 16 | sc_start(); 17 | 18 | cout << "done, time = " << sc_time_stamp() << endl; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/sc_top.cpp: -------------------------------------------------------------------------------- 1 | #include "sc_top.h" 2 | #include 3 | 4 | 5 | SC_MODULE_EXPORT(sc_top); 6 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/sc_top.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | 5 | #ifdef VERILATOR 6 | #define UINT32(n) uint32_t 7 | #else 8 | #define UINT32(n) sc_uint 9 | #endif 10 | 11 | SC_MODULE(bfm) { 12 | public: 13 | 14 | SC_CTOR(bfm) : 15 | clk("clk"), reset("reset"), addr("addr"), cs("cs"), rw("rw"), data_in("data_in"), 16 | ready("ready"), data_out("data_out"), reset_done(false) 17 | { 18 | SC_THREAD(reset_task); 19 | sensitive << clk.pos(); 20 | 21 | SC_THREAD(main); 22 | sensitive << clk.pos(); 23 | } 24 | 25 | sc_in clk; 26 | sc_out reset; 27 | sc_out cs; 28 | sc_out rw; 29 | sc_in ready; 30 | sc_out addr; 31 | sc_out data_out; 32 | sc_in data_in; 33 | 34 | private: 35 | bool reset_done; 36 | 37 | void reset_task(){ 38 | reset.write(true); 39 | for(int i=0;i<4;i++) 40 | wait(); 41 | reset.write(false); 42 | wait(); 43 | cout << "done reset" << endl; 44 | reset_done = true; 45 | } 46 | 47 | uint32_t read(uint32_t addr_){ 48 | cs.write(true); 49 | rw.write(true); 50 | addr.write(addr_); 51 | while(!ready.read()){ 52 | wait(); 53 | } 54 | cs.write(false); 55 | addr.write(0x0); 56 | uint32_t data = data_in.read(); 57 | wait(); 58 | return data; 59 | } 60 | 61 | void write(uint32_t addr_, uint32_t data_){ 62 | cs.write(true); 63 | rw.write(false); 64 | addr.write(addr_); 65 | data_out.write(data_); 66 | while(!ready.read()){ 67 | wait(); 68 | } 69 | cs.write(false); 70 | addr.write(0x0); 71 | data_out.write(0x0); 72 | wait(); 73 | } 74 | 75 | void test_main(){ 76 | cout << "start test_main" << endl; 77 | write(0x200, 0x12345678); 78 | uint32_t data = read(0x200); 79 | if(data != 0x12345678) 80 | cout << "<>, compare error, data = 0x" << hex << data << endl; 81 | cout << "finish test_main" << endl; 82 | } 83 | 84 | void main(){ 85 | cs.write(false); 86 | rw.write(true); 87 | addr.write(0x00); 88 | data_out.write(0x00); 89 | 90 | while(!reset_done) 91 | wait(); 92 | 93 | test_main(); 94 | 95 | sc_stop(); 96 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 97 | } 98 | }; 99 | 100 | SC_MODULE(sc_top) { 101 | 102 | sc_clock clk; 103 | 104 | sc_signal reset; 105 | sc_signal cs; 106 | sc_signal rw; 107 | sc_signal ready; 108 | sc_signal addr; 109 | sc_signal data_in; 110 | sc_signal data_out; 111 | 112 | Vtop *u_top; 113 | bfm *u_bfm; 114 | 115 | SC_CTOR(sc_top) : 116 | clk("clk", 10, SC_NS, 0.5, 5, SC_NS, true), 117 | reset("reset"), cs("cs"), rw("rw"), addr("addr"), ready("ready"), data_in("data_in"), data_out("data_out") { 118 | 119 | #ifdef VERILATOR 120 | u_top = new Vtop{"top"}; 121 | #else 122 | u_top = new Vtop{"top", "Vtop", 0, NULL}; 123 | #endif 124 | 125 | u_top->clk(clk); 126 | u_top->reset(reset); 127 | u_top->cs(cs); 128 | u_top->rw(rw); 129 | u_top->addr(addr); 130 | u_top->data_in(data_in); 131 | u_top->ready(ready); 132 | u_top->data_out(data_out); 133 | 134 | u_bfm = new bfm("bfm"); 135 | 136 | u_bfm->clk(clk); 137 | u_bfm->reset(reset); 138 | u_bfm->cs(cs); 139 | u_bfm->rw(rw); 140 | u_bfm->addr(addr); 141 | u_bfm->data_in(data_out); 142 | u_bfm->ready(ready); 143 | u_bfm->data_out(data_in); 144 | } 145 | 146 | ~sc_top() { 147 | #ifdef VERILATOR 148 | u_top->final(); 149 | #endif 150 | delete u_top; 151 | delete u_bfm; 152 | } 153 | }; 154 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_0/top.v: -------------------------------------------------------------------------------- 1 | `ifdef VERILATOR 2 | module top 3 | `else 4 | module Vtop 5 | `endif 6 | ( 7 | input logic clk, 8 | input logic reset, 9 | 10 | /* verilator lint_off UNUSED */ 11 | input logic [15:0] addr, 12 | /* verilator lint_on UNUSED */ 13 | input logic cs, 14 | input logic rw, 15 | input logic [31:0] data_in, 16 | output logic ready, 17 | output logic [31:0] data_out 18 | ); 19 | 20 | localparam ram_size = (17'h10000>>2); 21 | /* verilator lint_off WIDTH */ 22 | logic [31:0] ram[ram_size]; 23 | /* verilator lint_on WIDTH */ 24 | 25 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 26 | 27 | always_ff @(posedge clk) begin 28 | if(reset == 1'b1) 29 | state <= STATE_IDLE; 30 | else if(cs == 1'b1 && state == STATE_IDLE) 31 | state <= STATE_RUN; 32 | else if(cs == 1'b1 && state == STATE_RUN) 33 | state <= STATE_DONE; 34 | else if(cs == 1'b0) 35 | state <= STATE_IDLE; 36 | end 37 | 38 | always_ff @(posedge clk) begin 39 | if(reset == 1'b1) begin 40 | data_out <= 32'h0000_0000; 41 | ready <= 1'b0; 42 | end 43 | else if(state == STATE_RUN) begin 44 | if(rw == 1'b1) 45 | data_out <= ram[addr[15:2]]; 46 | else 47 | ram[addr[15:2]] <= data_in; 48 | ready <= 1'b1; 49 | end 50 | else begin 51 | data_out <= 32'h0000_0000; 52 | ready <= 1'b0; 53 | end 54 | end 55 | 56 | endmodule 57 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = -CFLAGS -DVERILATOR 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | TEST ?= 1 53 | 54 | # Input files for Verilator 55 | VERILATOR_INPUT = top.v sc_main.cpp bfm.cpp test_$(TEST).cpp 56 | 57 | # Check if SC exists via a verilator call (empty if not) 58 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 59 | 60 | ###################################################################### 61 | 62 | ifneq ($(SYSTEMC_EXISTS),) 63 | default: run 64 | else 65 | default: nosc 66 | endif 67 | 68 | run: 69 | rm -rf Vtop.h 70 | @echo 71 | @echo "-- Verilator tracing example" 72 | 73 | @echo 74 | @echo "-- VERILATE ----------------" 75 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 76 | 77 | @echo 78 | @echo "-- COMPILE -----------------" 79 | # To compile, we can either 80 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 81 | # 2. Or, run the make rules Verilator does: 82 | # $(MAKE) -j -C obj_dir -f Vtop.mk 83 | # 3. Or, call a submakefile where we can override the rules ourselves: 84 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 85 | 86 | @echo 87 | @echo "-- RUN ---------------------" 88 | obj_dir/Vtop 89 | @echo 90 | @echo "-- DONE --------------------" 91 | 92 | ###################################################################### 93 | # Other targets 94 | 95 | nosc: 96 | @echo 97 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 98 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 99 | @echo 100 | 101 | show-config: 102 | $(VERILATOR) -V 103 | 104 | maintainer-copy:: 105 | clean mostlyclean distclean maintainer-clean:: 106 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 107 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/Makefile.questa: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | vsim -c -do run_1.do 4 | vsim -c -do run_2.do 5 | 6 | clean: 7 | rm -rf work transcript Vtop.h 8 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/Makefile.questa~: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | rm -rf work ; vsim -c -do run_1.do 4 | rm -rf work ; vsim -c -do run_2.do 5 | 6 | clean: 7 | rm -rf work transcript Vtop.h 8 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/bfm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "bfm.h" 4 | 5 | using namespace std; 6 | using namespace sc_core; 7 | 8 | bfm::bfm(sc_module_name name) : sc_module(name), 9 | clk("clk"), reset("reset"), addr("addr"), cs("cs"), rw("rw"), data_in("data_in"), 10 | ready("ready"), data_out("data_out"), reset_done(false) 11 | { 12 | SC_THREAD(reset_task); 13 | sensitive << clk.pos(); 14 | 15 | SC_THREAD(main); 16 | sensitive << clk.pos(); 17 | } 18 | 19 | void bfm::reset_task() 20 | { 21 | reset.write(true); 22 | for(int i=0;i<4;i++) 23 | wait(); 24 | reset.write(false); 25 | wait(); 26 | cout << "done reset" << endl; 27 | reset_done = true; 28 | } 29 | 30 | uint32_t bfm::read(uint32_t addr_) 31 | { 32 | cs.write(true); 33 | rw.write(true); 34 | addr.write(addr_); 35 | while(!ready.read()){ 36 | wait(); 37 | } 38 | cs.write(false); 39 | addr.write(0x0); 40 | uint32_t data = data_in.read(); 41 | wait(); 42 | return data; 43 | } 44 | 45 | void bfm::write(uint32_t addr_, uint32_t data_){ 46 | cs.write(true); 47 | rw.write(false); 48 | addr.write(addr_); 49 | data_out.write(data_); 50 | while(!ready.read()){ 51 | wait(); 52 | } 53 | cs.write(false); 54 | addr.write(0x0); 55 | data_out.write(0x0); 56 | wait(); 57 | } 58 | 59 | void bfm::main(){ 60 | cs.write(false); 61 | rw.write(true); 62 | addr.write(0x00); 63 | data_out.write(0x00); 64 | 65 | while(!reset_done) 66 | wait(); 67 | 68 | test_main(); 69 | 70 | sc_stop(); 71 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BFM_H 4 | #define BFM_H 5 | 6 | using namespace std; 7 | using namespace sc_core; 8 | using namespace sc_dt; 9 | 10 | SC_MODULE(bfm) { 11 | public: 12 | 13 | SC_CTOR(bfm); 14 | 15 | sc_in clk; 16 | sc_out reset; 17 | sc_out cs; 18 | sc_out rw; 19 | sc_in ready; 20 | #ifdef VERILATOR 21 | sc_out addr; 22 | sc_out data_out; 23 | sc_in data_in; 24 | #else 25 | sc_out> addr; 26 | sc_in> data_in; 27 | sc_out> data_out; 28 | #endif 29 | 30 | private: 31 | bool reset_done; 32 | 33 | void reset_task(); 34 | uint32_t read(uint32_t addr_); 35 | void write(uint32_t addr_, uint32_t data_); 36 | 37 | void test_main(); 38 | void main(); 39 | }; 40 | 41 | #endif // BFM_H 42 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/run_1.do: -------------------------------------------------------------------------------- 1 | if [file exists work] { 2 | vdel -all 3 | } 4 | 5 | vlog -sv top.v 6 | scgenmod -bool -sc_uint Vtop > Vtop.h 7 | sccom -g sc_top.cpp bfm.cpp test_1.cpp 8 | sccom -link 9 | vsim -c sc_top -do "run -all" 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/run_2.do: -------------------------------------------------------------------------------- 1 | if [file exists work] { 2 | vdel -all 3 | } 4 | 5 | vlog -sv top.v 6 | scgenmod -bool -sc_uint Vtop > Vtop.h 7 | sccom -g sc_top.cpp bfm.cpp test_2.cpp 8 | sccom -link 9 | vsim -c sc_top -do "run -all" 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/sc_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | #include "bfm.h" 5 | 6 | int sc_main(int argc, char* argv[]) { 7 | 8 | if (false && argc && argv) {} 9 | 10 | Verilated::debug(0); 11 | Verilated::randReset(2); 12 | Verilated::commandArgs(argc, argv); 13 | 14 | ios::sync_with_stdio(); 15 | 16 | sc_clock clk{"clk", 10, SC_NS, 0.5, 5, SC_NS, true}; 17 | 18 | sc_signal reset; 19 | sc_signal cs; 20 | sc_signal rw; 21 | sc_signal addr; 22 | sc_signal data_in; 23 | sc_signal ready; 24 | sc_signal data_out; 25 | 26 | const std::unique_ptr top{new Vtop{"top"}}; 27 | 28 | top->clk(clk); 29 | top->reset(reset); 30 | top->cs(cs); 31 | top->rw(rw); 32 | top->addr(addr); 33 | top->data_in(data_in); 34 | top->ready(ready); 35 | top->data_out(data_out); 36 | 37 | const std::unique_ptr u_bfm{new bfm("bfm")}; 38 | 39 | u_bfm->clk(clk); 40 | u_bfm->reset(reset); 41 | u_bfm->cs(cs); 42 | u_bfm->rw(rw); 43 | u_bfm->addr(addr); 44 | u_bfm->data_in(data_out); 45 | u_bfm->ready(ready); 46 | u_bfm->data_out(data_in); 47 | 48 | sc_start(); 49 | 50 | top->final(); 51 | 52 | cout << "done, time = " << sc_time_stamp() << endl; 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/sc_top.cpp: -------------------------------------------------------------------------------- 1 | #include "sc_top.h" 2 | #include 3 | 4 | 5 | SC_MODULE_EXPORT(sc_top); 6 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/sc_top.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | #include "bfm.h" 5 | 6 | SC_MODULE(sc_top) { 7 | 8 | sc_clock clk; 9 | 10 | sc_signal reset; 11 | sc_signal cs; 12 | sc_signal rw; 13 | sc_signal ready; 14 | #ifdef VERILATOR 15 | sc_signal addr; 16 | sc_signal data_in; 17 | sc_signal data_out; 18 | #else 19 | sc_signal> addr; 20 | sc_signal> data_in; 21 | sc_signal> data_out; 22 | #endif 23 | 24 | Vtop *u_top; 25 | bfm *u_bfm; 26 | 27 | SC_CTOR(sc_top) : 28 | clk("clk", 10, SC_NS, 0.5, 5, SC_NS, true), 29 | reset("reset"), cs("cs"), rw("rw"), addr("addr"), ready("ready"), data_in("data_in"), data_out("data_out") { 30 | 31 | #ifdef VERILATOR 32 | u_top = new Vtop{"top"}; 33 | #else 34 | u_top = new Vtop{"top", "Vtop", 0, NULL}; 35 | #endif 36 | 37 | u_top->clk(clk); 38 | u_top->reset(reset); 39 | u_top->cs(cs); 40 | u_top->rw(rw); 41 | u_top->addr(addr); 42 | u_top->data_in(data_in); 43 | u_top->ready(ready); 44 | u_top->data_out(data_out); 45 | 46 | u_bfm = new bfm("bfm"); 47 | 48 | u_bfm->clk(clk); 49 | u_bfm->reset(reset); 50 | u_bfm->cs(cs); 51 | u_bfm->rw(rw); 52 | u_bfm->addr(addr); 53 | u_bfm->data_in(data_out); 54 | u_bfm->ready(ready); 55 | u_bfm->data_out(data_in); 56 | } 57 | 58 | ~sc_top() { 59 | #ifdef VERILATOR 60 | u_top->final(); 61 | #endif 62 | delete u_top; 63 | delete u_bfm; 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/test_1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | cout << "start test_main" << endl; 6 | write(0x200, 0x12345678); 7 | uint32_t data = read(0x200); 8 | if(data != 0x12345678) 9 | cout << "<>, compare error, data = 0x" << hex << data << endl; 10 | cout << "finish test_main" << endl; 11 | } 12 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/test_2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | uint32_t exp[0x10000>>2]; 6 | cout << "start test_main" << endl; 7 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 8 | exp[addr>>2] = rand(); 9 | write(addr, exp[addr>>2]); 10 | } 11 | cout << "done write" << endl; 12 | 13 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 14 | uint32_t data = read(addr); 15 | if(data != exp[addr>>2]) 16 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 17 | } 18 | 19 | cout << "finish test_main" << endl; 20 | } 21 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_1/top.v: -------------------------------------------------------------------------------- 1 | `ifdef VERILATOR 2 | module top 3 | `else 4 | module Vtop 5 | `endif 6 | ( 7 | input logic clk, 8 | input logic reset, 9 | 10 | /* verilator lint_off UNUSED */ 11 | input logic [15:0] addr, 12 | /* verilator lint_on UNUSED */ 13 | input logic cs, 14 | input logic rw, 15 | input logic [31:0] data_in, 16 | output logic ready, 17 | output logic [31:0] data_out 18 | ); 19 | 20 | localparam ram_size = (17'h10000>>2); 21 | 22 | /* verilator lint_off WIDTH */ 23 | logic [31:0] ram[ram_size]; 24 | /* verilator lint_on WIDTH */ 25 | 26 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 27 | 28 | always_ff @(posedge clk) begin 29 | if(reset == 1'b1) 30 | state <= STATE_IDLE; 31 | else if(cs == 1'b1 && state == STATE_IDLE) 32 | state <= STATE_RUN; 33 | else if(cs == 1'b1 && state == STATE_RUN) 34 | state <= STATE_DONE; 35 | else if(cs == 1'b0) 36 | state <= STATE_IDLE; 37 | end 38 | 39 | always_ff @(posedge clk) begin 40 | if(reset == 1'b1) begin 41 | data_out <= 32'h0000_0000; 42 | ready <= 1'b0; 43 | end 44 | else if(state == STATE_RUN) begin 45 | if(rw == 1'b1) 46 | data_out <= ram[addr[15:2]]; 47 | else 48 | ram[addr[15:2]] <= data_in; 49 | ready <= 1'b1; 50 | end 51 | else begin 52 | data_out <= 32'h0000_0000; 53 | ready <= 1'b0; 54 | end 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | FST ?= 0 43 | ifeq ($(FST),1) 44 | VERILATOR_FLAGS += --trace-fst -CFLAGS -DFST 45 | else 46 | VERILATOR_FLAGS += --trace 47 | endif 48 | # Check SystemVerilog assertions 49 | VERILATOR_FLAGS += --assert 50 | # Generate coverage analysis 51 | #VERILATOR_FLAGS += --coverage 52 | # Run Verilator in debug mode 53 | # VERILATOR_FLAGS += --debug 54 | # Add this trace to get a backtrace in gdb 55 | #VERILATOR_FLAGS += --gdbbt 56 | 57 | TEST ?= 1 58 | 59 | # Input files for Verilator 60 | VERILATOR_INPUT = top.v sc_main.cpp bfm.cpp test_$(TEST).cpp 61 | 62 | # Check if SC exists via a verilator call (empty if not) 63 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 64 | 65 | ###################################################################### 66 | 67 | ifneq ($(SYSTEMC_EXISTS),) 68 | default: run 69 | else 70 | default: nosc 71 | endif 72 | 73 | run: 74 | @echo 75 | @echo "-- VERILATE ----------------" 76 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 77 | 78 | @echo 79 | @echo "-- COMPILE -----------------" 80 | # To compile, we can either 81 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 82 | # 2. Or, run the make rules Verilator does: 83 | # $(MAKE) -j -C obj_dir -f Vtop.mk 84 | # 3. Or, call a submakefile where we can override the rules ourselves: 85 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 86 | 87 | @echo 88 | @echo "-- RUN ---------------------" 89 | obj_dir/Vtop +trace 90 | @echo 91 | @echo "-- DONE --------------------" 92 | 93 | ###################################################################### 94 | # Other targets 95 | 96 | nosc: 97 | @echo 98 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 99 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 100 | @echo 101 | 102 | show-config: 103 | $(VERILATOR) -V 104 | 105 | maintainer-copy:: 106 | clean mostlyclean distclean maintainer-clean:: 107 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 108 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/bfm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "bfm.h" 4 | 5 | using namespace std; 6 | using namespace sc_core; 7 | 8 | bfm::bfm(sc_module_name name) : sc_module(name), 9 | clk("clk"), reset("reset"), addr("addr"), cs("cs"), rw("rw"), data_in("data_in"), 10 | ready("ready"), data_out("data_out"), reset_done(false) 11 | { 12 | SC_THREAD(reset_task); 13 | sensitive << clk.pos(); 14 | 15 | SC_THREAD(main); 16 | sensitive << clk.pos(); 17 | } 18 | 19 | void bfm::reset_task() 20 | { 21 | reset.write(true); 22 | for(int i=0;i<4;i++) 23 | wait(); 24 | reset.write(false); 25 | wait(); 26 | cout << "done reset" << endl; 27 | reset_done = true; 28 | } 29 | 30 | uint32_t bfm::read(uint32_t addr_) 31 | { 32 | cs.write(true); 33 | rw.write(true); 34 | addr.write(addr_); 35 | while(!ready.read()){ 36 | wait(); 37 | } 38 | cs.write(false); 39 | addr.write(0x0); 40 | uint32_t data = data_in.read(); 41 | wait(); 42 | return data; 43 | } 44 | 45 | void bfm::write(uint32_t addr_, uint32_t data_){ 46 | cs.write(true); 47 | rw.write(false); 48 | addr.write(addr_); 49 | data_out.write(data_); 50 | while(!ready.read()){ 51 | wait(); 52 | } 53 | cs.write(false); 54 | addr.write(0x0); 55 | data_out.write(0x0); 56 | wait(); 57 | } 58 | 59 | void bfm::main(){ 60 | cs.write(false); 61 | rw.write(true); 62 | addr.write(0x00); 63 | data_out.write(0x00); 64 | 65 | while(!reset_done) 66 | wait(); 67 | 68 | test_main(); 69 | 70 | sc_stop(); 71 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BFM_H 4 | #define BFM_H 5 | 6 | using namespace std; 7 | using namespace sc_core; 8 | 9 | SC_MODULE(bfm) { 10 | public: 11 | 12 | SC_CTOR(bfm); 13 | 14 | sc_in clk; 15 | sc_out reset; 16 | sc_out addr; 17 | sc_out cs; 18 | sc_out rw; 19 | sc_out data_out; 20 | sc_in ready; 21 | sc_in data_in; 22 | 23 | private: 24 | bool reset_done; 25 | 26 | void reset_task(); 27 | uint32_t read(uint32_t addr_); 28 | void write(uint32_t addr_, uint32_t data_); 29 | 30 | void test_main(); 31 | void main(); 32 | }; 33 | 34 | #endif // BFM_H 35 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/sc_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | #include "bfm.h" 5 | 6 | #ifdef FST 7 | #include "verilated_fst_sc.h" 8 | #else 9 | #include "verilated_vcd_sc.h" 10 | #endif 11 | 12 | int sc_main(int argc, char* argv[]) { 13 | 14 | if (false && argc && argv) {} 15 | 16 | Verilated::debug(0); 17 | Verilated::randReset(2); 18 | Verilated::commandArgs(argc, argv); 19 | 20 | ios::sync_with_stdio(); 21 | 22 | sc_clock clk{"clk", 10, SC_NS, 0.5, 5, SC_NS, true}; 23 | 24 | sc_signal reset; 25 | sc_signal cs; 26 | sc_signal rw; 27 | sc_signal addr; 28 | sc_signal data_in; 29 | sc_signal ready; 30 | sc_signal data_out; 31 | 32 | const std::unique_ptr top{new Vtop{"top"}}; 33 | 34 | top->clk(clk); 35 | top->reset(reset); 36 | top->cs(cs); 37 | top->rw(rw); 38 | top->addr(addr); 39 | top->data_in(data_in); 40 | top->ready(ready); 41 | top->data_out(data_out); 42 | 43 | const std::unique_ptr u_bfm{new bfm("bfm")}; 44 | 45 | u_bfm->clk(clk); 46 | u_bfm->reset(reset); 47 | u_bfm->cs(cs); 48 | u_bfm->rw(rw); 49 | u_bfm->addr(addr); 50 | u_bfm->data_in(data_out); 51 | u_bfm->ready(ready); 52 | u_bfm->data_out(data_in); 53 | 54 | Verilated::traceEverOn(true); 55 | // If verilator was invoked with --trace argument, 56 | // and if at run time passed the +trace argument, turn on tracing 57 | #ifdef FST 58 | VerilatedFstSc* tfp = NULL; 59 | const char* flag = Verilated::commandArgsPlusMatch("trace"); 60 | if (flag && 0 == strcmp(flag, "+trace")) { 61 | tfp = new VerilatedFstSc; 62 | top->trace(tfp,99); 63 | tfp->open("vlt_dump.fst"); 64 | } 65 | #else 66 | VerilatedVcdSc* tfp = NULL; 67 | const char* flag = Verilated::commandArgsPlusMatch("trace"); 68 | if (flag && 0 == strcmp(flag, "+trace")) { 69 | tfp = new VerilatedVcdSc; 70 | top->trace(tfp,99); 71 | tfp->open("vlt_dump.vcd"); 72 | } 73 | #endif 74 | sc_start(); 75 | 76 | top->final(); 77 | 78 | if(tfp) { 79 | tfp->flush(); 80 | tfp->close(); 81 | tfp = NULL; 82 | } 83 | 84 | cout << "done, time = " << sc_time_stamp() << endl; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/test_1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | cout << "start test_main" << endl; 6 | write(0x200, 0x12345678); 7 | uint32_t data = read(0x200); 8 | if(data != 0x12345678) 9 | cout << "<>, compare error, data = 0x" << hex << data << endl; 10 | cout << "finish test_main" << endl; 11 | } 12 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/test_2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | uint32_t exp[0x10000>>2]; 6 | cout << "start test_main" << endl; 7 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 8 | exp[addr>>2] = rand(); 9 | write(addr, exp[addr>>2]); 10 | } 11 | cout << "done write" << endl; 12 | 13 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 14 | uint32_t data = read(addr); 15 | if(data != exp[addr>>2]) 16 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 17 | } 18 | 19 | cout << "finish test_main" << endl; 20 | } 21 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_2/top.v: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | 6 | /* verilator lint_off UNUSED */ 7 | input logic [15:0] addr, 8 | /* verilator lint_on UNUSED */ 9 | input logic cs, 10 | input logic rw, 11 | input logic [31:0] data_in, 12 | output logic ready, 13 | output logic [31:0] data_out 14 | ); 15 | 16 | localparam ram_size = (17'h10000>>2); 17 | 18 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 19 | 20 | always_ff @(posedge clk) begin 21 | if(reset == 1'b1) 22 | state <= STATE_IDLE; 23 | else if(cs == 1'b1 && state == STATE_IDLE) 24 | state <= STATE_RUN; 25 | else if(cs == 1'b1 && state == STATE_RUN) 26 | state <= STATE_DONE; 27 | else if(cs == 1'b0) 28 | state <= STATE_IDLE; 29 | end 30 | 31 | always_ff @(posedge clk) begin 32 | if(reset == 1'b1) begin 33 | data_out <= 32'h0000_0000; 34 | ready <= 1'b0; 35 | end 36 | else if(state == STATE_RUN) begin 37 | if(rw == 1'b1) 38 | data_out <= ram[addr[15:2]]; 39 | else 40 | ram[addr[15:2]] <= data_in; 41 | ready <= 1'b1; 42 | end 43 | else begin 44 | data_out <= 32'h0000_0000; 45 | ready <= 1'b0; 46 | end 47 | end 48 | 49 | /* verilator lint_off WIDTH */ 50 | logic [31:0] ram[ram_size]; 51 | /* verilator lint_on WIDTH */ 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = -CFLAGS -DVL_USER_STOP 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | TEST ?= 1 53 | 54 | # Input files for Verilator 55 | VERILATOR_INPUT = top.v sc_main.cpp bfm.cpp test_$(TEST).cpp 56 | 57 | # Check if SC exists via a verilator call (empty if not) 58 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 59 | 60 | ###################################################################### 61 | 62 | ifneq ($(SYSTEMC_EXISTS),) 63 | default: run 64 | else 65 | default: nosc 66 | endif 67 | 68 | run: 69 | @echo 70 | @echo "-- Verilator tracing example" 71 | 72 | @echo 73 | @echo "-- VERILATE ----------------" 74 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 75 | 76 | @echo 77 | @echo "-- COMPILE -----------------" 78 | # To compile, we can either 79 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 80 | # 2. Or, run the make rules Verilator does: 81 | # $(MAKE) -j -C obj_dir -f Vtop.mk 82 | # 3. Or, call a submakefile where we can override the rules ourselves: 83 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 84 | 85 | @echo 86 | @echo "-- RUN ---------------------" 87 | obj_dir/Vtop 88 | @echo 89 | @echo "-- DONE --------------------" 90 | 91 | ###################################################################### 92 | # Other targets 93 | 94 | nosc: 95 | @echo 96 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 97 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 98 | @echo 99 | 100 | show-config: 101 | $(VERILATOR) -V 102 | 103 | maintainer-copy:: 104 | clean mostlyclean distclean maintainer-clean:: 105 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 106 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/bfm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "bfm.h" 4 | 5 | using namespace std; 6 | using namespace sc_core; 7 | 8 | bfm::bfm(sc_module_name name) : sc_module(name), 9 | clk("clk"), reset("reset"), addr("addr"), cs("cs"), rw("rw"), data_in("data_in"), 10 | ready("ready"), data_out("data_out"), reset_done(false) 11 | { 12 | SC_THREAD(reset_task); 13 | sensitive << clk.pos(); 14 | 15 | SC_THREAD(main); 16 | sensitive << clk.pos(); 17 | } 18 | 19 | void bfm::reset_task() 20 | { 21 | reset.write(true); 22 | for(int i=0;i<4;i++) 23 | wait(); 24 | reset.write(false); 25 | wait(); 26 | cout << "done reset" << endl; 27 | reset_done = true; 28 | } 29 | 30 | uint32_t bfm::read(uint32_t addr_) 31 | { 32 | cs.write(true); 33 | rw.write(true); 34 | addr.write(addr_); 35 | while(!ready.read()){ 36 | wait(); 37 | } 38 | cs.write(false); 39 | addr.write(0x0); 40 | uint32_t data = data_in.read(); 41 | wait(); 42 | return data; 43 | } 44 | 45 | void bfm::write(uint32_t addr_, uint32_t data_){ 46 | cs.write(true); 47 | rw.write(false); 48 | addr.write(addr_); 49 | data_out.write(data_); 50 | while(!ready.read()){ 51 | wait(); 52 | } 53 | cs.write(false); 54 | addr.write(0x0); 55 | data_out.write(0x0); 56 | wait(); 57 | } 58 | 59 | void bfm::main(){ 60 | cs.write(false); 61 | rw.write(true); 62 | addr.write(0x00); 63 | data_out.write(0x00); 64 | 65 | while(!reset_done) 66 | wait(); 67 | 68 | test_main(); 69 | 70 | sc_stop(); 71 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BFM_H 4 | #define BFM_H 5 | 6 | using namespace std; 7 | using namespace sc_core; 8 | 9 | SC_MODULE(bfm) { 10 | public: 11 | 12 | SC_CTOR(bfm); 13 | 14 | sc_in clk; 15 | sc_out reset; 16 | sc_out addr; 17 | sc_out cs; 18 | sc_out rw; 19 | sc_out data_out; 20 | sc_in ready; 21 | sc_in data_in; 22 | 23 | private: 24 | bool reset_done; 25 | 26 | void reset_task(); 27 | uint32_t read(uint32_t addr_); 28 | void write(uint32_t addr_, uint32_t data_); 29 | 30 | void test_main(); 31 | void main(); 32 | }; 33 | 34 | #endif // BFM_H 35 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/sc_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | #include "bfm.h" 5 | 6 | int sc_main(int argc, char* argv[]) { 7 | 8 | if (false && argc && argv) {} 9 | 10 | Verilated::debug(0); 11 | Verilated::randReset(2); 12 | Verilated::commandArgs(argc, argv); 13 | 14 | ios::sync_with_stdio(); 15 | 16 | sc_clock clk{"clk", 10, SC_NS, 0.5, 5, SC_NS, true}; 17 | 18 | sc_signal reset; 19 | sc_signal cs; 20 | sc_signal rw; 21 | sc_signal addr; 22 | sc_signal data_in; 23 | sc_signal ready; 24 | sc_signal data_out; 25 | 26 | const std::unique_ptr top{new Vtop{"top"}}; 27 | 28 | top->clk(clk); 29 | top->reset(reset); 30 | top->cs(cs); 31 | top->rw(rw); 32 | top->addr(addr); 33 | top->data_in(data_in); 34 | top->ready(ready); 35 | top->data_out(data_out); 36 | 37 | const std::unique_ptr u_bfm{new bfm("bfm")}; 38 | 39 | u_bfm->clk(clk); 40 | u_bfm->reset(reset); 41 | u_bfm->cs(cs); 42 | u_bfm->rw(rw); 43 | u_bfm->addr(addr); 44 | u_bfm->data_in(data_out); 45 | u_bfm->ready(ready); 46 | u_bfm->data_out(data_in); 47 | 48 | sc_start(); 49 | 50 | top->final(); 51 | 52 | cout << "done, time = " << sc_time_stamp() << endl; 53 | return 0; 54 | } 55 | 56 | #ifdef VL_USER_STOP 57 | void vl_stop(const char *filename, int linenum, const char *hier) VL_MT_UNSAFE 58 | { 59 | sc_stop(); 60 | cout << "call vl_stop" << endl; 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/test_1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | cout << "start test_main" << endl; 6 | write(0x200, 0x12345678); 7 | uint32_t data = read(0x200); 8 | if(data != 0x12345678) 9 | cout << "<>, compare error, data = 0x" << hex << data << endl; 10 | cout << "finish test_main" << endl; 11 | } 12 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/test_2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | void bfm::test_main(){ 5 | uint32_t exp[0x10000>>2]; 6 | cout << "start test_main" << endl; 7 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 8 | exp[addr>>2] = rand(); 9 | write(addr, exp[addr>>2]); 10 | } 11 | cout << "done write" << endl; 12 | 13 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 14 | uint32_t data = read(addr); 15 | if(data != exp[addr>>2]) 16 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 17 | } 18 | 19 | cout << "finish test_main" << endl; 20 | } 21 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/test_3.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | #include "svdpi.h" 5 | 6 | extern "C" { 7 | extern int direct_read(int addr_); 8 | extern void direct_write(int addr_, int data_); 9 | } 10 | 11 | uint32_t direct_top_read(uint32_t addr){ 12 | svScope scope = svSetScope(svGetScopeFromName("top.top")); 13 | int data = direct_read((int)addr); 14 | svSetScope(scope); 15 | return (uint32_t)data; 16 | } 17 | 18 | void direct_top_write(uint32_t addr, uint32_t data){ 19 | svScope scope = svSetScope(svGetScopeFromName("top.top")); 20 | direct_write((int)addr, (int)data); 21 | svSetScope(scope); 22 | } 23 | 24 | void bfm::test_main(){ 25 | uint32_t exp[0x10000>>2]; 26 | cout << "start test_main" << endl; 27 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 28 | exp[addr>>2] = rand(); 29 | direct_top_write(addr, exp[addr>>2]); 30 | } 31 | cout << "done write" << endl; 32 | 33 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 34 | uint32_t data = direct_top_read(addr); 35 | if(data != exp[addr>>2]) 36 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 37 | } 38 | 39 | cout << "finish test_main" << endl; 40 | } 41 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_3/top.v: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | 6 | /* verilator lint_off UNUSED */ 7 | input logic [15:0] addr, 8 | /* verilator lint_on UNUSED */ 9 | input logic cs, 10 | input logic rw, 11 | input logic [31:0] data_in, 12 | output logic ready, 13 | output logic [31:0] data_out 14 | ); 15 | 16 | localparam ram_size = (17'h10000>>2); 17 | 18 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 19 | 20 | always_ff @(posedge clk) begin 21 | if(reset == 1'b1) 22 | state <= STATE_IDLE; 23 | else if(cs == 1'b1 && state == STATE_IDLE) 24 | state <= STATE_RUN; 25 | else if(cs == 1'b1 && state == STATE_RUN) 26 | state <= STATE_DONE; 27 | else if(cs == 1'b0) 28 | state <= STATE_IDLE; 29 | end 30 | 31 | always_ff @(posedge clk) begin 32 | if(reset == 1'b1) begin 33 | data_out <= 32'h0000_0000; 34 | ready <= 1'b0; 35 | end 36 | else if(state == STATE_RUN) begin 37 | if(rw == 1'b1) 38 | data_out <= ram[addr[15:2]]; 39 | else 40 | ram[addr[15:2]] <= data_in; 41 | ready <= 1'b1; 42 | end 43 | else begin 44 | data_out <= 32'h0000_0000; 45 | ready <= 1'b0; 46 | end 47 | end 48 | 49 | /* verilator lint_off WIDTH */ 50 | logic [31:0] ram[ram_size]; 51 | /* verilator lint_on WIDTH */ 52 | 53 | export "DPI-C" function direct_read; 54 | export "DPI-C" function direct_write; 55 | export "DPI-C" function direct_write_integer; 56 | 57 | function automatic void address_check(input int addr_); 58 | if((addr_>>2)>ram_size) begin 59 | $display("write, address range error at %h", addr_); 60 | $stop; 61 | end 62 | 63 | if((addr_ & 32'h3) != 32'h0) begin 64 | $display("write, address boundary error at %h", addr_); 65 | $stop; 66 | end 67 | endfunction : address_check 68 | 69 | function int direct_read(input int addr_); 70 | int data_; 71 | address_check(addr_); 72 | data_ = ram[addr_>>2]; 73 | return data_; 74 | endfunction : direct_read 75 | 76 | function void direct_write(input int addr_, input int data_); 77 | address_check(addr_); 78 | ram[addr_>>2] = data_; 79 | endfunction : direct_write 80 | 81 | function void direct_write_integer(input integer addr_, input integer data_); 82 | address_check(addr_); 83 | ram[addr_>>2] = data_; 84 | endfunction : direct_write_integer 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/.gitignore: -------------------------------------------------------------------------------- 1 | *.dmp 2 | *.log 3 | *.csrc 4 | *.vcd 5 | obj_* 6 | logs 7 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # DESCRIPTION: Verilator Example: Small Makefile 4 | # 5 | # This calls the object directory makefile. That allows the objects to 6 | # be placed in the "current directory" which simplifies the Makefile. 7 | # 8 | # This file ONLY is placed under the Creative Commons Public Domain, for 9 | # any use, without warranty, 2020 by Wilson Snyder. 10 | # SPDX-License-Identifier: CC0-1.0 11 | # 12 | ###################################################################### 13 | # Check for sanity to avoid later confusion 14 | 15 | ifneq ($(words $(CURDIR)),1) 16 | $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') 17 | endif 18 | 19 | ###################################################################### 20 | # Set up variables 21 | 22 | # If $VERILATOR_ROOT isn't in the environment, we assume it is part of a 23 | # package install, and verilator is in your path. Otherwise find the 24 | # binary relative to $VERILATOR_ROOT (such as when inside the git sources). 25 | ifeq ($(VERILATOR_ROOT),) 26 | VERILATOR = verilator 27 | else 28 | export VERILATOR_ROOT 29 | VERILATOR = $(VERILATOR_ROOT)/bin/verilator 30 | endif 31 | 32 | VERILATOR_FLAGS = -CFLAGS -DVL_USER_STOP -CFLAGS -DVERILATOR 33 | # Generate SystemC in executable form 34 | VERILATOR_FLAGS += -sc --exe 35 | # Generate makefile dependencies (not shown as complicates the Makefile) 36 | #VERILATOR_FLAGS += -MMD 37 | # Optimize 38 | VERILATOR_FLAGS += -Os -x-assign 0 39 | # Warn abount lint issues; may not want this on less solid designs 40 | VERILATOR_FLAGS += -Wall 41 | # Make waveforms 42 | VERILATOR_FLAGS += --trace 43 | # Check SystemVerilog assertions 44 | VERILATOR_FLAGS += --assert 45 | # Generate coverage analysis 46 | #VERILATOR_FLAGS += --coverage 47 | # Run Verilator in debug mode 48 | # VERILATOR_FLAGS += --debug 49 | # Add this trace to get a backtrace in gdb 50 | #VERILATOR_FLAGS += --gdbbt 51 | 52 | TEST ?= 1 53 | 54 | # Input files for Verilator 55 | VERILATOR_INPUT = top.v sc_main.cpp bfm.cpp bfm_api.cpp test_$(TEST).cpp 56 | 57 | # Check if SC exists via a verilator call (empty if not) 58 | SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) 59 | 60 | ###################################################################### 61 | 62 | ifneq ($(SYSTEMC_EXISTS),) 63 | default: run 64 | else 65 | default: nosc 66 | endif 67 | 68 | run: 69 | rm -rf Vtop.h 70 | @echo 71 | @echo "-- Verilator tracing example" 72 | 73 | @echo 74 | @echo "-- VERILATE ----------------" 75 | $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) 76 | 77 | @echo 78 | @echo "-- COMPILE -----------------" 79 | # To compile, we can either 80 | # 1. Pass --build to Verilator by editing VERILATOR_FLAGS above. 81 | # 2. Or, run the make rules Verilator does: 82 | # $(MAKE) -j -C obj_dir -f Vtop.mk 83 | # 3. Or, call a submakefile where we can override the rules ourselves: 84 | $(MAKE) -j -C obj_dir -f ../../common/Makefile_obj 85 | 86 | @echo 87 | @echo "-- RUN ---------------------" 88 | obj_dir/Vtop 89 | @echo 90 | @echo "-- DONE --------------------" 91 | 92 | ###################################################################### 93 | # Other targets 94 | 95 | nosc: 96 | @echo 97 | @echo "%Skip: SYSTEMC_INCLUDE not in environment" 98 | @echo "(If you have SystemC see the README, and rebuild Verilator)" 99 | @echo 100 | 101 | show-config: 102 | $(VERILATOR) -V 103 | 104 | maintainer-copy:: 105 | clean mostlyclean distclean maintainer-clean:: 106 | -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core 107 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/Makefile.questa: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | vsim -c -do run_1.do 4 | vsim -c -do run_2.do 5 | vsim -c -do run_3.do 6 | 7 | clean: 8 | rm -rf work transcript Vtop.h 9 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/Makefile.questa~: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | rm -rf work ; vsim -c -do run_1.do 4 | rm -rf work ; vsim -c -do run_2.do 5 | rm -rf work ; vsim -c -do run_3.do 6 | 7 | clean: 8 | rm -rf work transcript Vtop.h 9 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/Vtop.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCGENMOD_Vtop_ 2 | #define _SCGENMOD_Vtop_ 3 | 4 | #include "systemc.h" 5 | 6 | class Vtop : public sc_foreign_module 7 | { 8 | public: 9 | sc_in clk; 10 | sc_in reset; 11 | sc_in > addr; 12 | sc_in cs; 13 | sc_in rw; 14 | sc_in > data_in; 15 | sc_out ready; 16 | sc_out > data_out; 17 | 18 | 19 | Vtop(sc_module_name nm, const char* hdl_name, 20 | int num_generics, const char** generic_list) 21 | : sc_foreign_module(nm), 22 | clk("clk"), 23 | reset("reset"), 24 | addr("addr"), 25 | cs("cs"), 26 | rw("rw"), 27 | data_in("data_in"), 28 | ready("ready"), 29 | data_out("data_out") 30 | { 31 | elaborate_foreign_module(hdl_name, num_generics, generic_list); 32 | } 33 | ~Vtop() 34 | {} 35 | 36 | }; 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/bfm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "bfm.h" 4 | 5 | using namespace std; 6 | using namespace sc_core; 7 | 8 | void set_bfm(bfm* bfm); // from bfm_api.cpp 9 | 10 | bfm::bfm(sc_module_name name) : sc_module(name), 11 | clk("clk"), reset("reset"), cs("cs"), rw("rw"), ready("ready"), 12 | addr("addr"), data_in("data_in"), data_out("data_out"), reset_done(false) 13 | { 14 | SC_THREAD(reset_task); 15 | sensitive << clk.pos(); 16 | 17 | SC_THREAD(main); 18 | sensitive << clk.pos(); 19 | 20 | set_bfm(this); 21 | } 22 | 23 | void bfm::reset_task() 24 | { 25 | reset.write(true); 26 | for(int i=0;i<4;i++) 27 | wait(); 28 | reset.write(false); 29 | wait(); 30 | cout << "done reset" << endl; 31 | reset_done = true; 32 | } 33 | 34 | uint32_t bfm::read(uint32_t addr_) 35 | { 36 | cs.write(true); 37 | rw.write(true); 38 | addr.write(addr_); 39 | while(!ready.read()){ 40 | wait(); 41 | } 42 | cs.write(false); 43 | addr.write(0x0); 44 | uint32_t data = data_in.read(); 45 | wait(); 46 | return data; 47 | } 48 | 49 | void bfm::write(uint32_t addr_, uint32_t data_){ 50 | cs.write(true); 51 | rw.write(false); 52 | addr.write(addr_); 53 | data_out.write(data_); 54 | while(!ready.read()){ 55 | wait(); 56 | } 57 | cs.write(false); 58 | addr.write(0x0); 59 | data_out.write(0x0); 60 | wait(); 61 | } 62 | 63 | void test_main(); 64 | 65 | void bfm::main(){ 66 | cs.write(false); 67 | rw.write(true); 68 | addr.write(0x00); 69 | data_out.write(0x00); 70 | 71 | while(!reset_done) 72 | wait(); 73 | 74 | test_main(); 75 | 76 | sc_stop(); 77 | cout << "sc_stop(), time = " << sc_time_stamp() << endl; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BFM_H 4 | #define BFM_H 5 | 6 | using namespace std; 7 | using namespace sc_core; 8 | using namespace sc_dt; 9 | 10 | SC_MODULE(bfm) { 11 | public: 12 | 13 | SC_CTOR(bfm); 14 | 15 | sc_in clk; 16 | sc_out reset; 17 | sc_out cs; 18 | sc_out rw; 19 | sc_in ready; 20 | #ifdef VERILATOR 21 | sc_out addr; 22 | sc_out data_out; 23 | sc_in data_in; 24 | #else 25 | sc_out> addr; 26 | sc_in> data_in; 27 | sc_out> data_out; 28 | #endif 29 | 30 | uint32_t read(uint32_t addr_); 31 | void write(uint32_t addr_, uint32_t data_); 32 | 33 | private: 34 | bool reset_done; 35 | 36 | void reset_task(); 37 | 38 | void main(); 39 | }; 40 | #endif 41 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/bfm_api.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm.h" 2 | #include "bfm_api.h" 3 | 4 | static bfm *bfmp = nullptr; 5 | 6 | void set_bfm(bfm* bfm) { 7 | bfmp = bfm; 8 | } 9 | 10 | bool check_bfm() { 11 | return (bfmp == nullptr); 12 | } 13 | 14 | uint32_t read(uint32_t addr_) { 15 | if(!check_bfm()) 16 | return bfmp->read(addr_); 17 | return 0; 18 | } 19 | 20 | void write(uint32_t addr_, uint32_t data_) { 21 | if(!check_bfm()) 22 | bfmp->write(addr_, data_); 23 | return; 24 | } 25 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/bfm_api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | uint32_t read(uint32_t addr); 9 | void write(uint32_t addr, uint32_t data); 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/run_1.do: -------------------------------------------------------------------------------- 1 | if [file exists work] { 2 | vdel -all 3 | } 4 | 5 | vlog -sv top.v 6 | scgenmod -bool -sc_uint Vtop > Vtop.h 7 | sccom -g sc_top.cpp bfm.cpp bfm_api.cpp test_1.cpp 8 | sccom -link 9 | vsim -c sc_top -do "run -all" 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/run_2.do: -------------------------------------------------------------------------------- 1 | if [file exists work] { 2 | vdel -all 3 | } 4 | 5 | vlog -sv top.v 6 | scgenmod -bool -sc_uint Vtop > Vtop.h 7 | sccom -g sc_top.cpp bfm.cpp bfm_api.cpp test_2.cpp 8 | sccom -link 9 | vsim -c sc_top -do "run -all" 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/run_3.do: -------------------------------------------------------------------------------- 1 | if [file exists work] { 2 | vdel -all 3 | } 4 | 5 | vlog -sv top.v 6 | scgenmod -bool -sc_uint Vtop > Vtop.h 7 | sccom -g sc_top.cpp bfm.cpp bfm_api.cpp test_1.cpp 8 | sccom -link 9 | vsim -c sc_top -do "run -all" 10 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/sc_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "sc_top.h" 5 | 6 | int sc_main(int argc, char* argv[]) { 7 | 8 | if (false && argc && argv) {} 9 | 10 | Verilated::debug(0); 11 | Verilated::randReset(2); 12 | Verilated::commandArgs(argc, argv); 13 | 14 | ios::sync_with_stdio(); 15 | 16 | const std::unique_ptr u_sc_top{new sc_top("sc_top")}; 17 | 18 | sc_start(); 19 | 20 | cout << "done, time = " << sc_time_stamp() << endl; 21 | return 0; 22 | } 23 | 24 | #ifdef VL_USER_STOP 25 | void vl_stop(const char *filename, int linenum, const char *hier) VL_MT_UNSAFE 26 | { 27 | sc_stop(); 28 | cout << "call vl_stop" << endl; 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/sc_top.cpp: -------------------------------------------------------------------------------- 1 | #include "sc_top.h" 2 | #include 3 | 4 | 5 | SC_MODULE_EXPORT(sc_top); 6 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/sc_top.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Vtop.h" 4 | #include "bfm.h" 5 | 6 | SC_MODULE(sc_top) { 7 | 8 | sc_clock clk; 9 | 10 | sc_signal reset; 11 | sc_signal cs; 12 | sc_signal rw; 13 | sc_signal ready; 14 | #ifdef VERILATOR 15 | sc_signal addr; 16 | sc_signal data_in; 17 | sc_signal data_out; 18 | #else 19 | sc_signal> addr; 20 | sc_signal> data_in; 21 | sc_signal> data_out; 22 | #endif 23 | 24 | Vtop *u_top; 25 | bfm *u_bfm; 26 | 27 | SC_CTOR(sc_top) : 28 | clk("clk", 10, SC_NS, 0.5, 5, SC_NS, true), 29 | reset("reset"), cs("cs"), rw("rw"), addr("addr"), ready("ready"), data_in("data_in"), data_out("data_out") { 30 | 31 | #ifdef VERILATOR 32 | u_top = new Vtop{"top"}; 33 | #else 34 | u_top = new Vtop{"top", "Vtop", 0, NULL}; 35 | #endif 36 | 37 | u_top->clk(clk); 38 | u_top->reset(reset); 39 | u_top->cs(cs); 40 | u_top->rw(rw); 41 | u_top->addr(addr); 42 | u_top->data_in(data_in); 43 | u_top->ready(ready); 44 | u_top->data_out(data_out); 45 | 46 | u_bfm = new bfm("bfm"); 47 | 48 | u_bfm->clk(clk); 49 | u_bfm->reset(reset); 50 | u_bfm->cs(cs); 51 | u_bfm->rw(rw); 52 | u_bfm->addr(addr); 53 | u_bfm->data_in(data_out); 54 | u_bfm->ready(ready); 55 | u_bfm->data_out(data_in); 56 | } 57 | 58 | ~sc_top() { 59 | #ifdef VERILATOR 60 | u_top->final(); 61 | #endif 62 | delete u_top; 63 | delete u_bfm; 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/test_1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm_api.h" 3 | 4 | void test_main(){ 5 | cout << "start test_main" << endl; 6 | write(0x200, 0x12345678); 7 | uint32_t data = read(0x200); 8 | if(data != 0x12345678) 9 | cout << "<>, compare error, data = 0x" << hex << data << endl; 10 | cout << "finish test_main" << endl; 11 | } 12 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/test_2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm_api.h" 3 | 4 | void test_main(){ 5 | uint32_t exp[0x10000>>2]; 6 | cout << "start test_main" << endl; 7 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 8 | exp[addr>>2] = rand(); 9 | write(addr, exp[addr>>2]); 10 | } 11 | cout << "done write" << endl; 12 | 13 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 14 | uint32_t data = read(addr); 15 | if(data != exp[addr>>2]) 16 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 17 | } 18 | 19 | cout << "finish test_main" << endl; 20 | } 21 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/test_3.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm_api.h" 3 | 4 | #include "svdpi.h" 5 | 6 | extern "C" { 7 | extern int direct_read(int addr_); 8 | extern void direct_write(int addr_, int data_); 9 | } 10 | 11 | uint32_t direct_top_read(uint32_t addr){ 12 | svScope scope = svSetScope(svGetScopeFromName("top.top")); 13 | int data = direct_read((int)addr); 14 | svSetScope(scope); 15 | return (uint32_t)data; 16 | } 17 | 18 | void direct_top_write(uint32_t addr, uint32_t data){ 19 | svScope scope = svSetScope(svGetScopeFromName("top.top")); 20 | direct_write((int)addr, (int)data); 21 | svSetScope(scope); 22 | } 23 | 24 | void test_main(){ 25 | uint32_t add, data; 26 | uint32_t exp[0x10000>>2]; 27 | cout << "start test_main" << endl; 28 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 29 | exp[addr>>2] = rand(); 30 | direct_top_write(addr, exp[addr>>2]); 31 | } 32 | cout << "done write" << endl; 33 | 34 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 35 | uint32_t data = direct_top_read(addr); 36 | if(data != exp[addr>>2]) 37 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 38 | } 39 | 40 | cout << "finish test_main" << endl; 41 | } 42 | -------------------------------------------------------------------------------- /verilator/sample_sc_bfm_4/top.v: -------------------------------------------------------------------------------- 1 | `ifdef VERILATOR 2 | module top 3 | `else 4 | module Vtop 5 | `endif 6 | ( 7 | input logic clk, 8 | input logic reset, 9 | 10 | /* verilator lint_off UNUSED */ 11 | input logic [15:0] addr, 12 | /* verilator lint_on UNUSED */ 13 | input logic cs, 14 | input logic rw, 15 | input logic [31:0] data_in, 16 | output logic ready, 17 | output logic [31:0] data_out 18 | ); 19 | 20 | localparam ram_size = (17'h10000>>2); 21 | 22 | /* verilator lint_off WIDTH */ 23 | logic [31:0] ram[ram_size]; 24 | /* verilator lint_on WIDTH */ 25 | 26 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 27 | 28 | always_ff @(posedge clk) begin 29 | if(reset == 1'b1) 30 | state <= STATE_IDLE; 31 | else if(cs == 1'b1 && state == STATE_IDLE) 32 | state <= STATE_RUN; 33 | else if(cs == 1'b1 && state == STATE_RUN) 34 | state <= STATE_DONE; 35 | else if(cs == 1'b0) 36 | state <= STATE_IDLE; 37 | end 38 | 39 | always_ff @(posedge clk) begin 40 | if(reset == 1'b1) begin 41 | data_out <= 32'h0000_0000; 42 | ready <= 1'b0; 43 | end 44 | else if(state == STATE_RUN) begin 45 | if(rw == 1'b1) 46 | data_out <= ram[addr[15:2]]; 47 | else 48 | ram[addr[15:2]] <= data_in; 49 | ready <= 1'b1; 50 | end 51 | else begin 52 | data_out <= 32'h0000_0000; 53 | ready <= 1'b0; 54 | end 55 | end 56 | 57 | export "DPI-C" function direct_read; 58 | export "DPI-C" function direct_write; 59 | export "DPI-C" function direct_write_integer; 60 | 61 | function automatic void address_check(input int addr_); 62 | if((addr_>>2)>ram_size) begin 63 | $display("write, address range error at %h", addr_); 64 | $stop; 65 | end 66 | 67 | if((addr_ & 32'h3) != 32'h0) begin 68 | $display("write, address boundary error at %h", addr_); 69 | $stop; 70 | end 71 | endfunction : address_check 72 | 73 | function int direct_read(input int addr_); 74 | int data_; 75 | address_check(addr_); 76 | data_ = ram[addr_>>2]; 77 | return data_; 78 | endfunction : direct_read 79 | 80 | function void direct_write(input int addr_, input int data_); 81 | address_check(addr_); 82 | ram[addr_>>2] = data_; 83 | endfunction : direct_write 84 | 85 | function void direct_write_integer(input integer addr_, input integer data_); 86 | address_check(addr_); 87 | ram[addr_>>2] = data_; 88 | endfunction : direct_write_integer 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/bfm.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | using namespace std; 5 | 6 | const s_xsi_vlog_logicval one_val = {0X00000001, 0X00000000}; 7 | const s_xsi_vlog_logicval zero_val = {0X00000000, 0X00000000}; 8 | const int clock_period_2 = 5; 9 | 10 | bfm::bfm() : xsi("xsim.dir/top/xsimk.so", "librdi_simulator_kernel.so") 11 | { 12 | s_xsi_setup_info info; 13 | memset(&info, 0, sizeof(info)); 14 | info.logFileName = NULL; 15 | char wdbName[] = "test.wdb"; 16 | info.wdbFileName = wdbName; 17 | xsi.open(&info); 18 | xsi.trace_all(); 19 | 20 | clock = xsi.get_port_number("clk"); 21 | reset = xsi.get_port_number("reset"); 22 | cs = xsi.get_port_number("cs"); 23 | rw = xsi.get_port_number("rw"); 24 | addr = xsi.get_port_number("addr"); 25 | data_in = xsi.get_port_number("data_in"); 26 | data_out = xsi.get_port_number("data_out"); 27 | ready = xsi.get_port_number("ready"); 28 | 29 | write_low(cs); 30 | write_low(rw); 31 | write_addr(0x00); 32 | write_data(0x00); 33 | } 34 | 35 | bfm::~bfm(){ 36 | xsi.close(); 37 | } 38 | 39 | void bfm::write_hi(int sig) { 40 | xsi.put_value(sig, &one_val); 41 | } 42 | 43 | void bfm::write_low(int sig) { 44 | xsi.put_value(sig, &zero_val); 45 | } 46 | 47 | void bfm::wait_hi() { 48 | write_hi(clock); 49 | xsi.run(clock_period_2); 50 | } 51 | 52 | void bfm::wait_low() { 53 | write_low(clock); 54 | xsi.run(clock_period_2); 55 | } 56 | 57 | void bfm::wait() { 58 | wait_hi(); 59 | wait_low(); 60 | } 61 | 62 | void bfm::reset_task(){ 63 | write_hi(reset); 64 | for(int i=0;i<4;i++) { 65 | wait(); 66 | } 67 | write_low(reset); 68 | wait(); 69 | cout << "done reset" << endl; 70 | } 71 | 72 | bool bfm::read_ready() { 73 | s_xsi_vlog_logicval val; 74 | xsi.get_value(ready, &val); 75 | cout << "time : " << dec << xsi.get_time() << ", val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 76 | return ((val.aVal & 0x1) ? true : false); 77 | } 78 | 79 | void bfm::write_addr(uint32_t data) { 80 | s_xsi_vlog_logicval val = {data, 0x0}; 81 | cout << "write_addr(0x" << hex << data << ")" << endl; 82 | xsi.put_value(addr, &val); 83 | } 84 | 85 | void bfm::write_data(uint32_t data) { 86 | s_xsi_vlog_logicval val = {data, 0x0}; 87 | cout << "write_data(0x" << hex << data << ")" << endl; 88 | xsi.put_value(data_in, &val); 89 | } 90 | 91 | uint32_t bfm::read_data() { 92 | s_xsi_vlog_logicval val; 93 | xsi.get_value(data_out, &val); 94 | cout << "read_data : " << "val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 95 | return val.aVal; 96 | } 97 | 98 | uint32_t bfm::read(uint32_t addr_){ 99 | write_hi(cs); 100 | write_hi(rw); 101 | write_addr(addr_); 102 | wait_hi(); 103 | 104 | wait_low(); 105 | while(!read_ready()){ 106 | wait(); 107 | } 108 | uint32_t data = read_data(); 109 | 110 | write_low(cs); 111 | write_low(rw); 112 | write_addr(0x0); 113 | wait_hi(); 114 | 115 | wait_low(); 116 | return data; 117 | } 118 | 119 | void bfm::write(uint32_t addr_, uint32_t data_){ 120 | write_hi(cs); 121 | write_low(rw); 122 | write_addr(addr_); 123 | write_data(data_); 124 | wait_hi(); 125 | 126 | wait_low(); 127 | while(!read_ready()){ 128 | wait(); 129 | } 130 | 131 | write_low(cs); 132 | write_low(rw); 133 | write_addr(0x0); 134 | write_data(0x0); 135 | wait_hi(); 136 | 137 | wait_low(); 138 | } 139 | 140 | void bfm::test_main(){ 141 | cout << "start test_main" << endl; 142 | write(0x200, 0x12345678); 143 | uint32_t data = read(0x200); 144 | if(data != 0x12345678) 145 | cout << "<>, compare error, data = 0x" << hex << data << endl; 146 | cout << "finish test_main" << endl; 147 | } 148 | 149 | void bfm::main(){ 150 | reset_task(); 151 | 152 | test_main(); 153 | 154 | cout << "ime = " << xsi.get_time() << endl; 155 | } 156 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "xsi_loader.h" 5 | 6 | class bfm { 7 | public: 8 | 9 | bfm(); 10 | ~bfm(); 11 | void main(); 12 | 13 | private: 14 | 15 | Xsi::Loader xsi; 16 | 17 | int clock; 18 | int reset; 19 | int cs; 20 | int rw; 21 | int addr; 22 | int data_in; 23 | int data_out; 24 | int ready; 25 | 26 | void write_hi(int sig); 27 | void write_low(int sig); 28 | 29 | void wait_hi(); 30 | void wait_low(); 31 | void wait(); 32 | 33 | void reset_task(); 34 | 35 | bool read_ready(); 36 | void write_addr(uint32_t data); 37 | void write_data(uint32_t data); 38 | uint32_t read_data(); 39 | 40 | uint32_t read(uint32_t addr_); 41 | void write(uint32_t addr_, uint32_t data_); 42 | 43 | void test_main(); 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #VIVADO_BIN_DIR to the directory which has vivado executable 4 | 5 | #VIVADO_BIN_DIR="$RDI_ROOT/prep/rdi/vivado/bin" 6 | VIVADO_BIN_DIR="$XILINX_VIVADO/bin" 7 | 8 | OUT_SIM_SNAPSHOT="top" 9 | XSI_INCLUDE_DIR="$VIVADO_BIN_DIR/../data/xsim/include" 10 | GCC_COMPILER="/usr/bin/g++" 11 | XSIM_ELAB="xelab" 12 | OUT_EXE="run_simulation" 13 | export LD_LIBRARY_PATH="$XILINX_VIVADO/lib/lnx64.o" 14 | 15 | # Start clean 16 | #rm -rf xsim.dir xsim.log xelab* $OUT_EXE 17 | 18 | # Compile the HDL design into a simulatable Shared Library 19 | $XSIM_ELAB work.top -prj top.prj -dll -s $OUT_SIM_SNAPSHOT -debug wave 20 | 21 | # Compile the C++ code that interfaces with XSI of ISim 22 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o xsi_loader.o xsi_loader.cpp 23 | 24 | # Compile the program that needs to simulate the HDL design 25 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o bfm.o bfm.cpp 26 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o testbench.o testbench.cpp 27 | 28 | $GCC_COMPILER -o $OUT_EXE bfm.o testbench.o xsi_loader.o -ldl -lrt 29 | 30 | # Run the program 31 | ./$OUT_EXE 32 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/testbench.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm.h" 2 | 3 | int main() { 4 | 5 | bfm u_bfm; 6 | 7 | u_bfm.main(); 8 | 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/top.prj: -------------------------------------------------------------------------------- 1 | sv work top.v 2 | # List other design files here 3 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/top.v: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | 6 | /* verilator lint_off UNUSED */ 7 | input logic [15:0] addr, 8 | /* verilator lint_on UNUSED */ 9 | input logic cs, 10 | input logic rw, 11 | input logic [31:0] data_in, 12 | output logic ready, 13 | output logic [31:0] data_out 14 | ); 15 | 16 | localparam ram_size = (17'h10000>>2); 17 | /* verilator lint_off WIDTH */ 18 | logic [31:0] ram[ram_size]; 19 | /* verilator lint_on WIDTH */ 20 | 21 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 22 | 23 | always_ff @(posedge clk) begin 24 | if(reset == 1'b1) 25 | state <= STATE_IDLE; 26 | else if(cs == 1'b1 && state == STATE_IDLE) 27 | state <= STATE_RUN; 28 | else if(cs == 1'b1 && state == STATE_RUN) 29 | state <= STATE_DONE; 30 | else if(cs == 1'b0) 31 | state <= STATE_IDLE; 32 | end 33 | 34 | always_ff @(posedge clk) begin 35 | if(reset == 1'b1) begin 36 | data_out <= 32'h0000_0000; 37 | ready <= 1'b0; 38 | end 39 | else if(state == STATE_RUN) begin 40 | if(rw == 1'b1) 41 | data_out <= ram[addr[15:2]]; 42 | else 43 | ram[addr[15:2]] <= data_in; 44 | ready <= 1'b1; 45 | end 46 | else begin 47 | data_out <= 32'h0000_0000; 48 | ready <= 1'b0; 49 | end 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/xsi_loader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "xsi_loader.h" 3 | 4 | using namespace Xsi; 5 | 6 | Loader::Loader(const std::string& design_libname, const std::string& simkernel_libname) : 7 | _design_libname(design_libname), 8 | _simkernel_libname(simkernel_libname), 9 | _design_handle(NULL), 10 | _xsi_open(NULL), 11 | _xsi_close(NULL), 12 | _xsi_run(NULL), 13 | _xsi_get_value(NULL), 14 | _xsi_put_value(NULL), 15 | _xsi_get_status(NULL), 16 | _xsi_get_error_info(NULL), 17 | _xsi_restart(NULL), 18 | _xsi_get_port_number(NULL), 19 | _xsi_get_port_name(NULL), 20 | _xsi_trace_all(NULL), 21 | _xsi_get_time(NULL) 22 | { 23 | 24 | if (!initialize()) { 25 | throw LoaderException("Failed to Load up XSI."); 26 | } 27 | 28 | } 29 | 30 | Loader::~Loader() 31 | { 32 | close(); 33 | } 34 | 35 | bool 36 | Loader::isopen() const 37 | { 38 | return (_design_handle != NULL); 39 | } 40 | 41 | void 42 | Loader::open(p_xsi_setup_info setup_info) 43 | { 44 | _design_handle = _xsi_open(setup_info); 45 | } 46 | 47 | void 48 | Loader::close() 49 | { 50 | if (_design_handle) { 51 | _xsi_close(_design_handle); 52 | _design_handle = NULL; 53 | } 54 | } 55 | 56 | void 57 | Loader::run(XSI_INT64 step) 58 | { 59 | _xsi_run(_design_handle, step); 60 | } 61 | 62 | void 63 | Loader::restart() 64 | { 65 | _xsi_restart(_design_handle); 66 | } 67 | 68 | int 69 | Loader::get_value(int port_number, void* value) 70 | { 71 | return _xsi_get_value(_design_handle, port_number, value); 72 | } 73 | 74 | int 75 | Loader::get_port_number(const char* port_name) 76 | { 77 | return _xsi_get_port_number(_design_handle, port_name); 78 | } 79 | 80 | const char* 81 | Loader::get_port_name(int port_number) 82 | { 83 | return _xsi_get_port_name(_design_handle, port_number); 84 | } 85 | 86 | void 87 | Loader::put_value(int port_number, const void* value) 88 | { 89 | _xsi_put_value(_design_handle, port_number, const_cast(value)); 90 | } 91 | 92 | int 93 | Loader::get_status() 94 | { 95 | return _xsi_get_status(_design_handle); 96 | } 97 | 98 | const char* 99 | Loader::get_error_info() 100 | { 101 | return _xsi_get_error_info(_design_handle); 102 | } 103 | 104 | void 105 | Loader::trace_all() 106 | { 107 | _xsi_trace_all(_design_handle); 108 | } 109 | 110 | XSI_INT64 Loader::get_time() 111 | { 112 | return _xsi_get_time(_design_handle); 113 | } 114 | 115 | bool 116 | Loader::initialize() 117 | { 118 | 119 | // Load ISIM design shared library 120 | if (!_design_lib.load(_design_libname)) { 121 | std::cerr << "Could not load XSI simulation shared library (" << _design_libname <<"): " << _design_lib.error() << std::endl; 122 | return false; 123 | } 124 | 125 | 126 | if (!_simkernel_lib.load(_simkernel_libname)) { 127 | std::cerr << "Could not load simulaiton kernel library (" << _simkernel_libname << ") :" << _simkernel_lib.error() << "\n"; 128 | return false; 129 | } 130 | 131 | // Get function pointer for getting an ISIM design handle 132 | _xsi_open = (t_fp_xsi_open) _design_lib.getfunction("xsi_open"); 133 | if (!_xsi_open) { 134 | return false; 135 | } 136 | 137 | 138 | // Get function pointer for running ISIM simulation 139 | _xsi_run = (t_fp_xsi_run) _simkernel_lib.getfunction("xsi_run"); 140 | if (!_xsi_run) { 141 | return false; 142 | } 143 | 144 | // Get function pointer for terminating ISIM simulation 145 | _xsi_close = (t_fp_xsi_close) _simkernel_lib.getfunction("xsi_close"); 146 | if (!_xsi_close) { 147 | return false; 148 | } 149 | 150 | // Get function pointer for running ISIM simulation 151 | _xsi_restart = (t_fp_xsi_restart) _simkernel_lib.getfunction("xsi_restart"); 152 | if (!_xsi_restart) { 153 | return false; 154 | } 155 | 156 | // Get function pointer for reading data from ISIM 157 | _xsi_get_value = (t_fp_xsi_get_value) _simkernel_lib.getfunction("xsi_get_value"); 158 | if (!_xsi_get_value) { 159 | return false; 160 | } 161 | 162 | // Get function pointer for reading data from ISIM 163 | _xsi_get_port_number = (t_fp_xsi_get_port_number) _simkernel_lib.getfunction("xsi_get_port_number"); 164 | if (!_xsi_get_port_number) { 165 | return false; 166 | } 167 | 168 | // Get function pointer for reading data from ISIM 169 | _xsi_get_port_name = (t_fp_xsi_get_port_name) _simkernel_lib.getfunction("xsi_get_port_name"); 170 | if (!_xsi_get_port_name) { 171 | return false; 172 | } 173 | 174 | // Get function pointer for passing data to ISIM 175 | _xsi_put_value = (t_fp_xsi_put_value) _simkernel_lib.getfunction("xsi_put_value"); 176 | if (!_xsi_put_value) { 177 | return false; 178 | } 179 | 180 | // Get function pointer for checking error status 181 | _xsi_get_status = (t_fp_xsi_get_status) _simkernel_lib.getfunction("xsi_get_status"); 182 | if (!_xsi_get_status) { 183 | return false; 184 | } 185 | 186 | // Get function pointer for getting error message 187 | _xsi_get_error_info = (t_fp_xsi_get_error_info) _simkernel_lib.getfunction("xsi_get_error_info"); 188 | if (!_xsi_get_error_info) { 189 | return false; 190 | } 191 | 192 | // Get function pointer for tracing all signals to WDB 193 | _xsi_trace_all = (t_fp_xsi_trace_all) _simkernel_lib.getfunction("xsi_trace_all"); 194 | if (!_xsi_trace_all) { 195 | return false; 196 | } 197 | 198 | _xsi_get_time = (t_fp_xsi_get_time) _simkernel_lib.getfunction("xsi_get_time"); 199 | if (!_xsi_get_time) { 200 | return false; 201 | } 202 | 203 | return true; 204 | } 205 | 206 | 207 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/xsi_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef _XSI_LOADER_H_ 2 | #define _XSI_LOADER_H_ 3 | 4 | #include "xsi.h" 5 | #include "xsi_shared_lib.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace Xsi { 11 | 12 | class LoaderException : public std::exception { 13 | public: 14 | LoaderException(const std::string& msg) : _msg("ISim engine error: " + msg) { } 15 | 16 | virtual ~LoaderException() throw() { } 17 | 18 | virtual const char * what() const throw() { return _msg.c_str(); } 19 | private: 20 | std::string _msg; 21 | }; 22 | 23 | class Loader { 24 | public: 25 | Loader(const std::string& dll_name, const std::string& simkernel_libname); 26 | ~Loader(); 27 | 28 | bool isopen() const; 29 | void open(p_xsi_setup_info setup_info); 30 | void close(); 31 | void run(XSI_INT64 step); 32 | void restart(); 33 | int get_value(int port_number, void* value); 34 | int get_port_number(const char* port_name); 35 | const char *get_port_name(int port_number); 36 | void put_value(int port_number, const void* value); 37 | int get_status(); 38 | const char* get_error_info(); 39 | void trace_all(); 40 | XSI_INT64 get_time(); 41 | 42 | private: 43 | bool initialize(); 44 | 45 | Xsi::SharedLibrary _design_lib; 46 | Xsi::SharedLibrary _simkernel_lib; 47 | std::string _design_libname; 48 | std::string _simkernel_libname; 49 | 50 | xsiHandle _design_handle; 51 | 52 | t_fp_xsi_open _xsi_open; 53 | t_fp_xsi_close _xsi_close; 54 | t_fp_xsi_run _xsi_run; 55 | t_fp_xsi_get_value _xsi_get_value; 56 | t_fp_xsi_put_value _xsi_put_value; 57 | t_fp_xsi_get_status _xsi_get_status; 58 | t_fp_xsi_get_error_info _xsi_get_error_info; 59 | t_fp_xsi_restart _xsi_restart; 60 | t_fp_xsi_get_port_number _xsi_get_port_number; 61 | t_fp_xsi_get_port_name _xsi_get_port_name; 62 | t_fp_xsi_trace_all _xsi_trace_all; 63 | t_fp_xsi_get_time _xsi_get_time; 64 | 65 | }; // class Loader 66 | 67 | } // namespace Xsi 68 | 69 | #endif // _XSI_LOADER_H_ 70 | 71 | 72 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_0/xsi_shared_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * xsi_shared_library.h 3 | * Copyright (c) 2012, Xilinx, Inc. All Rights Reserved. 4 | * Class for loading shared libraries generated by xelab 5 | */ 6 | 7 | #ifndef _XSI_SHARED_LIB_H 8 | #define _XSI_SHARED_LIB_H 9 | 10 | #if defined(_WIN32) 11 | # include 12 | #else 13 | # include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | namespace Xsi { 20 | 21 | class SharedLibrary { 22 | public: 23 | #if defined(_WIN32) 24 | typedef HINSTANCE handle_type; 25 | #else 26 | typedef void * handle_type; 27 | #endif 28 | typedef void * symbol_type; 29 | 30 | SharedLibrary() : _lib(0), _retain(false) { } 31 | ~SharedLibrary() { unload(); } 32 | operator bool() const { return (_lib != 0); } 33 | bool loaded() const { return (_lib != 0); } 34 | handle_type handle() const { return _lib; } 35 | const std::string& path() const { return _path; } 36 | const std::string& error() const { return _err; } 37 | bool load(const std::string& path) 38 | { 39 | unload(); 40 | // reset the retain flag 41 | _retain = false; 42 | 43 | if (path.empty()) { 44 | _err = "Failed to load shared library. " 45 | "Path of the shared library is not specified."; 46 | return false; 47 | } 48 | std::string msg; 49 | bool ok = load_impl(path, msg); 50 | if (ok) { 51 | _path = path; 52 | _err.clear(); 53 | } 54 | else { 55 | _err = "Failed to load shared library \"" + path + 56 | "\". " + msg; 57 | } 58 | return ok; 59 | } 60 | 61 | bool load_impl(const std::string& path, std::string& errmsg) 62 | { 63 | bool ok = true; 64 | #if defined(_WIN32) 65 | SetLastError(0); 66 | _lib = LoadLibrary(path.c_str()); 67 | if (_lib == 0) { 68 | translate_error_message(GetLastError(), errmsg); 69 | ok = false; 70 | } 71 | #else 72 | _lib = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); 73 | char *err = dlerror(); 74 | if (err != NULL) { 75 | errmsg = err; 76 | ok = false; 77 | } 78 | #endif 79 | return ok; 80 | } 81 | 82 | void unload() 83 | { 84 | if (_lib) { 85 | if (!_retain) { 86 | #if defined(_WIN32) 87 | FreeLibrary(_lib); 88 | #else 89 | dlclose(_lib); 90 | #endif 91 | } 92 | _lib = 0; 93 | } 94 | _err.clear(); 95 | } 96 | 97 | void retain() 98 | { 99 | _retain = true; 100 | } 101 | 102 | bool getsymbol(const std::string& name, symbol_type& sym) 103 | { 104 | std::string msg; 105 | bool ok = true; 106 | 107 | if (_lib == 0) { 108 | msg = "The shared library is not loaded."; 109 | ok = false; 110 | } 111 | else { 112 | 113 | #if defined(_WIN32) 114 | sym = (void*) GetProcAddress(_lib, name.c_str()); 115 | if (sym == NULL) { 116 | translate_error_message(GetLastError(), msg); 117 | ok = false; 118 | } 119 | #else 120 | dlerror(); // clear error 121 | sym = (void *) dlsym(_lib, name.c_str()); 122 | char *err = dlerror(); 123 | if (err != NULL) { 124 | msg = err; 125 | ok = false; 126 | } 127 | #endif 128 | } 129 | 130 | if (ok) { 131 | _err.clear(); 132 | } 133 | else { 134 | _err = "Failed to obtain symbol \"" + name + 135 | "\" from shared library. " + msg; 136 | } 137 | 138 | return ok; 139 | } 140 | 141 | symbol_type getfunction(const std::string& name) 142 | { 143 | symbol_type sym = NULL; 144 | return getsymbol(name, sym) ? sym : NULL; 145 | } 146 | 147 | private: 148 | // shared library is non-copyable 149 | SharedLibrary(const SharedLibrary&); 150 | const SharedLibrary& operator=(const SharedLibrary&); 151 | 152 | #if defined(_WIN32) 153 | static void translate_error_message(DWORD errid, std::string& msg) 154 | { 155 | LPVOID bufptr; 156 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 157 | FORMAT_MESSAGE_FROM_SYSTEM | 158 | FORMAT_MESSAGE_IGNORE_INSERTS, 159 | NULL, 160 | errid, 161 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 162 | (LPTSTR) &bufptr, 163 | 0, 164 | NULL); 165 | msg.clear(); 166 | if (bufptr) { 167 | msg = reinterpret_cast(bufptr); 168 | } 169 | LocalFree(bufptr); 170 | } 171 | 172 | static const std::string& library_suffix() 173 | { 174 | static const std::string s = ".dll"; 175 | return s; 176 | } 177 | #else 178 | static const std::string& library_suffix() 179 | { 180 | static const std::string s = ".so"; 181 | return s; 182 | } 183 | #endif 184 | 185 | handle_type _lib; 186 | std::string _path; 187 | std::string _err; 188 | bool _retain; 189 | }; 190 | 191 | } // namespace Xsi 192 | 193 | #endif // _XSI_SHARED_LIB_H 194 | 195 | 196 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/bfm.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | using namespace std; 5 | 6 | const s_xsi_vlog_logicval one_val = {0X00000001, 0X00000000}; 7 | const s_xsi_vlog_logicval zero_val = {0X00000000, 0X00000000}; 8 | const int clock_period_2 = 5; 9 | 10 | bfm::bfm() : xsi("xsim.dir/top/xsimk.so", "librdi_simulator_kernel.so") 11 | { 12 | s_xsi_setup_info info; 13 | memset(&info, 0, sizeof(info)); 14 | info.logFileName = NULL; 15 | char wdbName[] = "test.wdb"; 16 | info.wdbFileName = wdbName; 17 | xsi.open(&info); 18 | xsi.trace_all(); 19 | 20 | clock = xsi.get_port_number("clk"); 21 | reset = xsi.get_port_number("reset"); 22 | cs = xsi.get_port_number("cs"); 23 | rw = xsi.get_port_number("rw"); 24 | addr = xsi.get_port_number("addr"); 25 | data_in = xsi.get_port_number("data_in"); 26 | data_out = xsi.get_port_number("data_out"); 27 | ready = xsi.get_port_number("ready"); 28 | 29 | write_low(cs); 30 | write_low(rw); 31 | write_addr(0x00); 32 | write_data(0x00); 33 | } 34 | 35 | bfm::~bfm(){ 36 | xsi.close(); 37 | } 38 | 39 | void bfm::write_hi(int sig) { 40 | xsi.put_value(sig, &one_val); 41 | } 42 | 43 | void bfm::write_low(int sig) { 44 | xsi.put_value(sig, &zero_val); 45 | } 46 | 47 | void bfm::wait_hi() { 48 | write_hi(clock); 49 | xsi.run(clock_period_2); 50 | } 51 | 52 | void bfm::wait_low() { 53 | write_low(clock); 54 | xsi.run(clock_period_2); 55 | } 56 | 57 | void bfm::wait() { 58 | wait_hi(); 59 | wait_low(); 60 | } 61 | 62 | void bfm::reset_task(){ 63 | write_hi(reset); 64 | for(int i=0;i<4;i++) { 65 | wait(); 66 | } 67 | write_low(reset); 68 | wait(); 69 | cout << "done reset" << endl; 70 | } 71 | 72 | bool bfm::read_ready() { 73 | s_xsi_vlog_logicval val; 74 | xsi.get_value(ready, &val); 75 | cout << "time : " << dec << xsi.get_time() << ", val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 76 | return ((val.aVal & 0x1) ? true : false); 77 | } 78 | 79 | void bfm::write_addr(uint32_t data) { 80 | s_xsi_vlog_logicval val = {data, 0x0}; 81 | cout << "write_addr(0x" << hex << data << ")" << endl; 82 | xsi.put_value(addr, &val); 83 | } 84 | 85 | void bfm::write_data(uint32_t data) { 86 | s_xsi_vlog_logicval val = {data, 0x0}; 87 | cout << "write_data(0x" << hex << data << ")" << endl; 88 | xsi.put_value(data_in, &val); 89 | } 90 | 91 | uint32_t bfm::read_data() { 92 | s_xsi_vlog_logicval val; 93 | xsi.get_value(data_out, &val); 94 | cout << "read_data : " << "val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 95 | return val.aVal; 96 | } 97 | 98 | uint32_t bfm::read(uint32_t addr_){ 99 | write_hi(cs); 100 | write_hi(rw); 101 | write_addr(addr_); 102 | wait_hi(); 103 | 104 | wait_low(); 105 | while(!read_ready()){ 106 | wait(); 107 | } 108 | uint32_t data = read_data(); 109 | 110 | write_low(cs); 111 | write_low(rw); 112 | write_addr(0x0); 113 | wait_hi(); 114 | 115 | wait_low(); 116 | return data; 117 | } 118 | 119 | void bfm::write(uint32_t addr_, uint32_t data_){ 120 | write_hi(cs); 121 | write_low(rw); 122 | write_addr(addr_); 123 | write_data(data_); 124 | wait_hi(); 125 | 126 | wait_low(); 127 | while(!read_ready()){ 128 | wait(); 129 | } 130 | 131 | write_low(cs); 132 | write_low(rw); 133 | write_addr(0x0); 134 | write_data(0x0); 135 | wait_hi(); 136 | 137 | wait_low(); 138 | } 139 | 140 | void bfm::main(){ 141 | reset_task(); 142 | 143 | test_main(); 144 | 145 | cout << "ime = " << xsi.get_time() << endl; 146 | } 147 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "xsi_loader.h" 5 | 6 | class bfm { 7 | public: 8 | 9 | bfm(); 10 | ~bfm(); 11 | void main(); 12 | 13 | private: 14 | 15 | Xsi::Loader xsi; 16 | 17 | int clock; 18 | int reset; 19 | int cs; 20 | int rw; 21 | int addr; 22 | int data_in; 23 | int data_out; 24 | int ready; 25 | 26 | void write_hi(int sig); 27 | void write_low(int sig); 28 | 29 | void wait_hi(); 30 | void wait_low(); 31 | void wait(); 32 | 33 | void reset_task(); 34 | 35 | bool read_ready(); 36 | void write_addr(uint32_t data); 37 | void write_data(uint32_t data); 38 | uint32_t read_data(); 39 | 40 | uint32_t read(uint32_t addr_); 41 | void write(uint32_t addr_, uint32_t data_); 42 | 43 | void test_main(); 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEST=$1 4 | 5 | if [ ! -e ${TEST}.cpp ]; then 6 | echo "can't find ${TEST}.cpp" 7 | fi 8 | 9 | #VIVADO_BIN_DIR to the directory which has vivado executable 10 | 11 | #VIVADO_BIN_DIR="$RDI_ROOT/prep/rdi/vivado/bin" 12 | VIVADO_BIN_DIR="$XILINX_VIVADO/bin" 13 | 14 | OUT_SIM_SNAPSHOT="top" 15 | XSI_INCLUDE_DIR="$VIVADO_BIN_DIR/../data/xsim/include" 16 | GCC_COMPILER="/usr/bin/g++" 17 | XSIM_ELAB="xelab" 18 | OUT_EXE="run_simulation" 19 | export LD_LIBRARY_PATH="$XILINX_VIVADO/lib/lnx64.o" 20 | 21 | # Start clean 22 | #rm -rf xsim.dir xsim.log xelab* $OUT_EXE 23 | 24 | # Compile the HDL design into a simulatable Shared Library 25 | $XSIM_ELAB work.top -prj top.prj -dll -s $OUT_SIM_SNAPSHOT -debug wave 26 | 27 | # Compile the C++ code that interfaces with XSI of ISim 28 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o xsi_loader.o xsi_loader.cpp 29 | 30 | # Compile the program that needs to simulate the HDL design 31 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o bfm.o bfm.cpp 32 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o test.o ${TEST}.cpp 33 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o testbench.o testbench.cpp 34 | 35 | $GCC_COMPILER -o $OUT_EXE bfm.o test.o testbench.o xsi_loader.o -ldl -lrt 36 | 37 | # Run the program 38 | ./$OUT_EXE 39 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/test_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "bfm.h" 5 | 6 | void bfm::test_main(){ 7 | cout << "start test_main" << endl; 8 | write(0x200, 0x12345678); 9 | uint32_t data = read(0x200); 10 | if(data != 0x12345678) 11 | cout << "<>, compare error, data = 0x" << hex << data << endl; 12 | cout << "finish test_main" << endl; 13 | } 14 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/test_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "bfm.h" 5 | 6 | void bfm::test_main(){ 7 | uint32_t exp[0x10000>>2]; 8 | cout << "start test_main" << endl; 9 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 10 | exp[addr>>2] = rand(); 11 | write(addr, exp[addr>>2]); 12 | } 13 | cout << "done write" << endl; 14 | 15 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 16 | uint32_t data = read(addr); 17 | if(data != exp[addr>>2]) 18 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 19 | } 20 | 21 | cout << "finish test_main" << endl; 22 | } 23 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/testbench.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm.h" 2 | 3 | int main() { 4 | 5 | bfm u_bfm; 6 | 7 | u_bfm.main(); 8 | 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/top.prj: -------------------------------------------------------------------------------- 1 | sv work top.v 2 | # List other design files here 3 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/top.v: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | 6 | /* verilator lint_off UNUSED */ 7 | input logic [15:0] addr, 8 | /* verilator lint_on UNUSED */ 9 | input logic cs, 10 | input logic rw, 11 | input logic [31:0] data_in, 12 | output logic ready, 13 | output logic [31:0] data_out 14 | ); 15 | 16 | localparam ram_size = (17'h10000>>2); 17 | /* verilator lint_off WIDTH */ 18 | logic [31:0] ram[ram_size]; 19 | /* verilator lint_on WIDTH */ 20 | 21 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 22 | 23 | always_ff @(posedge clk) begin 24 | if(reset == 1'b1) 25 | state <= STATE_IDLE; 26 | else if(cs == 1'b1 && state == STATE_IDLE) 27 | state <= STATE_RUN; 28 | else if(cs == 1'b1 && state == STATE_RUN) 29 | state <= STATE_DONE; 30 | else if(cs == 1'b0) 31 | state <= STATE_IDLE; 32 | end 33 | 34 | always_ff @(posedge clk) begin 35 | if(reset == 1'b1) begin 36 | data_out <= 32'h0000_0000; 37 | ready <= 1'b0; 38 | end 39 | else if(state == STATE_RUN) begin 40 | if(rw == 1'b1) 41 | data_out <= ram[addr[15:2]]; 42 | else 43 | ram[addr[15:2]] <= data_in; 44 | ready <= 1'b1; 45 | end 46 | else begin 47 | data_out <= 32'h0000_0000; 48 | ready <= 1'b0; 49 | end 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/xsi_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef _XSI_LOADER_H_ 2 | #define _XSI_LOADER_H_ 3 | 4 | #include "xsi.h" 5 | #include "xsi_shared_lib.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace Xsi { 11 | 12 | class LoaderException : public std::exception { 13 | public: 14 | LoaderException(const std::string& msg) : _msg("ISim engine error: " + msg) { } 15 | 16 | virtual ~LoaderException() throw() { } 17 | 18 | virtual const char * what() const throw() { return _msg.c_str(); } 19 | private: 20 | std::string _msg; 21 | }; 22 | 23 | class Loader { 24 | public: 25 | Loader(const std::string& dll_name, const std::string& simkernel_libname); 26 | ~Loader(); 27 | 28 | bool isopen() const; 29 | void open(p_xsi_setup_info setup_info); 30 | void close(); 31 | void run(XSI_INT64 step); 32 | void restart(); 33 | int get_value(int port_number, void* value); 34 | int get_port_number(const char* port_name); 35 | const char *get_port_name(int port_number); 36 | void put_value(int port_number, const void* value); 37 | int get_status(); 38 | const char* get_error_info(); 39 | void trace_all(); 40 | XSI_INT64 get_time(); 41 | 42 | private: 43 | bool initialize(); 44 | 45 | Xsi::SharedLibrary _design_lib; 46 | Xsi::SharedLibrary _simkernel_lib; 47 | std::string _design_libname; 48 | std::string _simkernel_libname; 49 | 50 | xsiHandle _design_handle; 51 | 52 | t_fp_xsi_open _xsi_open; 53 | t_fp_xsi_close _xsi_close; 54 | t_fp_xsi_run _xsi_run; 55 | t_fp_xsi_get_value _xsi_get_value; 56 | t_fp_xsi_put_value _xsi_put_value; 57 | t_fp_xsi_get_status _xsi_get_status; 58 | t_fp_xsi_get_error_info _xsi_get_error_info; 59 | t_fp_xsi_restart _xsi_restart; 60 | t_fp_xsi_get_port_number _xsi_get_port_number; 61 | t_fp_xsi_get_port_name _xsi_get_port_name; 62 | t_fp_xsi_trace_all _xsi_trace_all; 63 | t_fp_xsi_get_time _xsi_get_time; 64 | 65 | }; // class Loader 66 | 67 | } // namespace Xsi 68 | 69 | #endif // _XSI_LOADER_H_ 70 | 71 | 72 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_1/xsi_shared_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * xsi_shared_library.h 3 | * Copyright (c) 2012, Xilinx, Inc. All Rights Reserved. 4 | * Class for loading shared libraries generated by xelab 5 | */ 6 | 7 | #ifndef _XSI_SHARED_LIB_H 8 | #define _XSI_SHARED_LIB_H 9 | 10 | #if defined(_WIN32) 11 | # include 12 | #else 13 | # include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | namespace Xsi { 20 | 21 | class SharedLibrary { 22 | public: 23 | #if defined(_WIN32) 24 | typedef HINSTANCE handle_type; 25 | #else 26 | typedef void * handle_type; 27 | #endif 28 | typedef void * symbol_type; 29 | 30 | SharedLibrary() : _lib(0), _retain(false) { } 31 | ~SharedLibrary() { unload(); } 32 | operator bool() const { return (_lib != 0); } 33 | bool loaded() const { return (_lib != 0); } 34 | handle_type handle() const { return _lib; } 35 | const std::string& path() const { return _path; } 36 | const std::string& error() const { return _err; } 37 | bool load(const std::string& path) 38 | { 39 | unload(); 40 | // reset the retain flag 41 | _retain = false; 42 | 43 | if (path.empty()) { 44 | _err = "Failed to load shared library. " 45 | "Path of the shared library is not specified."; 46 | return false; 47 | } 48 | std::string msg; 49 | bool ok = load_impl(path, msg); 50 | if (ok) { 51 | _path = path; 52 | _err.clear(); 53 | } 54 | else { 55 | _err = "Failed to load shared library \"" + path + 56 | "\". " + msg; 57 | } 58 | return ok; 59 | } 60 | 61 | bool load_impl(const std::string& path, std::string& errmsg) 62 | { 63 | bool ok = true; 64 | #if defined(_WIN32) 65 | SetLastError(0); 66 | _lib = LoadLibrary(path.c_str()); 67 | if (_lib == 0) { 68 | translate_error_message(GetLastError(), errmsg); 69 | ok = false; 70 | } 71 | #else 72 | _lib = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); 73 | char *err = dlerror(); 74 | if (err != NULL) { 75 | errmsg = err; 76 | ok = false; 77 | } 78 | #endif 79 | return ok; 80 | } 81 | 82 | void unload() 83 | { 84 | if (_lib) { 85 | if (!_retain) { 86 | #if defined(_WIN32) 87 | FreeLibrary(_lib); 88 | #else 89 | dlclose(_lib); 90 | #endif 91 | } 92 | _lib = 0; 93 | } 94 | _err.clear(); 95 | } 96 | 97 | void retain() 98 | { 99 | _retain = true; 100 | } 101 | 102 | bool getsymbol(const std::string& name, symbol_type& sym) 103 | { 104 | std::string msg; 105 | bool ok = true; 106 | 107 | if (_lib == 0) { 108 | msg = "The shared library is not loaded."; 109 | ok = false; 110 | } 111 | else { 112 | 113 | #if defined(_WIN32) 114 | sym = (void*) GetProcAddress(_lib, name.c_str()); 115 | if (sym == NULL) { 116 | translate_error_message(GetLastError(), msg); 117 | ok = false; 118 | } 119 | #else 120 | dlerror(); // clear error 121 | sym = (void *) dlsym(_lib, name.c_str()); 122 | char *err = dlerror(); 123 | if (err != NULL) { 124 | msg = err; 125 | ok = false; 126 | } 127 | #endif 128 | } 129 | 130 | if (ok) { 131 | _err.clear(); 132 | } 133 | else { 134 | _err = "Failed to obtain symbol \"" + name + 135 | "\" from shared library. " + msg; 136 | } 137 | 138 | return ok; 139 | } 140 | 141 | symbol_type getfunction(const std::string& name) 142 | { 143 | symbol_type sym = NULL; 144 | return getsymbol(name, sym) ? sym : NULL; 145 | } 146 | 147 | private: 148 | // shared library is non-copyable 149 | SharedLibrary(const SharedLibrary&); 150 | const SharedLibrary& operator=(const SharedLibrary&); 151 | 152 | #if defined(_WIN32) 153 | static void translate_error_message(DWORD errid, std::string& msg) 154 | { 155 | LPVOID bufptr; 156 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 157 | FORMAT_MESSAGE_FROM_SYSTEM | 158 | FORMAT_MESSAGE_IGNORE_INSERTS, 159 | NULL, 160 | errid, 161 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 162 | (LPTSTR) &bufptr, 163 | 0, 164 | NULL); 165 | msg.clear(); 166 | if (bufptr) { 167 | msg = reinterpret_cast(bufptr); 168 | } 169 | LocalFree(bufptr); 170 | } 171 | 172 | static const std::string& library_suffix() 173 | { 174 | static const std::string s = ".dll"; 175 | return s; 176 | } 177 | #else 178 | static const std::string& library_suffix() 179 | { 180 | static const std::string s = ".so"; 181 | return s; 182 | } 183 | #endif 184 | 185 | handle_type _lib; 186 | std::string _path; 187 | std::string _err; 188 | bool _retain; 189 | }; 190 | 191 | } // namespace Xsi 192 | 193 | #endif // _XSI_SHARED_LIB_H 194 | 195 | 196 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/bfm.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bfm.h" 3 | 4 | using namespace std; 5 | 6 | const s_xsi_vlog_logicval one_val = {0X00000001, 0X00000000}; 7 | const s_xsi_vlog_logicval zero_val = {0X00000000, 0X00000000}; 8 | const int clock_period_2 = 5; 9 | 10 | void set_bfm(bfm* bfm); // from bfm_api.cpp 11 | 12 | bfm::bfm() : xsi("xsim.dir/top/xsimk.so", "librdi_simulator_kernel.so") 13 | { 14 | s_xsi_setup_info info; 15 | memset(&info, 0, sizeof(info)); 16 | info.logFileName = NULL; 17 | char wdbName[] = "test.wdb"; 18 | info.wdbFileName = wdbName; 19 | xsi.open(&info); 20 | xsi.trace_all(); 21 | 22 | clock = xsi.get_port_number("clk"); 23 | reset = xsi.get_port_number("reset"); 24 | cs = xsi.get_port_number("cs"); 25 | rw = xsi.get_port_number("rw"); 26 | addr = xsi.get_port_number("addr"); 27 | data_in = xsi.get_port_number("data_in"); 28 | data_out = xsi.get_port_number("data_out"); 29 | ready = xsi.get_port_number("ready"); 30 | 31 | set_bfm(this); 32 | 33 | write_low(cs); 34 | write_low(rw); 35 | write_addr(0x00); 36 | write_data(0x00); 37 | } 38 | 39 | bfm::~bfm(){ 40 | xsi.close(); 41 | } 42 | 43 | void bfm::write_hi(int sig) { 44 | xsi.put_value(sig, &one_val); 45 | } 46 | 47 | void bfm::write_low(int sig) { 48 | xsi.put_value(sig, &zero_val); 49 | } 50 | 51 | void bfm::wait_hi() { 52 | write_hi(clock); 53 | xsi.run(clock_period_2); 54 | } 55 | 56 | void bfm::wait_low() { 57 | write_low(clock); 58 | xsi.run(clock_period_2); 59 | } 60 | 61 | void bfm::wait() { 62 | wait_hi(); 63 | wait_low(); 64 | } 65 | 66 | void bfm::reset_task(){ 67 | write_hi(reset); 68 | for(int i=0;i<4;i++) { 69 | wait(); 70 | } 71 | write_low(reset); 72 | wait(); 73 | cout << "done reset" << endl; 74 | } 75 | 76 | bool bfm::read_ready() { 77 | s_xsi_vlog_logicval val; 78 | xsi.get_value(ready, &val); 79 | cout << "time : " << dec << xsi.get_time() << ", val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 80 | return ((val.aVal & 0x1) ? true : false); 81 | } 82 | 83 | void bfm::write_addr(uint32_t data) { 84 | s_xsi_vlog_logicval val = {data, 0x0}; 85 | cout << "write_addr(0x" << hex << data << ")" << endl; 86 | xsi.put_value(addr, &val); 87 | } 88 | 89 | void bfm::write_data(uint32_t data) { 90 | s_xsi_vlog_logicval val = {data, 0x0}; 91 | cout << "write_data(0x" << hex << data << ")" << endl; 92 | xsi.put_value(data_in, &val); 93 | } 94 | 95 | uint32_t bfm::read_data() { 96 | s_xsi_vlog_logicval val; 97 | xsi.get_value(data_out, &val); 98 | cout << "read_data : " << "val.aVal(0x" << hex << val.aVal << "), val.bVal(0x" << val.bVal << ")" << endl; 99 | return val.aVal; 100 | } 101 | 102 | uint32_t bfm::read(uint32_t addr_){ 103 | write_hi(cs); 104 | write_hi(rw); 105 | write_addr(addr_); 106 | wait_hi(); 107 | 108 | wait_low(); 109 | while(!read_ready()){ 110 | wait(); 111 | } 112 | uint32_t data = read_data(); 113 | 114 | write_low(cs); 115 | write_low(rw); 116 | write_addr(0x0); 117 | wait_hi(); 118 | 119 | wait_low(); 120 | return data; 121 | } 122 | 123 | void bfm::write(uint32_t addr_, uint32_t data_){ 124 | write_hi(cs); 125 | write_low(rw); 126 | write_addr(addr_); 127 | write_data(data_); 128 | wait_hi(); 129 | 130 | wait_low(); 131 | while(!read_ready()){ 132 | wait(); 133 | } 134 | 135 | write_low(cs); 136 | write_low(rw); 137 | write_addr(0x0); 138 | write_data(0x0); 139 | wait_hi(); 140 | 141 | wait_low(); 142 | } 143 | 144 | void test_main(); 145 | 146 | void bfm::main(){ 147 | reset_task(); 148 | 149 | test_main(); 150 | 151 | cout << "ime = " << xsi.get_time() << endl; 152 | } 153 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/bfm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "xsi_loader.h" 5 | 6 | class bfm { 7 | public: 8 | 9 | bfm(); 10 | ~bfm(); 11 | void main(); 12 | 13 | uint32_t read(uint32_t addr_); 14 | void write(uint32_t addr_, uint32_t data_); 15 | 16 | private: 17 | 18 | Xsi::Loader xsi; 19 | 20 | int clock; 21 | int reset; 22 | int cs; 23 | int rw; 24 | int addr; 25 | int data_in; 26 | int data_out; 27 | int ready; 28 | 29 | void write_hi(int sig); 30 | void write_low(int sig); 31 | 32 | void wait_hi(); 33 | void wait_low(); 34 | void wait(); 35 | 36 | void reset_task(); 37 | 38 | bool read_ready(); 39 | void write_addr(uint32_t data); 40 | void write_data(uint32_t data); 41 | uint32_t read_data(); 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/bfm_api.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm.h" 2 | #include "bfm_api.h" 3 | 4 | static bfm *bfmp = nullptr; 5 | 6 | void set_bfm(bfm* bfm) { 7 | bfmp = bfm; 8 | } 9 | 10 | bool check_bfm() { 11 | return (bfmp == nullptr); 12 | } 13 | 14 | uint32_t read(uint32_t addr_) { 15 | if(!check_bfm()) 16 | return bfmp->read(addr_); 17 | return 0; 18 | } 19 | 20 | void write(uint32_t addr_, uint32_t data_) { 21 | if(!check_bfm()) 22 | bfmp->write(addr_, data_); 23 | return; 24 | } 25 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/bfm_api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | uint32_t read(uint32_t addr); 9 | void write(uint32_t addr, uint32_t data); 10 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEST=$1 4 | 5 | if [ ! -e ${TEST}.cpp ]; then 6 | echo "can't find ${TEST}.cpp" 7 | fi 8 | 9 | #VIVADO_BIN_DIR to the directory which has vivado executable 10 | 11 | #VIVADO_BIN_DIR="$RDI_ROOT/prep/rdi/vivado/bin" 12 | VIVADO_BIN_DIR="$XILINX_VIVADO/bin" 13 | 14 | OUT_SIM_SNAPSHOT="top" 15 | XSI_INCLUDE_DIR="$VIVADO_BIN_DIR/../data/xsim/include" 16 | GCC_COMPILER="/usr/bin/g++" 17 | XSIM_ELAB="xelab" 18 | OUT_EXE="run_simulation" 19 | export LD_LIBRARY_PATH="$XILINX_VIVADO/lib/lnx64.o" 20 | 21 | # Start clean 22 | #rm -rf xsim.dir xsim.log xelab* $OUT_EXE 23 | 24 | # Compile the HDL design into a simulatable Shared Library 25 | $XSIM_ELAB work.top -prj top.prj -dll -s $OUT_SIM_SNAPSHOT -debug wave 26 | 27 | # Compile the C++ code that interfaces with XSI of ISim 28 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o xsi_loader.o xsi_loader.cpp 29 | 30 | # Compile the program that needs to simulate the HDL design 31 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o bfm.o bfm.cpp 32 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o bfm_api.o bfm_api.cpp 33 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o test.o ${TEST}.cpp 34 | $GCC_COMPILER -I$XSI_INCLUDE_DIR -O3 -c -o testbench.o testbench.cpp 35 | 36 | $GCC_COMPILER -o $OUT_EXE bfm.o bfm_api.o test.o testbench.o xsi_loader.o -ldl -lrt 37 | 38 | # Run the program 39 | ./$OUT_EXE 40 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/test_1.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm_api.h" 2 | 3 | void test_main(){ 4 | cout << "start test_main" << endl; 5 | write(0x200, 0x12345678); 6 | uint32_t data = read(0x200); 7 | if(data != 0x12345678) 8 | cout << "<>, compare error, data = 0x" << hex << data << endl; 9 | cout << "finish test_main" << endl; 10 | } 11 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/test_2.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm_api.h" 2 | 3 | void bfm::test_main(){ 4 | uint32_t exp[0x10000>>2]; 5 | cout << "start test_main" << endl; 6 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 7 | exp[addr>>2] = rand(); 8 | write(addr, exp[addr>>2]); 9 | } 10 | cout << "done write" << endl; 11 | 12 | for(uint32_t addr=0x0;addr<0x10000;addr+=4){ 13 | uint32_t data = read(addr); 14 | if(data != exp[addr>>2]) 15 | cout << "<>, compare error, addr = 0x" << hex << addr << ", data = 0x" << hex << data << endl; 16 | } 17 | 18 | cout << "finish test_main" << endl; 19 | } 20 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/testbench.cpp: -------------------------------------------------------------------------------- 1 | #include "bfm.h" 2 | 3 | int main() { 4 | 5 | bfm u_bfm; 6 | 7 | u_bfm.main(); 8 | 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/top.prj: -------------------------------------------------------------------------------- 1 | sv work top.v 2 | # List other design files here 3 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/top.v: -------------------------------------------------------------------------------- 1 | module top 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | 6 | /* verilator lint_off UNUSED */ 7 | input logic [15:0] addr, 8 | /* verilator lint_on UNUSED */ 9 | input logic cs, 10 | input logic rw, 11 | input logic [31:0] data_in, 12 | output logic ready, 13 | output logic [31:0] data_out 14 | ); 15 | 16 | localparam ram_size = (17'h10000>>2); 17 | /* verilator lint_off WIDTH */ 18 | logic [31:0] ram[ram_size]; 19 | /* verilator lint_on WIDTH */ 20 | 21 | enum {STATE_IDLE, STATE_RUN, STATE_DONE} state; 22 | 23 | always_ff @(posedge clk) begin 24 | if(reset == 1'b1) 25 | state <= STATE_IDLE; 26 | else if(cs == 1'b1 && state == STATE_IDLE) 27 | state <= STATE_RUN; 28 | else if(cs == 1'b1 && state == STATE_RUN) 29 | state <= STATE_DONE; 30 | else if(cs == 1'b0) 31 | state <= STATE_IDLE; 32 | end 33 | 34 | always_ff @(posedge clk) begin 35 | if(reset == 1'b1) begin 36 | data_out <= 32'h0000_0000; 37 | ready <= 1'b0; 38 | end 39 | else if(state == STATE_RUN) begin 40 | if(rw == 1'b1) 41 | data_out <= ram[addr[15:2]]; 42 | else 43 | ram[addr[15:2]] <= data_in; 44 | ready <= 1'b1; 45 | end 46 | else begin 47 | data_out <= 32'h0000_0000; 48 | ready <= 1'b0; 49 | end 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/xsi_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef _XSI_LOADER_H_ 2 | #define _XSI_LOADER_H_ 3 | 4 | #include "xsi.h" 5 | #include "xsi_shared_lib.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace Xsi { 11 | 12 | class LoaderException : public std::exception { 13 | public: 14 | LoaderException(const std::string& msg) : _msg("ISim engine error: " + msg) { } 15 | 16 | virtual ~LoaderException() throw() { } 17 | 18 | virtual const char * what() const throw() { return _msg.c_str(); } 19 | private: 20 | std::string _msg; 21 | }; 22 | 23 | class Loader { 24 | public: 25 | Loader(const std::string& dll_name, const std::string& simkernel_libname); 26 | ~Loader(); 27 | 28 | bool isopen() const; 29 | void open(p_xsi_setup_info setup_info); 30 | void close(); 31 | void run(XSI_INT64 step); 32 | void restart(); 33 | int get_value(int port_number, void* value); 34 | int get_port_number(const char* port_name); 35 | const char *get_port_name(int port_number); 36 | void put_value(int port_number, const void* value); 37 | int get_status(); 38 | const char* get_error_info(); 39 | void trace_all(); 40 | XSI_INT64 get_time(); 41 | 42 | private: 43 | bool initialize(); 44 | 45 | Xsi::SharedLibrary _design_lib; 46 | Xsi::SharedLibrary _simkernel_lib; 47 | std::string _design_libname; 48 | std::string _simkernel_libname; 49 | 50 | xsiHandle _design_handle; 51 | 52 | t_fp_xsi_open _xsi_open; 53 | t_fp_xsi_close _xsi_close; 54 | t_fp_xsi_run _xsi_run; 55 | t_fp_xsi_get_value _xsi_get_value; 56 | t_fp_xsi_put_value _xsi_put_value; 57 | t_fp_xsi_get_status _xsi_get_status; 58 | t_fp_xsi_get_error_info _xsi_get_error_info; 59 | t_fp_xsi_restart _xsi_restart; 60 | t_fp_xsi_get_port_number _xsi_get_port_number; 61 | t_fp_xsi_get_port_name _xsi_get_port_name; 62 | t_fp_xsi_trace_all _xsi_trace_all; 63 | t_fp_xsi_get_time _xsi_get_time; 64 | 65 | }; // class Loader 66 | 67 | } // namespace Xsi 68 | 69 | #endif // _XSI_LOADER_H_ 70 | 71 | 72 | -------------------------------------------------------------------------------- /xsim/sample_xsi_bfm_4/xsi_shared_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * xsi_shared_library.h 3 | * Copyright (c) 2012, Xilinx, Inc. All Rights Reserved. 4 | * Class for loading shared libraries generated by xelab 5 | */ 6 | 7 | #ifndef _XSI_SHARED_LIB_H 8 | #define _XSI_SHARED_LIB_H 9 | 10 | #if defined(_WIN32) 11 | # include 12 | #else 13 | # include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | namespace Xsi { 20 | 21 | class SharedLibrary { 22 | public: 23 | #if defined(_WIN32) 24 | typedef HINSTANCE handle_type; 25 | #else 26 | typedef void * handle_type; 27 | #endif 28 | typedef void * symbol_type; 29 | 30 | SharedLibrary() : _lib(0), _retain(false) { } 31 | ~SharedLibrary() { unload(); } 32 | operator bool() const { return (_lib != 0); } 33 | bool loaded() const { return (_lib != 0); } 34 | handle_type handle() const { return _lib; } 35 | const std::string& path() const { return _path; } 36 | const std::string& error() const { return _err; } 37 | bool load(const std::string& path) 38 | { 39 | unload(); 40 | // reset the retain flag 41 | _retain = false; 42 | 43 | if (path.empty()) { 44 | _err = "Failed to load shared library. " 45 | "Path of the shared library is not specified."; 46 | return false; 47 | } 48 | std::string msg; 49 | bool ok = load_impl(path, msg); 50 | if (ok) { 51 | _path = path; 52 | _err.clear(); 53 | } 54 | else { 55 | _err = "Failed to load shared library \"" + path + 56 | "\". " + msg; 57 | } 58 | return ok; 59 | } 60 | 61 | bool load_impl(const std::string& path, std::string& errmsg) 62 | { 63 | bool ok = true; 64 | #if defined(_WIN32) 65 | SetLastError(0); 66 | _lib = LoadLibrary(path.c_str()); 67 | if (_lib == 0) { 68 | translate_error_message(GetLastError(), errmsg); 69 | ok = false; 70 | } 71 | #else 72 | _lib = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); 73 | char *err = dlerror(); 74 | if (err != NULL) { 75 | errmsg = err; 76 | ok = false; 77 | } 78 | #endif 79 | return ok; 80 | } 81 | 82 | void unload() 83 | { 84 | if (_lib) { 85 | if (!_retain) { 86 | #if defined(_WIN32) 87 | FreeLibrary(_lib); 88 | #else 89 | dlclose(_lib); 90 | #endif 91 | } 92 | _lib = 0; 93 | } 94 | _err.clear(); 95 | } 96 | 97 | void retain() 98 | { 99 | _retain = true; 100 | } 101 | 102 | bool getsymbol(const std::string& name, symbol_type& sym) 103 | { 104 | std::string msg; 105 | bool ok = true; 106 | 107 | if (_lib == 0) { 108 | msg = "The shared library is not loaded."; 109 | ok = false; 110 | } 111 | else { 112 | 113 | #if defined(_WIN32) 114 | sym = (void*) GetProcAddress(_lib, name.c_str()); 115 | if (sym == NULL) { 116 | translate_error_message(GetLastError(), msg); 117 | ok = false; 118 | } 119 | #else 120 | dlerror(); // clear error 121 | sym = (void *) dlsym(_lib, name.c_str()); 122 | char *err = dlerror(); 123 | if (err != NULL) { 124 | msg = err; 125 | ok = false; 126 | } 127 | #endif 128 | } 129 | 130 | if (ok) { 131 | _err.clear(); 132 | } 133 | else { 134 | _err = "Failed to obtain symbol \"" + name + 135 | "\" from shared library. " + msg; 136 | } 137 | 138 | return ok; 139 | } 140 | 141 | symbol_type getfunction(const std::string& name) 142 | { 143 | symbol_type sym = NULL; 144 | return getsymbol(name, sym) ? sym : NULL; 145 | } 146 | 147 | private: 148 | // shared library is non-copyable 149 | SharedLibrary(const SharedLibrary&); 150 | const SharedLibrary& operator=(const SharedLibrary&); 151 | 152 | #if defined(_WIN32) 153 | static void translate_error_message(DWORD errid, std::string& msg) 154 | { 155 | LPVOID bufptr; 156 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 157 | FORMAT_MESSAGE_FROM_SYSTEM | 158 | FORMAT_MESSAGE_IGNORE_INSERTS, 159 | NULL, 160 | errid, 161 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 162 | (LPTSTR) &bufptr, 163 | 0, 164 | NULL); 165 | msg.clear(); 166 | if (bufptr) { 167 | msg = reinterpret_cast(bufptr); 168 | } 169 | LocalFree(bufptr); 170 | } 171 | 172 | static const std::string& library_suffix() 173 | { 174 | static const std::string s = ".dll"; 175 | return s; 176 | } 177 | #else 178 | static const std::string& library_suffix() 179 | { 180 | static const std::string s = ".so"; 181 | return s; 182 | } 183 | #endif 184 | 185 | handle_type _lib; 186 | std::string _path; 187 | std::string _err; 188 | bool _retain; 189 | }; 190 | 191 | } // namespace Xsi 192 | 193 | #endif // _XSI_SHARED_LIB_H 194 | 195 | 196 | --------------------------------------------------------------------------------