diff --git a/include/verilated_timing.cpp b/include/verilated_timing.cpp index 61d66b2f0..3f74c4403 100644 --- a/include/verilated_timing.cpp +++ b/include/verilated_timing.cpp @@ -243,6 +243,12 @@ void VlProcess::forkSyncOnKill(VlForkSync* forkSyncp) { m_forkSyncOnKillDone = false; } +void VlProcess::forkSyncOnKillClear(VlForkSync* forkSyncp) { + if (m_forkSyncOnKillp != forkSyncp) return; + m_forkSyncOnKillp = nullptr; + m_forkSyncOnKillDone = false; +} + void VlProcess::state(int s) { if (s == KILLED && m_state != KILLED && m_state != FINISHED && m_forkSyncOnKillp && !m_forkSyncOnKillDone) { @@ -254,8 +260,16 @@ void VlProcess::state(int s) { m_state = s; } +VlForkSync::~VlForkSync() { + for (std::weak_ptr& weakp : m_onKillProcessps) { + if (VlProcessRef processp = weakp.lock()) processp->forkSyncOnKillClear(this); + } +} + void VlForkSync::onKill(VlProcessRef process) { - if (process) process->forkSyncOnKill(this); + if (!process) return; + m_onKillProcessps.emplace_back(process); + process->forkSyncOnKill(this); } void VlForkSync::done(const char* filename, int lineno) { diff --git a/include/verilated_timing.h b/include/verilated_timing.h index 4eb07402d..1827da956 100644 --- a/include/verilated_timing.h +++ b/include/verilated_timing.h @@ -393,8 +393,10 @@ class VlForkSync final { // The join info is shared among all forked processes std::shared_ptr m_join; + std::vector> m_onKillProcessps; // Branches registered for kill hooks public: + ~VlForkSync(); // Create the join object and set the counter to the specified number void init(size_t count, VlProcessRef process) { m_join.reset(new VlJoin{count, {process}}); } // Register process kill callback so killed fork branches still decrement join counter diff --git a/include/verilated_types.h b/include/verilated_types.h index 487b7066e..e246b8e80 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -157,6 +157,7 @@ public: for (VlProcess* childp : m_children) childp->disable(); } void forkSyncOnKill(VlForkSync* forkSyncp); + void forkSyncOnKillClear(VlForkSync* forkSyncp); bool completed() const { return state() == FINISHED || state() == KILLED; } bool completedFork() const { for (const VlProcess* const childp : m_children) diff --git a/test_regress/t/t_disable_task_scope_bad.out b/test_regress/t/t_disable_task_scope_bad.out index 2fa1c2987..48b3881fc 100644 --- a/test_regress/t/t_disable_task_scope_bad.out +++ b/test_regress/t/t_disable_task_scope_bad.out @@ -1,20 +1,20 @@ -%Error: t/t_disable_task_scope_bad.v:34:18: Can't find definition of 'missing_task' in dotted block/task: 'ifc1.missing_task' - 34 | disable ifc1.missing_task; +%Error: t/t_disable_task_scope_bad.v:36:18: Can't find definition of 'missing_task' in dotted block/task: 'ifc1.missing_task' + 36 | disable ifc1.missing_task; | ^~~~~~~~~~~~ ... Known scopes under 'ifc1': ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_disable_task_scope_bad.v:35:19: Can't find definition of 'missing_task' in dotted block/task: 'prog1.missing_task' - 35 | disable prog1.missing_task; +%Error: t/t_disable_task_scope_bad.v:37:19: Can't find definition of 'missing_task' in dotted block/task: 'prog1.missing_task' + 37 | disable prog1.missing_task; | ^~~~~~~~~~~~ ... Known scopes under 'prog1': -%Error: t/t_disable_task_scope_bad.v:36:26: Can't find definition of 'missing_task' in dotted block/task: 'outer1.inner.missing_task' - 36 | disable outer1.inner.missing_task; +%Error: t/t_disable_task_scope_bad.v:38:26: Can't find definition of 'missing_task' in dotted block/task: 'outer1.inner.missing_task' + 38 | disable outer1.inner.missing_task; | ^~~~~~~~~~~~ ... Known scopes under 'outer1.inner': -%Error: t/t_disable_task_scope_bad.v:37:18: Found definition of 'ifc1.data' as a VAR but expected a block/task - 37 | disable ifc1.data; +%Error: t/t_disable_task_scope_bad.v:39:18: Found definition of 'ifc1.data' as a VAR but expected a block/task + 39 | disable ifc1.data; | ^~~~ -%Error: t/t_disable_task_scope_bad.v:38:19: Found definition of 'prog1.data' as a VAR but expected a block/task - 38 | disable prog1.data; +%Error: t/t_disable_task_scope_bad.v:40:19: Found definition of 'prog1.data' as a VAR but expected a block/task + 40 | disable prog1.data; | ^~~~ %Error: Exiting due to diff --git a/test_regress/t/t_disable_task_target_bad.out b/test_regress/t/t_disable_task_target_bad.out index 613440744..8d14a77c3 100644 --- a/test_regress/t/t_disable_task_target_bad.out +++ b/test_regress/t/t_disable_task_target_bad.out @@ -1,11 +1,11 @@ -%Error: t/t_disable_task_target_bad.v:21:13: Found definition of 'foo' as a VAR but expected a block/task - 21 | disable foo; +%Error: t/t_disable_task_target_bad.v:23:13: Found definition of 'foo' as a VAR but expected a block/task + 23 | disable foo; | ^~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_disable_task_target_bad.v:22:13: Found definition of 'c' as a VAR but expected a block/task - 22 | disable c.run; +%Error: t/t_disable_task_target_bad.v:24:13: Found definition of 'c' as a VAR but expected a block/task + 24 | disable c.run; | ^ -%Error: t/t_disable_task_target_bad.v:22:15: Can't find definition of block/task: 'run' - 22 | disable c.run; +%Error: t/t_disable_task_target_bad.v:24:15: Can't find definition of block/task: 'run' + 24 | disable c.run; | ^~~ %Error: Exiting due to