diff --git a/docs/internals.rst b/docs/internals.rst index c2031c857..a3f70ea36 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -588,6 +588,31 @@ This split is done to avoid self-triggering and triggering coroutines multiple times. See the `Scheduling with timing` section for details on how this is used. +``VlDynamicTriggerScheduler`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Like ``VlTriggerScheduler``, ``VlDynamicTriggerScheduler`` manages processes +that await triggers. However, it does not rely on triggers evaluated externally +by the 'act' trigger eval function. Instead, it is also responsible for trigger +evaluation. Coroutines that make use of this scheduler must adhere to a certain +procedure: + +:: + __Vtrigger = 0; + + while (!__Vtrigger) { + co_await __VdynSched.evaluation(); +
;
+      __Vtrigger = ;
+      [optionally] co_await __VdynSched.postUpdate();
+      ;
+  }
+  co_await __VdynSched.resumption();
+
+The coroutines get resumed at trigger evaluation time, evaluate their local
+triggers, optionally await the post update step, and if the trigger is set,
+await proper resumption in the 'act' eval step.
+
 ``VlForkSync``
 ^^^^^^^^^^^^^^
 
@@ -616,6 +641,11 @@ The visitor in ``V3Timing.cpp`` transforms each timing control into a ``co_await
   ``trigger`` method. The awaited trigger scheduler is the one corresponding to
   the sentree referenced by the event control. This sentree is also referenced
   by the ``AstCAwait`` node, to be used later by the static scheduling code.
+* if an event control waits on a local variable or class member, it uses a
+  local trigger which it evaluates inline. It awaits a dynamic trigger
+  scheduler multiple times: for trigger evaluation, updates, and resumption.
+  The dynamic trigger scheduler is responsible for resuming the coroutine at
+  the correct point of evaluation.
 * delays are turned into ``co_await`` on a delay scheduler's ``delay`` method.
   The created ``AstCAwait`` nodes also reference a special sentree related to
   delays, to be used later by the static scheduling code.
diff --git a/include/verilated_timing.cpp b/include/verilated_timing.cpp
index 7f996d7f7..f644ed64f 100644
--- a/include/verilated_timing.cpp
+++ b/include/verilated_timing.cpp
@@ -139,6 +139,54 @@ void VlTriggerScheduler::dump(const char* eventDescription) const {
 }
 #endif
 
+//======================================================================
+// VlDynamicTriggerScheduler:: Methods
+
+bool VlDynamicTriggerScheduler::evaluate() {
+    VL_DEBUG_IF(dump(););
+    std::swap(m_suspended, m_evaluated);
+    for (auto& coro : m_evaluated) coro.resume();
+    m_evaluated.clear();
+    return !m_triggered.empty();
+}
+
+void VlDynamicTriggerScheduler::doPostUpdates() {
+    VL_DEBUG_IF(if (!m_post.empty())
+                    VL_DBG_MSGF("         Doing post updates for processes:\n");  //
+                for (const auto& susp
+                     : m_post) {
+                    VL_DBG_MSGF("           - ");
+                    susp.dump();
+                });
+    for (auto& coro : m_post) coro.resume();
+    m_post.clear();
+}
+
+void VlDynamicTriggerScheduler::resume() {
+    VL_DEBUG_IF(if (!m_triggered.empty()) VL_DBG_MSGF("         Resuming processes:\n");  //
+                for (const auto& susp
+                     : m_triggered) {
+                    VL_DBG_MSGF("           - ");
+                    susp.dump();
+                });
+    for (auto& coro : m_triggered) coro.resume();
+    m_triggered.clear();
+}
+
+#ifdef VL_DEBUG
+void VlDynamicTriggerScheduler::dump() const {
+    if (m_suspended.empty()) {
+        VL_DBG_MSGF("         No suspended processes waiting for dynamic trigger evaluation\n");
+    } else {
+        for (const auto& susp : m_suspended) {
+            VL_DBG_MSGF("         Suspended processes waiting for dynamic trigger evaluation:\n");
+            VL_DBG_MSGF("           - ");
+            susp.dump();
+        }
+    }
+}
+#endif
+
 //======================================================================
 // VlForkSync:: Methods
 
diff --git a/include/verilated_timing.h b/include/verilated_timing.h
index 79eb1c0dd..f39d88ed6 100644
--- a/include/verilated_timing.h
+++ b/include/verilated_timing.h
@@ -238,6 +238,80 @@ public:
     }
 };
 
+//=============================================================================
+// VlDynamicTriggerScheduler is used for cases where triggers cannot be statically referenced and
+// evaluated. Coroutines that make use of this scheduler must adhere to a certain procedure:
+//     __Vtrigger = 0;
+//     
+//     while (!__Vtrigger) {
+//         co_await __VdynSched.evaluation();
+//         
;
+//         __Vtrigger = ;
+//         [optionally] co_await __VdynSched.postUpdate();
+//         ;
+//     }
+//    co_await __VdynSched.resumption();
+// The coroutines get resumed at trigger evaluation time, evaluate their local triggers, optionally
+// await the post update step, and if the trigger is set, await proper resumption in the 'act' eval
+// step.
+
+class VlDynamicTriggerScheduler final {
+    // TYPES
+    using VlCoroutineVec = std::vector;
+
+    // MEMBERS
+    VlCoroutineVec m_suspended;  // Suspended coroutines awaiting trigger evaluation
+    VlCoroutineVec m_evaluated;  // Coroutines currently being evaluated (for evaluate())
+    VlCoroutineVec m_triggered;  // Coroutines whose triggers were set, and are awaiting resumption
+    VlCoroutineVec m_post;  // Coroutines awaiting the post update step (only relevant for triggers
+                            // with destructive post updates, e.g. named events)
+
+    // METHODS
+    auto awaitable(VlCoroutineVec& queue, const char* filename, int lineno) {
+        struct Awaitable {
+            VlCoroutineVec& suspended;  // Coros waiting on trigger
+            VlFileLineDebug fileline;
+
+            bool await_ready() const { return false; }  // Always suspend
+            void await_suspend(std::coroutine_handle<> coro) {
+                suspended.emplace_back(coro, fileline);
+            }
+            void await_resume() const {}
+        };
+        return Awaitable{queue, VlFileLineDebug{filename, lineno}};
+    }
+
+public:
+    // Evaluates all dynamic triggers (resumed coroutines that co_await evaluation())
+    bool evaluate();
+    // Runs post updates for all dynamic triggers (resumes coroutines that co_await postUpdate())
+    void doPostUpdates();
+    // Resumes all coroutines whose triggers are set (those that co_await resumption())
+    void resume();
+#ifdef VL_DEBUG
+    void dump() const;
+#endif
+    // Used by coroutines for co_awaiting trigger evaluation
+    auto evaluation(const char* eventDescription, const char* filename, int lineno) {
+        VL_DEBUG_IF(VL_DBG_MSGF("         Suspending process waiting for %s at %s:%d\n",
+                                eventDescription, filename, lineno););
+        return awaitable(m_suspended, filename, lineno);
+    }
+    // Used by coroutines for co_awaiting the trigger post update step
+    auto postUpdate(const char* eventDescription, const char* filename, int lineno) {
+        VL_DEBUG_IF(
+            VL_DBG_MSGF("         Process waiting for %s at %s:%d awaiting the post update step\n",
+                        eventDescription, filename, lineno););
+        return awaitable(m_post, filename, lineno);
+    }
+    // Used by coroutines for co_awaiting the resumption step (in 'act' eval)
+    auto resumption(const char* eventDescription, const char* filename, int lineno) {
+        VL_DEBUG_IF(VL_DBG_MSGF("         Process waiting for %s at %s:%d awaiting resumption\n",
+                                eventDescription, filename, lineno););
+        return awaitable(m_triggered, filename, lineno);
+    }
+};
+
 //=============================================================================
 // VlNow is a helper awaitable type that always suspends, and then immediately resumes a coroutine.
 // Allows forcing the move of coroutine locals to the heap.
diff --git a/src/V3Ast.h b/src/V3Ast.h
index ecac64da1..0253e20fe 100644
--- a/src/V3Ast.h
+++ b/src/V3Ast.h
@@ -460,6 +460,7 @@ public:
         TRIGGERVEC,
         DELAY_SCHEDULER,
         TRIGGER_SCHEDULER,
+        DYNAMIC_TRIGGER_SCHEDULER,
         FORK_SYNC,
         // Unsigned and two state; fundamental types
         UINT32,
@@ -490,6 +491,7 @@ public:
                                             "VlTriggerVec",
                                             "VlDelayScheduler",
                                             "VlTriggerScheduler",
+                                            "VlDynamicTriggerScheduler",
                                             "VlFork",
                                             "IData",
                                             "QData",
@@ -498,30 +500,12 @@ public:
         return names[m_e];
     }
     const char* dpiType() const {
-        static const char* const names[] = {"%E-unk",
-                                            "svBit",
-                                            "char",
-                                            "void*",
-                                            "char",
-                                            "int",
-                                            "%E-integer",
-                                            "svLogic",
-                                            "long long",
-                                            "double",
-                                            "short",
-                                            "%E-time",
-                                            "const char*",
-                                            "dpiScope",
-                                            "const char*",
-                                            "%E-mtaskstate",
-                                            "%E-triggervec",
-                                            "%E-dly-sched",
-                                            "%E-trig-sched",
-                                            "%E-fork",
-                                            "IData",
-                                            "QData",
-                                            "%E-logic-implct",
-                                            " MAX"};
+        static const char* const names[]
+            = {"%E-unk",        "svBit",         "char",         "void*",           "char",
+               "int",           "%E-integer",    "svLogic",      "long long",       "double",
+               "short",         "%E-time",       "const char*",  "dpiScope",        "const char*",
+               "%E-mtaskstate", "%E-triggervec", "%E-dly-sched", "%E-trig-sched",   "%E-dyn-sched",
+               "%E-fork",       "IData",         "QData",        "%E-logic-implct", " MAX"};
         return names[m_e];
     }
     static void selfTest() {
@@ -558,6 +542,7 @@ public:
         case TRIGGERVEC: return 0;  // opaque
         case DELAY_SCHEDULER: return 0;  // opaque
         case TRIGGER_SCHEDULER: return 0;  // opaque
+        case DYNAMIC_TRIGGER_SCHEDULER: return 0;  // opaque
         case FORK_SYNC: return 0;  // opaque
         case UINT32: return 32;
         case UINT64: return 64;
@@ -596,7 +581,8 @@ public:
     bool isOpaque() const VL_MT_SAFE {  // IE not a simple number we can bit optimize
         return (m_e == EVENT || m_e == STRING || m_e == SCOPEPTR || m_e == CHARPTR
                 || m_e == MTASKSTATE || m_e == TRIGGERVEC || m_e == DELAY_SCHEDULER
-                || m_e == TRIGGER_SCHEDULER || m_e == FORK_SYNC || m_e == DOUBLE);
+                || m_e == TRIGGER_SCHEDULER || m_e == DYNAMIC_TRIGGER_SCHEDULER || m_e == FORK_SYNC
+                || m_e == DOUBLE);
     }
     bool isDouble() const VL_MT_SAFE { return m_e == DOUBLE; }
     bool isEvent() const { return m_e == EVENT; }
diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h
index f8547b265..010a78d20 100644
--- a/src/V3AstNodeDType.h
+++ b/src/V3AstNodeDType.h
@@ -440,6 +440,9 @@ public:
     bool isTriggerScheduler() const VL_MT_SAFE {
         return keyword() == VBasicDTypeKwd::TRIGGER_SCHEDULER;
     }
+    bool isDynamicTriggerScheduler() const VL_MT_SAFE {
+        return keyword() == VBasicDTypeKwd::DYNAMIC_TRIGGER_SCHEDULER;
+    }
     bool isOpaque() const VL_MT_SAFE { return keyword().isOpaque(); }
     bool isString() const VL_MT_SAFE { return keyword().isString(); }
     bool isZeroInit() const { return keyword().isZeroInit(); }
diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp
index bb0ca080e..92e0b2fce 100644
--- a/src/V3AstNodes.cpp
+++ b/src/V3AstNodes.cpp
@@ -754,6 +754,8 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const {
             info.m_type = "VlDelayScheduler";
         } else if (bdtypep->isTriggerScheduler()) {
             info.m_type = "VlTriggerScheduler";
+        } else if (bdtypep->isDynamicTriggerScheduler()) {
+            info.m_type = "VlDynamicTriggerScheduler";
         } else if (bdtypep->isForkSync()) {
             info.m_type = "VlForkSync";
         } else if (bdtypep->isEvent()) {
diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp
index 7ec97f234..f81998976 100644
--- a/src/V3EmitCFunc.cpp
+++ b/src/V3EmitCFunc.cpp
@@ -694,6 +694,8 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
         return "";
     } else if (basicp && basicp->isTriggerScheduler()) {
         return "";
+    } else if (basicp && basicp->isDynamicTriggerScheduler()) {
+        return "";
     } else if (basicp) {
         const bool zeroit
             = (varp->attrFileDescr()  // Zero so we don't do file IO if never $fopen
diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp
index bb48fa171..36a23771f 100644
--- a/src/V3Sched.cpp
+++ b/src/V3Sched.cpp
@@ -363,7 +363,8 @@ public:
 //============================================================================
 // Create a TRIGGERVEC and the related TriggerKit for the given AstSenTree vector
 
-const TriggerKit createTriggers(AstNetlist* netlistp, SenExprBuilder& senExprBuilder,
+const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
+                                SenExprBuilder& senExprBuilder,
                                 const std::vector& senTreeps,
                                 const string& name, const ExtraTriggers& extraTriggers,
                                 bool slow = false) {
@@ -463,7 +464,10 @@ const TriggerKit createTriggers(AstNetlist* netlistp, SenExprBuilder& senExprBui
         //
         ++triggerNumber;
     }
-    // Add the update statements
+    // Add the init and update statements
+    for (AstNodeStmt* const nodep : senExprBuilder.getAndClearInits()) {
+        initFuncp->addStmtsp(nodep);
+    }
     for (AstNodeStmt* const nodep : senExprBuilder.getAndClearPostUpdates()) {
         funcp->addStmtsp(nodep);
     }
@@ -604,7 +608,7 @@ std::pair makeEvalLoop(AstNetlist* netlistp, const strin
 //============================================================================
 // Order the combinational logic to create the settle loop
 
-void createSettle(AstNetlist* netlistp, SenExprBuilder& senExprBulider,
+void createSettle(AstNetlist* netlistp, AstCFunc* const initFuncp, SenExprBuilder& senExprBulider,
                   LogicClasses& logicClasses) {
     AstCFunc* const funcp = makeTopFunction(netlistp, "_eval_settle", true);
 
@@ -622,8 +626,8 @@ void createSettle(AstNetlist* netlistp, SenExprBuilder& senExprBulider,
 
     // Gather the relevant sensitivity expressions and create the trigger kit
     const auto& senTreeps = getSenTreesUsedBy({&comb, &hybrid});
-    const TriggerKit& trig
-        = createTriggers(netlistp, senExprBulider, senTreeps, "stl", extraTriggers, true);
+    const TriggerKit& trig = createTriggers(netlistp, initFuncp, senExprBulider, senTreeps, "stl",
+                                            extraTriggers, true);
 
     // Remap sensitivities (comb has none, so only do the hybrid)
     remapSensitivities(hybrid, trig.m_map);
@@ -662,8 +666,8 @@ void createSettle(AstNetlist* netlistp, SenExprBuilder& senExprBulider,
 //============================================================================
 // Order the replicated combinational logic to create the 'ico' region
 
-AstNode* createInputCombLoop(AstNetlist* netlistp, SenExprBuilder& senExprBuilder,
-                             LogicByScope& logic) {
+AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp,
+                             SenExprBuilder& senExprBuilder, LogicByScope& logic) {
     // Nothing to do if no combinational logic is sensitive to top level inputs
     if (logic.empty()) return nullptr;
 
@@ -693,7 +697,7 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, SenExprBuilder& senExprBuilde
     // Gather the relevant sensitivity expressions and create the trigger kit
     const auto& senTreeps = getSenTreesUsedBy({&logic});
     const TriggerKit& trig
-        = createTriggers(netlistp, senExprBuilder, senTreeps, "ico", extraTriggers);
+        = createTriggers(netlistp, initFuncp, senExprBuilder, senTreeps, "ico", extraTriggers);
 
     if (dpiExportTriggerVscp) {
         trig.addDpiExportTriggerAssignment(dpiExportTriggerVscp, dpiExportTriggerIndex);
@@ -904,10 +908,12 @@ void schedule(AstNetlist* netlistp) {
 
     // We pass around a single SenExprBuilder instance, as we only need one set of 'prev' variables
     // for edge/change detection in sensitivity expressions, which this keeps track of.
-    SenExprBuilder senExprBuilder{netlistp, initp};
+    AstTopScope* const topScopep = netlistp->topScopep();
+    AstScope* const scopeTopp = topScopep->scopep();
+    SenExprBuilder senExprBuilder{scopeTopp};
 
     // Step 4: Create 'settle' region that restores the combinational invariant
-    createSettle(netlistp, senExprBuilder, logicClasses);
+    createSettle(netlistp, initp, senExprBuilder, logicClasses);
     if (v3Global.opt.stats()) V3Stats::statsStage("sched-settle");
 
     // Step 5: Partition the clocked and combinational (including hybrid) logic into pre/act/nba.
@@ -932,7 +938,8 @@ void schedule(AstNetlist* netlistp) {
     }
 
     // Step 7: Create input combinational logic loop
-    AstNode* const icoLoopp = createInputCombLoop(netlistp, senExprBuilder, logicReplicas.m_ico);
+    AstNode* const icoLoopp
+        = createInputCombLoop(netlistp, initp, senExprBuilder, logicReplicas.m_ico);
     if (v3Global.opt.stats()) V3Stats::statsStage("sched-create-ico");
 
     // Step 8: Create the pre/act/nba triggers
@@ -949,15 +956,15 @@ void schedule(AstNetlist* netlistp) {
                                                &logicRegions.m_nba,  //
                                                &timingKit.m_lbs});
     const TriggerKit& actTrig
-        = createTriggers(netlistp, senExprBuilder, senTreeps, "act", extraTriggers);
+        = createTriggers(netlistp, initp, senExprBuilder, senTreeps, "act", extraTriggers);
+
+    // Add post updates from the timing kit
+    if (timingKit.m_postUpdates) actTrig.m_funcp->addStmtsp(timingKit.m_postUpdates);
 
     if (dpiExportTriggerVscp) {
         actTrig.addDpiExportTriggerAssignment(dpiExportTriggerVscp, dpiExportTriggerIndex);
     }
 
-    AstTopScope* const topScopep = netlistp->topScopep();
-    AstScope* const scopeTopp = topScopep->scopep();
-
     AstVarScope* const actTrigVscp = actTrig.m_vscp;
     AstVarScope* const preTrigVscp = scopeTopp->createTempLike("__VpreTriggered", actTrigVscp);
     AstVarScope* const nbaTrigVscp = scopeTopp->createTempLike("__VnbaTriggered", actTrigVscp);
diff --git a/src/V3Sched.h b/src/V3Sched.h
index 9846ada1d..efde069af 100644
--- a/src/V3Sched.h
+++ b/src/V3Sched.h
@@ -125,6 +125,7 @@ class TimingKit final {
 
 public:
     LogicByScope m_lbs;  // Actives that resume timing schedulers
+    AstNodeStmt* m_postUpdates = nullptr;  // Post updates for the trigger eval function
 
     // Remaps external domains using the specified trigger map
     std::map>
@@ -135,10 +136,11 @@ public:
     AstCCall* createCommit(AstNetlist* const netlistp);
 
     TimingKit() = default;
-    TimingKit(LogicByScope&& lbs,
+    TimingKit(LogicByScope&& lbs, AstNodeStmt* postUpdates,
               std::map>&& externalDomains)
         : m_externalDomains{externalDomains}
-        , m_lbs{lbs} {}
+        , m_lbs{lbs}
+        , m_postUpdates{postUpdates} {}
     VL_UNCOPYABLE(TimingKit);
     TimingKit(TimingKit&&) = default;
     TimingKit& operator=(TimingKit&&) = default;
diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp
index ac208122a..de8845b43 100644
--- a/src/V3SchedTiming.cpp
+++ b/src/V3SchedTiming.cpp
@@ -89,7 +89,8 @@ AstCCall* TimingKit::createCommit(AstNetlist* const netlistp) {
             UASSERT_OBJ(!resumep->nextp(), resumep, "Should be the only statement here");
             AstVarScope* const schedulerp = VN_AS(resumep->fromp(), VarRef)->varScopep();
             UASSERT_OBJ(schedulerp->dtypep()->basicp()->isDelayScheduler()
-                            || schedulerp->dtypep()->basicp()->isTriggerScheduler(),
+                            || schedulerp->dtypep()->basicp()->isTriggerScheduler()
+                            || schedulerp->dtypep()->basicp()->isDynamicTriggerScheduler(),
                         schedulerp, "Unexpected type");
             if (!schedulerp->dtypep()->basicp()->isTriggerScheduler()) continue;
             // Create the global commit function only if we have trigger schedulers
@@ -143,6 +144,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
         bool m_gatherVars = false;  // Should we gather vars in m_writtenBySuspendable?
         AstScope* const m_scopeTopp;  // Scope at the top
         LogicByScope& m_lbs;  // Timing resume actives
+        AstNodeStmt*& m_postUpdatesr;  // Post updates for the trigger eval function
         // Additional var sensitivities
         std::map>& m_externalDomains;
         std::set m_processDomains;  // Sentrees from the current process
@@ -159,11 +161,15 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
             // Create a resume() call on the timing scheduler
             auto* const resumep = new AstCMethodHard{
                 flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "resume"};
-            if (schedulerp->dtypep()->basicp()->isTriggerScheduler() && methodp->pinsp()) {
-                resumep->addPinsp(methodp->pinsp()->cloneTree(false));
-            }
             resumep->statement(true);
             resumep->dtypeSetVoid();
+            if (schedulerp->dtypep()->basicp()->isTriggerScheduler()) {
+                if (methodp->pinsp()) resumep->addPinsp(methodp->pinsp()->cloneTree(false));
+            } else if (schedulerp->dtypep()->basicp()->isDynamicTriggerScheduler()) {
+                auto* const postp = resumep->cloneTree(false);
+                postp->name("doPostUpdates");
+                m_postUpdatesr = AstNode::addNext(m_postUpdatesr, postp);
+            }
             // Put it in an active and put that in the global resume function
             auto* const activep = new AstActive{flp, "_timing", sensesp};
             activep->addStmtsp(resumep);
@@ -215,19 +221,21 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
 
     public:
         // CONSTRUCTORS
-        explicit AwaitVisitor(AstNetlist* nodep, LogicByScope& lbs,
+        explicit AwaitVisitor(AstNetlist* nodep, LogicByScope& lbs, AstNodeStmt*& postUpdatesr,
                               std::map>& externalDomains)
             : m_scopeTopp{nodep->topScopep()->scopep()}
             , m_lbs{lbs}
+            , m_postUpdatesr{postUpdatesr}
             , m_externalDomains{externalDomains} {
             iterate(nodep);
         }
         ~AwaitVisitor() override = default;
     };
     LogicByScope lbs;
+    AstNodeStmt* postUpdates = nullptr;
     std::map> externalDomains;
-    AwaitVisitor{netlistp, lbs, externalDomains};
-    return {std::move(lbs), std::move(externalDomains)};
+    AwaitVisitor{netlistp, lbs, postUpdates, externalDomains};
+    return {std::move(lbs), postUpdates, std::move(externalDomains)};
 }
 
 //============================================================================
diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h
index c1e5ef57c..97b31e5b2 100644
--- a/src/V3SenExprBuilder.h
+++ b/src/V3SenExprBuilder.h
@@ -29,10 +29,10 @@
 
 class SenExprBuilder final {
     // STATE
-    AstCFunc* const m_initp;  // The initialization function
-    AstScope* const m_scopeTopp;  // Top level scope
+    AstScope* const m_scopep;  // The scope
 
     std::vector m_locals;  // Trigger eval local variables
+    std::vector m_inits;  // Initialization statements for prevoius values
     std::vector m_preUpdates;  // Pre update assignments
     std::vector m_postUpdates;  // Post update assignments
 
@@ -76,8 +76,8 @@ class SenExprBuilder final {
                 = new AstVar{flp, VVarType::BLOCKTEMP, m_currNames.get(exprp), exprp->dtypep()};
             varp->funcLocal(true);
             m_locals.push_back(varp);
-            AstVarScope* vscp = new AstVarScope{flp, m_scopeTopp, varp};
-            m_scopeTopp->addVarsp(vscp);
+            AstVarScope* vscp = new AstVarScope{flp, m_scopep, varp};
+            m_scopep->addVarsp(vscp);
             result.first->second = vscp;
         }
         AstVarScope* const currp = result.first->second;
@@ -106,13 +106,23 @@ class SenExprBuilder final {
                 name = m_prevNames.get(exprp);
             }
 
-            AstVarScope* const prevp = m_scopeTopp->createTemp(name, exprp->dtypep());
+            AstVarScope* prevp;
+            if (m_scopep->isTop()) {
+                prevp = m_scopep->createTemp(name, exprp->dtypep());
+            } else {
+                AstVar* const varp = new AstVar{flp, VVarType::BLOCKTEMP, m_prevNames.get(exprp),
+                                                exprp->dtypep()};
+                varp->funcLocal(true);
+                m_locals.push_back(varp);
+                prevp = new AstVarScope{flp, m_scopep, varp};
+                m_scopep->addVarsp(prevp);
+            }
             it = m_prev.emplace(*exprp, prevp).first;
 
             // Add the initializer init
-            AstNode* const initp = exprp->cloneTree(false);
-            m_initp->addStmtsp(
-                new AstAssign{flp, new AstVarRef{flp, prevp, VAccess::WRITE}, initp});
+            AstAssign* const initp = new AstAssign{flp, new AstVarRef{flp, prevp, VAccess::WRITE},
+                                                   exprp->cloneTree(false)};
+            m_inits.push_back(initp);
         }
 
         AstVarScope* const prevp = it->second;
@@ -222,6 +232,7 @@ public:
         return {resultp, firedAtInitialization};
     }
 
+    std::vector getAndClearInits() { return std::move(m_inits); }
     std::vector getAndClearLocals() { return std::move(m_locals); }
 
     std::vector getAndClearPreUpdates() {
@@ -235,9 +246,8 @@ public:
     }
 
     // CONSTRUCTOR
-    SenExprBuilder(AstNetlist* netlistp, AstCFunc* initp)
-        : m_initp{initp}
-        , m_scopeTopp{netlistp->topScopep()->scopep()} {}
+    SenExprBuilder(AstScope* scopep)
+        : m_scopep{scopep} {}
 };
 
 #endif  // Guard
diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp
index 02cdee3e5..8f657e0b0 100644
--- a/src/V3Timing.cpp
+++ b/src/V3Timing.cpp
@@ -50,6 +50,7 @@
 #include "V3Const.h"
 #include "V3EmitV.h"
 #include "V3Graph.h"
+#include "V3SenExprBuilder.h"
 #include "V3SenTree.h"
 #include "V3UniqueNames.h"
 
@@ -114,6 +115,7 @@ private:
     V3UniqueNames m_intraLsbNames{"__Vintralsb"};  // Intra assign delay LSB var names
     V3UniqueNames m_forkNames{"__Vfork"};  // Fork name generator
     V3UniqueNames m_trigSchedNames{"__VtrigSched"};  // Trigger scheduler name generator
+    V3UniqueNames m_dynTrigNames{"__VdynTrigger"};  // Dynamic trigger name generator
 
     // DTypes
     AstBasicDType* m_forkDtp = nullptr;  // Fork variable type
@@ -121,7 +123,9 @@ private:
 
     // Timing-related globals
     AstVarScope* m_delaySchedp = nullptr;  // Global delay scheduler
+    AstVarScope* m_dynamicSchedp = nullptr;  // Global dynamic trigger scheduler
     AstSenTree* m_delaySensesp = nullptr;  // Domain to trigger if a delayed coroutine is resumed
+    AstSenTree* m_dynamicSensesp = nullptr;  // Domain to trigger if a dynamic trigger is set
 
     // Other
     V3Graph m_depGraph;  // Dependency graph where a node is a dependency of another if it being
@@ -228,6 +232,44 @@ private:
         m_netlistp->topScopep()->addSenTreesp(m_delaySensesp);
         return m_delaySensesp;
     }
+    // Creates the global dynamic trigger scheduler variable
+    AstVarScope* getCreateDynamicTriggerScheduler() {
+        if (m_dynamicSchedp) return m_dynamicSchedp;
+        auto* const dynSchedDtp
+            = new AstBasicDType{m_scopeTopp->fileline(), VBasicDTypeKwd::DYNAMIC_TRIGGER_SCHEDULER,
+                                VSigning::UNSIGNED};
+        m_netlistp->typeTablep()->addTypesp(dynSchedDtp);
+        m_dynamicSchedp = m_scopeTopp->createTemp("__VdynSched", dynSchedDtp);
+        return m_dynamicSchedp;
+    }
+    // Creates the dynamic trigger sentree
+    AstSenTree* getCreateDynamicTriggerSenTree() {
+        if (m_dynamicSensesp) return m_dynamicSensesp;
+        FileLine* const flp = m_scopeTopp->fileline();
+        auto* const awaitingCurrentTimep = new AstCMethodHard{
+            flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::READ},
+            "evaluate"};
+        awaitingCurrentTimep->dtypeSetBit();
+        m_dynamicSensesp
+            = new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE, awaitingCurrentTimep}};
+        m_netlistp->topScopep()->addSenTreesp(m_dynamicSensesp);
+        return m_dynamicSensesp;
+    }
+    // Returns true if we are under a class or the given tree has any references to locals. These
+    // are cases where static, globally-evaluated triggers are not suitable.
+    bool needDynamicTrigger(AstNode* const nodep) const {
+        return m_classp || nodep->exists([](const AstNodeVarRef* const refp) {
+            return refp->varp()->isFuncLocal();
+        });
+    }
+    // Returns true if the given trigger expression needs a destructive post update after trigger
+    // evaluation. Currently this only applies to named events.
+    bool destructivePostUpdate(AstNode* const exprp) const {
+        return exprp->exists([](const AstNodeVarRef* const refp) {
+            AstBasicDType* const dtypep = refp->dtypep()->basicp();
+            return dtypep && dtypep->isEvent();
+        });
+    }
     // Creates a trigger scheduler variable
     AstVarScope* getCreateTriggerSchedulerp(AstSenTree* const sensesp) {
         if (!sensesp->user1p()) {
@@ -483,26 +525,90 @@ private:
         VL_DO_DANGLING(nodep->deleteTree(), nodep);
     }
     void visit(AstEventControl* nodep) override {
-        if (m_classp) nodep->v3warn(E_UNSUPPORTED, "Unsupported: event controls in methods");
-        auto* const sensesp = m_finder.getSenTree(nodep->sensesp());
-        nodep->sensesp()->unlinkFrBack()->deleteTree();
-        // Get this sentree's trigger scheduler
-        FileLine* const flp = nodep->fileline();
-        // Replace self with a 'co_await trigSched.trigger()'
-        auto* const triggerMethodp = new AstCMethodHard{
-            flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sensesp), VAccess::WRITE},
-            "trigger"};
-        triggerMethodp->dtypeSetVoid();
-        // Add debug info
-        addEventDebugInfo(triggerMethodp, sensesp);
-        // Create the co_await
-        auto* const awaitp = new AstCAwait{flp, triggerMethodp, sensesp};
-        awaitp->statement(true);
-        // Relink child statements after the co_await
-        if (nodep->stmtsp()) {
-            AstNode::addNext(awaitp, nodep->stmtsp()->unlinkFrBackWithNext());
+        // Do not allow waiting on local named events, as they get enqueued for clearing, but can
+        // go out of scope before that happens
+        if (nodep->sensesp()->exists([](const AstNodeVarRef* refp) {
+                AstBasicDType* const dtypep = refp->dtypep()->skipRefp()->basicp();
+                return dtypep && dtypep->isEvent() && refp->varp()->isFuncLocal();
+            })) {
+            nodep->v3warn(E_UNSUPPORTED, "Unsupported: waiting on local event variables");
+        }
+        FileLine* const flp = nodep->fileline();
+        // Relink child statements after the event control
+        if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBackWithNext());
+        if (needDynamicTrigger(nodep->sensesp())) {
+            // Create the trigger variable and init it with 0
+            AstVarScope* const trigvscp
+                = createTemp(flp, m_dynTrigNames.get(nodep), nodep->findBitDType(), nodep);
+            auto* const initp = new AstAssign{flp, new AstVarRef{flp, trigvscp, VAccess::WRITE},
+                                              new AstConst{flp, AstConst::BitFalse{}}};
+            nodep->addHereThisAsNext(initp);
+            // Await the eval step with the dynamic trigger scheduler. First, create the method
+            // call
+            auto* const evalMethodp = new AstCMethodHard{
+                flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::WRITE},
+                "evaluation"};
+            evalMethodp->dtypeSetVoid();
+            auto* const sensesp = nodep->sensesp();
+            addEventDebugInfo(evalMethodp, sensesp);
+            // Create the co_await
+            auto* const awaitEvalp
+                = new AstCAwait{flp, evalMethodp, getCreateDynamicTriggerSenTree()};
+            awaitEvalp->statement(true);
+            // Construct the sen expression for this sentree
+            SenExprBuilder senExprBuilder{m_scopep};
+            auto* const assignp = new AstAssign{flp, new AstVarRef{flp, trigvscp, VAccess::WRITE},
+                                                senExprBuilder.build(sensesp).first};
+            // Put all the locals and inits before the trigger eval loop
+            for (AstVar* const varp : senExprBuilder.getAndClearLocals()) {
+                nodep->addHereThisAsNext(varp);
+            }
+            for (AstNodeStmt* const stmtp : senExprBuilder.getAndClearInits()) {
+                nodep->addHereThisAsNext(stmtp);
+            }
+            // Create the trigger eval loop, which will await the evaluation step and check the
+            // trigger
+            auto* const loopp = new AstWhile{
+                flp, new AstLogNot{flp, new AstVarRef{flp, trigvscp, VAccess::READ}}, awaitEvalp};
+            // Put pre updates before the trigger check and assignment
+            for (AstNodeStmt* const stmtp : senExprBuilder.getAndClearPreUpdates()) {
+                loopp->addStmtsp(stmtp);
+            }
+            // Then the trigger check and assignment
+            loopp->addStmtsp(assignp);
+            // If the post update is destructive (e.g. event vars are cleared), create an await for
+            // the post update step
+            if (destructivePostUpdate(sensesp)) {
+                auto* const awaitPostUpdatep = awaitEvalp->cloneTree(false);
+                VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->name("postUpdate");
+                loopp->addStmtsp(awaitPostUpdatep);
+            }
+            // Put the post updates at the end of the loop
+            for (AstNodeStmt* const stmtp : senExprBuilder.getAndClearPostUpdates()) {
+                loopp->addStmtsp(stmtp);
+            }
+            // Finally, await the resumption step in 'act'
+            auto* const awaitResumep = awaitEvalp->cloneTree(false);
+            VN_AS(awaitResumep->exprp(), CMethodHard)->name("resumption");
+            AstNode::addNext(loopp, awaitResumep);
+            // Replace the event control with the loop
+            nodep->replaceWith(loopp);
+        } else {
+            auto* const sensesp = m_finder.getSenTree(nodep->sensesp());
+            nodep->sensesp()->unlinkFrBack()->deleteTree();
+            // Get this sentree's trigger scheduler
+            FileLine* const flp = nodep->fileline();
+            // Replace self with a 'co_await trigSched.trigger()'
+            auto* const triggerMethodp = new AstCMethodHard{
+                flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sensesp), VAccess::WRITE},
+                "trigger"};
+            triggerMethodp->dtypeSetVoid();
+            addEventDebugInfo(triggerMethodp, sensesp);
+            // Create the co_await
+            auto* const awaitp = new AstCAwait{flp, triggerMethodp, sensesp};
+            awaitp->statement(true);
+            nodep->replaceWith(awaitp);
         }
-        nodep->replaceWith(awaitp);
         VL_DO_DANGLING(nodep->deleteTree(), nodep);
     }
     void visit(AstNodeAssign* nodep) override {
@@ -584,22 +690,14 @@ private:
     }
     void visit(AstWait* nodep) override {
         // Wait on changed events related to the vars in the wait statement
-        AstSenItem* const senItemsp = varRefpsToSenItemsp(nodep->condp());
-        AstNode* const condp = nodep->condp()->unlinkFrBack();
+        FileLine* const flp = nodep->fileline();
         AstNode* const stmtsp = nodep->stmtsp();
         if (stmtsp) stmtsp->unlinkFrBackWithNext();
-        FileLine* const flp = nodep->fileline();
-        if (senItemsp) {
-            // Put the event control in a while loop with the wait expression as condition
-            AstNode* const loopp
-                = new AstWhile{flp, new AstLogNot{flp, condp},
-                               new AstEventControl{flp, new AstSenTree{flp, senItemsp}, nullptr}};
-            if (stmtsp) loopp->addNext(stmtsp);
-            nodep->replaceWith(loopp);
-        } else {
+        AstNode* const condp = V3Const::constifyEdit(nodep->condp()->unlinkFrBack());
+        auto* const constp = VN_CAST(condp, Const);
+        if (constp) {
             condp->v3warn(WAITCONST, "Wait statement condition is constant");
-            auto* constCondp = VN_AS(V3Const::constifyEdit(condp), Const);
-            if (constCondp->isZero()) {
+            if (constp->isZero()) {
                 // We have to await forever instead of simply returning in case we're deep in a
                 // callstack
                 auto* const awaitp = new AstCAwait{flp, new AstCStmt{flp, "VlForever{}"}};
@@ -607,10 +705,30 @@ private:
                 nodep->replaceWith(awaitp);
                 if (stmtsp) VL_DO_DANGLING(stmtsp->deleteTree(), stmtsp);
             } else if (stmtsp) {
-                // Just put the body there
+                // Just put the statements there
                 nodep->replaceWith(stmtsp);
             }
-            VL_DO_DANGLING(constCondp->deleteTree(), condp);
+            VL_DO_DANGLING(condp->deleteTree(), condp);
+        } else if (needDynamicTrigger(condp)) {
+            // No point in making a sentree, just use the expression as sensitivity
+            // Put the event control in an if so we only wait if the condition isn't met already
+            auto* const ifp = new AstIf{
+                flp, new AstLogNot{flp, condp},
+                new AstEventControl{flp,
+                                    new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE,
+                                                                       condp->cloneTree(false)}},
+                                    nullptr}};
+            if (stmtsp) AstNode::addNext(ifp, stmtsp);
+            nodep->replaceWith(ifp);
+        } else {
+            AstSenItem* const senItemsp = varRefpsToSenItemsp(condp);
+            UASSERT_OBJ(senItemsp, nodep, "No varrefs in wait statement condition");
+            // Put the event control in a while loop with the wait expression as condition
+            auto* const loopp
+                = new AstWhile{flp, new AstLogNot{flp, condp},
+                               new AstEventControl{flp, new AstSenTree{flp, senItemsp}, nullptr}};
+            if (stmtsp) AstNode::addNext(loopp, stmtsp);
+            nodep->replaceWith(loopp);
         }
         VL_DO_DANGLING(nodep->deleteTree(), nodep);
     }
diff --git a/test_regress/t/t_mailbox_class.out b/test_regress/t/t_mailbox_class.out
deleted file mode 100644
index da24a9ec0..000000000
--- a/test_regress/t/t_mailbox_class.out
+++ /dev/null
@@ -1,17 +0,0 @@
-%Error-UNSUPPORTED: t/t_mailbox_class.v:21:25: Unsupported: event controls in methods
-                                             : ... In instance $unit::mailbox_cls
-   21 |       if (m_bound != 0) wait (m_q.size() < m_bound);
-      |                         ^~~~
-                    ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
-%Error-UNSUPPORTED: t/t_mailbox_class.v:35:7: Unsupported: event controls in methods
-                                            : ... In instance $unit::mailbox_cls
-   35 |       wait (m_q.size() != 0);
-      |       ^~~~
-%Error-UNSUPPORTED: t/t_mailbox_class.v:49:7: Unsupported: event controls in methods
-                                            : ... In instance $unit::mailbox_cls
-   49 |       wait (m_q.size() != 0);
-      |       ^~~~
-%Error-UNSUPPORTED: t/t_mailbox_class.v:21:31: Unsupported: Cannot detect changes on expression of complex type (see combinational cycles reported by UNOPTFLAT)
-   21 |       if (m_bound != 0) wait (m_q.size() < m_bound);
-      |                               ^~~
-%Error: Exiting due to
diff --git a/test_regress/t/t_mailbox_class.pl b/test_regress/t/t_mailbox_class.pl
index 830c5f044..3329d516e 100755
--- a/test_regress/t/t_mailbox_class.pl
+++ b/test_regress/t/t_mailbox_class.pl
@@ -10,15 +10,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 
 scenarios(simulator => 1);
 
-compile(
-    verilator_flags2 => ["--timing"],
-    fails => $Self->{vlt_all},
-    expect_filename => $Self->{golden_filename},
-    );
-
-execute(
-    check_finished => 1,
-    ) if !$Self->{vlt_all};
+if (!$Self->have_coroutines) {
+    skip("No coroutine support");
+}
+else {
+    compile(
+        verilator_flags2 => ["--timing"],
+        );
+}
 
 ok(1);
 1;
diff --git a/test_regress/t/t_semaphore_class.out b/test_regress/t/t_semaphore_class.out
deleted file mode 100644
index 54be71860..000000000
--- a/test_regress/t/t_semaphore_class.out
+++ /dev/null
@@ -1,6 +0,0 @@
-%Error-UNSUPPORTED: t/t_semaphore_class.v:17:7: Unsupported: event controls in methods
-                                              : ... In instance $unit::semaphore_cls
-   17 |       wait (m_keys >= keyCount);
-      |       ^~~~
-                    ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
-%Error: Exiting due to
diff --git a/test_regress/t/t_semaphore_class.pl b/test_regress/t/t_semaphore_class.pl
index 830c5f044..3329d516e 100755
--- a/test_regress/t/t_semaphore_class.pl
+++ b/test_regress/t/t_semaphore_class.pl
@@ -10,15 +10,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 
 scenarios(simulator => 1);
 
-compile(
-    verilator_flags2 => ["--timing"],
-    fails => $Self->{vlt_all},
-    expect_filename => $Self->{golden_filename},
-    );
-
-execute(
-    check_finished => 1,
-    ) if !$Self->{vlt_all};
+if (!$Self->have_coroutines) {
+    skip("No coroutine support");
+}
+else {
+    compile(
+        verilator_flags2 => ["--timing"],
+        );
+}
 
 ok(1);
 1;
diff --git a/test_regress/t/t_timing_class.v b/test_regress/t/t_timing_class.v
index b79139153..263b2e44f 100644
--- a/test_regress/t/t_timing_class.v
+++ b/test_regress/t/t_timing_class.v
@@ -15,27 +15,95 @@ module t;
     // EVENTS
     class EventClass;
         event e;
+        int trig_count;
 
-        task sleep; /* @e; */ endtask  // Unsupported
-        task wake; ->e; endtask
+        function new;
+            trig_count = 0;
+        endfunction
+
+        task inc_trig_count;
+            trig_count++;
+        endtask;
+
+        task sleep;
+            @e inc_trig_count;
+            `WRITE_VERBOSE(("Event in class triggered at time %0t!\n", $time));
+        endtask
+
+        task wake;
+            ->e;
+        endtask
+    endclass
+
+    class WaitClass;
+        int a;
+        int b;
+        logic ok;
+
+        function new;
+            a = 0;
+            b = 0;
+            ok = 0;
+        endfunction
+
+        task await;
+            wait(a == 4 && b > 16) if (a != 4 || b <= 16) $stop;
+            ok = 1;
+            `WRITE_VERBOSE(("Condition in object met at time %0t!\n", $time));
+        endtask
+    endclass
+
+    class LocalWaitClass;
+        logic ok;
+
+        function new;
+            ok = 0;
+        endfunction
+
+        task await;
+            int a = 0;
+            int b = 100;
+            fork
+                wait(a == 42 || b != 100) if (a != 42 && b == 100) $stop;
+                #10 a = 42;
+            join
+            ok = 1;
+            `WRITE_VERBOSE(("Condition with local variables met at time %0t!\n", $time));
+        endtask
     endclass
 
     EventClass ec = new;
