Fix multidimensional packed array type handling (#8235)

Signed-off-by: Artur Bieniek <[email protected]>
This commit is contained in:
Artur Bieniek
2026-09-07 14:04:17 -04:00
committed by GitHub
parent 048d18a84f
commit 76df8b4a7e
5 changed files with 97 additions and 32 deletions
+11 -5
View File
@@ -230,7 +230,6 @@ class WidthVisitor final : public VNVisitor {
bool m_underSExpr = false; // Visiting under a sequence expression
bool m_underPackedArray = false; // Visiting under a AstPackArrayDType
bool m_underMemberSel = false; // Viting under a MemberSel
bool m_hasNamedType = false; // Packed array is defined using named type
AstNode* m_seqUnsupp = nullptr; // Property has unsupported node
bool m_hasSExpr = false; // Property has a sequence expression
const AstCell* m_cellp = nullptr; // Current cell for arrayed instantiations
@@ -2507,8 +2506,6 @@ class WidthVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(basicp), basicp);
}
}
if (!m_underPackedArray) m_hasNamedType = false; // Outermost dimension
VL_RESTORER(m_hasNamedType);
VL_RESTORER(m_underPackedArray);
if (VN_IS(nodep, PackArrayDType)) m_underPackedArray = true;
// Iterate into subDTypep() to resolve that type and update pointer.
@@ -2522,13 +2519,23 @@ class WidthVisitor final : public VNVisitor {
nodep->widthFromSub(nodep->subDTypep());
if (nodep->subDTypep()->skipRefp()->isCompound()) adtypep->isCompound(true);
} else {
const AstNodeDType* const elemDTypep = nodep->subDTypep()->skipRefp();
if (!elemDTypep->isIntegralOrPacked()) {
nodep->v3error("Unpacked data type " << elemDTypep->prettyDTypeNameQ()
<< " in packed array (IEEE 1800-2023 7.4.1)");
}
const int width = nodep->subDTypep()->width() * nodep->rangep()->elementsConst();
nodep->widthForce(width, width);
if (!VL_RESTORER_PREV(m_underPackedArray)) { // Outermost dimension
// IEEE 1800-2023 7.4.1 "Packed arrays" says
// If a packed array is declared as signed,
// then the array viewed as a single vector shall be signed.
if (!m_hasNamedType && nodep->basicp()->isSigned()) {
const AstNodeDType* baseDTypep = nodep->subDTypep();
while (!VN_IS(baseDTypep, RefDType) && baseDTypep->subDTypep()) {
baseDTypep = baseDTypep->subDTypep();
}
const AstBasicDType* const basicp = nodep->basicp();
if (!VN_IS(baseDTypep, RefDType) && basicp && basicp->isSigned()) {
nodep->numeric(VSigning::fromBool(true));
}
}
@@ -2653,7 +2660,6 @@ class WidthVisitor final : public VNVisitor {
UINFO(4, "dtWidthed " << nodep);
}
void visit(AstRefDType* nodep) override {
m_hasNamedType = m_underPackedArray;
if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed
nodep->doingWidth(true);
if (nodep->typeofp()) { // type(typeofp_expression)