Services - tools - models - for embedded software development
Embecosm divider strip
Prev  Next

6.1.  Fixing the Initial Errors

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.


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:


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

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)
    if ( reset_i )
        ram_out <= #1 8'h0 ;
    else if ( translation_table_enable )
        reg [7:0] bit_num ;

        bit_num = translation_table_address[4:0] << 3 ;

            ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ;
            bit_num = bit_num + 1'b1 ;

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:

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.

Embecosm divider strip