mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
This commit is contained in:
parent
9bde98e912
commit
5470cf9fa9
@ -570,6 +570,7 @@ public:
|
|||||||
m_deque.resize(size, atDefault());
|
m_deque.resize(size, atDefault());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void resize(size_t size) { m_deque.resize(size, atDefault()); }
|
||||||
|
|
||||||
// function void q.push_front(value)
|
// function void q.push_front(value)
|
||||||
void push_front(const T_Value& value) {
|
void push_front(const T_Value& value) {
|
||||||
|
@ -2903,6 +2903,7 @@ void AstCMethodHard::setPurity() {
|
|||||||
{"r_xor", true},
|
{"r_xor", true},
|
||||||
{"renew", false},
|
{"renew", false},
|
||||||
{"renew_copy", false},
|
{"renew_copy", false},
|
||||||
|
{"resize", false},
|
||||||
{"resume", false},
|
{"resume", false},
|
||||||
{"reverse", false},
|
{"reverse", false},
|
||||||
{"rsort", false},
|
{"rsort", false},
|
||||||
|
@ -606,6 +606,12 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||||||
// VISITORS
|
// VISITORS
|
||||||
void visit(AstNodeVarRef* nodep) override {
|
void visit(AstNodeVarRef* nodep) override {
|
||||||
AstVar* const varp = nodep->varp();
|
AstVar* const varp = nodep->varp();
|
||||||
|
if (varp->user4p()) {
|
||||||
|
varp->user4p()->v3warn(
|
||||||
|
CONSTRAINTIGN,
|
||||||
|
"Size constraint combined with element constraint may not work correctly");
|
||||||
|
}
|
||||||
|
|
||||||
AstNodeModule* const classOrPackagep = nodep->classOrPackagep();
|
AstNodeModule* const classOrPackagep = nodep->classOrPackagep();
|
||||||
const RandomizeMode randMode = {.asInt = varp->user1()};
|
const RandomizeMode randMode = {.asInt = varp->user1()};
|
||||||
if (!randMode.usesMode && editFormat(nodep)) return;
|
if (!randMode.usesMode && editFormat(nodep)) return;
|
||||||
@ -1132,7 +1138,9 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
// AstClass::user2p() -> AstVar*. Rand mode state variable
|
// AstClass::user2p() -> AstVar*. Rand mode state variable
|
||||||
// AstVar::user3() -> bool. Handled in constraints
|
// AstVar::user3() -> bool. Handled in constraints
|
||||||
// AstClass::user3p() -> AstVar*. Constrained randomizer variable
|
// AstClass::user3p() -> AstVar*. Constrained randomizer variable
|
||||||
|
// AstConstraint::user3p() -> AstTask*. Pointer to resize procedure
|
||||||
// AstClass::user4p() -> AstVar*. Constraint mode state variable
|
// AstClass::user4p() -> AstVar*. Constraint mode state variable
|
||||||
|
// AstVar::user4p() -> AstVar*. Size variable for constrained queues
|
||||||
// VNUser1InUse m_inuser1; (Allocated for use in RandomizeMarkVisitor)
|
// VNUser1InUse m_inuser1; (Allocated for use in RandomizeMarkVisitor)
|
||||||
// VNUser2InUse m_inuser2; (Allocated for use in RandomizeMarkVisitor)
|
// VNUser2InUse m_inuser2; (Allocated for use in RandomizeMarkVisitor)
|
||||||
const VNUser3InUse m_inuser3;
|
const VNUser3InUse m_inuser3;
|
||||||
@ -1150,6 +1158,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
size_t m_enumValueTabCount = 0; // Number of tables with enum values created
|
size_t m_enumValueTabCount = 0; // Number of tables with enum values created
|
||||||
int m_randCaseNum = 0; // Randcase number within a module for var naming
|
int m_randCaseNum = 0; // Randcase number within a module for var naming
|
||||||
std::map<std::string, AstCDType*> m_randcDtypes; // RandC data type deduplication
|
std::map<std::string, AstCDType*> m_randcDtypes; // RandC data type deduplication
|
||||||
|
AstConstraint* m_constraintp = nullptr; // Current constraint
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void createRandomGenerator(AstClass* const classp) {
|
void createRandomGenerator(AstClass* const classp) {
|
||||||
@ -1180,6 +1189,17 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
m_memberMap.insert(classp, setupAllTaskp);
|
m_memberMap.insert(classp, setupAllTaskp);
|
||||||
return setupAllTaskp;
|
return setupAllTaskp;
|
||||||
}
|
}
|
||||||
|
AstTask* getCreateAggrResizeTask(AstClass* const classp) {
|
||||||
|
static const char* const name = "__Vresize_constrained_arrays";
|
||||||
|
AstTask* resizeTaskp = VN_AS(m_memberMap.findMember(classp, name), Task);
|
||||||
|
if (resizeTaskp) return resizeTaskp;
|
||||||
|
resizeTaskp = new AstTask{classp->fileline(), name, nullptr};
|
||||||
|
resizeTaskp->classMethod(true);
|
||||||
|
resizeTaskp->isVirtual(true);
|
||||||
|
classp->addMembersp(resizeTaskp);
|
||||||
|
m_memberMap.insert(classp, resizeTaskp);
|
||||||
|
return resizeTaskp;
|
||||||
|
}
|
||||||
AstVar* getCreateRandModeVar(AstClass* const classp) {
|
AstVar* getCreateRandModeVar(AstClass* const classp) {
|
||||||
if (classp->user2p()) return VN_AS(classp->user2p(), Var);
|
if (classp->user2p()) return VN_AS(classp->user2p(), Var);
|
||||||
if (AstClassExtends* const extendsp = classp->extendsp()) {
|
if (AstClassExtends* const extendsp = classp->extendsp()) {
|
||||||
@ -1281,8 +1301,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
FileLine* fl = modeVarp->fileline();
|
FileLine* fl = modeVarp->fileline();
|
||||||
AstCMethodHard* const dynarrayNewp
|
AstCMethodHard* const dynarrayNewp
|
||||||
= new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
|
= new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
|
||||||
"renew_copy", new AstConst{fl, modeCount}};
|
"resize", new AstConst{fl, modeCount}};
|
||||||
dynarrayNewp->addPinsp(new AstVarRef{fl, modeVarModp, modeVarp, VAccess::READ});
|
|
||||||
dynarrayNewp->dtypeSetVoid();
|
dynarrayNewp->dtypeSetVoid();
|
||||||
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
|
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
|
||||||
UASSERT_OBJ(newp, classp, "No new() in class");
|
UASSERT_OBJ(newp, classp, "No new() in class");
|
||||||
@ -1565,6 +1584,13 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
nodep->addMembersp(taskp);
|
nodep->addMembersp(taskp);
|
||||||
return taskp;
|
return taskp;
|
||||||
}
|
}
|
||||||
|
AstTask* newResizeConstrainedArrayTask(AstClass* const nodep, const std::string& name) {
|
||||||
|
AstTask* const taskp
|
||||||
|
= new AstTask{nodep->fileline(), name + "_resize_constrained_array", nullptr};
|
||||||
|
taskp->classMethod(true);
|
||||||
|
nodep->addMembersp(taskp);
|
||||||
|
return taskp;
|
||||||
|
}
|
||||||
AstNodeStmt* implementConstraintsClear(FileLine* const fileline, AstVar* const genp) {
|
AstNodeStmt* implementConstraintsClear(FileLine* const fileline, AstVar* const genp) {
|
||||||
AstCMethodHard* const clearp = new AstCMethodHard{
|
AstCMethodHard* const clearp = new AstCMethodHard{
|
||||||
fileline,
|
fileline,
|
||||||
@ -1898,6 +1924,15 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
|
|
||||||
setupAllTaskp->addStmtsp(setupTaskRefp->makeStmt());
|
setupAllTaskp->addStmtsp(setupTaskRefp->makeStmt());
|
||||||
|
|
||||||
|
if (AstTask* const resizeTaskp = VN_CAST(constrp->user3p(), Task)) {
|
||||||
|
AstTask* const resizeAllTaskp = getCreateAggrResizeTask(nodep);
|
||||||
|
AstTaskRef* const resizeTaskRefp
|
||||||
|
= new AstTaskRef{constrp->fileline(), resizeTaskp->name(), nullptr};
|
||||||
|
resizeTaskRefp->taskp(resizeTaskp);
|
||||||
|
resizeTaskRefp->classOrPackagep(classp);
|
||||||
|
resizeAllTaskp->addStmtsp(resizeTaskRefp->makeStmt());
|
||||||
|
}
|
||||||
|
|
||||||
ConstraintExprVisitor{m_memberMap, constrp->itemsp(), nullptr, genp, randModeVarp};
|
ConstraintExprVisitor{m_memberMap, constrp->itemsp(), nullptr, genp, randModeVarp};
|
||||||
if (constrp->itemsp()) {
|
if (constrp->itemsp()) {
|
||||||
taskp->addStmtsp(wrapIfConstraintMode(
|
taskp->addStmtsp(wrapIfConstraintMode(
|
||||||
@ -1933,6 +1968,13 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
AstVarRef* const fvarRefp = new AstVarRef{fl, fvarp, VAccess::WRITE};
|
AstVarRef* const fvarRefp = new AstVarRef{fl, fvarp, VAccess::WRITE};
|
||||||
randomizep->addStmtsp(new AstAssign{fl, fvarRefp, beginValp});
|
randomizep->addStmtsp(new AstAssign{fl, fvarRefp, beginValp});
|
||||||
|
|
||||||
|
if (AstTask* const resizeAllTaskp
|
||||||
|
= VN_AS(m_memberMap.findMember(nodep, "__Vresize_constrained_arrays"), Task)) {
|
||||||
|
AstTaskRef* const resizeTaskRefp = new AstTaskRef{fl, resizeAllTaskp->name(), nullptr};
|
||||||
|
resizeTaskRefp->taskp(resizeAllTaskp);
|
||||||
|
randomizep->addStmtsp(resizeTaskRefp->makeStmt());
|
||||||
|
}
|
||||||
|
|
||||||
AstFunc* const basicRandomizep
|
AstFunc* const basicRandomizep
|
||||||
= V3Randomize::newRandomizeFunc(m_memberMap, nodep, "__Vbasic_randomize");
|
= V3Randomize::newRandomizeFunc(m_memberMap, nodep, "__Vbasic_randomize");
|
||||||
addBasicRandomizeBody(basicRandomizep, nodep, randModeVarp);
|
addBasicRandomizeBody(basicRandomizep, nodep, randModeVarp);
|
||||||
@ -2161,6 +2203,57 @@ class RandomizeVisitor final : public VNVisitor {
|
|||||||
UINFO(9, "Added `%s` randomization procedure");
|
UINFO(9, "Added `%s` randomization procedure");
|
||||||
VL_DO_DANGLING(withp->deleteTree(), withp);
|
VL_DO_DANGLING(withp->deleteTree(), withp);
|
||||||
}
|
}
|
||||||
|
void visit(AstConstraint* nodep) override {
|
||||||
|
VL_RESTORER(m_constraintp);
|
||||||
|
m_constraintp = nodep;
|
||||||
|
iterateChildren(nodep);
|
||||||
|
}
|
||||||
|
void visit(AstCMethodHard* nodep) override {
|
||||||
|
iterateChildren(nodep);
|
||||||
|
FileLine* const fl = nodep->fileline();
|
||||||
|
if (m_constraintp && nodep->fromp()->user1() && nodep->name() == "size") {
|
||||||
|
AstClass* const classp = VN_AS(m_modp, Class);
|
||||||
|
AstVarRef* const queueVarRefp = VN_CAST(nodep->fromp(), VarRef);
|
||||||
|
if (!queueVarRefp) {
|
||||||
|
// Warning from ConstraintExprVisitor will be thrown
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AstVar* const queueVarp = queueVarRefp->varp();
|
||||||
|
AstVar* sizeVarp = VN_CAST(queueVarp->user4p(), Var);
|
||||||
|
if (!sizeVarp) {
|
||||||
|
sizeVarp = new AstVar{fl, VVarType::BLOCKTEMP, "__V" + queueVarp->name() + "_size",
|
||||||
|
nodep->findSigned32DType()};
|
||||||
|
classp->addMembersp(sizeVarp);
|
||||||
|
m_memberMap.insert(classp, sizeVarp);
|
||||||
|
sizeVarp->user2p(classp);
|
||||||
|
|
||||||
|
queueVarp->user4p(sizeVarp);
|
||||||
|
|
||||||
|
AstTask* resizerTaskp = VN_AS(m_constraintp->user3p(), Task);
|
||||||
|
if (!resizerTaskp) {
|
||||||
|
resizerTaskp = newResizeConstrainedArrayTask(classp, m_constraintp->name());
|
||||||
|
m_constraintp->user3p(resizerTaskp);
|
||||||
|
}
|
||||||
|
AstCMethodHard* const resizep
|
||||||
|
= new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), "resize",
|
||||||
|
new AstVarRef{fl, sizeVarp, VAccess::READ}};
|
||||||
|
resizep->dtypep(nodep->findVoidDType());
|
||||||
|
resizerTaskp->addStmtsp(new AstStmtExpr{fl, resizep});
|
||||||
|
|
||||||
|
// Since size variable is signed int, we need additional constraint
|
||||||
|
// to make sure it is always >= 0.
|
||||||
|
AstVarRef* const sizeVarRefp = new AstVarRef{fl, sizeVarp, VAccess::READ};
|
||||||
|
sizeVarRefp->user1(true);
|
||||||
|
AstGteS* const sizeGtep = new AstGteS{fl, sizeVarRefp, new AstConst{fl, 0}};
|
||||||
|
sizeGtep->user1(true);
|
||||||
|
m_constraintp->addItemsp(new AstConstraintExpr{fl, sizeGtep});
|
||||||
|
}
|
||||||
|
AstVarRef* const sizeVarRefp = new AstVarRef{fl, sizeVarp, VAccess::READ};
|
||||||
|
sizeVarRefp->user1(true);
|
||||||
|
nodep->replaceWith(sizeVarRefp);
|
||||||
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
|
}
|
||||||
|
}
|
||||||
void visit(AstNodeStmt* nodep) override {
|
void visit(AstNodeStmt* nodep) override {
|
||||||
VL_RESTORER(m_stmtp);
|
VL_RESTORER(m_stmtp);
|
||||||
m_stmtp = nodep;
|
m_stmtp = nodep;
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:13:32: Unsupported: randomizing this expression, treating as state
|
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:17:17: Unsupported: randomizing this expression, treating as state
|
||||||
13 | constraint dynsize { dynarr.size < 20; }
|
17 | dynarr[1].size < 10;
|
||||||
| ^~~~
|
| ^~~~
|
||||||
... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest
|
... 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.
|
... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message.
|
||||||
%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:10:13: Unsupported: random member variable with the type of the containing class
|
%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:21:9: Size constraint combined with element constraint may not work correctly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
21 | 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
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
10 | rand Cls cls;
|
11 | 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; };
|
||||||
|
| ^~~~
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
@ -6,12 +6,21 @@
|
|||||||
|
|
||||||
class Cls;
|
class Cls;
|
||||||
rand int assocarr[string];
|
rand int assocarr[string];
|
||||||
rand int dynarr[];
|
rand int dynarr[][];
|
||||||
|
rand int q[$];
|
||||||
rand Cls cls;
|
rand Cls cls;
|
||||||
rand int i;
|
rand int i;
|
||||||
int st;
|
int st;
|
||||||
constraint dynsize { dynarr.size < 20; }
|
constraint dynsize {
|
||||||
|
dynarr.size < 20;
|
||||||
|
dynarr.size > 0;
|
||||||
|
dynarr[1].size < 10;
|
||||||
|
}
|
||||||
constraint statedep { i < st + 2; }
|
constraint statedep { i < st + 2; }
|
||||||
|
constraint q_size_elem {
|
||||||
|
q.size < 5;
|
||||||
|
q[i] < 10;
|
||||||
|
}
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
module t (/*AUTOARG*/);
|
module t (/*AUTOARG*/);
|
||||||
@ -21,5 +30,6 @@ module t (/*AUTOARG*/);
|
|||||||
initial begin
|
initial begin
|
||||||
obj = new;
|
obj = new;
|
||||||
res = obj.randomize();
|
res = obj.randomize();
|
||||||
|
res = obj.randomize() with { dynarr.size > 2; };
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
21
test_regress/t/t_randomize_queue_size.py
Executable file
21
test_regress/t/t_randomize_queue_size.py
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# 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
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
if not test.have_solver:
|
||||||
|
test.skip("No constraint solver installed")
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
85
test_regress/t/t_randomize_queue_size.v
Executable file
85
test_regress/t/t_randomize_queue_size.v
Executable file
@ -0,0 +1,85 @@
|
|||||||
|
// 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; \
|
||||||
|
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;
|
||||||
|
rand int q[$];
|
||||||
|
rand int q2[$][$];
|
||||||
|
int x = 1;
|
||||||
|
constraint c {
|
||||||
|
q.size() == 15;
|
||||||
|
q2.size() == 10;
|
||||||
|
}
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class Bar;
|
||||||
|
rand int q[$];
|
||||||
|
rand int min_size;
|
||||||
|
rand int q2[$];
|
||||||
|
constraint c {
|
||||||
|
min_size > 2;
|
||||||
|
q.size() >= min_size;
|
||||||
|
q.size() < 10;
|
||||||
|
};
|
||||||
|
constraint c2 {
|
||||||
|
q2.size() < 7;
|
||||||
|
}
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class Baz;
|
||||||
|
rand Foo foo_arr[];
|
||||||
|
constraint c_foo {
|
||||||
|
foo_arr.size == 7;
|
||||||
|
}
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
Foo foo = new;
|
||||||
|
Bar bar = new;
|
||||||
|
Baz baz = new;
|
||||||
|
|
||||||
|
void'(foo.randomize());
|
||||||
|
if (foo.q.size() != 15) $stop;
|
||||||
|
if (foo.q2.size() != 10) $stop;
|
||||||
|
|
||||||
|
`check_rand(bar, bar.q.size(), bar.q.size() > 2 && bar.q.size() < 10);
|
||||||
|
`check_rand(bar, bar.q2.size(), bar.q2.size() < 7);
|
||||||
|
|
||||||
|
baz.foo_arr = new[4];
|
||||||
|
for (int i = 0; i < 4; i++) baz.foo_arr[i] = new;
|
||||||
|
baz.foo_arr[2].x = 2;
|
||||||
|
void'(baz.randomize());
|
||||||
|
|
||||||
|
if (baz.foo_arr.size() != 7) $stop;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if (baz.foo_arr[i] == null) $stop;
|
||||||
|
for (int i = 4; i < 7; i++)
|
||||||
|
if (baz.foo_arr[i] != null) $stop;
|
||||||
|
if (baz.foo_arr[2].x != 2) $stop;
|
||||||
|
`check_rand(baz, baz.foo_arr[1].q[5], 1'b1);
|
||||||
|
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
@ -22444,9 +22444,7 @@ class uvm_reg_item extends uvm_sequence_item;
|
|||||||
uvm_elem_kind_e element_kind;
|
uvm_elem_kind_e element_kind;
|
||||||
uvm_object element;
|
uvm_object element;
|
||||||
rand uvm_access_e kind;
|
rand uvm_access_e kind;
|
||||||
//TODO issue-5582 - Rand constraint with .size
|
rand uvm_reg_data_t value[];
|
||||||
//TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state
|
|
||||||
/*rand*/ uvm_reg_data_t value[];
|
|
||||||
constraint max_values { value.size() > 0 && value.size() < 1000; }
|
constraint max_values { value.size() > 0 && value.size() < 1000; }
|
||||||
rand uvm_reg_addr_t offset;
|
rand uvm_reg_addr_t offset;
|
||||||
uvm_status_e status;
|
uvm_status_e status;
|
||||||
@ -26866,9 +26864,7 @@ class uvm_reg_fifo extends uvm_reg;
|
|||||||
local uvm_reg_field value;
|
local uvm_reg_field value;
|
||||||
local int m_set_cnt;
|
local int m_set_cnt;
|
||||||
local int unsigned m_size;
|
local int unsigned m_size;
|
||||||
//TODO issue-5582 - Rand constraint with .size
|
rand uvm_reg_data_t fifo[$];
|
||||||
//TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state
|
|
||||||
/*rand*/ uvm_reg_data_t fifo[$];
|
|
||||||
constraint valid_fifo_size {
|
constraint valid_fifo_size {
|
||||||
fifo.size() <= m_size;
|
fifo.size() <= m_size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user