Fix unique constraint in derived class (#7022)
This commit is contained in:
parent
a28bd5a085
commit
a660fa54a7
|
|
@ -1339,15 +1339,34 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
void visit(AstConstraintUnique* nodep) override {
|
||||
if (!m_classp) return;
|
||||
if (!m_classp) {
|
||||
nodep->v3warn(CONSTRAINTIGN,
|
||||
"Unsupported: Unique constraint in std::randomize() with {}");
|
||||
pushDeletep(nodep->unlinkFrBack());
|
||||
return;
|
||||
}
|
||||
UASSERT_OBJ(m_classp, nodep, "m_classp not set");
|
||||
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
||||
AstNodeFTask* const initTaskp = VN_AS(m_memberMap.findMember(m_classp, "new"), NodeFTask);
|
||||
if (!initTaskp) return;
|
||||
UASSERT_OBJ(initTaskp, nodep, "Class has no init Task");
|
||||
|
||||
AstVar* const genVarp = VN_AS(m_classp->user3p(), Var);
|
||||
if (!genVarp) return;
|
||||
AstVar* const genVarp = [](const AstClass* classp) {
|
||||
while (classp->extendsp()) classp = classp->extendsp()->classp();
|
||||
return VN_AS(classp->user3p(), Var);
|
||||
}(m_classp);
|
||||
|
||||
// UASSERT_OBJ(genVarp, nodep, "No generator variable");
|
||||
if (!genVarp) {
|
||||
// This shall be substituted with an assert when it will be supported
|
||||
nodep->v3warn(CONSTRAINTIGN, "Unsupported: Unique constraint in randomize() with {}");
|
||||
pushDeletep(nodep->unlinkFrBack());
|
||||
return;
|
||||
}
|
||||
|
||||
AstNodeModule* const modp = VN_AS(genVarp->user2p(), NodeModule);
|
||||
UASSERT_OBJ(modp, nodep, "genVarp has no NodeModule set");
|
||||
|
||||
for (AstNode* itemp = nodep->rangesp(); itemp; itemp = itemp->nextp()) {
|
||||
if (AstVarRef* const varRefp = VN_CAST(itemp, VarRef)) {
|
||||
|
|
@ -1380,8 +1399,9 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
continue;
|
||||
}
|
||||
|
||||
AstCMethodHard* const wCallp = new AstCMethodHard{
|
||||
fl, new AstVarRef{fl, genVarp, VAccess::READ}, VCMethod::RANDOMIZER_WRITE_VAR};
|
||||
AstCMethodHard* const wCallp
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, modp, genVarp, VAccess::READ},
|
||||
VCMethod::RANDOMIZER_WRITE_VAR};
|
||||
wCallp->addPinsp(new AstVarRef{fl, varp, VAccess::READ});
|
||||
wCallp->addPinsp(new AstConst{fl, AstConst::Unsized64{},
|
||||
static_cast<uint64_t>(varp->dtypep()->width())});
|
||||
|
|
@ -1406,7 +1426,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
uPins->addNext(new AstConst{fl, arraySize});
|
||||
|
||||
AstCMethodHard* const uCallp
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, genVarp, VAccess::READ},
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, modp, genVarp, VAccess::READ},
|
||||
VCMethod::RANDOMIZER_UNIQUE, uPins};
|
||||
uCallp->dtypep(nodep->findVoidDType());
|
||||
initTaskp->addStmtsp(new AstStmtExpr{fl, uCallp});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
if not test.have_solver:
|
||||
test.skip("No constraint solver installed")
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
typedef enum bit [4:0] {
|
||||
ZERO = 5'b00000,
|
||||
RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7,
|
||||
S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
|
||||
} EnumType;
|
||||
|
||||
class Base;
|
||||
rand EnumType b_scratch_reg;
|
||||
rand EnumType b_pmp_reg[2];
|
||||
rand EnumType b_sp;
|
||||
rand EnumType b_tp;
|
||||
|
||||
constraint b_example_constraint {
|
||||
unique {b_pmp_reg};
|
||||
{b_pmp_reg[0] > 0};
|
||||
{b_pmp_reg[0] < 3};
|
||||
{b_pmp_reg[1] > 0};
|
||||
{b_pmp_reg[1] < 3};
|
||||
}
|
||||
endclass
|
||||
|
||||
class Foo extends Base;
|
||||
rand EnumType scratch_reg;
|
||||
rand EnumType pmp_reg[2];
|
||||
rand EnumType sp;
|
||||
rand EnumType tp;
|
||||
|
||||
constraint example_constraint {
|
||||
unique {pmp_reg};
|
||||
{pmp_reg[0] > 0};
|
||||
{pmp_reg[0] < 3};
|
||||
{pmp_reg[1] > 0};
|
||||
{pmp_reg[1] < 3};
|
||||
}
|
||||
endclass
|
||||
|
||||
module t;
|
||||
Foo foo;
|
||||
initial begin
|
||||
foo = new;
|
||||
repeat(100) if (foo.randomize() != 1 || foo.pmp_reg[0] == foo.pmp_reg[1]) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
%Warning-CONSTRAINTIGN: t/t_constraint_unq_arr_derived_inline_unsup.v:32:7: Unsupported: Unique constraint in randomize() with {}
|
||||
: ... note: In instance 't'
|
||||
32 | unique{foo.pmp_reg};
|
||||
| ^~~~~~
|
||||
... 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.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
typedef enum bit [4:0] {
|
||||
ZERO = 5'b00000,
|
||||
RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7,
|
||||
S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
|
||||
} EnumType;
|
||||
|
||||
class Base;
|
||||
rand EnumType b_scratch_reg;
|
||||
rand EnumType b_pmp_reg[2];
|
||||
rand EnumType b_sp;
|
||||
rand EnumType b_tp;
|
||||
endclass
|
||||
|
||||
class Foo extends Base;
|
||||
rand EnumType scratch_reg;
|
||||
rand EnumType pmp_reg[2];
|
||||
rand EnumType sp;
|
||||
rand EnumType tp;
|
||||
endclass
|
||||
|
||||
module t;
|
||||
Foo foo;
|
||||
initial begin
|
||||
foo = new;
|
||||
repeat(100) if (foo.randomize() with {
|
||||
unique{foo.pmp_reg};
|
||||
foo.pmp_reg[0] inside {1,2};
|
||||
foo.pmp_reg[1] inside {1,2};}
|
||||
!= 1 || foo.pmp_reg[0] == foo.pmp_reg[1]) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
%Warning-CONSTRAINTIGN: t/t_std_randomize_unsup_unq_arr.v:10:39: Unsupported: Unique constraint in std::randomize() with {}
|
||||
: ... note: In instance 't'
|
||||
10 | if (!bit'(std::randomize(x) with {unique{x};}) || x[0] == x[1]) $stop;
|
||||
| ^~~~~~
|
||||
... 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.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
bit x[2];
|
||||
if (!bit'(std::randomize(x) with {unique{x};}) || x[0] == x[1]) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue