It is simple to take the baseline command file from the Icarus Verilog
simulation (see Chapter 4) and modify
it for use with Verilator. All that is needed is to remove the
reference to orpsoc_bench.v
and
or1200_monitor.v
.
As noted earlier, there are multiple instances of
timescale.v
, with different values for time unit
and precision. Now all the Verilog files form a single SoC design, and
all their header directories are specified using
+incdir+
. So now all components will use the same
timescale.v
, the copy in
$RTL_DIR
(orp_soc/rtl/verilog). This specifies
1ps/1ps
, a different value to that used in
simulation, but does not have any practical impact.
The model can be built with:
make verilate COMMAND_FILE=cf-baseline.scr
This immediately produces a slew of warnings and errors
%Warning-CASEX: ../orp_soc/rtl/verilog/or1200/or1200_alu.v:207: Suggest casez (w ith ?'s) in place of casex (with X's) %Warning-CASEX: Use "/* verilator lint_off CASEX */" and lint_on around source t o disable this message. %Warning-CASEX: ../orp_soc/rtl/verilog/or1200/or1200_alu.v:278: Suggest casez (w ith ?'s) in place of casex (with X's) %Warning-CASEX: ../orp_soc/rtl/verilog/or1200/or1200_alu.v:280: Suggest casez (w ith ?'s) in place of casex (with X's) ... %Warning-CASEX: ../orp_soc/rtl/verilog/or1200/or1200_mult_mac.v:196: Suggest cas ez (with ?'s) in place of casex (with X's) %Error: ../orp_soc/rtl/verilog/mem_if/flash_top.v:210: syntax error, unexpected ')' %Error: Cannot continue %Error: Command Failed /home/jeremy/tools/verilator/verilator-3.700/verilator_bi n -Mdir . -sc -f v-processed.scr
The first step is to turn off the warnings, to allow the errors to
stand out, using the VFLAGS
macro.
make verilate COMMAND_FILE=cf-baseline.scr VFLAGS=-Wno-lint
The result of this is:
%Error: ../orp_soc/rtl/verilog/mem_if/flash_top.v:210: syntax error, unexpected ')' %Error: Cannot continue %Error: Command Failed /home/jeremy/tools/verilator/verilator-3.700/verilator_bi n -Mdir . -sc -f v-processed.scr
Looking at the source file concerned
(flash_top.v
) shows the problem at line 210:
// synopsys translate_off integer fflash; initial fflash = $fopen("flash.log"); always @(posedge wb_clk_i) if (wb_cyc_i)
The problem is the use of the multi-channel descriptor form of
$fopen
, which is not supported by Verilator.
There are two solutions to this problem. A simple solution is to turn
this into a standard file descriptor open:
initial fflash = $fopen("flash.log", "w");
The alternative is to recognize that logging flash accesses is not of great interest to this model (it is something of greater concern to a hardware verification engineer with event-driven simulation).
Furthermore, this model will not be using external flash memory, and
only loads its image from file at start up. This is the time to replace
flash_top.v
by a much simpler model suitable for
cycle accurate use in our environment. This is provided in the local
directory, rtl/verilog/mem_if/flash_top.v
.
Tip | |
---|---|
There is always a balance between making the least possible change (minimizing the risk of introducing behavioral bugs) and complete replacement. In general making the least possible change is the right strategy. However memories are usually central to a model's performance, and can often be full of RTL structures, which are irrelevant to cycle-accurate modeling—for example buffering each input and output bit. In these cases (as here), it is worth replacing the original completely. The value of having a baseline event driven simulation model now becomes clear: VCD traces can be used to verify that the behavior of replacement models is consistent. |
The command file is modified to use the reference to this local
version instead of the standard flash_top.v
:
$RTL_LOCAL/mem_if/flash_top.v
Verilator is now re-run:
make verilate COMMAND_FILE=cf-baseline-2.scr VFLAGS=-Wno-lint
Verilator immediately hits its next error.
%Error: ../orp_soc/rtl/verilog/mem_if/sram_top.v:236: syntax error, unexpected ' )' %Error: Cannot continue %Error: Command Failed /home/jeremy/tools/verilator/verilator-3.700/verilator_bi n -Wno-lint -Mdir . -sc -f v-processed.scr
Exactly the same issue with logging in the SRAM model:
integer fsram; initial begin fsram = $fopen("sram.log"); for (i = 0; i < 2097152; i = i + 1) mem[i] = 0;
As before, the solution in this case is to replace
sram_top.v
with a simplified version suitable for
cycle accurate modeling. We then run Verilator again:
make verilate COMMAND_FILE=cf-baseline-3.scr VFLAGS=-Wno-lint
The next problem materializes:
%Error: ../orp_soc/rtl/verilog/ethernet/eth_wishbone.v:564: syntax error, unexpe cted do, expecting IDENTIFIER %Error: Cannot continue %Error: Command Failed /home/jeremy/tools/verilator/verilator-3.700/verilator_bi n -Wno-lint -Mdir . -sc -f v-processed.scr
Note | |
---|---|
It will be clear that getting rid of errors in Verilator can be quite tedious, because most errors will cause compilation to stop. This is a common problem, even with commercial tools, because of the nature of Verilog. All files depend on each other (they are not modular in the software sense), so a failure in one affects all the others in unknown ways. |
This error is a consequence of Verilator being able to process all
flavors of Verilog and SystemVerilog. In SystemVerilog
do
is a keyword, and may not be used as a
variable.
The correct fix is to replace the occurrences with a different
variable name. However the short term fix is to restrict Verilator
to just a particular language, in this case Verilog according to IEEE
1364-2001. This is achieved by using Verilator's
-language
option:
make verilate COMMAND_FILE=cf-baseline-3.scr \ VFLAGS="-Wno-lint -language 1364-2001"
The next error is an example of Verilator requiring synthesizable RTL as its input:
%Error: ../orp_soc/rtl/verilog/ps2/ps2_translation_table.v:181: Unsupported: Ver ilog 1995 reserved word not implemented: repeat %Error: ../orp_soc/rtl/verilog/ps2/ps2_translation_table.v:181: syntax error, un expected '(', expecting case or casex or casez or if %Error: Cannot continue %Error: Command Failed /home/jeremy/tools/verilator/verilator-3.700/verilator_bi n -Wno-lint -language 1364-2001 -Mdir . -sc -f v-processed.scr
Here is the code in ps2_translation_table.v
which
causes the problem.
always@(posedge clock_i or posedge reset_i) begin if ( reset_i ) ram_out <= #1 8'h0 ; else if ( translation_table_enable ) begin:get_dat_out reg [7:0] bit_num ; bit_num = translation_table_address[4:0] << 3 ; repeat(8) begin ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ; bit_num = bit_num + 1'b1 ; end end end
According the the IEEE standard, repeat
is not
synthesizable, even if, as in this case, it has a constant argument
and a clear synthesizable meaning.
The issue is confused, because some commercial synthesis tools will accept constructs like this, even though they are not permitted in the standard.
In this case the fix is very simple. The contents of the always block are just written out in full:
ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ; bit_num = bit_num + 8'b1 ; ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ; bit_num = bit_num + 8'b1 ; <5 more times> ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ; bit_num = bit_num + 8'b1 ;
The modified version of ps2_translation_table.v
is placed in the local directory
(rtl/verilog/ps2
), the command file altered and
Verilator rerun.
This time Verilator does not encounter any errors, but a whole load
of new warnings. The flag -Wno-lint
turns off many
warnings, but not all. Two warnings in particular are common:
Warning COMBDLY
. Use of non-blocking assignment
(delayed assignment) in combinatorial always
blocks. This issue is discussed in more detail in Chapter 7, but indicates a coding style that
may cause unexpected behavior in a cycle accurate model.
Warning UNOPTFLAT
. The presence of
combinatorial loops, which can seriously damage model
performance. This issue is discussed in more detail in Chapter 7, where it is a fruitful source of
performance enhancements.
For now both these warnings can be explicitly turned off using the
flags -Wno-COMBDLY
and
-Wno-UNOPTFLAT
.
make verilate COMMAND_FILE=cf-baseline-4.scr \ VFLAGS="-Wno-lint -Wno-COMBDLY -Wno-UNOPTFLAT -language 1364-2001"
This is sufficient for Verilator to successfully process the entire source and generate a model. However the complete SystemC model will not built—some header files needed by the C++ code are missing.
These headers are part of the system for accessing signals within the Verilator model. These must now be added.