mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
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:
+15
-5
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user