From 7d71c3bb760f1d03396f84f585a5781c83de7566 Mon Sep 17 00:00:00 2001 From: Igor Zaworski Date: Fri, 13 Feb 2026 17:01:19 +0100 Subject: [PATCH] Fix of event triggering with V3Life (#6932 effect) (#7068 partial) (#7072) --- src/V3AstNodeExpr.h | 3 ++ src/V3SchedTrigger.cpp | 1 + .../t/t_scheduling_beforeTrig_life_opt.py | 18 +++++++ .../t/t_scheduling_beforeTrig_life_opt.v | 53 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100755 test_regress/t/t_scheduling_beforeTrig_life_opt.py create mode 100644 test_regress/t/t_scheduling_beforeTrig_life_opt.v diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index f228f7ca5..35725db2d 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1349,6 +1349,7 @@ class AstExprStmt final : public AstNodeExpr { // @astgen op2 := resultp : AstNodeExpr private: bool m_hasResult = true; + bool m_containsTimingControl = false; public: AstExprStmt(FileLine* fl, AstNode* stmtsp, AstNodeExpr* resultp) @@ -1369,6 +1370,8 @@ public: bool sameNode(const AstNode*) const override { return true; } bool hasResult() const { return m_hasResult; } void hasResult(bool flag) { m_hasResult = flag; } + void setTimingControl() { m_containsTimingControl = true; } + bool isTimingControl() const override { return m_containsTimingControl; } }; class AstFError final : public AstNodeExpr { // @astgen op1 := filep : AstNode diff --git a/src/V3SchedTrigger.cpp b/src/V3SchedTrigger.cpp index 3bb745a91..c9aeda84a 100644 --- a/src/V3SchedTrigger.cpp +++ b/src/V3SchedTrigger.cpp @@ -896,6 +896,7 @@ class AwaitBeforeTrigVisitor final : public VNVisitor { nodep->unlinkFrBack(&relinker); AstExprStmt* const exprstmtp = new AstExprStmt{flp, beforeTrigp->makeStmt(), nodep}; + exprstmtp->setTimingControl(); relinker.relink(exprstmtp); m_senTreeToSched.emplace(nodep->sentreep(), cMethodHardp->fromp()); } diff --git a/test_regress/t/t_scheduling_beforeTrig_life_opt.py b/test_regress/t/t_scheduling_beforeTrig_life_opt.py new file mode 100755 index 000000000..6fe7d000c --- /dev/null +++ b/test_regress/t/t_scheduling_beforeTrig_life_opt.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"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_scheduling_beforeTrig_life_opt.v b/test_regress/t/t_scheduling_beforeTrig_life_opt.v new file mode 100644 index 000000000..ad01c9375 --- /dev/null +++ b/test_regress/t/t_scheduling_beforeTrig_life_opt.v @@ -0,0 +1,53 @@ +// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias' +// +// Alias type check error test. +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +module s ( + input clk, + output wire rdy, + input reset +); + parameter ss = 5; + localparam w = 1 << ss; + reg [ss-1:0] bitl; + assign rdy = bitl[ss-1]; + (* ivl_synthesis_on *) + always @(posedge clk or posedge reset) begin + if (!reset) begin + bitl <= bitl - 1; + end + end +endmodule +module t; + parameter ss = 5; + parameter w = 1 << ss; + reg clk, reset; + wire done; + s dut ( + .clk (clk), + .rdy (done), + .reset(reset) + ); + always #5 clk = !clk; + task reset_dut; + reset = 1; + @(posedge clk); + #1 reset = 0; + endtask + task run_dut; + while (done == 0) begin + @(posedge clk); + end + endtask + initial begin + clk = 0; + reset_dut; + run_dut; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule