Skip to content

vvp crashes with a stack overflow on a stable loop through a strength-aware or real net #1513

Open

Description

@haskiindahouse

vvp overflows the stack and crashes at time 0 on some loops through a strength-aware net or a real net, even when the loop is stable. In both examples below the value going around the loop never changes (StX and 0.0).

// bufif_loop.sv
module top;
  wire n, en;
  bufif1 (n, n, en);
endmodule
// real_loop.sv
module top;
  real r;
  assign r = r / 1.0;
endmodule
$ iverilog -g2012 -o bufif_loop.vvp bufif_loop.sv && vvp bufif_loop.vvp; echo "exit status $?"
Segmentation fault
exit status 139
$ iverilog -g2012 -o real_loop.vvp real_loop.sv && vvp real_loop.vvp; echo "exit status $?"
Segmentation fault
exit status 139

Reproduced with master (c9ed764) and 13.0. The same loop through notif1 (n, n, en); runs normally: it uses the same vvp_fun_bufif functor, but its output is a plain 4-state net. So does assign c = c + 4'd1;. A delay does not help: bufif1 #1 (n, n, en); also crashes at time 0.

In a debug build both crashes are unbounded recursion with the same value in every frame: vvp_fun_bufif::recv_vec4, vvp_net_t::send_vec8, vvp_send_vec8, vvp_net_fun_t::recv_vec8 and back to vvp_fun_bufif::recv_vec4; and vvp_arith_div_real::recv_real, vvp_net_t::send_real, vvp_send_real and back to vvp_arith_div_real::recv_real.

vvp_wire_vec4::filter_vec4 stops propagation when the value is unchanged (vvp_net_sig.cc#L901-L907), so a stable loop through a 4-state net ends. vvp_wire_vec8::filter_vec8 (L1081-L1096) and vvp_wire_real::filter_real (L1228-L1232) have no such check. vvp_fun_bufif::recv_vec4 (bufif.cc#L82) and the real operators (arith.cc#L1088-L1089) send their result from inside the input handler, so the same value goes around the loop recursively until the stack overflows. The same unchanged-value check in these two filters looks like a possible fix, but I have not tested it. vvp_wire_real has no needs_init_ flag, so it would also need the release() handling that vvp_wire_vec8::release() already has (L1141).

A loop that never settles, such as wire a; assign a = (a === 1'b0);, crashes the same way on a 4-state net, which is closer to #1131.


Found by property-based testing with an Idris 2 design generator built on DepTyCheck.
This report was edited with the help of AI.
If you need any additional information, I will be happy to answer. Thank you for your time.

Activity

  1. larsclausen commented on Sep 18, 2026

    @larsclausen
    Collaborator

    Reopening since there is a second part to this where we still get a stack overflow when we have a feedback loop that never settles. Goal should be

    1. no stack overflow
    2. allow users to set a limit after how many iterations on the same signal in the same time step the simulation exits with an error
  2. caryr commented on Sep 18, 2026

    @caryr
    Collaborator

    The commercial tools do not report a loop when the value is not stable. My initial thought was we need some form of analysis like is done for procedural code loops, no loop, possible loop and definitely a loop. I considered this separate from the resolution when the loop has a stable value.

  3. caryr commented on Sep 18, 2026

    @caryr
    Collaborator

    I remember there being a different issue that also reported a zero time assignment loop. If this is something you are going to take on look for this other report as well.

  4. larsclausen commented on Sep 20, 2026

    @larsclausen
    Collaborator

    we should at least fix the stack overflow, and once we do that we might have already half of the mechanism needed to stop after N iterations. I think it also makes sense to detect loops, but that might not be easy other than for the trivial cases of where a signal directly drives itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions