From 550cf4462d24f4a80dfc114c091559f18f614251 Mon Sep 17 00:00:00 2001 From: Igor Zaworski Date: Thu, 15 Jan 2026 12:53:00 +0100 Subject: [PATCH] Fix of dynamic scheduler temporary varable locations (#6859) (#6926) --- src/V3SenExprBuilder.h | 2 ++ src/V3Timing.cpp | 34 ++++++++++++++++++++++++++++ test_regress/t/t_scheduling_7.py | 18 +++++++++++++++ test_regress/t/t_scheduling_7.v | 39 ++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100755 test_regress/t/t_scheduling_7.py create mode 100644 test_regress/t/t_scheduling_7.v diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 8ae70cb4a..2bf7ec432 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -34,6 +34,7 @@ public: std::vector m_inits; // Initialization statements for previous values std::vector m_preUpdates; // Pre update assignments std::vector m_postUpdates; // Post update assignments + std::vector m_vars; // Created temporary variables }; private: @@ -84,6 +85,7 @@ private: } AstVarScope* const vscp = m_scopep->createTemp(name, exprp->dtypep()); vscp->varp()->isInternal(true); + m_results.m_vars.push_back(vscp->varp()); return vscp; } diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index 322f23e88..308e2eb1f 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -762,6 +762,39 @@ class TimingControlVisitor final : public VNVisitor { forkp->addNextHere(awaitp->makeStmt()); } + // `procp` shall be a NodeProcedure/CFunc/Begin and within it vars from `varsp` will be placed. + // `varsp` vector of vars which shall be localized. + static void localizeVars(AstNode* const procp, const std::vector& varsp) { + UASSERT(procp, "procp is nullptr"); + AstNode* firstStmtp; + if (AstNodeProcedure* const nodeProcp = VN_CAST(procp, NodeProcedure)) { + firstStmtp = nodeProcp->stmtsp(); + } else if (AstCFunc* const cfuncp = VN_CAST(procp, CFunc)) { + if (!cfuncp->varsp()) { + for (AstVar* const varp : varsp) { + varp->funcLocal(true); + cfuncp->addVarsp(varp->unlinkFrBack()); + } + return; + } + firstStmtp = cfuncp->varsp(); + } else if (AstBegin* const beginp = VN_CAST(procp, Begin)) { + firstStmtp = beginp->stmtsp(); + } else { + procp->v3fatalSrc( + procp->prettyNameQ() + << " is not of an expected type NodeProcedure/CFunc/Begin instead it is: " + << procp->prettyTypeName()); + } + UASSERT_OBJ(firstStmtp, procp, + procp->prettyNameQ() << " has no non-var statement. 'localizeVars()' is ment " + "to be called on non empty NodeProcedure/CFunc/Begin"); + for (AstVar* const varp : varsp) { + varp->funcLocal(true); + firstStmtp->addHereThisAsNext(varp->unlinkFrBack()); + } + } + // VISITORS void visit(AstNodeModule* nodep) override { UASSERT_OBJ(!m_classp, nodep, "Module or class under class"); @@ -961,6 +994,7 @@ class TimingControlVisitor final : public VNVisitor { m_senExprBuilderp->build(sentreep).first}; // Get the SenExprBuilder results const SenExprBuilder::Results senResults = m_senExprBuilderp->getAndClearResults(); + localizeVars(m_procp, senResults.m_vars); // Put all and inits before the trigger eval loop for (AstNodeStmt* const stmtp : senResults.m_inits) { nodep->addHereThisAsNext(stmtp); diff --git a/test_regress/t/t_scheduling_7.py b/test_regress/t/t_scheduling_7.py new file mode 100755 index 000000000..c33f8d1e2 --- /dev/null +++ b/test_regress/t/t_scheduling_7.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2026 by Wilson Snyder. 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-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_7.v b/test_regress/t/t_scheduling_7.v new file mode 100644 index 000000000..f3ba92a07 --- /dev/null +++ b/test_regress/t/t_scheduling_7.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias' +// +// Alias type check error test. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2026 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +static int counter = 0; + +task wait_for_nba_region; + static int nba; + static int next_nba; + next_nba++; + nba <= next_nba; + @(nba); + counter++; +endtask + +class Foo; + task run_phases(); + repeat(2) begin + fork + if ($c(1)) wait_for_nba_region(); + join_none + end + endtask +endclass + +module top; + initial begin + static Foo p = new; + p.run_phases(); + #1; + if (counter != 2) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule