Support foreach constraints (#5302)
Signed-off-by: Arkadiusz Kozdra <akozdra@antmicro.com>
This commit is contained in:
parent
a61178bd89
commit
54f9f4b6a9
|
|
@ -513,9 +513,31 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
}
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
void visit(AstForeach* nodep) override {}
|
||||
void visit(AstConstraintForeach* nodep) override {
|
||||
nodep->v3warn(CONSTRAINTIGN, "Constraint expression ignored (unsupported)");
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
// Convert to plain foreach
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
||||
if (m_wantSingle) {
|
||||
AstNode* const itemp = editSingle(fl, nodep->stmtsp());
|
||||
AstNode* const cstmtp = new AstText{fl, "ret += \" \" + "};
|
||||
cstmtp->addNext(itemp);
|
||||
cstmtp->addNext(new AstText{fl, ";"});
|
||||
AstNode* const exprsp = new AstText{fl, "([&]{ std::string ret = \"(and\";"};
|
||||
exprsp->addNext(new AstBegin{
|
||||
fl, "",
|
||||
new AstForeach{fl, nodep->arrayp()->unlinkFrBack(), new AstCStmt{fl, cstmtp}},
|
||||
false, true});
|
||||
exprsp->addNext(new AstText{fl, "return ret + \")\"; })()"});
|
||||
AstNodeExpr* const newp = new AstCExpr{fl, exprsp};
|
||||
newp->dtypeSetString();
|
||||
nodep->replaceWith(new AstSFormatF{fl, "%@", false, newp});
|
||||
} else {
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
nodep->replaceWith(new AstForeach{fl, nodep->arrayp()->unlinkFrBack(),
|
||||
nodep->stmtsp()->unlinkFrBackWithNext()});
|
||||
}
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
void visit(AstConstraintBefore* nodep) override {
|
||||
nodep->v3warn(CONSTRAINTIGN, "Constraint expression ignored (unsupported)");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
if (!$Self->have_solver) {
|
||||
skip("No constraint solver installed");
|
||||
} else {
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Antmicro Ltd.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define check_rand(cl, field, cond) \
|
||||
begin \
|
||||
longint prev_result; \
|
||||
int ok = 0; \
|
||||
for (int i = 0; i < 10; i++) begin \
|
||||
longint result; \
|
||||
if (!bit'(cl.randomize())) $stop; \
|
||||
result = longint'(field); \
|
||||
if (!(cond)) $stop; \
|
||||
if (i > 0 && result != prev_result) ok = 1; \
|
||||
prev_result = result; \
|
||||
end \
|
||||
if (ok != 1) $stop; \
|
||||
end
|
||||
|
||||
class C;
|
||||
rand int x;
|
||||
int q[$] = {0, 0, 0, 0, 0};
|
||||
constraint fore {
|
||||
x < 7;
|
||||
foreach(q[i])
|
||||
x > i;
|
||||
};
|
||||
endclass
|
||||
|
||||
class D;
|
||||
rand bit posit;
|
||||
rand int x;
|
||||
int q[$] = {0, 0, 0, 0, 0};
|
||||
constraint fore {
|
||||
if (posit == 1) {
|
||||
x < 7;
|
||||
foreach(q[i])
|
||||
x > i;
|
||||
} else {
|
||||
x > -3;
|
||||
foreach(q[i])
|
||||
x < i;
|
||||
}
|
||||
};
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
C c = new;
|
||||
D d = new;
|
||||
`check_rand(c, c.x, 4 < c.x && c.x < 7);
|
||||
`check_rand(d, d.posit, (d.posit ? 4 : -3) < d.x && d.x < (d.posit ? 7 : 0));
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -4,10 +4,6 @@
|
|||
| ^~~~
|
||||
... 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]) {
|
||||
| ^~~~~~~
|
||||
%Warning-CONSTRAINTIGN: t/t_randomize.v:40:7: Constraint expression ignored (unsupported)
|
||||
: ... note: In instance 't'
|
||||
40 | unique { array[0], array[1] };
|
||||
|
|
@ -16,8 +12,4 @@
|
|||
: ... note: In instance 't'
|
||||
43 | constraint order { solve length before header; }
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_randomize.v:14:13: Unsupported: random member variable with type 'int$[0:1]'
|
||||
: ... note: In instance 't'
|
||||
14 | rand int array[2];
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class Packet;
|
|||
rand bit if_4;
|
||||
rand bit iff_5_6;
|
||||
|
||||
rand int array[2]; // 2,4,6
|
||||
/*rand*/ int array[2]; // 2,4,6 // TODO: add rand when supported
|
||||
|
||||
constraint empty {}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue