Fix unpacked array concatenation function arguments (#6900)

This commit is contained in:
Pawel Kojma
2026-01-14 16:23:55 -05:00
committed by GitHub
parent 4563501192
commit 3072907ea4
3 changed files with 97 additions and 1 deletions
+29 -1
View File
@@ -32,6 +32,7 @@
#include "V3EmitCBase.h"
#include "V3Graph.h"
#include "V3Stats.h"
#include "V3UniqueNames.h"
#include <tuple>
@@ -393,6 +394,8 @@ class TaskVisitor final : public VNVisitor {
// STATE
TaskStateVisitor* const m_statep; // Common state between visitors
V3UniqueNames m_initArrayTmpNames; // For generating unique temporary variable names for
// arguments being AstInitArray
AstNodeModule* m_modp = nullptr; // Current module
AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope
AstScope* m_scopep = nullptr; // Current scope
@@ -1441,6 +1444,29 @@ class TaskVisitor final : public VNVisitor {
UINFOTREE(9, newp, "", "newfunc");
m_insStmtp->addHereThisAsNext(newp);
}
void processPins(AstNodeFTaskRef* nodep) {
// Create a fresh variable for each concat array present in pins list
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
AstArg* const argp = VN_AS(pinp, Arg);
AstInitArray* const arrayp = VN_CAST(argp->exprp(), InitArray);
if (!arrayp) continue;
FileLine* const flp = arrayp->fileline();
const std::string tempName = m_initArrayTmpNames.get(argp);
AstVar* const substp = new AstVar{flp, VVarType::VAR, tempName, arrayp->dtypep()};
substp->funcLocal(true);
AstVarScope* const substvscp = createVarScope(substp, tempName);
AstAssign* const assignp
= new AstAssign{flp, new AstVarRef{arrayp->fileline(), substvscp, VAccess::WRITE},
arrayp->unlinkFrBack()};
AstExprStmt* const exprstmtp = new AstExprStmt{
flp, substp, new AstVarRef{arrayp->fileline(), substvscp, VAccess::READ}};
exprstmtp->stmtsp()->addNext(assignp);
argp->exprp(exprstmtp);
}
}
// VISITORS
void visit(AstNodeModule* nodep) override {
@@ -1497,6 +1523,7 @@ class TaskVisitor final : public VNVisitor {
AstNode* beginp;
AstCNew* cnewp = nullptr;
if (m_statep->ftaskNoInline(nodep->taskp())) {
processPins(nodep);
// This may share VarScope's with a public task, if any. Yuk.
beginp = createNonInlinedFTask(nodep, namePrefix, outvscp, cnewp /*ref*/);
} else {
@@ -1672,7 +1699,8 @@ class TaskVisitor final : public VNVisitor {
public:
// CONSTRUCTORS
TaskVisitor(AstNetlist* nodep, TaskStateVisitor* statep)
: m_statep{statep} {
: m_statep{statep}
, m_initArrayTmpNames{"__VInitArrayTemp"} {
iterate(nodep);
}
~TaskVisitor() {