はじめに
Bluespec SystemVerilogで実装されている回路例の紹介、今回はBluespecのAPBです。
テストベンチ (Testbench)
テストベンチは、Testbench.sv です。
module mkTestbench (Empty); APB_Initiator_IFC source <- mkSource; APB_Target_IFC mem_model <- mkAPB_Mem_Model; mkConnection (source, mem_model); rule rl_dummy_APB_decoder_and_mux; mem_model.psel (True); endrule endmodule
APB_Initiator_IFC と APB_Target_IFC を接続しています。
APB_Initiator_IFC と APB_Target_IFC は、APB_Types.bsv の中で定義されています。
ビルド
cd build/APB-Fabric32 make compile mkdir -p build_dir mkdir -p Verilog_RTL INFO: Verilog RTL generation ... bsc -u -elab -sim -bdir build_dir -simdir build_dir -info-dir build_dir -D RV32 -D FABRIC32 -keep-fires -aggressive-conditions -no-warn-action-shadowing -no-show-timestamps -check-assert -suppress-warnings G0020 +RTS -K128M -RTS -show-range-conflict -p ./src_bsv:../../src:../../src_tb:+ ../../src_tb/Testbench.bsv checking package dependencies compiling ../../src/APB_Defs.bsv compiling ../../src/APB_Types.bsv compiling ../../src_tb/Cur_Cycle.bsv compiling ../../src_tb/Testbench_Commons.bsv compiling ../../src_tb/APB_Mem_Model.bsv code generation for mkAPB_Mem_Model starts Elaborated module file created: build_dir/mkAPB_Mem_Model.ba compiling ./src_bsv/EdgeFIFOFs.bsv compiling ./src_bsv/ISA_Decls.bsv compiling ./src_bsv/Semi_FIFOF.bsv compiling ./src_bsv/AXI4_Types.bsv compiling ./src_bsv/Fabric_Defs.bsv compiling ./src_bsv/MMU_Cache_Common.bsv compiling ../../src/APB_Adapter.bsv compiling ../../src_tb/Testbench.bsv code generation for mkSource starts Elaborated module file created: build_dir/mkSource.ba code generation for mkTestbench starts Warning: "../../src_tb/Testbench.bsv", line 35, column 8: (G0010) Rule "rl_connect_psel" was treated as more urgent than "rl_dummy_APB_decoder_and_mux". Conflicts: "rl_connect_psel" cannot fire before "rl_dummy_APB_decoder_and_mux": calls to mem_model.psel vs. mem_model.psel "rl_dummy_APB_decoder_and_mux" cannot fire before "rl_connect_psel": calls to mem_model.psel vs. mem_model.psel Warning: "../../src_tb/Testbench.bsv", line 41, column 9: (G0021) According to the generated schedule, rule `rl_dummy_APB_decoder_and_mux' can never fire. Elaborated module file created: build_dir/mkTestbench.ba All packages are up to date. bsc -u -elab -verilog -vdir Verilog_RTL -bdir build_dir -info-dir build_dir -D RV32 -D FABRIC32 -keep-fires -aggressive-conditions -no-warn-action-shadowing -no-show-timestamps -check-assert -suppress-warnings G0020 +RTS -K128M -RTS -show-range-conflict -p ./src_bsv:../../src:../../src_tb:+ ../../src_tb/Testbench.bsv checking package dependencies compiling ../../src_tb/APB_Mem_Model.bsv code generation for mkAPB_Mem_Model starts Verilog file created: Verilog_RTL/mkAPB_Mem_Model.v Elaborated module file created: build_dir/mkAPB_Mem_Model.ba compiling ../../src_tb/Testbench.bsv code generation for mkSource starts Verilog file created: Verilog_RTL/mkSource.v Elaborated module file created: build_dir/mkSource.ba code generation for mkTestbench starts Warning: "../../src_tb/Testbench.bsv", line 35, column 8: (G0010) Rule "rl_connect_psel" was treated as more urgent than "rl_dummy_APB_decoder_and_mux". Conflicts: "rl_connect_psel" cannot fire before "rl_dummy_APB_decoder_and_mux": calls to mem_model.psel vs. mem_model.psel "rl_dummy_APB_decoder_and_mux" cannot fire before "rl_connect_psel": calls to mem_model.psel vs. mem_model.psel Warning: "../../src_tb/Testbench.bsv", line 41, column 9: (G0021) According to the generated schedule, rule `rl_dummy_APB_decoder_and_mux' can never fire. Verilog file created: Verilog_RTL/mkTestbench.v Elaborated module file created: build_dir/mkTestbench.ba All packages are up to date. INFO: Verilog RTL generation finished
make bluesim_simulator
にて、実行プログラムを生成
- exe_HW_sim
- exe_HW_sim.so
exe_HW_sim は、shell script で次のようになっています。bluesim.tcl に対して、共有ライブラリ exe_HW_sim.so を渡し、トップテストベンチとして mkTestbech を指定しています。
#!/bin/sh BLUESPECDIR=`echo 'puts $env(BLUESPECDIR)' | bluetcl` for arg in $@ do if (test "$arg" = "-h") then exec $BLUESPECDIR/tcllib/bluespec/bluesim.tcl $0.so mkTestbench --script_name `basename $0` -h fi done exec $BLUESPECDIR/tcllib/bluespec/bluesim.tcl $0.so mkTestbench --script_name `basename $0` --creation_time 1689472003 "$@"
exe_sim_HW の実行
exe_sim_HW を実行すると、次のようなメッセージが表示されます。
./exe_sim_HW 1: top.source.rl_wr_32: Single_Req { is_read: False, addr: 'h00000000, size_code: 'h2 } 0x00000000 2:[D]:top.source.rl_new_tfr (paddr 0x00000000) (pwrite: True) (pstrb: 1111) (pwdata 0x00000000) 3:[D]:top.source.rl_setup: (addr 0x00000000) (wdata 0x00000000) 40: top.mem_model.rl_new_write_tfr: IDLE 50: top.mem_model.rl_write_response: (addr 00) (data 00000000) WR_RSP 5:[D]:top.source.rl_write_response 6: top.source.rl_wr_32: Single_Req { is_read: False, addr: 'h00000004, size_code: 'h2 } 0x00000004 7:[D]:top.source.rl_new_tfr (paddr 0x00000004) (pwrite: True) (pstrb: 1111) (pwdata 0x00000004) 8:[D]:top.source.rl_setup: (addr 0x00000004) (wdata 0x00000004) .... 44790: top.mem_model.rl_new_read_tfr: IDLE 44800: top.mem_model.rl_read_response: (addr fc) (data fffefdfc) RD_RSP 4480:[D]:top.source.rl_read_response: Read_Data { ok: False, data: 'hfffefdfc } 4481: top.source.rl_rd_rsp_8: Read_Data { ok: False, data: 'hfffefdfc }
verilator_simulator
Verilator にて実行してみます。
make verilator_simulator INFO: Verilating Verilog files (in newly created obj_dir) sed -f ../../build/Resources/Verilator_resources/sed_script.txt Verilog_RTL/mkTestbench.v > tmp1.v cat ../../build/Resources/Verilator_resources/verilator_config.vlt \ ../../build/Resources/Verilator_resources/import_DPI_C_decls.v \ tmp1.v > Verilog_RTL/mkTestbench_edited.v rm -f tmp1.v verilator \ -IVerilog_RTL \ -I../../src_bsc_lib_RTL \ --stats -O3 -CFLAGS -O3 -LDFLAGS -static --x-assign fast --x-initial fast --noassert --trace --trace-depth 10 -CFLAGS -DVM_TRACE \ --cc mkTestbench_edited.v \ --exe sim_main.cpp \ ../../src_tb/C_Imported_Functions.c %Error: Verilog_RTL/mkTestbench_edited.v:6:10: syntax error, unexpected '-' 6 | lint_off -msg WIDTH | ^ %Error: Exiting due to 1 error(s) make: *** [Makefile:85: verilator_simulator] Error 1
生成された Verilog_RTL/mkTestbench_edited.v の 6行目でエラーになります。Verilog_RTL/mkTestbench_edited.vをみてみます。どうやら、下記の部分がエラーになっています。
`verilator_config lint_off -msg WIDTH lint_off -msg CASEINCOMPLETE lint_off -msg STMTDLY lint_off -msg INITIALDLY lint_off -msg UNSIGNED lint_off -msg CMPCONST `verilog
この部分は、build/Resources/Verilator_resources/verilator_config.vlt なので、これをコメントアウトしてみました。
rm -rf Verilator_RTL make compile make verilator_simulator INFO: Verilating Verilog files (in newly created obj_dir) sed -f ../../build/Resources/Verilator_resources/sed_script.txt Verilog_RTL/mkTestbench.v > tmp1.v cat ../../build/Resources/Verilator_resources/verilator_config.vlt \ ../../build/Resources/Verilator_resources/import_DPI_C_decls.v \ tmp1.v > Verilog_RTL/mkTestbench_edited.v rm -f tmp1.v verilator \ -IVerilog_RTL \ -I../../src_bsc_lib_RTL \ --stats -O3 -CFLAGS -O3 -LDFLAGS -static --x-assign fast --x-initial fast --noassert --trace --trace-depth 10 -CFLAGS -DVM_TRACE \ --cc mkTestbench_edited.v \ --exe sim_main.cpp \ ../../src_tb/C_Imported_Functions.c %Error: Verilog_RTL/mkSource.v:292:3: Cannot find file containing module: 'FIFO1' 292 | FIFO1 #(.width(32'd33), .guarded(1'd1)) f_mem_rdata(.RST(RST_N), | ^~~~~ Verilog_RTL/mkTestbench_edited.v:194:1: ... note: In file included from mkTestbench_edited.v ... Looked in: Verilog_RTL/FIFO1 Verilog_RTL/FIFO1.v Verilog_RTL/FIFO1.sv ../../src_bsc_lib_RTL/FIFO1 ../../src_bsc_lib_RTL/FIFO1.v ../../src_bsc_lib_RTL/FIFO1.sv FIFO1 FIFO1.v FIFO1.sv obj_dir/FIFO1 obj_dir/FIFO1.v obj_dir/FIFO1.sv %Error: Verilog_RTL/mkSource.v:303:3: Cannot find file containing module: 'FIFO1' 303 | FIFO1 #(.width(32'd35), .guarded(1'd1)) f_mem_req(.RST(RST_N), | ^~~~~ Verilog_RTL/mkTestbench_edited.v:194:1: ... note: In file included from mkTestbench_edited.v %Error: Verilog_RTL/mkSource.v:314:3: Cannot find file containing module: 'FIFO1' 314 | FIFO1 #(.width(32'd32), .guarded(1'd1)) f_mem_wdata(.RST(RST_N), | ^~~~~
FIFO1が無いと怒られます。上記のコマンドの引数を見ると、../../src_bsc_lib_RTL なるディレクトリを参照しています。APB には src_bsc_lib_RTL なるディレクトリはありません。調べてみたら、AHB-Lte という repo に src_bsc_lib_RTL ディレクトリがありましたので、コピーしてみました。再度、make を実行しましたら、
Verilog_RTL/mkTestbench_edited.v:180:1: ... note: In file included from mkTestbench_edited.v %Error-NEEDTIMINGOPT: Verilog_RTL/mkSource.v:668:5: Use --timing or --no-timing to specify how delays should be handled : ... In instance mkTestbench.source 668 | #0; | ^
ここで使っている verilator は 5.002 なので、上記のように #0 を使う時は、--timing オプションを使うことになっています。Makefileの中で
verilator \ --timing \ <===== これを追加 -IVerilog_RTL \ -I$(REPO)/src_bsc_lib_RTL \ $(VERILATOR_FLAGS) \ --cc $(TOPMODULE)_edited.v \ --exe sim_main.cpp \ $(REPO)/src_tb/C_Imported_Functions.c
再度実行したら、下記のようなエラーが発生しました。
%Error-ZERODLY: Verilog_RTL/mkAPB_Mem_Model.v:387:5: Unsupported: #0 delays do not schedule process resumption in the Inactive region 387 | #0; | ^
--timing を --no-timingにしたら、上記のエラーは無くなりましたが、make コマンドは失敗します。
%Error: Exiting due to 38 warning(s) make: *** [Makefile:85: verilator_simulator] Error 1
verilator の後の下記の部分を手動で実行してみました。
@echo "INFO: Linking verilated files" cp -p $(VERILATOR_RESOURCES)/sim_main.cpp obj_dir/sim_main.cpp cd obj_dir; \ make -j -f V$(TOPMODULE)_edited.mk $(VTOP); \
生成された VmkTestbench_edited ($VTOP) を実行したら、bluesim_simulator ターゲットで生成された exe_sim_HW のログとだいたい同じになりました。 (Pathの top と TOP.mkTestbench の違いと、タイムスタンプの上位ビットが0で埋まっているぐらいの違い)
verilator v5.012
Verilator v5.012 にて、同じように行ったら、
--no-timing / --timing 共に、 `` ./VmkTestbench_edited Segmentation fault
となってしまいました。 # おわりに Verilator が Warningだけなのに、exit status が 0 じゃないのは仕様なんでしょうか?