Add warning on dist in constraints (#5264)
This commit is contained in:
parent
34e37d7bd0
commit
0a9b31bb30
|
|
@ -1142,6 +1142,39 @@ public:
|
||||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
bool cleanOut() const override { return true; }
|
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 {
|
class AstDot final : public AstNodeExpr {
|
||||||
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
||||||
// These are eliminated in the link stage
|
// These are eliminated in the link stage
|
||||||
|
|
|
||||||
|
|
@ -1064,24 +1064,6 @@ public:
|
||||||
bool same(const AstNode*) const override { return true; }
|
bool same(const AstNode*) const override { return true; }
|
||||||
string path() const { return m_path; }
|
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 {
|
class AstDpiExport final : public AstNode {
|
||||||
// We could put an AstNodeFTaskRef instead of the verilog function name,
|
// We could put an AstNodeFTaskRef instead of the verilog function name,
|
||||||
// however we're not *calling* it, so that seems somehow wrong.
|
// however we're not *calling* it, so that seems somehow wrong.
|
||||||
|
|
|
||||||
|
|
@ -328,6 +328,11 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
// Fall back to "(ite cond then else)"
|
// Fall back to "(ite cond then else)"
|
||||||
visit(static_cast<AstNodeTriop*>(nodep));
|
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 {
|
void visit(AstReplicate* nodep) override {
|
||||||
// Biop, but RHS is harmful
|
// Biop, but RHS is harmful
|
||||||
if (editFormat(nodep)) return;
|
if (editFormat(nodep)) return;
|
||||||
|
|
|
||||||
|
|
@ -2150,8 +2150,11 @@ class WidthVisitor final : public VNVisitor {
|
||||||
userIterateAndNext(nodep->rangesp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(nodep->rangesp(), WidthVP{SELF, BOTH}.p());
|
||||||
}
|
}
|
||||||
void visit(AstDistItem* nodep) override {
|
void visit(AstDistItem* nodep) override {
|
||||||
userIterate(nodep->rangep(), WidthVP{SELF, BOTH}.p());
|
userIterate(nodep->rangep(), m_vup);
|
||||||
userIterate(nodep->weightp(), WidthVP{SELF, BOTH}.p());
|
if (m_vup->prelim()) { // First stage evaluation
|
||||||
|
userIterate(nodep->weightp(), WidthVP{SELF, BOTH}.p());
|
||||||
|
}
|
||||||
|
nodep->dtypep(nodep->rangep()->dtypep());
|
||||||
}
|
}
|
||||||
void visit(AstVar* nodep) override {
|
void visit(AstVar* nodep) override {
|
||||||
// if (debug()) nodep->dumpTree("- InitPre: ");
|
// 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 {
|
void visit(AstInside* nodep) override {
|
||||||
userIterateAndNext(nodep->exprp(), WidthVP{CONTEXT_DET, PRELIM}.p());
|
userIterateAndNext(nodep->exprp(), WidthVP{CONTEXT_DET, PRELIM}.p());
|
||||||
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
|
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
|
||||||
|
|
|
||||||
|
|
@ -5057,7 +5057,7 @@ expr<nodeExprp>: // IEEE: part of expression/constant_expression/
|
||||||
//
|
//
|
||||||
// // IEEE: expression_or_dist - here to avoid reduce problems
|
// // IEEE: expression_or_dist - here to avoid reduce problems
|
||||||
// // "expr yDIST '{' dist_list '}'"
|
// // "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 <=)
|
fexpr<nodeExprp>: // For use as first part of statement (disambiguates <=)
|
||||||
|
|
@ -7383,7 +7383,7 @@ constraint_set<nodep>: // ==IEEE: constraint_set
|
||||||
| '{' constraint_expressionList '}' { $$ = $2; }
|
| '{' constraint_expressionList '}' { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
dist_list<nodep>: // ==IEEE: dist_list
|
dist_list<distItemp>: // ==IEEE: dist_list
|
||||||
dist_item { $$ = $1; }
|
dist_item { $$ = $1; }
|
||||||
| dist_list ',' dist_item { $$ = addNextNull($1, $3); }
|
| dist_list ',' dist_item { $$ = addNextNull($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -216,14 +216,14 @@
|
||||||
{"type":"CONST","name":"\\\"(bvsge length header)\\\"","addr":"(RE)","loc":"d,24:14,24:16","dtypep":"(M)"}
|
{"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": [
|
"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": [
|
"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": [
|
"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": []},
|
],"scopeNamep": []},
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,10 @@
|
||||||
<const loc="d,24,14,24,16" name=""(bvsge length header)"" dtype_id="2"/>
|
<const loc="d,24,14,24,16" name=""(bvsge length header)"" dtype_id="2"/>
|
||||||
</cmethodhard>
|
</cmethodhard>
|
||||||
</stmtexpr>
|
</stmtexpr>
|
||||||
<stmtexpr loc="d,25,7,25,13">
|
<stmtexpr loc="d,25,14,25,18">
|
||||||
<cmethodhard loc="d,25,7,25,13" name="hard" dtype_id="7">
|
<cmethodhard loc="d,25,14,25,18" name="hard" dtype_id="7">
|
||||||
<varref loc="d,25,7,25,13" name="constraint" dtype_id="8"/>
|
<varref loc="d,25,14,25,18" name="constraint" dtype_id="8"/>
|
||||||
<const loc="d,25,7,25,13" name=""length"" dtype_id="2"/>
|
<const loc="d,25,14,25,18" name=""true"" dtype_id="2"/>
|
||||||
</cmethodhard>
|
</cmethodhard>
|
||||||
</stmtexpr>
|
</stmtexpr>
|
||||||
</task>
|
</task>
|
||||||
|
|
|
||||||
|
|
@ -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)
|
%Warning-CONSTRAINTIGN: t/t_randomize.v:37:7: Constraint expression ignored (unsupported)
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
37 | foreach (array[i]) {
|
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)
|
%Warning-CONSTRAINTIGN: t/t_randomize.v:40:7: Constraint expression ignored (unsupported)
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
40 | unique { array[0], array[1] };
|
40 | unique { array[0], array[1] };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue