From 06e8a06badab57d33f95ffd02b8099c634978135 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 16 Jan 2026 14:59:44 +0100 Subject: [PATCH] Don't use unpackDimensions Signed-off-by: Ryszard Rozak --- src/V3Force.cpp | 79 ++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/V3Force.cpp b/src/V3Force.cpp index 42c774d8f..7e2fae5da 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -100,48 +100,45 @@ public: AstNodeStmt* outerStmtp = nullptr; std::vector loopVarRefs; AstNodeDType* enRhsDTypep = m_enVscp->varp()->dtypep()->skipRefp(); - if (AstUnpackArrayDType* const unpackedp - = VN_CAST(m_rdVscp->varp()->dtypep()->skipRefp(), UnpackArrayDType)) { - // Create a loop to set all elements of __VforceEn array to 0. - // That loop node is then copied and used for updating elements of __VforceRd array - std::vector dims = unpackedp->unpackDimensions(); - loopVarRefs.reserve(dims.size()); - for (size_t i = 0; i < dims.size(); i++) { - AstVar* const loopVarp - = new AstVar{flp, VVarType::MODULETEMP, - m_rdVscp->varp()->name() + "__VwhileIter" + std::to_string(i), - 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}; - loopVarRefs.push_back(readRefp); - AstNodeStmt* const currInitp - = new AstAssign{flp, new AstVarRef{flp, loopVarScopep, VAccess::WRITE}, - new AstConst{flp, 0}}; - if (toInsertp) { - toInsertp->addNextHere(currInitp); - } else { - outerStmtp = currInitp; - } - 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(dims[i]->elementsConst())}}}; - currWhilep->addStmtsp(loopTestp); - toInsertp = loopTestp; - 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); - - // __En var has the same number of dimensions as __Rd var - enRhsDTypep = enRhsDTypep->subDTypep(); + AstNodeDType* currDtypep = m_rdVscp->varp()->dtypep()->skipRefp(); + // Create a loop to set all elements of __VforceEn array to 0. + // That loop node is then copied and used for updating elements of __VforceRd array + int cnt = 0; + while (AstUnpackArrayDType* const unpackedp = VN_CAST(currDtypep, UnpackArrayDType)) { + AstVar* const loopVarp + = new AstVar{flp, VVarType::MODULETEMP, + m_rdVscp->varp()->name() + "__VwhileIter" + 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}; + loopVarRefs.push_back(readRefp); + AstNodeStmt* const currInitp = new AstAssign{ + flp, new AstVarRef{flp, loopVarScopep, VAccess::WRITE}, new AstConst{flp, 0}}; + if (toInsertp) { + toInsertp->addNextHere(currInitp); + } else { + outerStmtp = currInitp; } + 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(unpackedp->elementsConst())}}}; + currWhilep->addStmtsp(loopTestp); + toInsertp = loopTestp; + 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); + + currDtypep = currDtypep->subDTypep(); + // __En var has the same number of dimensions as __Rd var + enRhsDTypep = enRhsDTypep->subDTypep(); } AstNodeExpr* enRhsp; if (AstNodeUOrStructDType* const structEnDtypep