mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Support constant expressions in bins (#8309)
Signed-off-by: Bartosz Skorowski <[email protected]>
This commit is contained in:
+21
-13
@@ -375,6 +375,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
// auto-bins are per-value only for small domains, so a partial set is harmless here.
|
||||
constexpr size_t maxEnumerate = 1ULL << 16;
|
||||
for (AstNode* np = nodep; np; np = np->nextp()) {
|
||||
np = V3Const::constifyEdit(np);
|
||||
if (AstConst* constp = VN_CAST(np, Const)) {
|
||||
if (constp->num().isFourState())
|
||||
continue; // wildcard patterns can't be enumerated
|
||||
@@ -388,7 +389,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
AstConst* const hiConstp = VN_CAST(rhsp, Const);
|
||||
if ((!loConstp && !loUnbounded) || (!hiConstp && !hiUnbounded)) {
|
||||
rangep->v3error("Non-constant expression in bin range; "
|
||||
"range bounds must be constants");
|
||||
"range bounds must be constants (IEEE 1800-2023 19.5)");
|
||||
continue;
|
||||
}
|
||||
if ((loConstp && loConstp->num().isFourState())
|
||||
@@ -401,7 +402,8 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
values.insert(v);
|
||||
}
|
||||
} else {
|
||||
np->v3error("Non-constant expression in bin value list; values must be constants");
|
||||
np->v3error("Non-constant expression in bin value list; values must be constants "
|
||||
"(IEEE 1800-2023 19.5)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -905,16 +907,17 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
const uint64_t maxVal = (width >= 64) ? UINT64_MAX : ((1ULL << width) - 1);
|
||||
std::vector<AstNodeExpr*> values;
|
||||
for (AstNode* rangep = arrayBinp->rangesp(); rangep; rangep = rangep->nextp()) {
|
||||
rangep = V3Const::constifyEdit(rangep);
|
||||
if (AstInsideRange* const irp = VN_CAST(rangep, InsideRange)) {
|
||||
AstNodeExpr* const lhsp = V3Const::constifyEdit(irp->lhsp());
|
||||
AstNodeExpr* const rhsp = V3Const::constifyEdit(irp->rhsp());
|
||||
AstNodeExpr* const lhsp = irp->lhsp();
|
||||
AstNodeExpr* const rhsp = irp->rhsp();
|
||||
const bool loUnb = VN_IS(lhsp, Unbounded);
|
||||
const bool hiUnb = VN_IS(rhsp, Unbounded);
|
||||
AstConst* const minp = VN_CAST(lhsp, Const);
|
||||
AstConst* const maxp = VN_CAST(rhsp, Const);
|
||||
if ((!minp && !loUnb) || (!maxp && !hiUnb)) {
|
||||
arrayBinp->v3error("Non-constant expression in array bins range; "
|
||||
"range bounds must be constants");
|
||||
"range bounds must be constants (IEEE 1800-2023 19.5)");
|
||||
return values;
|
||||
}
|
||||
if ((minp && minp->num().isFourState()) || (maxp && maxp->num().isFourState())) {
|
||||
@@ -945,7 +948,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
values.push_back(VN_AS(rangep->cloneTree(false), NodeExpr));
|
||||
} else {
|
||||
arrayBinp->v3error("Non-constant expression in array bins value list; "
|
||||
"values must be constants");
|
||||
"values must be constants (IEEE 1800-2023 19.5)");
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -1365,11 +1368,15 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
|
||||
for (AstNode* valp = itemp->valuesp(); valp; valp = valp->nextp()) {
|
||||
AstNodeExpr* singleCondp = nullptr;
|
||||
|
||||
AstConst* const constp = VN_AS(valp, Const);
|
||||
valp = V3Const::constifyEdit(valp);
|
||||
AstConst* const constp = VN_CAST(valp, Const);
|
||||
if (!constp) {
|
||||
valp->v3error("Non-constant expression in transition bin; "
|
||||
"values must be constants (IEEE 1800-2023 19.5)");
|
||||
return new AstConst{valp->fileline(), AstConst::BitFalseErroring{}};
|
||||
}
|
||||
singleCondp
|
||||
= new AstEq{constp->fileline(), exprp->cloneTree(false), constp->cloneTree(false)};
|
||||
|
||||
if (condp) {
|
||||
condp = new AstOr{itemp->fileline(), condp, singleCondp};
|
||||
} else {
|
||||
@@ -2200,6 +2207,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
|
||||
for (AstNode* currRangep = rangep; currRangep; currRangep = currRangep->nextp()) {
|
||||
AstNodeExpr* rangeCondp = nullptr;
|
||||
currRangep = V3Const::constifyEdit(currRangep);
|
||||
|
||||
if (AstInsideRange* irp = VN_CAST(currRangep, InsideRange)) {
|
||||
AstNodeExpr* const minExprp = irp->lhsp();
|
||||
@@ -2216,7 +2224,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
rangeCondp = new AstConst{irp->fileline(), AstConst::BitTrue{}};
|
||||
} else if (!boundp) {
|
||||
irp->v3error("Non-constant expression in bin range; "
|
||||
"range bounds must be constants");
|
||||
"range bounds must be constants (IEEE 1800-2023 19.5)");
|
||||
if (fullCondp) VL_DO_DANGLING(pushDeletep(fullCondp), fullCondp);
|
||||
return nullptr;
|
||||
} else if (boundp->num().isFourState()) {
|
||||
@@ -2230,7 +2238,7 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
}
|
||||
} else if (!minConstp || !maxConstp) {
|
||||
irp->v3error("Non-constant expression in bin range; "
|
||||
"range bounds must be constants");
|
||||
"range bounds must be constants (IEEE 1800-2023 19.5)");
|
||||
if (fullCondp) VL_DO_DANGLING(pushDeletep(fullCondp), fullCondp);
|
||||
return nullptr;
|
||||
} else if (minConstp->num().isFourState() || maxConstp->num().isFourState()) {
|
||||
@@ -2260,8 +2268,8 @@ class FunctionalCoverageVisitor final : public VNVisitor {
|
||||
constp->cloneTree(false)};
|
||||
}
|
||||
} else {
|
||||
currRangep->v3error(
|
||||
"Non-constant expression in bin range; values must be constants");
|
||||
currRangep->v3error("Non-constant expression in bin range; values must be "
|
||||
"constants (IEEE 1800-2023 19.5)");
|
||||
if (fullCondp) VL_DO_DANGLING(pushDeletep(fullCondp), fullCondp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user