WIP: Create nested loops in recursive function

Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
This commit is contained in:
Ryszard Rozak 2026-01-19 13:54:44 +01:00
parent 06e8a06bad
commit 0885422372
1 changed files with 47 additions and 8 deletions

View File

@ -154,7 +154,7 @@ public:
toInsertp->addNextHere(stmtp); toInsertp->addNextHere(stmtp);
stmtp = outerStmtp; stmtp = outerStmtp;
} }
activeInitp->addStmtsp(new AstInitial{flp, stmtp->cloneTree(true)}); activeInitp->addStmtsp(new AstInitial{flp, stmtp});
{ // Add the combinational override { // Add the combinational override
// Explicitly list dependencies for update. // Explicitly list dependencies for update.
// Note: rdVscp is also needed to retrigger assignment for the first time. // Note: rdVscp is also needed to retrigger assignment for the first time.
@ -174,16 +174,55 @@ public:
// Reuse the statements created for __VforceEn initialization // Reuse the statements created for __VforceEn initialization
// and replace var ref on the LHS and the RHS // and replace var ref on the LHS and the RHS
AstVarRef* const rdRefp = new AstVarRef{flp, m_rdVscp, VAccess::WRITE}; AstVarRef* const rdRefp = new AstVarRef{flp, m_rdVscp, VAccess::WRITE};
AstNodeExpr* const rdRhsp = forcedUpdate(vscp, loopVarRefs); AstVarRef* origRefp = new AstVarRef{flp, vscp, VAccess::READ};
enRefp->replaceWith(rdRefp); ForceState::markNonReplaceable(origRefp);
VL_DO_DANGLING(enRefp->deleteTree(), enRefp); activep->addStmtsp(new AstAlways{flp, VAlwaysKwd::ALWAYS, nullptr,
enRhsp->replaceWith(rdRhsp); getAssignStmtsp(rdRefp, origRefp)});
VL_DO_DANGLING(enRhsp->deleteTree(), enRhsp);
activep->addStmtsp(new AstAlways{flp, VAlwaysKwd::ALWAYS, nullptr, stmtp});
vscp->scopep()->addBlocksp(activep); vscp->scopep()->addBlocksp(activep);
} }
} }
AstNodeStmt* getAssignStmtsp(AstNodeExpr* lhsp, AstNodeExpr* rhsp) {
static int cnt = 0;
FileLine* const flp = lhsp->fileline();
const AstNodeDType* const lhsDtypep = lhsp->dtypep()->skipRefp();
if (lhsDtypep->isIntegralOrPacked()) {
return new AstAssign{flp, lhsp, rhsp};
} else if (const AstStructDType* const structDtypep
= VN_CAST(lhsDtypep, StructDType)) {
} else if (const AstUnpackArrayDType* const arrayDtypep
= VN_CAST(lhsDtypep, UnpackArrayDType)) {
AstVar* const loopVarp = new AstVar{flp, VVarType::MODULETEMP,
m_rdVscp->varp()->name() + "__VwhileIter_new"
+ std::to_string(cnt++),
VFlagBitPacked{}, 32};
m_rdVscp->varp()->addNext(loopVarp);
AstVarScope* const loopVarScopep
= new AstVarScope{flp, m_rdVscp->scopep(), loopVarp};
m_rdVscp->addNext(loopVarScopep);
AstVarRef* const readRefp = new AstVarRef{flp, loopVarScopep, VAccess::READ};
AstNodeStmt* const currInitp = new AstAssign{
flp, new AstVarRef{flp, loopVarScopep, VAccess::WRITE}, new AstConst{flp, 0}};
AstLoop* const currWhilep = new AstLoop{flp};
currInitp->addNextHere(currWhilep);
AstLoopTest* const loopTestp = new AstLoopTest{
flp, currWhilep,
new AstNeq{
flp, readRefp,
new AstConst{flp, static_cast<uint32_t>(arrayDtypep->elementsConst())}}};
currWhilep->addStmtsp(loopTestp);
AstArraySel* const lhsSelp
= new AstArraySel{flp, lhsp, readRefp->cloneTree(false)};
AstArraySel* const rhsSelp
= new AstArraySel{flp, rhsp, readRefp->cloneTree(false)};
currWhilep->addStmtsp(getAssignStmtsp(lhsSelp, rhsSelp));
AstAssign* const currIncrp = new AstAssign{
flp, new AstVarRef{flp, loopVarScopep, VAccess::WRITE},
new AstAdd{flp, readRefp->cloneTree(false), new AstConst{flp, 1}}};
currWhilep->addStmtsp(currIncrp);
return currInitp;
}
}
static AstNodeExpr* applySelects(AstNodeExpr* exprp, static AstNodeExpr* applySelects(AstNodeExpr* exprp,
const std::vector<AstNodeExpr*>& selectExprs) { const std::vector<AstNodeExpr*>& selectExprs) {
for (AstNodeExpr* const sp : selectExprs) { for (AstNodeExpr* const sp : selectExprs) {