Compare commits

...

2 Commits

Author SHA1 Message Date
Ethan Sifferman 6f2e2b64bb format 2026-04-23 17:21:07 -07:00
Ethan Sifferman c9283054bf fixed whole-array NBA to unpacked array in suspendable process 2026-04-23 17:20:33 -07:00
1 changed files with 48 additions and 0 deletions

View File

@ -899,6 +899,44 @@ class DelayedVisitor final : public VNVisitor {
postp->addStmtsp(callp->makeStmt());
}
// Create a properly-sized 32-bit unsigned constant (post-WidthCommit, width==widthMin).
AstConst* makeU32Const(FileLine* flp, const AstNode* contextp, uint32_t value) {
AstConst* const cp = new AstConst{flp, AstConst::DTyped{},
contextp->findBasicDType(VBasicDTypeKwd::UINT32)};
cp->num().setLong(value);
return cp;
}
// Split a whole-(sub-)array NBA ('arr <= rhs_arr') into per-element NBAs and convert each.
// The partial commit queue's enqueue() takes a scalar element, so we recurse through
// convertSchemeValueQueue - each per-element NBA then hits the normal ArraySel path.
void splitAndConvertWholeArrayNba(AstAssignDly* nodep, AstVarScope* vscp,
VarScopeInfo& vscpInfo,
const AstUnpackArrayDType* uaDTypep) {
FileLine* const flp = nodep->fileline();
AstScope* const scopep = VN_AS(nodep->user2p(), Scope);
AstNodeExpr* const origLhsp = nodep->lhsp()->unlinkFrBack();
AstNodeExpr* const origRhsp = nodep->rhsp()->unlinkFrBack();
const int loIdx = uaDTypep->rangep()->loConst();
const int hiIdx = loIdx + uaDTypep->elementsConst();
std::vector<AstAssignDly*> perElementNbas;
perElementNbas.reserve(hiIdx - loIdx);
for (int i = loIdx; i < hiIdx; ++i) {
AstAssignDly* const elemNbap = new AstAssignDly{
flp, new AstArraySel{flp, origLhsp->cloneTree(false), makeU32Const(flp, vscp, i)},
new AstArraySel{flp, origRhsp->cloneTree(false), makeU32Const(flp, vscp, i)}};
elemNbap->user2p(scopep);
nodep->addHereThisAsNext(elemNbap);
perElementNbas.push_back(elemNbap);
}
VL_DO_DANGLING(pushDeletep(origLhsp), origLhsp);
VL_DO_DANGLING(pushDeletep(origRhsp), origRhsp);
pushDeletep(nodep->unlinkFrBack());
for (AstAssignDly* const elemNbap : perElementNbas) {
convertSchemeValueQueue(elemNbap, vscp, vscpInfo, /* partial: */ true);
}
}
void convertSchemeValueQueue(AstAssignDly* nodep, AstVarScope* vscp, VarScopeInfo& vscpInfo,
bool partial) {
UASSERT_OBJ(partial ? vscpInfo.m_scheme == Scheme::ValueQueuePartial
@ -907,6 +945,16 @@ class DelayedVisitor final : public VNVisitor {
FileLine* const flp = vscp->fileline();
AstScope* const scopep = VN_AS(nodep->user2p(), Scope);
// A whole-(sub-)array NBA under the partial scheme needs splitting into per-element NBAs,
// as enqueue() takes a scalar element, not a whole VlUnpacked array.
if (partial) {
if (const AstUnpackArrayDType* const uaDTypep
= VN_CAST(nodep->lhsp()->dtypep()->skipRefp(), UnpackArrayDType)) {
splitAndConvertWholeArrayNba(nodep, vscp, vscpInfo, uaDTypep);
return;
}
}
// Base name suffix for signals constructed below
const std::string baseName = uniqueTmpName(scopep, vscp, vscpInfo);