Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong simulation result with adders and single-bit exclusive or gates #4709

Open
flaviens opened this issue Nov 20, 2023 · 3 comments
Open
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model status: asked reporter Bug is waiting for reporter to answer a question

Comments

@flaviens
Copy link

Hi there!

Summary

I found a bug where Verilator produces a wrong simulation result in a circuit made of XOR gates and adders.
One output bit is erroneous (out_data[160] in the specific case below) for some specific inputs.

Reproducing

You can find here a repository for helping you reproduce the issue.
This Docker image runs the same simulation with and without traces and gives different results. Icarus Verilog agrees with the result of Verilator with traces.
In inputs.txt, you will find some inputs that cause a mismatch on bit out_data[160].

I'm using the latest Verilator version Verilator 5.019 devel rev v5.018-44-gb8417abee on Ubuntu 20.04.
Please let me know if you need more information.

Thanks!
Flavien

@flaviens flaviens added the new New issue not seen by maintainers label Nov 20, 2023
@wsnyder wsnyder added status: ready Issue is ready for someone to fix; then goes to 'status: assigned' area: wrong runtime result Issue involves an incorrect runtine result from Verilated model and removed new New issue not seen by maintainers labels Nov 21, 2023
@wsnyder
Copy link
Member

wsnyder commented Nov 21, 2023

There's a lot of code there to look at.

  1. Please have the test use Verilator without docker, just assume it is installed. Or better use test_regress format as described in docs/internals.rst
  2. Can you reproduce using only verilog by itself, e.g. by passing the icarus input to verilator and using --binary?
  3. Please reduce the test case as much as possible, e.g. start commenting out assignments or setting to constants as long as the problem remains. Alternatively, tell us which exact assignment at which things go bad. (Normally tracing would point right to it, but in this case it goes away, which means it's almost certainly an optimizer bug.)
  4. Once 3 is done, you can also try the various -fno-* options to see if any workaround the issue. I'd try first -fno-const-bit-op-tree -fno-dfg-peephole -fno-dfg-pre-inline -fno-dfg-post-inline -fno-gate -fno-subst -fno-subst-const

@flaviens
Copy link
Author

Thank you for your fast response! I found a significantly simpler occurrence in the meanwhile. I'll go through the steps that you said and will let you know shortly 👍

@wsnyder wsnyder added status: asked reporter Bug is waiting for reporter to answer a question and removed status: ready Issue is ready for someone to fix; then goes to 'status: assigned' labels Nov 22, 2023
@flaviens flaviens changed the title Wrong simulation result when running without traces Wrong simulation result with adders and single-big exclusive or gates Nov 23, 2023
@flaviens
Copy link
Author

Hi @wsnyder, thank you again for your instructions.

Verilog only: The bug happens as well with a sv testbench instead of C++.

Case reduction: Here is a far smaller test case with a similar issue:

module top(in_data, out_data);
  wire _0_;
  wire _1_;
  wire [217:0] unused;
  input [1023:0] in_data;
  wire [1023:0] in_data;
  output [159:0] out_data;
  wire [159:0] out_data;
  assign out_data[64] = _1_ ^ _0_;
  assign { unused[217:172], _1_, unused[170:108], _0_, unused[106:59], out_data[159:128], unused[26:0] } = in_data[590:373] + in_data[547:330];
endmodule

where the input is set to 0x5b85eb56.

Results of optimizer deactivations: The results are super interesting.
Here is a summary of the results:

Optimization out_data [95:64]
-fno-const-bit-op-tree (no trace) 0
-fno-dfg-peephole (no trace) 0x1002
-fno-dfg-pre-inline (no trace) 0x1002
-fno-dfg-post-inline (no trace) 0x1002
-fno-gate (no trace) 0x1002
-fno-subst (no trace) 0
-fno-subst-const (no trace) 0
All -fno combined (no trace) 0
Default notrace 0x1002
Default traces 0x10e40
Icarus (cast to bit) 0x0
Expected (manually) 0x0

Please note that running with traces enabled also produces a wrong result in that case, and different from without traces.
An immediate hypothesis comes from the width of the wires: we would expect out_data [95:65] to be x, hence 0. They probably become accidentally assigned by interpreting _1_ and _0_ as more than a single-bit wire.

Thanks!
Flavien

@flaviens flaviens changed the title Wrong simulation result with adders and single-big exclusive or gates Wrong simulation result with adders and single-bit exclusive or gates Nov 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model status: asked reporter Bug is waiting for reporter to answer a question
Projects
None yet
Development

No branches or pull requests

2 participants