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

A specific pattern is verilated into an infinite loop when optimizations are enabled #5080

Open
ArthurRosaMelexis opened this issue Apr 29, 2024 · 2 comments
Assignees
Labels
area: scheduling Issue involves scheduling/ordering of events status: ready Issue is ready for someone to fix; then goes to 'status: assigned'

Comments

@ArthurRosaMelexis
Copy link

ArthurRosaMelexis commented Apr 29, 2024

I found a specific pattern that triggers a verilation bug.

From my initial testing, having:

  • optimizations enabled
  • an always block triggered by an inout signal
  • with 2 nested conditionals
  • that lead to a task call
  • in which a delay is present

makes Verilator not put the co_await operator on the VTrigSched corresponding to this always block, leading to an infinite loop at the first eval.

(I am not too familiar with Verilog or Verilator, so I may do some terminology errors)

An example of this pattern is given below.

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024.
// SPDX-License-Identifier: CC0-1.0

module test;

  wire inoutSignal;

  submod foo(inoutSignal);

  initial begin
`ifdef TEST_VERBOSE
    $display("The top module is starting");
`endif
    #2 $display("*-* All Finished *-*");
    $finish();
  end

endmodule

module submod (
    inoutSignal
);

  inout inoutSignal;

  reg cond1;
  reg cond2;

  initial begin
`ifdef TEST_VERBOSE
    $display("The module's initial is called before the infinite loop");
`endif
    // These conditions could have any value
    cond1 = 1;
    cond2 = 0;
  end

  task testTask;
    begin
      #1;
`ifdef TEST_VERBOSE
        $display("This task block is never actually called");
`endif
    end
  endtask  // pumpErr

  always @(inoutSignal) begin
    // The infinte loop is in the generated timing block for this block
    if (cond1) begin
      if (cond2) begin
        testTask;
      end
    end
  end

endmodule

The following command will trigger the bug :

verilator --binary --timing -DTEST_VERBOSE test.v

Simply adding the -O0 Verilator flag will avoid it.

The bug was discovered on Verilator v5.020, and is still present in the git master version.

I am using Pop!_OS 22.04 LTS (based on Ubuntu 22.04 LTS).

I am used to working with C++, but not very familiar with the Verilator code base, so I would need some help to fix this.

@ArthurRosaMelexis ArthurRosaMelexis added the new New issue not seen by maintainers label Apr 29, 2024
@wsnyder wsnyder added area: scheduling Issue involves scheduling/ordering of events status: ready Issue is ready for someone to fix; then goes to 'status: assigned' and removed new New issue not seen by maintainers labels Apr 29, 2024
@wsnyder
Copy link
Member

wsnyder commented Apr 29, 2024

Thanks for a clean simple test case.

@kbieganski might you take a look? If difficult can we short-term get a UNSUPPORTED error?

@kbieganski kbieganski self-assigned this Apr 29, 2024
@kbieganski
Copy link
Member

kbieganski commented May 2, 2024

The issue is that -fconst converts the sensitivity list of this always into an "initial" sentree (effectively, it converts the always into an initial). Later, any always with delays is being converted to a while (true) loop. Usually, the always' sentree serves as a timing control that breaks the loop. But in this case we don't have a real sentree, so we get an infinite loop.

I think this can be fixed by a tweak to that condition. If it works, I'll open a PR.
Turns out this is a bit tricky, because in V3Timing or V3Sched I cannot really distinguish these optimized out sentrees from an always that never had a sentree to begin with (e.g. always #1 ...). Some possible solutions:

  • Disable this sentree optimization if --timing is given,
  • Mark alwayses that never had a sentree so they can be recognized by V3Timing.
  • Introduce a special kind of SenItem (like InitialForever or something) to differentiate processes like always #1 ... from optimized out ones. Basically a different approach to the previous dot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: scheduling Issue involves scheduling/ordering of events status: ready Issue is ready for someone to fix; then goes to 'status: assigned'
Projects
None yet
Development

No branches or pull requests

3 participants