Add warning on dist in constraints (#5264)

This commit is contained in:
Arkadiusz Kozdra 2024-07-16 03:01:33 +02:00 committed by GitHub
parent 34e37d7bd0
commit 0a9b31bb30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 99 additions and 32 deletions

View File

@ -1142,6 +1142,39 @@ public:
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
};
class AstDist final : public AstNodeExpr {
// @astgen op1 := exprp : AstNodeExpr
// @astgen op2 := itemsp : List[AstDistItem]
public:
AstDist(FileLine* fl, AstNodeExpr* exprp, AstDistItem* itemsp)
: ASTGEN_SUPER_Inside(fl) {
this->exprp(exprp);
this->addItemsp(itemsp);
dtypeSetBit();
}
ASTGEN_MEMBERS_AstDist;
string emitVerilog() override { return "%l dist { %r }"; }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return false; } // NA
};
class AstDistItem final : public AstNodeExpr {
// Constraint distribution item
// @astgen op1 := rangep : AstNodeExpr
// @astgen op2 := weightp : AstNodeExpr
bool m_isWhole = false; // True for weight ':/', false for ':='
public:
AstDistItem(FileLine* fl, AstNodeExpr* rangep, AstNodeExpr* weightp)
: ASTGEN_SUPER_DistItem(fl) {
this->rangep(rangep);
this->weightp(weightp);
}
ASTGEN_MEMBERS_AstDistItem;
string emitVerilog() override { return "%l "s + (m_isWhole ? ":/" : ":=") + " %r"; }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return false; } // NA
void isWhole(bool flag) { m_isWhole = flag; }
bool isWhole() const { return m_isWhole; }
};
class AstDot final : public AstNodeExpr {
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
// These are eliminated in the link stage

View File

@ -1064,24 +1064,6 @@ public:
bool same(const AstNode*) const override { return true; }
string path() const { return m_path; }
};
class AstDistItem final : public AstNode {
// Constraint distribution item
// @astgen op1 := rangep : AstNodeExpr
// @astgen op2 := weightp : AstNodeExpr
bool m_isWhole = false; // True for weight ':/', false for ':='
public:
AstDistItem(FileLine* fl, AstNodeExpr* rangep, AstNodeExpr* weightp)
: ASTGEN_SUPER_DistItem(fl) {
this->rangep(rangep);
this->weightp(weightp);
}
ASTGEN_MEMBERS_AstDistItem;
bool isGateOptimizable() const override { return false; }
bool isPredictOptimizable() const override { return false; }
bool same(const AstNode* /*samep*/) const override { return true; }
void isWhole(bool flag) { m_isWhole = flag; }
bool isWhole() const { return m_isWhole; }
};
class AstDpiExport final : public AstNode {
// We could put an AstNodeFTaskRef instead of the verilog function name,
// however we're not *calling* it, so that seems somehow wrong.

View File

@ -328,6 +328,11 @@ class ConstraintExprVisitor final : public VNVisitor {
// Fall back to "(ite cond then else)"
visit(static_cast<AstNodeTriop*>(nodep));
}
void visit(AstDist* nodep) override {
nodep->v3warn(CONSTRAINTIGN, "Constraint expression ignored (unsupported)");
nodep->replaceWith(new AstSFormatF{nodep->fileline(), "true", false, nullptr});
VL_DO_DANGLING(nodep->deleteTree(), nodep);
}
void visit(AstReplicate* nodep) override {
// Biop, but RHS is harmful
if (editFormat(nodep)) return;

View File

@ -2150,8 +2150,11 @@ class WidthVisitor final : public VNVisitor {
userIterateAndNext(nodep->rangesp(), WidthVP{SELF, BOTH}.p());
}
void visit(AstDistItem* nodep) override {
userIterate(nodep->rangep(), WidthVP{SELF, BOTH}.p());
userIterate(nodep->weightp(), WidthVP{SELF, BOTH}.p());
userIterate(nodep->rangep(), m_vup);
if (m_vup->prelim()) { // First stage evaluation
userIterate(nodep->weightp(), WidthVP{SELF, BOTH}.p());
}
nodep->dtypep(nodep->rangep()->dtypep());
}
void visit(AstVar* nodep) override {
// if (debug()) nodep->dumpTree("- InitPre: ");
@ -2574,6 +2577,46 @@ class WidthVisitor final : public VNVisitor {
}
}
}
void visit(AstDist* nodep) override {
userIterateAndNext(nodep->exprp(), WidthVP{CONTEXT_DET, PRELIM}.p());
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip = itemp->nextp(); // iterate may cause the node to get replaced
VL_DO_DANGLING(userIterate(itemp, WidthVP{CONTEXT_DET, PRELIM}.p()), itemp);
}
AstBasicDType* dtype = VN_CAST(nodep->exprp()->dtypep(), BasicDType);
AstNodeDType* subDTypep = nullptr;
nodep->dtypeSetBit();
if (dtype && dtype->isString()) {
nodep->dtypeSetString();
subDTypep = nodep->findStringDType();
} else if (dtype && dtype->isDouble()) {
nodep->dtypeSetDouble();
subDTypep = nodep->findDoubleDType();
} else {
// Take width as maximum across all items
int width = nodep->exprp()->width();
int mwidth = nodep->exprp()->widthMin();
for (const AstNode* itemp = nodep->itemsp(); itemp; itemp = itemp->nextp()) {
width = std::max(width, itemp->width());
mwidth = std::max(mwidth, itemp->widthMin());
}
subDTypep = nodep->findLogicDType(width, mwidth, nodep->exprp()->dtypep()->numeric());
}
iterateCheck(nodep, "Dist expression", nodep->exprp(), CONTEXT_DET, FINAL, subDTypep,
EXTEND_EXP);
for (AstDistItem *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip
= VN_AS(itemp->nextp(), DistItem); // iterate may cause the node to get replaced
iterateCheck(nodep, "Dist Item", itemp, CONTEXT_DET, FINAL, subDTypep, EXTEND_EXP);
}
if (debug() >= 9) nodep->dumpTree("- dist-out: ");
nodep->dtypep(subDTypep);
}
void visit(AstInside* nodep) override {
userIterateAndNext(nodep->exprp(), WidthVP{CONTEXT_DET, PRELIM}.p());
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {

View File

@ -5057,7 +5057,7 @@ expr<nodeExprp>: // IEEE: part of expression/constant_expression/
//
// // IEEE: expression_or_dist - here to avoid reduce problems
// // "expr yDIST '{' dist_list '}'"
| ~l~expr yDIST '{' dist_list '}' { $$ = $1; $4->deleteTree(); }
| ~l~expr yDIST '{' dist_list '}' { $$ = new AstDist{$2, $1, $4}; }
;
fexpr<nodeExprp>: // For use as first part of statement (disambiguates <=)
@ -7383,7 +7383,7 @@ constraint_set<nodep>: // ==IEEE: constraint_set
| '{' constraint_expressionList '}' { $$ = $2; }
;
dist_list<nodep>: // ==IEEE: dist_list
dist_list<distItemp>: // ==IEEE: dist_list
dist_item { $$ = $1; }
| dist_list ',' dist_item { $$ = addNextNull($1, $3); }
;

View File

@ -216,14 +216,14 @@
{"type":"CONST","name":"\\\"(bvsge length header)\\\"","addr":"(RE)","loc":"d,24:14,24:16","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(SE)","loc":"d,25:7,25:13",
{"type":"STMTEXPR","name":"","addr":"(SE)","loc":"d,25:14,25:18",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(TE)","loc":"d,25:7,25:13","dtypep":"(LB)",
{"type":"CMETHODHARD","name":"hard","addr":"(TE)","loc":"d,25:14,25:18","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(UE)","loc":"d,25:7,25:13","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"constraint","addr":"(UE)","loc":"d,25:14,25:18","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"length\\\"","addr":"(VE)","loc":"d,25:7,25:13","dtypep":"(M)"}
{"type":"CONST","name":"\\\"true\\\"","addr":"(VE)","loc":"d,25:14,25:18","dtypep":"(M)"}
]}
]}
],"scopeNamep": []},

