Add more rand_mode unsupported errors (#5329)

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2024-08-05 23:56:03 +02:00 committed by GitHub
parent 7d5e19365e
commit f4cb2c8cf2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 12 deletions

View File

@ -64,23 +64,29 @@ struct RandModeTarget final {
return RandModeTarget::get(methodHardp->fromp(), modp); return RandModeTarget::get(methodHardp->fromp(), modp);
} }
AstVar* receiverp = nullptr; AstVar* receiverp = nullptr;
AstClass* classp = VN_CAST(modp, Class);
if (AstVarRef* const varrefp = VN_CAST(fromp, VarRef)) { if (AstVarRef* const varrefp = VN_CAST(fromp, VarRef)) {
receiverp = varrefp->varp(); receiverp = varrefp->varp();
if (receiverp->isRand()) {
fromp = nullptr;
if (receiverp->lifetime().isStatic()) {
classp = VN_AS(varrefp->classOrPackagep(), Class);
}
}
} else if (AstMemberSel* const memberSelp = VN_CAST(fromp, MemberSel)) { } else if (AstMemberSel* const memberSelp = VN_CAST(fromp, MemberSel)) {
receiverp = memberSelp->varp(); receiverp = memberSelp->varp();
if (receiverp->isRand()) {
fromp = memberSelp->fromp();
classp = VN_AS(fromp->dtypep()->skipRefp(), ClassRefDType)->classp();
}
} }
UASSERT_OBJ(receiverp, fromp, "Unknown rand_mode() receiver"); UASSERT_OBJ(receiverp, fromp, "Unknown rand_mode() receiver");
if (receiverp->isRand()) { if (!receiverp->isRand()) {
if (AstMemberSel* const memberselp = VN_CAST(fromp, MemberSel)) {
return {receiverp, memberselp->fromp(),
VN_AS(memberselp->fromp()->dtypep()->skipRefp(), ClassRefDType)->classp()};
}
} else {
AstClassRefDType* const classRefDtp AstClassRefDType* const classRefDtp
= VN_CAST(receiverp->dtypep()->skipRefp(), ClassRefDType); = VN_CAST(receiverp->dtypep()->skipRefp(), ClassRefDType);
if (classRefDtp) return {receiverp, fromp, classRefDtp->classp()}; if (classRefDtp) classp = classRefDtp->classp();
} }
return {receiverp, nullptr, VN_AS(modp, Class)}; return {receiverp, fromp, classp};
} }
}; };
@ -192,6 +198,10 @@ class RandomizeMarkVisitor final : public VNVisitor {
nodep->v3warn(E_UNSUPPORTED, nodep->v3warn(E_UNSUPPORTED,
"Unsupported: 'rand_mode()' on unpacked array element"); "Unsupported: 'rand_mode()' on unpacked array element");
valid = false; valid = false;
} else if (VN_IS(fromp, StructSel)) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: 'rand_mode()' on unpacked struct element");
valid = false;
} else if (VN_IS(fromp, Sel)) { } else if (VN_IS(fromp, Sel)) {
nodep->v3error("Cannot call 'rand_mode()' on packed array element"); nodep->v3error("Cannot call 'rand_mode()' on packed array element");
valid = false; valid = false;
@ -223,6 +233,11 @@ class RandomizeMarkVisitor final : public VNVisitor {
} else if (nodep->pinsp() && !VN_IS(nodep->backp(), StmtExpr)) { } else if (nodep->pinsp() && !VN_IS(nodep->backp(), StmtExpr)) {
nodep->v3error("'rand_mode()' with arguments cannot be called as a function"); nodep->v3error("'rand_mode()' with arguments cannot be called as a function");
valid = false; valid = false;
} else if (randModeTarget.receiverp
&& randModeTarget.receiverp->lifetime().isStatic()
&& randModeTarget.receiverp->isRand()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'rand_mode()' on static variable");
valid = false;
} else if (randModeTarget.receiverp && randModeTarget.receiverp->isRand()) { } else if (randModeTarget.receiverp && randModeTarget.receiverp->isRand()) {
// Called on a rand member variable // Called on a rand member variable
VarRandMode randMode = {}; VarRandMode randMode = {};
@ -232,6 +247,11 @@ class RandomizeMarkVisitor final : public VNVisitor {
// Called on 'this' or a non-rand class instance // Called on 'this' or a non-rand class instance
randModeTarget.classp->foreachMember([&](AstClass*, AstVar* varp) { randModeTarget.classp->foreachMember([&](AstClass*, AstVar* varp) {
if (!varp->isRand()) return; if (!varp->isRand()) return;
if (varp->lifetime().isStatic()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: 'rand_mode()' on static variable: "
<< varp->prettyNameQ());
}
VarRandMode randMode = {}; VarRandMode randMode = {};
randMode.usesRandMode = true; randMode.usesRandMode = true;
varp->user1(randMode.asInt); varp->user1(randMode.asInt);

View File

@ -1,10 +1,26 @@
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:15:22: Unsupported: 'rand_mode()' on dynamic array element %Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:17:22: Unsupported: 'rand_mode()' on dynamic array element
: ... note: In instance 't' : ... note: In instance 't'
15 | p.m_dyn_arr[0].rand_mode(0); 17 | p.m_dyn_arr[0].rand_mode(0);
| ^~~~~~~~~ | ^~~~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:16:22: Unsupported: 'rand_mode()' on unpacked array element %Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:18:22: Unsupported: 'rand_mode()' on unpacked array element
: ... note: In instance 't' : ... note: In instance 't'
16 | p.m_unp_arr[0].rand_mode(0); 18 | p.m_unp_arr[0].rand_mode(0);
| ^~~~~~~~~ | ^~~~~~~~~
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:19:20: Unsupported: 'rand_mode()' on unpacked struct element
: ... note: In instance 't'
19 | p.m_struct.y.rand_mode(0);
| ^~~~~~~~~
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:20:18: Unsupported: 'rand_mode()' on static variable
: ... note: In instance 't'
20 | p.m_static.rand_mode(0);
| ^~~~~~~~~
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:21:57: Unsupported: 'rand_mode()' on static variable
: ... note: In instance 't'
21 | $display("p.m_static.rand_mode()=%0d", p.m_static.rand_mode());
| ^~~~~~~~~
%Error-UNSUPPORTED: t/t_randomize_rand_mode_unsup.v:22:9: Unsupported: 'rand_mode()' on static variable: 'm_static'
: ... note: In instance 't'
22 | p.rand_mode(0);
| ^~~~~~~~~
%Error: Exiting due to %Error: Exiting due to

View File

@ -7,6 +7,8 @@
class Packet; class Packet;
rand int m_dyn_arr[]; rand int m_dyn_arr[];
rand int m_unp_arr[10]; rand int m_unp_arr[10];
rand struct { int y; } m_struct;
static rand int m_static;
endclass endclass
module t; module t;
@ -14,5 +16,9 @@ module t;
Packet p = new; Packet p = new;
p.m_dyn_arr[0].rand_mode(0); p.m_dyn_arr[0].rand_mode(0);
p.m_unp_arr[0].rand_mode(0); p.m_unp_arr[0].rand_mode(0);
p.m_struct.y.rand_mode(0);
p.m_static.rand_mode(0);
$display("p.m_static.rand_mode()=%0d", p.m_static.rand_mode());
p.rand_mode(0);
end end
endmodule endmodule