YosysHQ / yosys

Yosys Open SYnthesis Suite
https://yosyshq.net/yosys/
ISC License
3.3k stars 860 forks source link

Inconsistent simulation before and after yosys synthesis #4369

Closed WeneneW closed 1 month ago

WeneneW commented 2 months ago

Version

Yosys 0.39+165

On which OS did this happen?

Linux

Reproduction Steps

I encountered an issue of inconsistent simulation before and after synthesis in Yosys. In the original verilog design rtl. v, I tested it using identity.testbench.v and outputted its results using the iverilog and vvp commands. Specifically, the command is as follows:

iverilog -o identity_main identity_testbench.v 
vvp -n identity_main -rtx2

The output result is 0142910c5b18098977453acaf354aaf0

Afterwards, I used yosys to synthesize it, and the command is as follows:

read_verilog rtl.v
synth
write_verilog syn_yosys.v

Similarly, simulate the synthesized file with the following command:

iverilog -o yosys_main yosys_testbench.v
vvp -n yosys_main -lxt2

The output result is 030769f173f5fe27333d757a6d22a3cb

For the convenience of reproduction, I have written a script where you only need to run bash run_sim.sh to view the simulation output of vvp in the corresponding folder (you can synthesize syn_yosys. v again to replace the existing one)

yosys_5_4.zip

Expected Behavior

Consistent output before and after synthesis In order to eliminate interference, I also simulated the Verilog file synthesized by Vivado, and the results were consistent with those before synthesis 9ee1591bcfe98874c6587685d0fcfce2

Actual Behavior

Inconsistent output before and after synthesis

KrystalDelusion commented 2 months ago

I will note that using verific instead of read_verilog gives identical outputs for vvp_yosys and vvp_identity, meaning this is due to the verilog parsing rather than the synthesis; but trying to identify exactly where the bug is coming from is difficult given the nature of the source provided. Having a quick look at the code, it seems the read_verilog path has optimised out forvar5 and reg23 which looks like the difference might be coming from the interpretation of if ({(wire2[(1'h1):(1'h0)] ^~ "")}).

It would be great if you could cut this down to a Minimal, Complete, and Verifiable Example (MCVE) in order to make this easier to identify where the difference is coming from (whether that is a bug, or a different interpretation of the verilog standard and how to treat e.g. strings not assigned a type).