View File

@ -159,10 +159,10 @@
<const loc="d,24,14,24,16" name="&quot;(bvsge length header)&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,25,7,25,13">
<cmethodhard loc="d,25,7,25,13" name="hard" dtype_id="7">
<varref loc="d,25,7,25,13" name="constraint" dtype_id="8"/>
<const loc="d,25,7,25,13" name="&quot;length&quot;" dtype_id="2"/>
<stmtexpr loc="d,25,14,25,18">
<cmethodhard loc="d,25,14,25,18" name="hard" dtype_id="7">
<varref loc="d,25,14,25,18" name="constraint" dtype_id="8"/>
<const loc="d,25,14,25,18" name="&quot;true&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
</task>

View File

@ -1,9 +1,13 @@
%Warning-CONSTRAINTIGN: t/t_randomize.v:22:14: Constraint expression ignored (unsupported)
: ... note: In instance 't'
22 | length dist { [0:1], [2:5] :/ 2, 6 := 6, 7 := 10, 1};
| ^~~~
... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest
... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message.
%Warning-CONSTRAINTIGN: t/t_randomize.v:37:7: Constraint expression ignored (unsupported)
: ... note: In instance 't'
37 | foreach (array[i]) {
| ^~~~~~~
... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest
... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message.
%Warning-CONSTRAINTIGN: t/t_randomize.v:40:7: Constraint expression ignored (unsupported)
: ... note: In instance 't'
40 | unique { array[0], array[1] };