-    int event_trig_count = 0;
+    WaitClass wc = new;
+    LocalWaitClass lc = new;
 
     initial begin
         @ec.e;
         ec.sleep;
+        if (wc.ok) $stop;
+        wc.await;
+        if (lc.ok) $stop;
+        lc.await;
     end
 
-    initial #25 ec.wake;
-    initial #50 ->ec.e;
+    initial #20 ec.wake;
+    initial #40 ->ec.e;
+    initial begin
+        wc.a = #50 4;
+        wc.b = #10 32;
+    end
 
     always @ec.e begin
-        event_trig_count++;
+        ec.inc_trig_count;
         `WRITE_VERBOSE(("Event in class triggered at time %0t!\n", $time));
     end
 
+    initial begin
+        #80
+        if (ec.trig_count != 3) $stop;
+        if (!wc.ok) $stop;
+        if (!lc.ok) $stop;
+    end
+
     // =============================================
     // DELAYS
     virtual class DelayClass;
@@ -120,7 +188,6 @@ module t;
         fork #5 dAsgn.x = 0; join_none
         dAsgn.do_assign;
         if ($time != 80) $stop;
-        if (event_trig_count != 2) $stop;
         if (dAsgn.y != 1) $stop;
         // Test if the object is deleted before do_assign finishes:
         fork dAsgn.do_assign; join_none
diff --git a/test_regress/t/t_timing_class_unsup.out b/test_regress/t/t_timing_class_unsup.out
deleted file mode 100644
index 0cb96600b..000000000
--- a/test_regress/t/t_timing_class_unsup.out
+++ /dev/null
@@ -1,6 +0,0 @@
-%Error-UNSUPPORTED: t/t_timing_class_unsup.v:10:17: Unsupported: event controls in methods
-                                                  : ... In instance $unit::EventClass
-   10 |     task sleep; @e; endtask
-      |                 ^
-                    ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
-%Error: Exiting due to
diff --git a/test_regress/t/t_timing_class_unsup.v b/test_regress/t/t_timing_class_unsup.v
deleted file mode 100644
index 01795aa00..000000000
--- a/test_regress/t/t_timing_class_unsup.v
+++ /dev/null
@@ -1,12 +0,0 @@
-// DESCRIPTION: Verilator: Verilog Test module
-//
-// This file ONLY is placed under the Creative Commons Public Domain, for
-// any use, without warranty, 2022 by Antmicro Ltd.
-// SPDX-License-Identifier: CC0-1.0
-
-class EventClass;
-    event e;
-
-    task sleep; @e; endtask
-    task wake; ->e; endtask
-endclass
diff --git a/test_regress/t/t_timing_debug2.out b/test_regress/t/t_timing_debug2.out
index 4988bab73..6243cc26c 100644
--- a/test_regress/t/t_timing_debug2.out
+++ b/test_regress/t/t_timing_debug2.out
@@ -1,55 +1,109 @@
 -V{t#,#}- Verilated::debug is on. Message prefix indicates {,}.
 -V{t#,#}+    Vt_timing_debug2___024root___ctor_var_reset
+-V{t#,#}+      Vt_timing_debug2_t___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aAssignDelayClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aDelay10__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aDelay20__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aDelay40__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aDelayClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aEventClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aForkClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aForkDelayClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aLocalWaitClass__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aNoDelay__Vclpkg___ctor_var_reset
+-V{t#,#}+  Vt_timing_debug2_t__03a__03aWaitClass__Vclpkg___ctor_var_reset
 -V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
 -V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
 -V{t#,#}+ Initial
 -V{t#,#}+    Vt_timing_debug2___024root___eval_static
+-V{t#,#}+      Vt_timing_debug2_t___eval_static__TOP__t
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aWaitClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aWaitClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::_ctor_var_reset
 -V{t#,#}+    Vt_timing_debug2___024root___eval_initial
--V{t#,#}+    Vt_timing_debug2___024root___eval_initial__TOP__0
--V{t#,#}             Process forked at t/t_timing_fork_join.v:14 finished
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__1
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__2
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__3
-[0] fork..join process 4
--V{t#,#}             Process forked at t/t_timing_fork_join.v:18 finished
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__5
--V{t#,#}             Awaiting join of fork at: t/t_timing_fork_join.v:13
--V{t#,#}+    Vt_timing_debug2___024root___eval_initial__TOP__1
--V{t#,#}+    Vt_timing_debug2___024root___eval_initial__TOP__2
--V{t#,#}             Awaiting join of fork at: t/t_timing_fork_join.v:83
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__0
+-V{t#,#}         Suspending process waiting for @([event] t.ec.e) at t/t_timing_class.v:80
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__1
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__2
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__3
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__4
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__5
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay10::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay10::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay20::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay20::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay40::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay40::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aNoDelay::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aNoDelay::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aAssignDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aAssignDelayClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay10::__VnoInFunc_do_delay
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__6
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::_ctor_var_reset
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::__VnoInFunc_do_fork
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__0
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__1
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__2
+-V{t#,#}             Awaiting join of fork at: t/t_timing_class.v:209
+-V{t#,#}+      Vt_timing_debug2_t___eval_initial__TOP__t__7
 -V{t#,#}+    Vt_timing_debug2___024root___eval_settle
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}         Committing processes waiting for @([event] t.ec.e):
+-V{t#,#}           - Process waiting at t/t_timing_class.v:80
 -V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
 -V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 2: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 8: Process waiting at t/t_timing_fork_join.v:16
--V{t#,#}             Awaiting time 4: Process waiting at t/t_timing_fork_join.v:17
--V{t#,#}             Awaiting time 16: Process waiting at t/t_timing_fork_join.v:19
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:79
+-V{t#,#}             Awaiting time 10: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 20: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 10: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 30: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 40: Process waiting at t/t_timing_class.v:137
+-V{t#,#}             Awaiting time 50: Process waiting at t/t_timing_class.v:211
+-V{t#,#}             Awaiting time 20: Process waiting at t/t_timing_class.v:215
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:220
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:236
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:79
-[2] fork..join process 3
--V{t#,#}             Process forked at t/t_timing_fork_join.v:17 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:236
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay10::__VnoInFunc_do_sth_else
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay20::__VnoInFunc_do_delay
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:138
+-V{t#,#}             Process forked at t/t_timing_class.v:210 finished
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -58,26 +112,235 @@
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 4: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 8: Process waiting at t/t_timing_fork_join.v:16
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:17
--V{t#,#}             Awaiting time 16: Process waiting at t/t_timing_fork_join.v:19
+-V{t#,#}             Awaiting time 20: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 20: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 30: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 30: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 40: Process waiting at t/t_timing_class.v:137
+-V{t#,#}             Awaiting time 50: Process waiting at t/t_timing_class.v:211
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:215
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:220
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:19
-[4] fork..join process 2
--V{t#,#}             Process forked at t/t_timing_fork_join.v:16 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:220
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkDelayClass::new
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkDelayClass::_ctor_var_reset
+-V{t#,#}             Process forked at t/t_timing_class.v:214 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:215
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_wake
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 0 is active: @([event] t.ec.e)
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Ready processes waiting for @([event] t.ec.e):
+-V{t#,#}           - Process waiting at t/t_timing_class.v:80
+-V{t#,#}         Resuming processes waiting for @([event] t.ec.e)
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:80
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_sleep
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___eval_nba
+-V{t#,#}+      Vt_timing_debug2_t___nba_sequent__TOP__t__0
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_inc_trig_count
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
+-V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
+-V{t#,#}+ Eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Delayed processes:
+-V{t#,#}             Awaiting time 30: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 30: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 50: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 40: Process waiting at t/t_timing_class.v:137
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:211
+-V{t#,#}         Resuming delayed processes
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:211
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay20::__VnoInFunc_do_sth_else
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay40::__VnoInFunc_do_delay
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:139
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkDelayClass::__VnoInFunc_do_delay
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___eval_nba
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
+-V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
+-V{t#,#}+ Eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Delayed processes:
+-V{t#,#}             Awaiting time 40: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 50: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:137
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:202
+-V{t#,#}         Resuming delayed processes
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:202
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting the post update step
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 0 is active: @([event] t.ec.e)
+-V{t#,#}         Doing post updates for processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}         Process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29 awaiting resumption
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         No ready processes waiting for @([event] t.ec.e)
+-V{t#,#}         Resuming processes waiting for @([event] t.ec.e)
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 2 is active: @([true] __VdynSched.evaluate())
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Resuming processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:29
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:29
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_inc_trig_count
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aWaitClass::__VnoInFunc_await
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___eval_nba
+-V{t#,#}+      Vt_timing_debug2_t___nba_sequent__TOP__t__0
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_inc_trig_count
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
+-V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
+-V{t#,#}+ Eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Delayed processes:
+-V{t#,#}             Awaiting time 50: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:137
+-V{t#,#}         Resuming delayed processes
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:137
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -86,25 +349,55 @@
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 8: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 16: Process waiting at t/t_timing_fork_join.v:16
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:17
+-V{t#,#}             Awaiting time 60: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:92
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:17
-[8] fork..join process 1
--V{t#,#}             Process forked at t/t_timing_fork_join.v:15 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:92
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}         Process waiting for @([true] ((32'sh4 == t::WaitClass.a) & (32'sh10 < t::WaitClass.b))) at t/t_timing_class.v:50 awaiting resumption
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 2 is active: @([true] __VdynSched.evaluate())
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Resuming processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:50
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:50
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::__VnoInFunc_await
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::__Vfork_h########__0__0
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh2a == t::LocalWaitClass.a) | (32'sh64 != t::LocalWaitClass.b))) at t/t_timing_class.v:67
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::__Vfork_h########__0__1
+-V{t#,#}             Awaiting join of fork at: t/t_timing_class.v:66
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:67
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh2a == t::LocalWaitClass.a) | (32'sh64 != t::LocalWaitClass.b))) at t/t_timing_class.v:67
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:67
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh2a == t::LocalWaitClass.a) | (32'sh64 != t::LocalWaitClass.b))) at t/t_timing_class.v:67
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -113,114 +406,87 @@
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:67
+-V{t#,#}         Suspending process waiting for @([true] ((32'sh2a == t::LocalWaitClass.a) | (32'sh64 != t::LocalWaitClass.b))) at t/t_timing_class.v:67
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 16: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:16
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:101
+-V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_class.v:68
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:16
-[16] fork in fork starts
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__0
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__1
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__2
-[16] fork..join process 8
--V{t#,#}             Process forked at t/t_timing_fork_join.v:25 finished
--V{t#,#}             Awaiting join of fork at: t/t_timing_fork_join.v:21
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 20: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 24: Process waiting at t/t_timing_fork_join.v:22
--V{t#,#}             Awaiting time 32: Process waiting at t/t_timing_fork_join.v:23
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:24
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:24
-[20] fork..join process 7
--V{t#,#}             Process forked at t/t_timing_fork_join.v:24 finished
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 24: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:22
--V{t#,#}             Awaiting time 32: Process waiting at t/t_timing_fork_join.v:23
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:23
-[24] fork..join process 6
--V{t#,#}             Process forked at t/t_timing_fork_join.v:23 finished
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 32: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:22
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:22
-[32] fork..join process 5
--V{t#,#}             Process forked at t/t_timing_fork_join.v:22 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:68
+-V{t#,#}             Process forked at t/t_timing_class.v:219 finished
 -V{t#,#}             Resuming: Process waiting at (null):0
-[32] fork..join in fork ends
--V{t#,#}             Process forked at t/t_timing_fork_join.v:19 finished
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:101
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay40::__VnoInFunc_do_sth_else
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aNoDelay::__VnoInFunc_do_delay
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aNoDelay::__VnoInFunc_do_sth_else
+-V{t#,#}+      Vt_timing_debug2_t____Vfork_h########__0__0
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aAssignDelayClass::__VnoInFunc_do_assign
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:154
+-V{t#,#}             Process forked at t/t_timing_class.v:68 finished
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         Suspended processes waiting for dynamic trigger evaluation:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:67
+-V{t#,#}         Process waiting for @([true] ((32'sh2a == t::LocalWaitClass.a) | (32'sh64 != t::LocalWaitClass.b))) at t/t_timing_class.v:67 awaiting resumption
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 2 is active: @([true] __VdynSched.evaluate())
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Resuming processes:
+-V{t#,#}           - Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:67
+-V{t#,#}             Process forked at t/t_timing_class.v:67 finished
 -V{t#,#}             Resuming: Process waiting at (null):0
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
+-V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkDelayClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aForkClass::~
+-V{t#,#}+ Eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___timing_resume
+-V{t#,#}         Delayed processes:
+-V{t#,#}             Awaiting time 75: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:188
+-V{t#,#}         Resuming delayed processes
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:188
+-V{t#,#}+    Vt_timing_debug2___024root___eval_act
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
+-V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
+-V{t#,#}         No triggers active
+-V{t#,#}+    Vt_timing_debug2___024root___timing_commit
+-V{t#,#}+    Vt_timing_debug2___024root___eval_nba
+-V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -229,31 +495,29 @@
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 64: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:30
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 80: Process waiting at t/t_timing_class.v:89
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:91
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:30
-[64] main process
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__0
--V{t#,#}         Suspending process waiting for @([event] t.event1) at t/t_timing_fork_join.v:33
-fork..join_any process 2
--V{t#,#}             Process forked at t/t_timing_fork_join.v:37 finished
--V{t#,#}             Awaiting join of fork at: t/t_timing_fork_join.v:31
-back in main process
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:91
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:89
+-V{t#,#}+      Vt_timing_debug2_t____Vfork_h########__0__1
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aAssignDelayClass::__VnoInFunc_do_assign
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}         Committing processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:33
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -262,42 +526,26 @@ back in main process
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 65: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:40
+-V{t#,#}             Awaiting time 85: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:154
+-V{t#,#}             Awaiting time 90: Process waiting at t/t_timing_class.v:194
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:40
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 1 is active: @([event] t.event1)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:33
--V{t#,#}         Resuming processes waiting for @([event] t.event1)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:33
-fork..join_any process 1
--V{t#,#}             Process forked at t/t_timing_fork_join.v:32 finished
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 1 is active: @([event] t.event1)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         No ready processes waiting for @([event] t.event1)
--V{t#,#}         Resuming processes waiting for @([event] t.event1)
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:194
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
@@ -306,323 +554,67 @@ fork..join_any process 1
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 66: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:41
+-V{t#,#}             Awaiting time 90: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:154
+-V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_class.v:195
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:41
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__0
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__1
--V{t#,#}         Suspending process waiting for @([event] t.event1) at t/t_timing_fork_join.v:44
--V{t#,#}             Awaiting join of fork at: t/t_timing_fork_join.v:41
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}         Committing processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:44
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 68: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:42
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:42
-fork..join_any process 1
--V{t#,#}             Process forked at t/t_timing_fork_join.v:42 finished
--V{t#,#}             Resuming: Process waiting at (null):0
-back in main process
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:195
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
 -V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aAssignDelayClass::~
 -V{t#,#}+ Eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
+-V{t#,#}         'act' region trigger index 1 is active: @([true] __VdlySched.awaitingCurrentTime())
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___timing_resume
 -V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 69: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:50
+-V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_class.v:88
+-V{t#,#}             Awaiting time 101: Process waiting at t/t_timing_class.v:154
 -V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:50
--V{t#,#}         Suspending process waiting for @([event] t.event1) at t/t_timing_fork_join.v:51
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 1 is active: @([event] t.event1)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:44
--V{t#,#}         Uncommitted processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:51
--V{t#,#}         Resuming processes waiting for @([event] t.event1)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:44
-fork..join_any process 2
--V{t#,#}             Process forked at t/t_timing_fork_join.v:43 finished
--V{t#,#}         Committing processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:51
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 1 is active: @([event] t.event1)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:51
--V{t#,#}         Resuming processes waiting for @([event] t.event1)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:51
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__0
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__1
--V{t#,#}         Suspending process waiting for @([event] t.event2) at t/t_timing_fork_join.v:62
--V{t#,#}+    Vt_timing_debug2___024root____Vfork_h########__0__2
--V{t#,#}         Suspending process waiting for @([event] t.event3) at t/t_timing_fork_join.v:68
-in main process
--V{t#,#}         Suspending process waiting for @([event] t.event1) at t/t_timing_fork_join.v:75
--V{t#,#}         Committing processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:75
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}         Committing processes waiting for @([event] t.event2):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:62
--V{t#,#}         Committing processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:68
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 70: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:56
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:56
-fork..join_none process 1
--V{t#,#}         Suspending process waiting for @([event] t.event2) at t/t_timing_fork_join.v:58
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 2 is active: @([event] t.event2)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event2):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:62
--V{t#,#}         Uncommitted processes waiting for @([event] t.event2):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:58
--V{t#,#}         Resuming processes waiting for @([event] t.event2)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:62
-fork..join_none process 2
--V{t#,#}         Committing processes waiting for @([event] t.event2):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:58
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 71: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:63
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:63
--V{t#,#}         Suspending process waiting for @([event] t.event3) at t/t_timing_fork_join.v:64
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 3 is active: @([event] t.event3)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:68
--V{t#,#}         Uncommitted processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:64
--V{t#,#}         Resuming processes waiting for @([event] t.event3)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:68
-fork..join_none process 3
--V{t#,#}         Committing processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:64
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 72: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:69
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:69
--V{t#,#}         Suspending process waiting for @([event] t.event3) at t/t_timing_fork_join.v:70
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 3 is active: @([event] t.event3)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:64
--V{t#,#}         Uncommitted processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:70
--V{t#,#}         Resuming processes waiting for @([event] t.event3)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:64
-fork..join_none process 2 again
--V{t#,#}         Committing processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:70
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 73: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:65
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:65
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 2 is active: @([event] t.event2)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event2):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:58
--V{t#,#}         Resuming processes waiting for @([event] t.event2)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:58
-fork..join_none process 1 again
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___eval_nba
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         No triggers active
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
--V{t#,#}+    Vt_timing_debug2___024root___eval_debug_assertions
--V{t#,#}+ Eval
--V{t#,#}+    Vt_timing_debug2___024root___eval
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Delayed processes:
--V{t#,#}             Awaiting time 74: Process waiting at t/t_timing_fork_join.v:15
--V{t#,#}             Awaiting time 100: Process waiting at t/t_timing_fork_join.v:59
--V{t#,#}         Resuming delayed processes
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:59
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 3 is active: @([event] t.event3)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event3):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:70
--V{t#,#}         Resuming processes waiting for @([event] t.event3)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:70
-fork..join_none process 3 again
--V{t#,#}+    Vt_timing_debug2___024root___eval_act
--V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
--V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
--V{t#,#}         'act' region trigger index 1 is active: @([event] t.event1)
--V{t#,#}+    Vt_timing_debug2___024root___timing_commit
--V{t#,#}+    Vt_timing_debug2___024root___timing_resume
--V{t#,#}         Ready processes waiting for @([event] t.event1):
--V{t#,#}           - Process waiting at t/t_timing_fork_join.v:75
--V{t#,#}         Resuming processes waiting for @([event] t.event1)
--V{t#,#}             Resuming: Process waiting at t/t_timing_fork_join.v:75
+-V{t#,#}             Resuming: Process waiting at t/t_timing_class.v:154
 *-* All Finished *-*
 -V{t#,#}+    Vt_timing_debug2___024root___eval_act
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_nba
 -V{t#,#}+    Vt_timing_debug2___024root___eval_triggers__act
+-V{t#,#}         No suspended processes waiting for dynamic trigger evaluation
 -V{t#,#}+    Vt_timing_debug2___024root___dump_triggers__act
 -V{t#,#}         No triggers active
 -V{t#,#}+    Vt_timing_debug2___024root___timing_commit
 -V{t#,#}+    Vt_timing_debug2___024root___eval_final
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay40::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay20::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelay10::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aNoDelay::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aDelayClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aLocalWaitClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aWaitClass::~
+-V{t#,#}+        Vt_timing_debug2_t__03a__03aEventClass::~
diff --git a/test_regress/t/t_timing_debug2.pl b/test_regress/t/t_timing_debug2.pl
index c5b6b9286..56ef19876 100755
--- a/test_regress/t/t_timing_debug2.pl
+++ b/test_regress/t/t_timing_debug2.pl
@@ -14,7 +14,7 @@ if (!$Self->have_coroutines) {
     skip("No coroutine support");
 }
 else {
-    top_filename("t/t_timing_fork_join.v");
+    top_filename("t/t_timing_class.v");
 
     compile(
         verilator_flags2 => ["--exe --main --timing"],
diff --git a/test_regress/t/t_timing_localevent_unsup.out b/test_regress/t/t_timing_localevent_unsup.out
new file mode 100644
index 000000000..46578cb94
--- /dev/null
+++ b/test_regress/t/t_timing_localevent_unsup.out
@@ -0,0 +1,6 @@
+%Error-UNSUPPORTED: t/t_timing_localevent_unsup.v:12:17: Unsupported: waiting on local event variables
+                                                       : ... In instance t::Sleeper
+   12 |                 @e;
+      |                 ^
+                    ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
+%Error: Exiting due to
diff --git a/test_regress/t/t_timing_class_unsup.pl b/test_regress/t/t_timing_localevent_unsup.pl
similarity index 100%
rename from test_regress/t/t_timing_class_unsup.pl
rename to test_regress/t/t_timing_localevent_unsup.pl
diff --git a/test_regress/t/t_timing_localevent_unsup.v b/test_regress/t/t_timing_localevent_unsup.v
new file mode 100644
index 000000000..8091e2a4b
--- /dev/null
+++ b/test_regress/t/t_timing_localevent_unsup.v
@@ -0,0 +1,24 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed under the Creative Commons Public Domain, for
+// any use, without warranty, 2022 by Antmicro Ltd.
+// SPDX-License-Identifier: CC0-1.0
+
+module t;
+    class Sleeper;
+        task sleep;
+            event e;
+            fork
+                @e;
+                #1 ->e;
+            join;
+        endtask
+    endclass
+
+    initial begin
+        Sleeper sleeper = new;
+        sleeper.sleep;
+        $write("*-* All Finished *-*\n");
+        $finish;
+    end
+endmodule