はじめに
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 じゃないのは仕様なんでしょうか?