From 78b7679fd4b0c1a9716ddb70d657885ca9d053b9 Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Mon, 30 Mar 2026 14:20:59 +0200 Subject: [PATCH] refine comments and update test --- src/V3Timing.cpp | 4 ++-- test_regress/t/t_wait_iface_vif.v | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index 275f7c1c0..a25a6fdd5 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -892,8 +892,8 @@ class TimingControlVisitor final : public VNVisitor { m_underProcedure = true; // Workaround for killing `always` processes (doing that is pretty much UB) // TODO: Disallow killing `always` at runtime (throw an error) - // Combo blocks (always @*) must not become coroutines -- they have no - // suspend points and would spin forever. + // Skip for combinational blocks; if the body has timing controls + // iterateChildren will add T_SUSPENDEE, otherwise it would spin. if (hasFlags(nodep, T_HAS_PROC) && !(m_activep && m_activep->sentreep() && m_activep->sentreep()->hasCombo())) addFlags(nodep, T_SUSPENDEE); diff --git a/test_regress/t/t_wait_iface_vif.v b/test_regress/t/t_wait_iface_vif.v index f0cf919da..a91fc8445 100644 --- a/test_regress/t/t_wait_iface_vif.v +++ b/test_regress/t/t_wait_iface_vif.v @@ -54,11 +54,19 @@ endclass module t; my_if intf(); + // Verify combinational always with timing controls still works as coroutine + int combo_timing_count = 0; + always @* begin + combo_timing_count = combo_timing_count + 1; + #1; + end + initial begin automatic Driver d = new; d.vif = intf; d.run(); repeat (4) @(posedge intf.clk); + if (combo_timing_count == 0) $stop; $write("*-* All Finished *-*\n"); $finish; end