mirror of
https://github.com/verilator/verilator.git
synced 2025-04-06 04:32:39 +00:00
Add warning on global constraints (#5625)
This commit is contained in:
parent
58dae8f931
commit
ae990ebcda
@ -438,26 +438,16 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||
|
||||
if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep);
|
||||
|
||||
if (!nodep->varp()->rand().isRandomizable()) return;
|
||||
for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1();
|
||||
backp = backp->backp())
|
||||
backp->user1(true);
|
||||
if (nodep->varp()->rand().isRandomizable()) nodep->user1(true);
|
||||
}
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
if (!m_constraintExprGenp) return;
|
||||
if (VN_IS(nodep->fromp(), LambdaArgRef)) {
|
||||
if (!nodep->varp()->rand().isRandomizable()) return;
|
||||
for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1();
|
||||
backp = backp->backp())
|
||||
backp->user1(true);
|
||||
}
|
||||
}
|
||||
void visit(AstArraySel* nodep) override {
|
||||
if (!m_constraintExprGenp) return;
|
||||
for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1();
|
||||
backp = backp->backp())
|
||||
backp->user1(true);
|
||||
iterateChildrenConst(nodep);
|
||||
// Member select are randomized when both object and member are marked as rand.
|
||||
// Variable references in with clause are converted to member selects and their from() is
|
||||
// of type AstLambdaArgRef. They are randomized too.
|
||||
const bool randObject = nodep->fromp()->user1() || VN_IS(nodep->fromp(), LambdaArgRef);
|
||||
nodep->user1(randObject && nodep->varp()->rand().isRandomizable());
|
||||
}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
@ -473,6 +463,14 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
|
||||
void visit(AstNodeExpr* nodep) override {
|
||||
iterateChildrenConst(nodep);
|
||||
if (!m_constraintExprGenp) return;
|
||||
nodep->user1((nodep->op1p() && nodep->op1p()->user1())
|
||||
|| (nodep->op2p() && nodep->op2p()->user1())
|
||||
|| (nodep->op3p() && nodep->op3p()->user1())
|
||||
|| (nodep->op4p() && nodep->op4p()->user1()));
|
||||
}
|
||||
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
|
||||
public:
|
||||
@ -735,6 +733,12 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||
handle.relink(indexp);
|
||||
editSMT(nodep, nodep->fromp(), indexp);
|
||||
}
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
if (nodep->user1()) {
|
||||
nodep->v3warn(CONSTRAINTIGN, "Global constraints ignored (unsupported)");
|
||||
}
|
||||
editFormat(nodep);
|
||||
}
|
||||
void visit(AstSFormatF* nodep) override {}
|
||||
void visit(AstStmtExpr* nodep) override {}
|
||||
void visit(AstConstraintIf* nodep) override {
|
||||
|
@ -4,12 +4,50 @@
|
||||
// any use, without warranty, 2023 by Antmicro Ltd.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
|
||||
`define check_rand(cl, field, cond) \
|
||||
begin \
|
||||
longint prev_result; \
|
||||
int ok = 0; \
|
||||
if (!bit'(cl.randomize())) $stop; \
|
||||
prev_result = longint'(field); \
|
||||
if (!(cond)) $stop; \
|
||||
repeat(9) begin \
|
||||
longint result; \
|
||||
if (!bit'(cl.randomize())) $stop; \
|
||||
result = longint'(field); \
|
||||
if (!(cond)) $stop; \
|
||||
if (result != prev_result) ok = 1; \
|
||||
prev_result = result; \
|
||||
end \
|
||||
if (ok != 1) $stop; \
|
||||
end
|
||||
|
||||
class Foo;
|
||||
int x;
|
||||
endclass
|
||||
|
||||
class Bar;
|
||||
rand int y;
|
||||
endclass
|
||||
|
||||
class Packet;
|
||||
rand int rf;
|
||||
int state;
|
||||
rand int a;
|
||||
rand Foo foo;
|
||||
Bar bar;
|
||||
|
||||
constraint c { rf == state; }
|
||||
constraint c1 { rf == state; }
|
||||
constraint c2 { a > foo.x; a < bar.y; }
|
||||
|
||||
function new(int s, int x, int y);
|
||||
state = s;
|
||||
foo = new;
|
||||
foo.x = x;
|
||||
bar = new;
|
||||
bar.y = y;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
@ -19,12 +57,15 @@ module t (/*AUTOARG*/);
|
||||
int v;
|
||||
|
||||
initial begin
|
||||
p = new;
|
||||
p.state = 123;
|
||||
p = new(123, 10, 20);
|
||||
v = p.randomize();
|
||||
if (v != 1) $stop;
|
||||
if (p.rf != 123) $stop;
|
||||
|
||||
`check_rand(p, p.a, p.a > 10 && p.a < 20)
|
||||
if (p.foo.x != 10) $stop;
|
||||
if (p.bar.y != 20) $stop;
|
||||
|
||||
p.state = 234;
|
||||
v = p.randomize();
|
||||
if (v != 1) $stop;
|
||||
|
@ -1,17 +1,20 @@
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:17:17: Unsupported: randomizing this expression, treating as state
|
||||
17 | dynarr[1].size < 10;
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:23:17: Unsupported: randomizing this expression, treating as state
|
||||
23 | dynarr[1].size < 10;
|
||||
| ^~~~
|
||||
... 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_method_types_unsup.v:21:9: Size constraint combined with element constraint may not work correctly
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:27:9: Size constraint combined with element constraint may not work correctly
|
||||
: ... note: In instance 't'
|
||||
21 | q.size < 5;
|
||||
27 | q.size < 5;
|
||||
| ^~~~
|
||||
%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:11:13: Unsupported: random member variable with the type of the containing class
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:31:10: Global constraints ignored (unsupported)
|
||||
31 | foo.x < y;
|
||||
| ^
|
||||
%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:15:13: Unsupported: random member variable with the type of the containing class
|
||||
: ... note: In instance 't'
|
||||
11 | rand Cls cls;
|
||||
15 | rand Cls cls;
|
||||
| ^~~
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:33:43: Unsupported: randomizing this expression, treating as state
|
||||
33 | res = obj.randomize() with { dynarr.size > 2; };
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:43:43: Unsupported: randomizing this expression, treating as state
|
||||
43 | res = obj.randomize() with { dynarr.size > 2; };
|
||||
| ^~~~
|
||||
%Error: Exiting due to
|
||||
|
@ -4,12 +4,18 @@
|
||||
// any use, without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Foo;
|
||||
rand int x;
|
||||
endclass
|
||||
|
||||
class Cls;
|
||||
rand int assocarr[string];
|
||||
rand int dynarr[][];
|
||||
rand int q[$];
|
||||
rand Cls cls;
|
||||
rand int i;
|
||||
rand Foo foo;
|
||||
rand int y;
|
||||
int st;
|
||||
constraint dynsize {
|
||||
dynarr.size < 20;
|
||||
@ -21,6 +27,9 @@ class Cls;
|
||||
q.size < 5;
|
||||
q[i] < 10;
|
||||
}
|
||||
constraint global_constraint {
|
||||
foo.x < y;
|
||||
}
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
@ -29,6 +38,7 @@ module t (/*AUTOARG*/);
|
||||
|
||||
initial begin
|
||||
obj = new;
|
||||
obj.foo = new;
|
||||
res = obj.randomize();
|
||||
res = obj.randomize() with { dynarr.size > 2; };
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user