From 752b77ea778587710a742d571c2dcf9665f58d2b Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 7 May 2026 17:02:41 -0400 Subject: [PATCH] Fix events in observed region (#7546) --- src/V3Active.cpp | 14 +++++++++++++ test_regress/t/t_clocking_event_sense.py | 18 +++++++++++++++++ test_regress/t/t_clocking_event_sense.v | 25 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100755 test_regress/t/t_clocking_event_sense.py create mode 100644 test_regress/t/t_clocking_event_sense.v diff --git a/src/V3Active.cpp b/src/V3Active.cpp index c8122c2c4..846183f4c 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -486,6 +486,18 @@ class ActiveVisitor final : public VNVisitor { } } + static void markEventEdges(AstSenTree* sentreep) { + for (AstSenItem* senip = sentreep->sensesp(); senip; + senip = VN_AS(senip->nextp(), SenItem)) { + if (!senip->sensp()) continue; + if (const AstNodeDType* const dtypep = senip->sensp()->dtypep()) { + if (const AstBasicDType* const basicp = dtypep->basicp()) { + if (basicp->isEvent()) senip->edgeType(VEdgeType::ET_EVENT); + } + } + } + } + // VISITORS void visit(AstScope* nodep) override { m_namer.main(nodep); // Clear last scope's names, and collect this scope's existing names @@ -528,6 +540,7 @@ class ActiveVisitor final : public VNVisitor { } void visit(AstAlwaysObserved* nodep) override { UASSERT_OBJ(nodep->sentreep(), nodep, "Should have a sentree"); + markEventEdges(nodep->sentreep()); AstSenTree* const sentreep = nodep->sentreep(); sentreep->unlinkFrBack(); // Make a new active for it, needs to be the only item under the active for V3Sched @@ -536,6 +549,7 @@ class ActiveVisitor final : public VNVisitor { } void visit(AstAlwaysReactive* nodep) override { UASSERT_OBJ(nodep->sentreep(), nodep, "Should have a sentree"); + markEventEdges(nodep->sentreep()); AstSenTree* const sentreep = nodep->sentreep(); sentreep->unlinkFrBack(); // Make a new active for it, needs to be the only item under the active for V3Sched diff --git a/test_regress/t/t_clocking_event_sense.py b/test_regress/t/t_clocking_event_sense.py new file mode 100755 index 000000000..e6a0c4851 --- /dev/null +++ b/test_regress/t/t_clocking_event_sense.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=["--binary"], make_main=False) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_clocking_event_sense.v b/test_regress/t/t_clocking_event_sense.v new file mode 100644 index 000000000..57d850d3c --- /dev/null +++ b/test_regress/t/t_clocking_event_sense.v @@ -0,0 +1,25 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +`timescale 1ms / 1ns +module t; + event e; + bit data = 0; + + clocking cb @e; + input #0 data; + endclocking + + initial begin + #1; + data = 1; + -> e; + #1; + if (cb.data !== 1'b1) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule