I've found simulating using iverilog to be a less than suitable method, I can simulate designs that won't synthesise and conversely designs that will not only synthesize but also work as intended on physical hardware, won't synthesise with iverilog for simulation.
What I'm ideally looking to do take the output of yosys (a blif file) and create a simulation waveform (vcd) that I can have better confidence in.
A typical simulation waveform will contain thousands of cycles. There is probably some complex model reset, followed by many cycles of random or irrelevant activity until a particular test condition or failure is reached.
Yosys can be adapted to perform any synthesis job by combining the existing passes (algorithms) using synthesis scripts and adding additional passes as needed by extending the Yosys C++ code base. Yosys is free software licensed under the ISC license (a GPL compatible license that is similar in terms to the MIT license or the 2-clause BSD license).
Waveform files are typically generated by an interactive graphical waveform editor. The file is then read by the simulation tools to implement design test stimulus. One example is the HDL bencher from Xilinx.
The two most common types of simulation stimulus files are waveform and testbench files. In general waveform stimulus are avoided for rapid system prototyping efforts. For this reason, only a brief discussion of waveform simulation will be presented. Waveform files are typically generated by an interactive graphical waveform editor.
So you want to run post-synthesis simulation of iCE40 BLIF netlists.
Consider the following simple example design (test.v
):
module test(input clk, resetn, output reg [3:0] y);
always @(posedge clk)
y <= resetn ? y + 1 : 0;
endmodule
And its testbench (test_tb.v
):
module testbench;
reg clk = 1, resetn = 0;
wire [3:0] y;
always #5 clk = ~clk;
initial begin
repeat (10) @(posedge clk);
resetn <= 1;
repeat (20) @(posedge clk);
$finish;
end
always @(posedge clk) begin
$display("%b", y);
end
test uut (
.clk(clk),
.resetn(resetn),
`ifdef POST_SYNTHESIS
. \y[0] (y[0]),
. \y[1] (y[1]),
. \y[2] (y[2]),
. \y[3] (y[3])
`else
.y(y)
`endif
);
endmodule
Running pre-synthesis simulation is of course simple:
$ iverilog -o test_pre test.v test_tb.v
$ ./test_pre
For post-synthesis simulation we must first run synthesis:
$ yosys -p 'synth_ice40 -top test -blif test.blif' test.v
Then we must convert the BLIF netlist to a verilog netlist so it can be read by Icarus Verilog:
$ yosys -o test_syn.v test.blif
Now we can build the simulation binary from the test bench, the synthesized design, and the iCE40 simulation models, and run it:
$ iverilog -o test_post -D POST_SYNTHESIS test_tb.v test_syn.v \
`yosys-config --datdir/ice40/cells_sim.v`
$ ./test_post
[..] won't synthesize with iverilog for simulation.
This is most likely because Yosys is not as strict as iverilog when it comes to enforcing the Verilog standard. For example, in many cases Yosys will except Verilog files with the reg
keyword missing from wires that would require the reg
keyword according to the Verilog standard. For example, yosys will accept the following input, even though it is not valid Verilog code:
module test(input a, output y);
always @* y = !a;
endmodule
For Icarus Verilog you have to add the missing reg
:
module test(input a, output reg y);
always @* y = !a;
endmodule
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With