Fix of dynamic scheduler temporary varable locations (#6859) (#6926)

This commit is contained in:
Igor Zaworski 2026-01-15 12:53:00 +01:00 committed by GitHub
parent 8b2144a9db
commit 550cf4462d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 93 additions and 0 deletions

View File

@ -34,6 +34,7 @@ public:
std::vector<AstNodeStmt*> m_inits; // Initialization statements for previous values
std::vector<AstNodeStmt*> m_preUpdates; // Pre update assignments
std::vector<AstNodeStmt*> m_postUpdates; // Post update assignments
std::vector<AstVar*> 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;
}

View File

@ -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<AstVar*>& 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);

View File

@ -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()

View File

@ -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