leonardt / fault

A Python package for testing hardware (part of the magma ecosystem)
BSD 3-Clause "New" or "Revised" License
41 stars 13 forks source link

Ordering of -s argument for Icarus Verilog #252

Closed sgherbst closed 4 years ago

sgherbst commented 4 years ago

For the iverilog target, the -s argument specifying the top-level module comes after the source file list. https://github.com/leonardt/fault/blob/9b18b81c9157135ea3af4650cc81def7dc88d19e/fault/system_verilog_target.py#L1063-L1065

For the version of Icarus Verilog that I'm using (10.3) on macOS (10.15.5), this doesn't appear to work properly; -s and its value are interpreted as files, meaning that the top-level module isn't being specified.

For many cases, this is OK, but there are some scenarios where it is problematic. Consider this code example:

from pathlib import Path
import magma as m
import fault

class dut(m.Circuit):
    name = 'b' 
    io = m.IO(
        x = m.In(m.Bits[2]),
        y = m.Out(m.Bits[2])
    )   

tester = fault.Tester(dut)

tester.compile_and_run(
    target='system-verilog',
    simulator='iverilog',
    ext_srcs=[Path('a.v').resolve(),
              Path('b.v').resolve()],
    ext_model_file=True,
    disp_type='realtime',
    #no_top_module=True,
    #flags=['-s', 'b_tb']
)

where a.v is

module a(
    input [1:0] x,
    output [1:0] y
);
    assign y = x[0:1]; // invalid, but we're not actually instantiating this module...
endmodule

and b.v is

module b(
    input [1:0] x,
    output [1:0] y
);
    assign y = x[1:0];
endmodule

when the code is run, it produces this result:

Running command: iverilog -ob_tb -g2012 path/to/b_tb.sv path/to/a.v path/to/b.v -s b_tb
<STDERR>
-s: No such file or directory
path/to/a.v:5: error: part select x[0:1] is out of order.
1 error(s) during elaboration.
</STDERR>
Found 1 error(s):
1) Got return code 1.

Clearly the -s argument is not being interpreted correctly, and as a result, iverilog is trying to compile a.v as a top-level module even though that is not what we want.

The current workaround is to set no_top_module=True and manually specify the -s argument (i.e., the two commented-out lines in the Python code). Uncommenting them yields the expected result:

Running command: iverilog -s b_tb -ob_tb -g2012 path/to/b_tb.sv path/to/a.v path/to/b.v
Running command: vvp -N b_tb