Support nested array and associative array element member access in constraint 3/4 - associative arrays (#8244)

Signed-off-by: Kamil Danecki <[email protected]>
This commit is contained in:
Kamil Danecki
2026-09-28 08:08:57 -04:00
committed by GitHub
parent 510ae7b38b
commit a949674a6b
3 changed files with 46 additions and 9 deletions
+15 -5
View File
@@ -2225,6 +2225,15 @@ class ConstraintExprVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(origp), origp);
}
}
void addStringNamePart(AstNodeSel* nodep, const std::string& fmt = "%32x") {
if (m_nestedAccess) {
AstNodeExpr* const bitp = nodep->bitp()->cloneTreePure(false);
AstNodeExpr* const bitFormatp = new AstSFormatF{bitp->fileline(), fmt, false, bitp};
AstSFormatF* const herep
= new AstSFormatF{nodep->fileline(), "%s.%s", false, bitFormatp};
m_nestedAccess->addVarNamePart(herep, nodep->bitp()->name());
}
}
void visit(AstAssocSel* nodep) override {
if (editFormat(nodep)) return;
FileLine* const fl = nodep->fileline();
@@ -2232,6 +2241,7 @@ class ConstraintExprVisitor final : public VNVisitor {
AstNodeExpr* const origp = nodep->cloneTree(false);
AstSFormatF* newp = nullptr;
if (VN_IS(nodep->bitp(), VarRef) && VN_AS(nodep->bitp(), VarRef)->isString()) {
addStringNamePart(nodep);
VNRelinker handle;
AstNodeExpr* const idxp = new AstSFormatF{fl, (m_structSel ? "%32x" : "#x%32x"), false,
nodep->bitp()->unlinkFrBack(&handle)};
@@ -2247,6 +2257,7 @@ class ConstraintExprVisitor final : public VNVisitor {
"Unsupported: Constrained randomization of associative array keys of "
<< stringSize << "bits, limit is 128 bits");
}
addStringNamePart(nodep);
VNRelinker handle;
AstNodeExpr* const idxp = new AstSFormatF{fl, (m_structSel ? "%32x" : "#x%32x"), false,
stringp->lhsp()->unlinkFrBack(&handle)};
@@ -2258,7 +2269,6 @@ class ConstraintExprVisitor final : public VNVisitor {
&& VN_AS(nodep->bitp()->dtypep(), StructDType)->packed())
|| VN_IS(nodep->bitp()->dtypep(), EnumDType)
|| VN_IS(nodep->bitp()->dtypep(), PackArrayDType)) {
VNRelinker handle;
const int actual_width = nodep->bitp()->width();
std::string fmt;
// Normalize to standard bit width
@@ -2270,6 +2280,8 @@ class ConstraintExprVisitor final : public VNVisitor {
fmt = (m_structSel ? "%" : "#x%")
+ std::to_string(VL_WORDS_I(actual_width) * 8) + "x";
}
if (m_nestedAccess) addStringNamePart(nodep, fmt);
VNRelinker handle;
AstNodeExpr* const idxp
= new AstSFormatF{fl, fmt, false, nodep->bitp()->unlinkFrBack(&handle)};
handle.relink(idxp);
@@ -2278,6 +2290,7 @@ class ConstraintExprVisitor final : public VNVisitor {
nodep->bitp()->v3error(
"Illegal non-integral expression or subexpression in random constraint."
" (IEEE 1800-2023 18.3)");
if (m_nestedAccess) m_nestedAccess->error();
}
}
if (newp && m_structSel && newp->name() == "(select %s %s)") { newp->name("%s.%s"); }
@@ -2418,6 +2431,7 @@ class ConstraintExprVisitor final : public VNVisitor {
}
AstNodeSel* arraySelp = VN_CAST(rootNode, ArraySel);
if (!arraySelp) arraySelp = VN_CAST(rootNode, AssocSel);
if (arraySelp) {
AstNodeDType* const arrayDtp = arraySelp->fromp()->dtypep()->skipRefp();
@@ -2450,10 +2464,6 @@ class ConstraintExprVisitor final : public VNVisitor {
return;
}
}
if (VN_IS(rootNode, AssocSel) || VN_IS(rootNode, ArraySel)) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Array element access in global constraint");
}
// Check if the root variable participates in global constraints
if (const AstVarRef* const varRefp = VN_CAST(rootNode, VarRef)) {
AstVar* const constrainedVar = varRefp->varp();