You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
vvp crashes with a stack overflow on a stable loop through a strength-aware or real net #1513
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.svmoduletop;
wire n, en;
bufif1 (n, n, en);
endmodule
// real_loop.svmoduletop;
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.
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.
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.
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.
Activity
vvp: Stop propagating unchanged strength and real net values
larsclausen commentedon Sep 18, 2026
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
caryr commentedon Sep 18, 2026
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.
caryr commentedon Sep 18, 2026
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.
larsclausen commentedon Sep 20, 2026
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.