Fix mixed-width inside and dist range bounds failing randomization (#7875)

This commit is contained in:
Yilou Wang
2026-07-07 11:26:19 -07:00
committed by GitHub
parent 87d77f0133
commit f1a8192a36
4 changed files with 244 additions and 26 deletions
+27 -6
View File
@@ -3464,9 +3464,11 @@ class WidthVisitor final : public VNVisitor {
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip = itemp->nextp();
itemp = VN_AS(itemp, DistItem)->rangep();
// InsideRange will get replaced with Lte&Gte and finalized later
if (!VN_IS(itemp, InsideRange))
if (VN_IS(itemp, InsideRange)) {
userIterate(itemp, WidthVP{subDTypep, FINAL}.p());
} else {
iterateCheck(nodep, "Dist Item", itemp, CONTEXT_DET, FINAL, subDTypep, EXTEND_EXP);
}
}
// Inside a constraint, V3Randomize handles dist lowering with proper weights,
@@ -3541,10 +3543,12 @@ class WidthVisitor final : public VNVisitor {
EXTEND_EXP);
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip = itemp->nextp(); // iterate may cause the node to get replaced
// InsideRange will get replaced with Lte&Gte and finalized later
if (!VN_IS(itemp, InsideRange) && !itemp->dtypep()->isNonPackedArray())
if (VN_IS(itemp, InsideRange)) {
userIterate(itemp, WidthVP{expDTypep, FINAL}.p());
} else if (!itemp->dtypep()->isNonPackedArray()) {
iterateCheck(nodep, "Inside Item", itemp, CONTEXT_DET, FINAL, expDTypep,
EXTEND_EXP);
}
}
AstNodeExpr* exprp;
@@ -3636,8 +3640,25 @@ class WidthVisitor final : public VNVisitor {
V3Const::constifyEdit(nodep->lhsp()); // lhsp may change
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
} else {
userIterateAndNext(nodep->lhsp(), m_vup);
userIterateAndNext(nodep->rhsp(), m_vup);
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), m_vup);
userIterateAndNext(nodep->rhsp(), m_vup);
}
if (m_vup->final()) {
AstNodeDType* const expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
// Warning waivers match visit_cmp_eq_gt on the lowered Gte/Lte
const int expWidth = expDTypep->width();
const bool waiveLhs = expWidth == 32
&& !(expDTypep->isSigned() && nodep->lhsp()->isSigned())
&& expDTypep->widthMin() >= nodep->lhsp()->width();
const bool waiveRhs = expWidth == 32
&& !(expDTypep->isSigned() && nodep->rhsp()->isSigned())
&& expWidth >= nodep->rhsp()->widthMin();
iterateCheck(nodep, "Range LHS", nodep->lhsp(), CONTEXT_DET, FINAL, expDTypep,
EXTEND_EXP, !waiveLhs);
iterateCheck(nodep, "Range RHS", nodep->rhsp(), CONTEXT_DET, FINAL, expDTypep,
EXTEND_EXP, !waiveRhs);
}
}
nodep->dtypeFrom(nodep->lhsp());
}