Fix constrained random for > 64-bit associative arrays (#5670) (#5682)

This commit is contained in:
Yilou Wang
2025-01-09 08:33:38 -05:00
committed by GitHub
parent 44f49669a3
commit 0380a36c76
9 changed files with 312 additions and 82 deletions
+15 -20
View File
@@ -710,15 +710,19 @@ class ConstraintExprVisitor final : public VNVisitor {
if (editFormat(nodep)) return;
FileLine* const fl = nodep->fileline();
if (VN_IS(nodep->bitp(), CvtPackString)) {
// Extract and truncate the string index to fit within 64 bits
AstCvtPackString* const stringp = VN_AS(nodep->bitp(), CvtPackString);
const size_t stringSize = VN_AS(stringp->lhsp(), Const)->width();
if (stringSize > 128) {
stringp->v3warn(
CONSTRAINTIGN,
"Unsupported: Constrained randomization of associative array keys of "
<< stringSize << "bits, limit is 128 bits");
}
VNRelinker handle;
AstNodeExpr* const strIdxp = new AstSFormatF{
fl, "#x%16x", false,
new AstAnd{fl, stringp->lhsp()->unlinkFrBack(&handle),
new AstConst(fl, AstConst::Unsized64{}, 0xFFFFFFFFFFFFFFFF)}};
handle.relink(strIdxp);
editSMT(nodep, nodep->fromp(), strIdxp);
AstNodeExpr* const idxp
= new AstSFormatF{fl, "#x%32x", false, stringp->lhsp()->unlinkFrBack(&handle)};
handle.relink(idxp);
editSMT(nodep, nodep->fromp(), idxp);
} else {
VNRelinker handle;
const int actual_width = nodep->bitp()->width();
@@ -728,16 +732,10 @@ class ConstraintExprVisitor final : public VNVisitor {
fmt = "#x%2x";
} else if (actual_width <= 16) {
fmt = "#x%4x";
} else if (actual_width <= 32) {
fmt = "#x%8x";
} else if (actual_width <= 64) {
fmt = "#x%16x";
} else {
nodep->v3warn(CONSTRAINTIGN,
"Unsupported: Associative array index "
"widths of more than 64 bits during constraint randomization.");
return;
fmt = "#x%" + std::to_string(VL_WORDS_I(actual_width) * 8) + "x";
}
AstNodeExpr* const idxp
= new AstSFormatF{fl, fmt, false, nodep->bitp()->unlinkFrBack(&handle)};
handle.relink(idxp);
@@ -1450,11 +1448,8 @@ class RandomizeVisitor final : public VNVisitor {
AstNodeStmt* stmtsp = nullptr;
auto createLoopIndex = [&](AstNodeDType* tempDTypep) {
if (VN_IS(tempDTypep, AssocArrayDType)) {
return new AstVar{
fl, VVarType::VAR, uniqueNamep->get(""),
dtypep->findBasicDType(
((AstBasicDType*)VN_AS(tempDTypep, AssocArrayDType)->keyDTypep())
->keyword())};
return new AstVar{fl, VVarType::VAR, uniqueNamep->get(""),
VN_AS(tempDTypep, AssocArrayDType)->keyDTypep()};
}
return new AstVar{fl, VVarType::VAR, uniqueNamep->get(""),
dtypep->findBasicDType(VBasicDTypeKwd::UINT32)};