Fix unconstrained randomization of unpacked structs (#5252)
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
parent
abb46c9cb2
commit
2696a9a5bd
|
|
@ -478,17 +478,26 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
UINFO(9, "created " << varp << endl);
|
||||
return newp;
|
||||
}
|
||||
AstNodeStmt* newRandStmtsp(FileLine* fl, AstNodeVarRef* varrefp, AstVar* randcVarp,
|
||||
int offset = 0, AstMemberDType* memberp = nullptr) {
|
||||
AstNodeStmt* newRandStmtsp(FileLine* fl, AstNodeExpr* exprp, AstVar* randcVarp, int offset = 0,
|
||||
AstMemberDType* memberp = nullptr) {
|
||||
if (const auto* const structDtp
|
||||
= VN_CAST(memberp ? memberp->subDTypep()->skipRefp() : varrefp->dtypep()->skipRefp(),
|
||||
= VN_CAST(memberp ? memberp->subDTypep()->skipRefp() : exprp->dtypep()->skipRefp(),
|
||||
StructDType)) {
|
||||
AstNodeStmt* stmtsp = nullptr;
|
||||
offset += memberp ? memberp->lsb() : 0;
|
||||
if (structDtp->packed()) offset += memberp ? memberp->lsb() : 0;
|
||||
for (AstMemberDType* smemberp = structDtp->membersp(); smemberp;
|
||||
smemberp = VN_AS(smemberp->nextp(), MemberDType)) {
|
||||
AstNodeStmt* const randp = newRandStmtsp(
|
||||
fl, stmtsp ? varrefp->cloneTree(false) : varrefp, nullptr, offset, smemberp);
|
||||
AstNodeStmt* randp = nullptr;
|
||||
if (structDtp->packed()) {
|
||||
randp = newRandStmtsp(fl, stmtsp ? exprp->cloneTree(false) : exprp, nullptr,
|
||||
offset, smemberp);
|
||||
} else {
|
||||
AstStructSel* structSelp
|
||||
= new AstStructSel{fl, exprp->cloneTree(false), smemberp->name()};
|
||||
structSelp->dtypep(smemberp->childDTypep());
|
||||
if (!structSelp->dtypep()) structSelp->dtypep(smemberp->subDTypep());
|
||||
randp = newRandStmtsp(fl, structSelp, nullptr);
|
||||
}
|
||||
if (stmtsp) {
|
||||
stmtsp->addNext(randp);
|
||||
} else {
|
||||
|
|
@ -499,24 +508,24 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
} else {
|
||||
AstNodeExpr* valp;
|
||||
if (AstEnumDType* const enumDtp = VN_CAST(memberp ? memberp->subDTypep()->subDTypep()
|
||||
: varrefp->dtypep()->subDTypep(),
|
||||
: exprp->dtypep()->subDTypep(),
|
||||
EnumDType)) {
|
||||
AstVarRef* const tabRefp
|
||||
= new AstVarRef{fl, enumValueTabp(enumDtp), VAccess::READ};
|
||||
tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
AstNodeExpr* const randp
|
||||
= newRandValue(fl, randcVarp, varrefp->findBasicDType(VBasicDTypeKwd::UINT32));
|
||||
= newRandValue(fl, randcVarp, exprp->findBasicDType(VBasicDTypeKwd::UINT32));
|
||||
AstNodeExpr* const moddivp = new AstModDiv{
|
||||
fl, randp, new AstConst{fl, static_cast<uint32_t>(enumDtp->itemCount())}};
|
||||
moddivp->dtypep(enumDtp);
|
||||
valp = new AstArraySel{fl, tabRefp, moddivp};
|
||||
} else {
|
||||
valp = newRandValue(fl, randcVarp,
|
||||
(memberp ? memberp->dtypep() : varrefp->varp()->dtypep()));
|
||||
valp
|
||||
= newRandValue(fl, randcVarp, (memberp ? memberp->dtypep() : exprp->dtypep()));
|
||||
}
|
||||
return new AstAssign{fl,
|
||||
new AstSel{fl, varrefp, offset + (memberp ? memberp->lsb() : 0),
|
||||
memberp ? memberp->width() : varrefp->width()},
|
||||
new AstSel{fl, exprp, offset + (memberp ? memberp->lsb() : 0),
|
||||
memberp ? memberp->width() : exprp->width()},
|
||||
valp};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,13 @@ typedef struct packed {
|
|||
longint z;
|
||||
} StructOuter;
|
||||
|
||||
typedef struct {
|
||||
int i;
|
||||
StructOuter j;
|
||||
Enum k;
|
||||
longint z;
|
||||
} StructUnpacked;
|
||||
|
||||
class BaseCls;
|
||||
endclass
|
||||
|
||||
|
|
@ -79,7 +86,7 @@ class OtherCls;
|
|||
rand logic[47:0] x;
|
||||
rand logic[31:0] y;
|
||||
rand logic[23:0] z;
|
||||
rand StructOuter str;
|
||||
rand StructUnpacked str;
|
||||
|
||||
function new;
|
||||
v = 0;
|
||||
|
|
@ -87,7 +94,9 @@ class OtherCls;
|
|||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
str = '{x: 1'b0, y: ONE, z: 64'd0, s: '{a: 32'd0, b: 1'b0, c: ONE}};
|
||||
str.i = 0;
|
||||
str.j = '{x: 1'b0, y: ONE, z: 64'd0, s: '{a: 32'd0, b: 1'b0, c: ONE}};
|
||||
str.k = ONE;
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
@ -152,8 +161,9 @@ module t (/*AUTOARG*/);
|
|||
rand_result = der_int.randomize();
|
||||
rand_result = der_contain.randomize();
|
||||
if (!(derived.l inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (!(other.str.s.c inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (!(other.str.y inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (!(other.str.j.s.c inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (!(other.str.j.y inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (!(other.str.k inside {ONE, TWO, THREE, FOUR})) $stop;
|
||||
if (derived.i.e != 0) $stop;
|
||||
if (derived.k != 0) $stop;
|
||||
if (other.v != 0) $stop;
|
||||
|
|
@ -172,12 +182,14 @@ module t (/*AUTOARG*/);
|
|||
`check_rand(other, other.x);
|
||||
`check_rand(other, other.y);
|
||||
`check_rand(other, other.z);
|
||||
`check_rand(other, other.str.x);
|
||||
`check_rand(other, other.str.y);
|
||||
`check_rand(other, other.str.z);
|
||||
`check_rand(other, other.str.s.a);
|
||||
`check_rand(other, other.str.s.b);
|
||||
`check_rand(other, other.str.s.c);
|
||||
`check_rand(other, other.str.i);
|
||||
`check_rand(other, other.str.j.x);
|
||||
`check_rand(other, other.str.j.y);
|
||||
`check_rand(other, other.str.j.z);
|
||||
`check_rand(other, other.str.j.s.a);
|
||||
`check_rand(other, other.str.j.s.b);
|
||||
`check_rand(other, other.str.j.s.c);
|
||||
`check_rand(other, other.str.k);
|
||||
`check_rand(der_int, der_int.a);
|
||||
`check_rand(der_contain, der_contain.cls1.a);
|
||||
`check_rand(der_contain, der_contain.a);
|
||||
|
|
|
|||
Loading…
Reference in New Issue