Fix randomization when used with inheritance (#5268)

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2024-07-17 08:21:45 +02:00 committed by GitHub
parent e11bc6beeb
commit 2a30a87580
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 388 additions and 592 deletions

View File

@ -160,6 +160,10 @@ AstCExpr::AstCExpr(FileLine* fl, const string& textStmt, int setwidth, bool clea
AstVarRef::AstVarRef(FileLine* fl, AstVar* varp, const VAccess& access)
: ASTGEN_SUPER_VarRef(fl, varp, access) {}
AstVarRef::AstVarRef(FileLine* fl, AstNodeModule* pkgp, AstVar* varp, const VAccess& access)
: AstVarRef{fl, varp, access} {
classOrPackagep(pkgp);
}
// This form only allowed post-link (see above)
AstVarRef::AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access)
: ASTGEN_SUPER_VarRef(fl, varscp->varp(), access) {

View File

@ -5659,6 +5659,8 @@ public:
// This form only allowed post-link because output/wire compression may
// lead to deletion of AstVar's
inline AstVarRef(FileLine* fl, AstVar* varp, const VAccess& access);
inline AstVarRef(FileLine* fl, AstNodeModule* classOrPackagep, AstVar* varp,
const VAccess& access);
// This form only allowed post-link (see above)
inline AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access);
ASTGEN_MEMBERS_AstVarRef;

View File

@ -2334,6 +2334,21 @@ public:
// Return the lowest class extended from, or this class
AstClass* baseMostClassp();
static bool isCacheableChild(const AstNode* nodep);
// Iterates top level members of the class, taking into account inheritance (starting from the
// root superclass). Note: after V3Scope, several children are moved under an AstScope and will
// not be found by this.
template <typename Callable>
void foreachMember(const Callable& visit) {
using T_Node = typename FunctionArgNoPointerNoCV<Callable, 1>::type;
if (AstClassExtends* const extendsp = this->extendsp()) {
extendsp->classp()->foreachMember(visit);
}
for (AstNode* stmtp = stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (T_Node* memberp = AstNode::privateCast<T_Node, decltype(stmtp)>(stmtp)) {
visit(this, memberp);
}
}
}
};
class AstClassPackage final : public AstNodeModule {
// The static information portion of a class (treated similarly to a package)

View File

@ -50,7 +50,9 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
// AstClass::user1() -> bool. Set true to indicate needs randomize processing
// AstNodeExpr::user1() -> bool. Set true to indicate constraint expression depending on a
// randomized variable
// AstVar::user2p() -> AstNodeModule*. Pointer to containing module
const VNUser1InUse m_inuser1;
const VNUser2InUse m_inuser2;
using DerivedSet = std::unordered_set<AstClass*>;
using BaseToDerivedMap = std::unordered_map<const AstClass*, DerivedSet>;
@ -59,7 +61,6 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
AstClass* m_classp = nullptr; // Current class
AstNode* m_constraintExprp = nullptr; // Current constraint expression
AstNodeModule* m_modp; // Current module
std::map<AstVar*, AstNodeModule*> m_moduleMap; // Variable -> module under which it is
std::set<AstNodeVarRef*> m_staticRefs; // References to static variables under `with` clauses
// METHODS
@ -102,14 +103,15 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
void setPackageRefs() {
for (AstNodeVarRef* staticRefp : m_staticRefs) {
UINFO(9, "Updated classOrPackage ref for " << staticRefp->name() << endl);
staticRefp->classOrPackagep(m_moduleMap[staticRefp->varp()]);
staticRefp->classOrPackagep(VN_AS(staticRefp->varp()->user2p(), NodeModule));
}
}
// VISITORS
void visit(AstClass* nodep) override {
VL_RESTORER(m_classp);
m_classp = nodep;
VL_RESTORER(m_modp);
m_modp = m_classp = nodep;
iterateChildrenConst(nodep);
if (nodep->extendsp()) {
// Save pointer to derived class
@ -118,7 +120,6 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
}
}
void visit(AstMethodCall* nodep) override {
iterateChildrenConst(nodep);
if (nodep->name() != "randomize") return;
if (const AstClassRefDType* const classRefp
= VN_CAST(nodep->fromp()->dtypep()->skipRefp(), ClassRefDType)) {
@ -126,6 +127,7 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
classp->user1(true);
markMembers(classp);
}
iterateChildrenConst(nodep);
}
void visit(AstNodeFTaskRef* nodep) override {
iterateChildrenConst(nodep);
@ -162,7 +164,7 @@ class RandomizeMarkVisitor final : public VNVisitorConst {
iterateChildrenConst(nodep);
}
void visit(AstVar* nodep) override {
m_moduleMap.emplace(nodep, m_modp);
nodep->user2p(m_modp);
iterateChildrenConst(nodep);
}
@ -183,14 +185,15 @@ public:
class ConstraintExprVisitor final : public VNVisitor {
// NODE STATE
// AstVar::user4() -> bool. Handled in constraints
// AstVar::user3() -> bool. Handled in constraints
// AstNodeExpr::user1() -> bool. Depending on a randomized variable
// VNUser4InUse m_inuser4; (Allocated for use in RandomizeVisitor)
// VNuser3InUse m_inuser3; (Allocated for use in RandomizeVisitor)
AstNodeFTask* const m_taskp; // Method to add write_var calls to
AstNodeFTask* const m_inlineInitTaskp; // Method to add write_var calls to
// (may be null, then new() is used)
AstVar* const m_genp; // VlRandomizer variable of the class
bool m_markDeclaredConstrs; // Mark constraints as aready setup with `write_var`.
bool m_wantSingle = false; // Whether to merge constraint expressions with LOGAND
VMemberMap& m_memberMap; // Member names cached for fast lookup
bool editFormat(AstNodeExpr* nodep) {
if (nodep->user1()) return false;
@ -288,13 +291,16 @@ class ConstraintExprVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(nodep), nodep);
if (!varp->user4()) {
varp->user4(m_markDeclaredConstrs);
if (!varp->user3()) {
AstCMethodHard* const methodp = new AstCMethodHard{
varp->fileline(), new AstVarRef{varp->fileline(), m_genp, VAccess::READWRITE},
varp->fileline(),
new AstVarRef{varp->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp,
VAccess::READWRITE},
"write_var"};
methodp->dtypeSetVoid();
AstVarRef* varRefp = new AstVarRef{varp->fileline(), varp, VAccess::WRITE};
AstClass* const classp = VN_AS(varp->user2p(), Class);
AstVarRef* const varRefp
= new AstVarRef{varp->fileline(), classp, varp, VAccess::WRITE};
methodp->addPinsp(varRefp);
methodp->addPinsp(new AstConst{varp->dtypep()->fileline(), AstConst::Unsized64{},
(size_t)varp->width()});
@ -302,7 +308,13 @@ class ConstraintExprVisitor final : public VNVisitor {
= new AstCExpr{varp->fileline(), "\"" + smtName + "\"", varp->width()};
varnamep->dtypep(varp->dtypep());
methodp->addPinsp(varnamep);
m_taskp->addStmtsp(methodp->makeStmt());
AstNodeFTask* initTaskp = m_inlineInitTaskp;
if (!initTaskp) {
varp->user3(true); // Mark as set up in new()
initTaskp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
UASSERT_OBJ(initTaskp, classp, "No new() in class");
}
initTaskp->addStmtsp(methodp->makeStmt());
}
}
void visit(AstNodeBiop* nodep) override {
@ -381,7 +393,9 @@ class ConstraintExprVisitor final : public VNVisitor {
}
// Only hard constraints are currently supported
AstCMethodHard* const callp = new AstCMethodHard{
nodep->fileline(), new AstVarRef{nodep->fileline(), m_genp, VAccess::READWRITE},
nodep->fileline(),
new AstVarRef{nodep->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp,
VAccess::READWRITE},
"hard", nodep->exprp()->unlinkFrBack()};
callp->dtypeSetVoid();
nodep->replaceWith(callp->makeStmt());
@ -415,11 +429,11 @@ class ConstraintExprVisitor final : public VNVisitor {
public:
// CONSTRUCTORS
explicit ConstraintExprVisitor(AstNode* nodep, AstNodeFTask* taskp, AstVar* genp,
bool markDeclaredConstrs)
: m_taskp(taskp)
, m_genp(genp)
, m_markDeclaredConstrs(markDeclaredConstrs) {
explicit ConstraintExprVisitor(VMemberMap& memberMap, AstNode* nodep,
AstNodeFTask* inlineInitTaskp, AstVar* genp)
: m_inlineInitTaskp{inlineInitTaskp}
, m_genp{genp}
, m_memberMap{memberMap} {
iterateAndNextNull(nodep);
}
};
@ -518,15 +532,15 @@ class RandomizeVisitor final : public VNVisitor {
// NODE STATE
// Cleared on Netlist
// AstClass::user1() -> bool. Set true to indicate needs randomize processing
// AstVar::user2p() -> AstClass*. Pointer to containing class
// AstEnumDType::user2() -> AstVar*. Pointer to table with enum values
// AstConstraint::user2p() -> AstTask*. Pointer to constraint setup procedure
// AstClass::user3p() -> AstFunc*. Pointer to randomize() method of a class
// AstVar::user4() -> bool. Handled in constraints
// AstClass::user4() -> AstVar*. Constrained randomizer variable
// AstClass::user2p() -> AstTask*. Pointer to full constraint setup procedure
// AstVar::user3() -> bool. Handled in constraints
// AstClass::user3p() -> AstVar*. Constrained randomizer variable
// VNUser1InUse m_inuser1; (Allocated for use in RandomizeMarkVisitor)
const VNUser2InUse m_inuser2;
// VNUser2InUse m_inuser2; (Allocated for use in RandomizeMarkVisitor)
const VNUser3InUse m_inuser3;
const VNUser4InUse m_inuser4;
// STATE
V3UniqueNames m_inlineUniqueNames; // For generating unique function names
@ -536,7 +550,6 @@ class RandomizeVisitor final : public VNVisitor {
size_t m_enumValueTabCount = 0; // Number of tables with enum values created
int m_randCaseNum = 0; // Randcase number within a module for var naming
std::map<std::string, AstCDType*> m_randcDtypes; // RandC data type deduplication
bool m_inline = false; // Constraints are inline
// METHODS
AstVar* enumValueTabp(AstEnumDType* const nodep) {
@ -688,7 +701,9 @@ class RandomizeVisitor final : public VNVisitor {
}
AstNodeStmt* implementConstraintsClear(FileLine* const fileline, AstVar* const genp) {
AstCMethodHard* const clearp = new AstCMethodHard{
fileline, new AstVarRef{fileline, genp, VAccess::READWRITE}, "clear"};
fileline,
new AstVarRef{fileline, VN_AS(genp->user2p(), NodeModule), genp, VAccess::READWRITE},
"clear"};
clearp->dtypeSetVoid();
return clearp->makeStmt();
}
@ -706,6 +721,29 @@ class RandomizeVisitor final : public VNVisitor {
m_ftaskp = nodep;
iterateChildren(nodep);
}
AstVar* getCreateRandomGenerator(AstClass* classp) {
if (classp->user3p()) return VN_AS(classp->user3p(), Var);
AstVar* genp = nullptr;
if (classp->extendsp()) genp = getCreateRandomGenerator(classp->extendsp()->classp());
if (!genp) {
genp = new AstVar{classp->fileline(), VVarType::MEMBER, "constraint",
classp->findBasicDType(VBasicDTypeKwd::RANDOM_GENERATOR)};
genp->user2p(classp);
classp->addMembersp(genp);
classp->user3p(genp);
}
return genp;
}
AstTask* getCreateConstraintSetupFunc(AstClass* classp) {
if (classp->user2p()) return VN_AS(classp->user2p(), Task);
AstTask* const setupAllTaskp
= new AstTask{classp->fileline(), "__Vsetup_constraints", nullptr};
setupAllTaskp->classMethod(true);
setupAllTaskp->isVirtual(true);
classp->addMembersp(setupAllTaskp);
classp->user2p(setupAllTaskp);
return setupAllTaskp;
}
void visit(AstClass* nodep) override {
VL_RESTORER(m_modp);
VL_RESTORER(m_randCaseNum);
@ -715,107 +753,96 @@ class RandomizeVisitor final : public VNVisitor {
iterateChildren(nodep);
if (!nodep->user1()) return; // Doesn't need randomize, or already processed
UINFO(9, "Define randomize() for " << nodep << endl);
AstFunc* const funcp = V3Randomize::newRandomizeFunc(m_memberMap, nodep);
nodep->user3p(funcp);
AstVar* const fvarp = VN_AS(funcp->fvarp(), Var);
addPrePostCall(nodep, funcp, "pre_randomize");
AstFunc* const randomizep = V3Randomize::newRandomizeFunc(m_memberMap, nodep);
AstVar* const fvarp = VN_AS(randomizep->fvarp(), Var);
addPrePostCall(nodep, randomizep, "pre_randomize");
FileLine* fl = nodep->fileline();
AstNodeExpr* beginValp = nullptr;
if (nodep->extendsp()) {
// Call randomize() from the base class
AstFunc* const baseRandomizep = VN_AS(nodep->extendsp()->classp()->user3p(), Func);
if (baseRandomizep) {
AstFuncRef* const baseRandCallp = new AstFuncRef{fl, "randomize", nullptr};
baseRandCallp->taskp(baseRandomizep);
baseRandCallp->dtypeFrom(baseRandomizep->dtypep());
baseRandCallp->classOrPackagep(nodep->extendsp()->classp());
baseRandCallp->superReference(true);
beginValp = baseRandCallp;
AstVar* genp = nullptr;
nodep->foreachMember([&](AstClass* classp, AstConstraint* constrp) {
AstTask* taskp = VN_AS(constrp->user2p(), Task);
if (!taskp) {
taskp = newSetupConstraintTask(classp, constrp->name());
constrp->user2p(taskp);
}
}
if (m_modp->user4p()) {
AstVarRef* const genRefp = new AstVarRef{
nodep->fileline(), VN_AS(m_modp->user4p(), Var), VAccess::READWRITE};
genRefp->AstNode::addNext(new AstText{fl, ".next(__Vm_rng)"});
AstNodeExpr* const solverCallp = new AstCExpr{fl, genRefp};
AstTaskRef* const setupTaskRefp
= new AstTaskRef{constrp->fileline(), taskp->name(), nullptr};
setupTaskRefp->taskp(taskp);
setupTaskRefp->classOrPackagep(classp);
genp = getCreateRandomGenerator(nodep);
AstTask* setupAllTaskp = getCreateConstraintSetupFunc(nodep);
setupAllTaskp->addStmtsp(setupTaskRefp->makeStmt());
ConstraintExprVisitor{m_memberMap, constrp->itemsp(), nullptr, genp};
if (constrp->itemsp()) taskp->addStmtsp(constrp->itemsp()->unlinkFrBackWithNext());
});
if (genp) {
randomizep->addStmtsp(implementConstraintsClear(fl, genp));
AstTask* setupAllTaskp = getCreateConstraintSetupFunc(nodep);
AstTaskRef* const setupTaskRefp = new AstTaskRef{fl, setupAllTaskp->name(), nullptr};
setupTaskRefp->taskp(setupAllTaskp);
randomizep->addStmtsp(implementConstraintsClear(fl, genp));
randomizep->addStmtsp(setupTaskRefp->makeStmt());
AstVarRef* genRefp
= new AstVarRef{fl, VN_AS(genp->user2p(), NodeModule), genp, VAccess::READWRITE};
AstNode* const argsp = genRefp;
argsp->addNext(new AstText{fl, ".next(__Vm_rng)"});
AstNodeExpr* const solverCallp = new AstCExpr{fl, argsp};
solverCallp->dtypeSetBit();
beginValp = beginValp ? new AstLogAnd{fl, beginValp, solverCallp} : solverCallp;
beginValp = solverCallp;
} else {
beginValp = new AstConst{fl, AstConst::WidthedValue{}, 32, 1};
}
if (!beginValp) beginValp = new AstConst{fl, AstConst::WidthedValue{}, 32, 1};
AstVarRef* const fvarRefp = new AstVarRef{fl, fvarp, VAccess::WRITE};
funcp->addStmtsp(new AstAssign{fl, fvarRefp, beginValp});
randomizep->addStmtsp(new AstAssign{fl, fvarRefp, beginValp});
for (AstNode* memberp = nodep->stmtsp(); memberp; memberp = memberp->nextp()) {
AstVar* const memberVarp = VN_CAST(memberp, Var);
if (!memberVarp || !memberVarp->isRand() || memberVarp->user4()) continue;
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(nodep, "new"), NodeFTask);
UASSERT_OBJ(newp, nodep, "No new() in class");
nodep->foreachMember([&](AstClass* classp, AstVar* memberVarp) {
if (!memberVarp->isRand() || memberVarp->user3()) return;
const AstNodeDType* const dtypep = memberVarp->dtypep()->skipRefp();
if (VN_IS(dtypep, BasicDType) || VN_IS(dtypep, StructDType)) {
AstVar* const randcVarp = newRandcVarsp(memberVarp);
AstVarRef* const refp = new AstVarRef{fl, memberVarp, VAccess::WRITE};
AstVarRef* const refp = new AstVarRef{fl, classp, memberVarp, VAccess::WRITE};
AstNodeStmt* const stmtp = newRandStmtsp(fl, refp, randcVarp);
funcp->addStmtsp(stmtp);
randomizep->addStmtsp(stmtp);
} else if (const AstClassRefDType* const classRefp = VN_CAST(dtypep, ClassRefDType)) {
if (classRefp->classp() == nodep) {
memberVarp->v3warn(
E_UNSUPPORTED,
"Unsupported: random member variable with type of a current class");
continue;
memberVarp->v3warn(E_UNSUPPORTED,
"Unsupported: random member variable with the "
"type of the containing class");
return;
}
AstFunc* const memberFuncp
= V3Randomize::newRandomizeFunc(m_memberMap, classRefp->classp());
AstMethodCall* const callp = new AstMethodCall{
fl, new AstVarRef{fl, memberVarp, VAccess::WRITE}, "randomize", nullptr};
AstMethodCall* const callp
= new AstMethodCall{fl, new AstVarRef{fl, classp, memberVarp, VAccess::WRITE},
"randomize", nullptr};
callp->taskp(memberFuncp);
callp->dtypeFrom(memberFuncp);
AstVarRef* fvarRefReadp = fvarRefp->cloneTree(false);
fvarRefReadp->access(VAccess::READ);
AstIf* const assignIfNotNullp
= new AstIf{fl,
new AstNeq{fl, new AstVarRef{fl, memberVarp, VAccess::READ},
new AstConst{fl, AstConst::Null{}}},
new AstAssign{fl, fvarRefp->cloneTree(false),
new AstAnd{fl, fvarRefReadp, callp}}};
funcp->addStmtsp(assignIfNotNullp);
AstIf* const assignIfNotNullp = new AstIf{
fl,
new AstNeq{fl, new AstVarRef{fl, classp, memberVarp, VAccess::READ},
new AstConst{fl, AstConst::Null{}}},
new AstAssign{fl, fvarRefp->cloneTree(false),
new AstAnd{fl, fvarRefReadp, callp}}};
randomizep->addStmtsp(assignIfNotNullp);
} else {
memberVarp->v3warn(E_UNSUPPORTED, "Unsupported: random member variable with type "
<< memberVarp->dtypep()->prettyDTypeNameQ());
}
}
addPrePostCall(nodep, funcp, "post_randomize");
});
addPrePostCall(nodep, randomizep, "post_randomize");
nodep->user1(false);
}
void visit(AstConstraint* nodep) override {
if (nodep->user2p()) return; // Already visited
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(m_modp, "new"), NodeFTask);
UASSERT_OBJ(newp, m_modp, "No new() in class");
AstFunc* const randomizep
= V3Randomize::newRandomizeFunc(m_memberMap, VN_AS(m_modp, Class));
AstTask* const taskp = newSetupConstraintTask(VN_AS(m_modp, Class), nodep->name());
nodep->user2p(taskp);
AstTaskRef* const setupTaskRefp
= new AstTaskRef{nodep->fileline(), taskp->name(), nullptr};
setupTaskRefp->taskp(taskp);
AstVar* genp = VN_AS(m_modp->user4p(), Var);
if (!genp) {
genp = VN_AS(m_memberMap.findMember(m_modp, "constraint"), Var);
if (!genp) {
genp = new AstVar{nodep->fileline(), VVarType::MEMBER, "constraint",
m_modp->findBasicDType(VBasicDTypeKwd::RANDOM_GENERATOR)};
}
VN_AS(m_modp, Class)->addMembersp(genp);
m_modp->user4p(genp);
}
if (!randomizep->stmtsp()) {
randomizep->addStmtsp(implementConstraintsClear(randomizep->fileline(), genp));
}
randomizep->addStmtsp(setupTaskRefp->makeStmt());
{ ConstraintExprVisitor{nodep->itemsp(), (m_inline ? taskp : newp), genp, !m_inline}; }
if (nodep->itemsp()) taskp->addStmtsp(nodep->itemsp()->unlinkFrBackWithNext());
}
void visit(AstRandCase* nodep) override {
// RANDCASE
// CASEITEM expr1 : stmt1
@ -882,8 +909,6 @@ class RandomizeVisitor final : public VNVisitor {
return;
}
VL_RESTORER(m_inline);
m_inline = true;
iterateChildren(nodep);
UASSERT_OBJ(nodep->fromp()->dtypep(), nodep->fromp(), "Object dtype is not linked");
@ -902,7 +927,7 @@ class RandomizeVisitor final : public VNVisitor {
iterate(classp);
}
AstVar* const classGenp = VN_CAST(classp->user4p(), Var);
AstVar* const classGenp = getCreateRandomGenerator(classp);
AstVar* const localGenp
= new AstVar{nodep->fileline(), VVarType::BLOCKTEMP, "randomizer",
classp->findBasicDType(VBasicDTypeKwd::RANDOM_GENERATOR)};
@ -936,22 +961,20 @@ class RandomizeVisitor final : public VNVisitor {
// Copy (derive) class constraints if present
if (classGenp) {
classp->foreach([&](AstConstraint* constrp) {
AstTask* constrSetupFuncp = VN_AS(constrp->user2p(), Task);
UASSERT_OBJ(constrSetupFuncp, constrp, "Constraint not linked to setup procudure");
auto callp = new AstTaskRef{nodep->fileline(), constrSetupFuncp->name(), nullptr};
callp->taskp(constrSetupFuncp);
randomizeFuncp->addStmtsp(callp->makeStmt());
});
AstTask* const constrSetupFuncp = getCreateConstraintSetupFunc(classp);
AstTaskRef* const callp
= new AstTaskRef{nodep->fileline(), constrSetupFuncp->name(), nullptr};
callp->taskp(constrSetupFuncp);
randomizeFuncp->addStmtsp(callp->makeStmt());
randomizeFuncp->addStmtsp(new AstAssign{
nodep->fileline(), new AstVarRef{nodep->fileline(), localGenp, VAccess::WRITE},
new AstVarRef{nodep->fileline(), classGenp, VAccess::READ}});
new AstVarRef{nodep->fileline(), VN_AS(classGenp->user2p(), NodeModule), classGenp,
VAccess::READ}});
}
// Generate constraint setup code and a hardcoded call to the solver
randomizeFuncp->addStmtsp(captured.getTree());
{ ConstraintExprVisitor{captured.getTree(), randomizeFuncp, localGenp, !m_inline}; }
ConstraintExprVisitor{m_memberMap, captured.getTree(), randomizeFuncp, localGenp};
// Call the solver and set return value
AstVarRef* const randNextp

View File

@ -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;

View File

@ -0,0 +1,62 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Antmicro.
// 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
typedef class C;
class D extends C;
constraint x_lt_y { x < y; }
endclass
class A;
endclass
class B extends A;
rand int x;
constraint x_gt_0 { x > 0; }
endclass
class C extends B;
rand int y;
endclass
class E extends C;
constraint x_lt_20 { x < 20; }
constraint x_gt_y { x > y; }
endclass
module t;
initial begin
B b = new;
C c = new;
D d = new;
E e = new;
A a = b;
`check_rand(a, b.x, b.x > 0);
`check_rand(c, c.x, c.x > 0);
`check_rand(c, c.y, c.x > 0);
`check_rand(d, d.x, d.x > 0 && d.x < d.y);
`check_rand(d, d.y, d.x > 0 && d.x < d.y);
`check_rand(e, e.x, e.x > 0 && e.x < 20 && e.x > e.y);
`check_rand(e, e.y, e.x > 0 && e.x < 20 && e.x > e.y);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -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;

View File

@ -0,0 +1,62 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
`define check_rand(cl, field, constr, cond) \
begin \
longint prev_result; \
int ok = 0; \
for (int i = 0; i < 10; i++) begin \
longint result; \
if (!bit'(cl.randomize() with { constr; })) $stop; \
result = longint'(field); \
if (!(cond)) $stop; \
if (i > 0 && result != prev_result) ok = 1; \
prev_result = result; \
end \
if (ok != 1) $stop; \
end
typedef class C;
class D extends C;
rand int z;
constraint x_lt_y { x < y; }
endclass
class A;
rand int x;
endclass
class B extends A;
constraint x_gt_0 { x > 0; }
endclass
class C extends B;
rand int y;
endclass
class E extends C;
constraint x_gt_y { x > y; }
endclass
module t;
initial begin
B b = new;
C c = new;
D d = new;
E e = new;
A a = b;
`check_rand(a, a.x, x < 10, a.x > 0 && a.x < 10);
`check_rand(c, c.x, x < 100, c.x > 0 && c.x < 100);
`check_rand(c, c.y, x == 5, c.x == 5);
`check_rand(d, d.x, z > x && z < y, d.x > 0 && d.x < d.y);
`check_rand(d, d.y, z > x && z < y, d.x > 0 && d.x < d.y);
`check_rand(e, e.x, x inside {[10:20]}, e.x inside {[10:20]} && e.x > e.y);
`check_rand(e, e.y, x inside {[10:20]}, e.x inside {[10:20]} && e.x > e.y);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -48,272 +48,7 @@
{"type":"VARREF","name":"strings_equal","addr":"(JB)","loc":"d,62:7,62:13","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
],"scopeNamep": []},
{"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(MB)","loc":"d,8:13,8:19",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(NB)","loc":"d,8:13,8:19","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(OB)","loc":"d,8:13,8:19","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"header","addr":"(RB)","loc":"d,8:13,8:19","dtypep":"(Q)","access":"WR","varp":"(P)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h20","addr":"(SB)","loc":"d,8:9,8:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(UB)","loc":"d,8:13,8:19","dtypep":"(Q)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(VB)","loc":"d,8:13,8:19","shortText":"\"header\""}
]}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(WB)","loc":"d,9:13,9:19",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(XB)","loc":"d,9:13,9:19","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(YB)","loc":"d,9:13,9:19","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"length","addr":"(ZB)","loc":"d,9:13,9:19","dtypep":"(Q)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h20","addr":"(AC)","loc":"d,8:9,8:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(BC)","loc":"d,9:13,9:19","dtypep":"(Q)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(CC)","loc":"d,9:13,9:19","shortText":"\"length\""}
]}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(DC)","loc":"d,11:13,11:17",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(EC)","loc":"d,11:13,11:17","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(FC)","loc":"d,11:13,11:17","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"if_4","addr":"(GC)","loc":"d,11:13,11:17","dtypep":"(U)","access":"WR","varp":"(T)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h1","addr":"(HC)","loc":"d,11:9,11:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(IC)","loc":"d,11:13,11:17","dtypep":"(U)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(JC)","loc":"d,11:13,11:17","shortText":"\"if_4\""}
]}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(KC)","loc":"d,12:13,12:20",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(LC)","loc":"d,12:13,12:20","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(MC)","loc":"d,12:13,12:20","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"iff_5_6","addr":"(NC)","loc":"d,12:13,12:20","dtypep":"(U)","access":"WR","varp":"(V)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h1","addr":"(OC)","loc":"d,11:9,11:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(PC)","loc":"d,12:13,12:20","dtypep":"(U)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(QC)","loc":"d,12:13,12:20","shortText":"\"iff_5_6\""}
]}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(RC)","loc":"d,10:13,10:22",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(SC)","loc":"d,10:13,10:22","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(TC)","loc":"d,10:13,10:22","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"sublength","addr":"(UC)","loc":"d,10:13,10:22","dtypep":"(Q)","access":"WR","varp":"(S)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h20","addr":"(VC)","loc":"d,8:9,8:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(WC)","loc":"d,10:13,10:22","dtypep":"(Q)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(XC)","loc":"d,10:13,10:22","shortText":"\"sublength\""}
]}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(YC)","loc":"d,13:13,13:24",
"exprp": [
{"type":"CMETHODHARD","name":"write_var","addr":"(ZC)","loc":"d,13:13,13:24","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(AD)","loc":"d,13:13,13:24","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"VARREF","name":"if_state_ok","addr":"(BD)","loc":"d,13:13,13:24","dtypep":"(U)","access":"WR","varp":"(W)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"},
{"type":"CONST","name":"64'h1","addr":"(CD)","loc":"d,11:9,11:12","dtypep":"(TB)"},
{"type":"CEXPR","name":"","addr":"(DD)","loc":"d,13:13,13:24","dtypep":"(U)",
"exprsp": [
{"type":"TEXT","name":"","addr":"(ED)","loc":"d,13:13,13:24","shortText":"\"if_state_ok\""}
]}
]}
]}
],"scopeNamep": []},
{"type":"FUNC","name":"randomize","addr":"(FD)","loc":"d,7:1,7:6","dtypep":"(GD)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"randomize",
"fvarp": [
{"type":"VAR","name":"randomize","addr":"(HD)","loc":"d,7:1,7:6","dtypep":"(GD)","origName":"randomize","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(ID)","loc":"d,7:1,7:6",
"exprp": [
{"type":"CMETHODHARD","name":"clear","addr":"(JD)","loc":"d,7:1,7:6","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(KD)","loc":"d,7:1,7:6","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"pinsp": []}
]},
{"type":"STMTEXPR","name":"","addr":"(LD)","loc":"d,19:15,19:20",
"exprp": [
{"type":"TASKREF","name":"empty_setup_constraint","addr":"(MD)","loc":"d,19:15,19:20","dtypep":"(LB)","dotted":"","taskp":"(ND)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(OD)","loc":"d,21:15,21:19",
"exprp": [
{"type":"TASKREF","name":"size_setup_constraint","addr":"(PD)","loc":"d,21:15,21:19","dtypep":"(LB)","dotted":"","taskp":"(QD)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(RD)","loc":"d,28:15,28:18",
"exprp": [
{"type":"TASKREF","name":"ifs_setup_constraint","addr":"(SD)","loc":"d,28:15,28:18","dtypep":"(LB)","dotted":"","taskp":"(TD)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(UD)","loc":"d,41:15,41:23",
"exprp": [
{"type":"TASKREF","name":"arr_uniq_setup_constraint","addr":"(VD)","loc":"d,41:15,41:23","dtypep":"(LB)","dotted":"","taskp":"(WD)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(XD)","loc":"d,48:15,48:20",
"exprp": [
{"type":"TASKREF","name":"order_setup_constraint","addr":"(YD)","loc":"d,48:15,48:20","dtypep":"(LB)","dotted":"","taskp":"(ZD)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(AE)","loc":"d,50:15,50:18",
"exprp": [
{"type":"TASKREF","name":"dis_setup_constraint","addr":"(BE)","loc":"d,50:15,50:18","dtypep":"(LB)","dotted":"","taskp":"(CE)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]},
{"type":"STMTEXPR","name":"","addr":"(DE)","loc":"d,56:15,56:19",
"exprp": [
{"type":"TASKREF","name":"meth_setup_constraint","addr":"(EE)","loc":"d,56:15,56:19","dtypep":"(LB)","dotted":"","taskp":"(FE)","classOrPackagep":"UNLINKED","namep": [],"pinsp": [],"scopeNamep": []}
]}
],"scopeNamep": []},
{"type":"TASK","name":"empty_setup_constraint","addr":"(ND)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"empty_setup_constraint","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
{"type":"VAR","name":"constraint","addr":"(QB)","loc":"d,19:15,19:20","dtypep":"(PB)","origName":"constraint","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
{"type":"TASK","name":"size_setup_constraint","addr":"(QD)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"size_setup_constraint","fvarp": [],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(GE)","loc":"d,22:18,22:20",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(HE)","loc":"d,22:18,22:20","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(IE)","loc":"d,22:18,22:20","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(and (bvsgt header #x00000000) (bvsle header #x00000007))\\\"","addr":"(JE)","loc":"d,22:18,22:20","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(KE)","loc":"d,23:14,23:16",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(LE)","loc":"d,23:14,23:16","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(ME)","loc":"d,23:14,23:16","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(bvsle length #x0000000f)\\\"","addr":"(NE)","loc":"d,23:14,23:16","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(OE)","loc":"d,24:14,24:16",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(PE)","loc":"d,24:14,24:16","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(QE)","loc":"d,24:14,24:16","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(bvsge length header)\\\"","addr":"(RE)","loc":"d,24:14,24:16","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(SE)","loc":"d,25:14,25:18",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(TE)","loc":"d,25:14,25:18","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(UE)","loc":"d,25:14,25:18","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"true\\\"","addr":"(VE)","loc":"d,25:14,25:18","dtypep":"(M)"}
]}
]}
],"scopeNamep": []},
{"type":"TASK","name":"ifs_setup_constraint","addr":"(TD)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"ifs_setup_constraint","fvarp": [],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(WE)","loc":"d,29:7,29:9",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(XE)","loc":"d,29:7,29:9","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(YE)","loc":"d,29:7,29:9","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(=> (bvsgt header #x00000004) (= if_4 #b1))\\\"","addr":"(ZE)","loc":"d,29:7,29:9","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(AF)","loc":"d,32:7,32:9",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(BF)","loc":"d,32:7,32:9","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(CF)","loc":"d,32:7,32:9","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(ite (or (= header #x00000005) (= header #x00000006)) (and (= iff_5_6 #b1) (= iff_5_6 #b1) (= iff_5_6 #b1)) (= iff_5_6 #b0))\\\"","addr":"(DF)","loc":"d,32:7,32:9","dtypep":"(M)"}
]}
]}
],"scopeNamep": []},
{"type":"TASK","name":"arr_uniq_setup_constraint","addr":"(WD)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"arr_uniq_setup_constraint","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
{"type":"TASK","name":"order_setup_constraint","addr":"(ZD)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"order_setup_constraint","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
{"type":"TASK","name":"dis_setup_constraint","addr":"(CE)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"dis_setup_constraint","fvarp": [],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(EF)","loc":"d,51:7,51:11",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(FF)","loc":"d,51:7,51:11","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(GF)","loc":"d,51:7,51:11","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"sublength\\\"","addr":"(HF)","loc":"d,51:12,51:21","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(IF)","loc":"d,52:7,52:14",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(JF)","loc":"d,52:7,52:14","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(KF)","loc":"d,52:7,52:14","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"sublength\\\"","addr":"(LF)","loc":"d,52:20,52:29","dtypep":"(M)"}
]}
]},
{"type":"STMTEXPR","name":"","addr":"(MF)","loc":"d,53:17,53:19",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(NF)","loc":"d,53:17,53:19","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(OF)","loc":"d,53:17,53:19","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"CONST","name":"\\\"(bvsle sublength length)\\\"","addr":"(PF)","loc":"d,53:17,53:19","dtypep":"(M)"}
]}
]}
],"scopeNamep": []},
{"type":"TASK","name":"meth_setup_constraint","addr":"(FE)","loc":"d,7:1,7:6","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"meth_setup_constraint","fvarp": [],"classOrPackagep": [],
"stmtsp": [
{"type":"STMTEXPR","name":"","addr":"(QF)","loc":"d,57:7,57:9",
"exprp": [
{"type":"CMETHODHARD","name":"hard","addr":"(RF)","loc":"d,57:7,57:9","dtypep":"(LB)",
"fromp": [
{"type":"VARREF","name":"constraint","addr":"(SF)","loc":"d,57:7,57:9","dtypep":"(PB)","access":"RW","varp":"(QB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"pinsp": [
{"type":"SFORMATF","name":"(=> %@ (= if_state_ok #b1))","addr":"(TF)","loc":"d,57:7,57:9","dtypep":"(M)",
"exprsp": [
{"type":"SFORMATF","name":"#b%b","addr":"(UF)","loc":"d,57:11,57:24","dtypep":"(M)",
"exprsp": [
{"type":"FUNCREF","name":"strings_equal","addr":"(VF)","loc":"d,57:11,57:24","dtypep":"(U)","dotted":"","taskp":"(AB)","classOrPackagep":"(O)","namep": [],
"pinsp": [
{"type":"ARG","name":"","addr":"(WF)","loc":"d,57:25,57:30",
"exprp": [
{"type":"VARREF","name":"state","addr":"(XF)","loc":"d,57:25,57:30","dtypep":"(M)","access":"RD","varp":"(Z)","varScopep":"UNLINKED","classOrPackagep":"(O)"}
]},
{"type":"ARG","name":"","addr":"(YF)","loc":"d,57:32,57:36",
"exprp": [
{"type":"CONST","name":"\\\"ok\\\"","addr":"(ZF)","loc":"d,57:32,57:36","dtypep":"(M)"}
]}
],"scopeNamep": []}
],"scopeNamep": []}
],"scopeNamep": []}
]}
]}
],"scopeNamep": []}
{"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []}
],"activesp": [],"extendsp": []}
],"activesp": []}
],"filesp": [],
@ -321,31 +56,28 @@
{"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(LB)",
"typesp": [
{"type":"BASICDTYPE","name":"logic","addr":"(GB)","loc":"d,22:14,22:15","dtypep":"(GB)","keyword":"logic","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(AG)","loc":"d,25:21,25:22","dtypep":"(AG)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(MB)","loc":"d,25:21,25:22","dtypep":"(MB)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"string","addr":"(M)","loc":"d,73:7,73:13","dtypep":"(M)","keyword":"string","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"int","addr":"(Q)","loc":"d,8:9,8:12","dtypep":"(Q)","keyword":"int","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"bit","addr":"(U)","loc":"d,11:9,11:12","dtypep":"(U)","keyword":"bit","generic":true,"rangep": []},
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(Y)","loc":"d,15:18,15:19","dtypep":"(Y)","isCompound":false,"declRange":"[0:1]","generic":false,"refDTypep":"(Q)","childDTypep": [],
"rangep": [
{"type":"RANGE","name":"","addr":"(BG)","loc":"d,15:18,15:19","ascending":true,
{"type":"RANGE","name":"","addr":"(NB)","loc":"d,15:18,15:19","ascending":true,
"leftp": [
{"type":"CONST","name":"32'h0","addr":"(CG)","loc":"d,15:19,15:20","dtypep":"(AG)"}
{"type":"CONST","name":"32'h0","addr":"(OB)","loc":"d,15:19,15:20","dtypep":"(MB)"}
],
"rightp": [
{"type":"CONST","name":"32'h1","addr":"(DG)","loc":"d,15:19,15:20","dtypep":"(AG)"}
{"type":"CONST","name":"32'h1","addr":"(PB)","loc":"d,15:19,15:20","dtypep":"(MB)"}
]}
]},
{"type":"VOIDDTYPE","name":"","addr":"(LB)","loc":"d,7:1,7:6","dtypep":"(LB)","generic":false},
{"type":"CLASSREFDTYPE","name":"Packet","addr":"(H)","loc":"d,69:4,69:10","dtypep":"(H)","generic":false,"classp":"(O)","classOrPackagep":"(O)","paramsp": []},
{"type":"BASICDTYPE","name":"bit","addr":"(GD)","loc":"d,7:1,7:6","dtypep":"(GD)","keyword":"bit","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"VlRandomizer","addr":"(PB)","loc":"d,7:1,7:6","dtypep":"(PB)","keyword":"VlRandomizer","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(TB)","loc":"d,8:9,8:12","dtypep":"(TB)","keyword":"logic","range":"63:0","generic":true,"rangep": []}
{"type":"CLASSREFDTYPE","name":"Packet","addr":"(H)","loc":"d,69:4,69:10","dtypep":"(H)","generic":false,"classp":"(O)","classOrPackagep":"(O)","paramsp": []}
]},
{"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(EG)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [],
{"type":"MODULE","name":"@CONST-POOL@","addr":"(QB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [],
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(FG)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(EG)","varsp": [],"blocksp": [],"inlinesp": []}
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(RB)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(QB)","varsp": [],"blocksp": [],"inlinesp": []}
],"activesp": []}
]}
]}

View File

@ -47,199 +47,23 @@
<varref loc="d,62,7,62,13" name="strings_equal" dtype_id="4"/>
</assign>
</func>
<func loc="d,7,1,7,6" name="new" dtype_id="7">
<stmtexpr loc="d,8,13,8,19">
<cmethodhard loc="d,8,13,8,19" name="write_var" dtype_id="7">
<varref loc="d,8,13,8,19" name="constraint" dtype_id="8"/>
<varref loc="d,8,13,8,19" name="header" dtype_id="3"/>
<const loc="d,8,9,8,12" name="64&apos;h20" dtype_id="9"/>
<cexpr loc="d,8,13,8,19" dtype_id="3">
<text loc="d,8,13,8,19"/>
</cexpr>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,9,13,9,19">
<cmethodhard loc="d,9,13,9,19" name="write_var" dtype_id="7">
<varref loc="d,9,13,9,19" name="constraint" dtype_id="8"/>
<varref loc="d,9,13,9,19" name="length" dtype_id="3"/>
<const loc="d,8,9,8,12" name="64&apos;h20" dtype_id="9"/>
<cexpr loc="d,9,13,9,19" dtype_id="3">
<text loc="d,9,13,9,19"/>
</cexpr>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,11,13,11,17">
<cmethodhard loc="d,11,13,11,17" name="write_var" dtype_id="7">
<varref loc="d,11,13,11,17" name="constraint" dtype_id="8"/>
<varref loc="d,11,13,11,17" name="if_4" dtype_id="4"/>
<const loc="d,11,9,11,12" name="64&apos;h1" dtype_id="9"/>
<cexpr loc="d,11,13,11,17" dtype_id="4">
<text loc="d,11,13,11,17"/>
</cexpr>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,12,13,12,20">
<cmethodhard loc="d,12,13,12,20" name="write_var" dtype_id="7">
<varref loc="d,12,13,12,20" name="constraint" dtype_id="8"/>
<varref loc="d,12,13,12,20" name="iff_5_6" dtype_id="4"/>
<const loc="d,11,9,11,12" name="64&apos;h1" dtype_id="9"/>
<cexpr loc="d,12,13,12,20" dtype_id="4">
<text loc="d,12,13,12,20"/>
</cexpr>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,10,13,10,22">
<cmethodhard loc="d,10,13,10,22" name="write_var" dtype_id="7">
<varref loc="d,10,13,10,22" name="constraint" dtype_id="8"/>
<varref loc="d,10,13,10,22" name="sublength" dtype_id="3"/>
<const loc="d,8,9,8,12" name="64&apos;h20" dtype_id="9"/>
<cexpr loc="d,10,13,10,22" dtype_id="3">
<text loc="d,10,13,10,22"/>
</cexpr>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,13,13,13,24">
<cmethodhard loc="d,13,13,13,24" name="write_var" dtype_id="7">
<varref loc="d,13,13,13,24" name="constraint" dtype_id="8"/>
<varref loc="d,13,13,13,24" name="if_state_ok" dtype_id="4"/>
<const loc="d,11,9,11,12" name="64&apos;h1" dtype_id="9"/>
<cexpr loc="d,13,13,13,24" dtype_id="4">
<text loc="d,13,13,13,24"/>
</cexpr>
</cmethodhard>
</stmtexpr>
</func>
<func loc="d,7,1,7,6" name="randomize" dtype_id="10">
<var loc="d,7,1,7,6" name="randomize" dtype_id="10" dir="output" vartype="bit" origName="randomize"/>
<stmtexpr loc="d,7,1,7,6">
<cmethodhard loc="d,7,1,7,6" name="clear" dtype_id="7">
<varref loc="d,7,1,7,6" name="constraint" dtype_id="8"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,19,15,19,20">
<taskref loc="d,19,15,19,20" name="empty_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,21,15,21,19">
<taskref loc="d,21,15,21,19" name="size_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,28,15,28,18">
<taskref loc="d,28,15,28,18" name="ifs_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,41,15,41,23">
<taskref loc="d,41,15,41,23" name="arr_uniq_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,48,15,48,20">
<taskref loc="d,48,15,48,20" name="order_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,50,15,50,18">
<taskref loc="d,50,15,50,18" name="dis_setup_constraint" dtype_id="7"/>
</stmtexpr>
<stmtexpr loc="d,56,15,56,19">
<taskref loc="d,56,15,56,19" name="meth_setup_constraint" dtype_id="7"/>
</stmtexpr>
</func>
<task loc="d,7,1,7,6" name="empty_setup_constraint"/>
<var loc="d,19,15,19,20" name="constraint" dtype_id="8" vartype="VlRandomizer" origName="constraint"/>
<task loc="d,7,1,7,6" name="size_setup_constraint">
<stmtexpr loc="d,22,18,22,20">
<cmethodhard loc="d,22,18,22,20" name="hard" dtype_id="7">
<varref loc="d,22,18,22,20" name="constraint" dtype_id="8"/>
<const loc="d,22,18,22,20" name="&quot;(and (bvsgt header #x00000000) (bvsle header #x00000007))&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,23,14,23,16">
<cmethodhard loc="d,23,14,23,16" name="hard" dtype_id="7">
<varref loc="d,23,14,23,16" name="constraint" dtype_id="8"/>
<const loc="d,23,14,23,16" name="&quot;(bvsle length #x0000000f)&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,24,14,24,16">
<cmethodhard loc="d,24,14,24,16" name="hard" dtype_id="7">
<varref loc="d,24,14,24,16" name="constraint" dtype_id="8"/>
<const loc="d,24,14,24,16" name="&quot;(bvsge length header)&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,25,14,25,18">
<cmethodhard loc="d,25,14,25,18" name="hard" dtype_id="7">
<varref loc="d,25,14,25,18" name="constraint" dtype_id="8"/>
<const loc="d,25,14,25,18" name="&quot;true&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
</task>
<task loc="d,7,1,7,6" name="ifs_setup_constraint">
<stmtexpr loc="d,29,7,29,9">
<cmethodhard loc="d,29,7,29,9" name="hard" dtype_id="7">
<varref loc="d,29,7,29,9" name="constraint" dtype_id="8"/>
<const loc="d,29,7,29,9" name="&quot;(=&gt; (bvsgt header #x00000004) (= if_4 #b1))&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,32,7,32,9">
<cmethodhard loc="d,32,7,32,9" name="hard" dtype_id="7">
<varref loc="d,32,7,32,9" name="constraint" dtype_id="8"/>
<const loc="d,32,7,32,9" name="&quot;(ite (or (= header #x00000005) (= header #x00000006)) (and (= iff_5_6 #b1) (= iff_5_6 #b1) (= iff_5_6 #b1)) (= iff_5_6 #b0))&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
</task>
<task loc="d,7,1,7,6" name="arr_uniq_setup_constraint"/>
<task loc="d,7,1,7,6" name="order_setup_constraint"/>
<task loc="d,7,1,7,6" name="dis_setup_constraint">
<stmtexpr loc="d,51,7,51,11">
<cmethodhard loc="d,51,7,51,11" name="hard" dtype_id="7">
<varref loc="d,51,7,51,11" name="constraint" dtype_id="8"/>
<const loc="d,51,12,51,21" name="&quot;sublength&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,52,7,52,14">
<cmethodhard loc="d,52,7,52,14" name="hard" dtype_id="7">
<varref loc="d,52,7,52,14" name="constraint" dtype_id="8"/>
<const loc="d,52,20,52,29" name="&quot;sublength&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
<stmtexpr loc="d,53,17,53,19">
<cmethodhard loc="d,53,17,53,19" name="hard" dtype_id="7">
<varref loc="d,53,17,53,19" name="constraint" dtype_id="8"/>
<const loc="d,53,17,53,19" name="&quot;(bvsle sublength length)&quot;" dtype_id="2"/>
</cmethodhard>
</stmtexpr>
</task>
<task loc="d,7,1,7,6" name="meth_setup_constraint">
<stmtexpr loc="d,57,7,57,9">
<cmethodhard loc="d,57,7,57,9" name="hard" dtype_id="7">
<varref loc="d,57,7,57,9" name="constraint" dtype_id="8"/>
<sformatf loc="d,57,7,57,9" name="(=&gt; %@ (= if_state_ok #b1))" dtype_id="2">
<sformatf loc="d,57,11,57,24" name="#b%b" dtype_id="2">
<funcref loc="d,57,11,57,24" name="strings_equal" dtype_id="4">
<arg loc="d,57,25,57,30">
<varref loc="d,57,25,57,30" name="state" dtype_id="2"/>
</arg>
<arg loc="d,57,32,57,36">
<const loc="d,57,32,57,36" name="&quot;ok&quot;" dtype_id="2"/>
</arg>
</funcref>
</sformatf>
</sformatf>
</cmethodhard>
</stmtexpr>
</task>
<func loc="d,7,1,7,6" name="new" dtype_id="7"/>
</class>
</package>
<typetable loc="a,0,0,0,0">
<basicdtype loc="d,22,14,22,15" id="6" name="logic"/>
<basicdtype loc="d,25,21,25,22" id="11" name="logic" left="31" right="0"/>
<basicdtype loc="d,25,21,25,22" id="8" name="logic" left="31" right="0"/>
<basicdtype loc="d,73,7,73,13" id="2" name="string"/>
<basicdtype loc="d,8,9,8,12" id="3" name="int" left="31" right="0" signed="true"/>
<basicdtype loc="d,11,9,11,12" id="4" name="bit"/>
<unpackarraydtype loc="d,15,18,15,19" id="5" sub_dtype_id="3">
<range loc="d,15,18,15,19">
<const loc="d,15,19,15,20" name="32&apos;h0" dtype_id="11"/>
<const loc="d,15,19,15,20" name="32&apos;h1" dtype_id="11"/>
<const loc="d,15,19,15,20" name="32&apos;h0" dtype_id="8"/>
<const loc="d,15,19,15,20" name="32&apos;h1" dtype_id="8"/>
</range>
</unpackarraydtype>
<voiddtype loc="d,7,1,7,6" id="7"/>
<classrefdtype loc="d,69,4,69,10" id="1" name="Packet"/>
<basicdtype loc="d,7,1,7,6" id="10" name="bit" left="31" right="0" signed="true"/>
<basicdtype loc="d,7,1,7,6" id="8" name="VlRandomizer"/>
<basicdtype loc="d,8,9,8,12" id="9" name="logic" left="63" right="0"/>
</typetable>
</netlist>
</verilator_xml>

View File

@ -1,4 +1,4 @@
// DESCRIPTION: Verilator: Verilog Test module
// DESCRIPTION: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2020 by Wilson Snyder.
@ -45,7 +45,7 @@ typedef struct {
longint z;
} StructUnpacked;
class BaseCls;
class BaseCls1;
endclass
class Inner;
@ -65,7 +65,7 @@ class Inner;
endclass
class DerivedCls extends BaseCls;
class DerivedCls1 extends BaseCls1;
rand Inner i;
rand int j;
int k;
@ -80,6 +80,24 @@ class DerivedCls extends BaseCls;
endclass
class BaseCls2;
rand int i;
function new;
i = 0;
endfunction
endclass
class DerivedCls2 extends BaseCls2;
rand int j;
function new;
super.new;
j = 0;
endfunction
endclass
class OtherCls;
logic[63:0] v;
rand logic[63:0] w;
@ -102,7 +120,7 @@ class OtherCls;
endclass
class ContainsNull;
rand BaseCls b;
rand BaseCls1 b;
endclass
class ClsWithInt;
@ -137,35 +155,37 @@ endclass
module t (/*AUTOARG*/);
DerivedCls derived;
DerivedCls1 derived1;
DerivedCls2 derived2;
OtherCls other;
BaseCls base;
BaseCls1 base;
ContainsNull cont;
DeriveClsWithInt der_int;
DeriveAndContainClsWithInt der_contain;
ClsContainUsedOnlyHere cls_cont_used;
initial begin
int rand_result;
derived = new;
derived1 = new;
derived2 = new;
other = new;
cont = new;
der_int = new;
der_contain = new;
base = derived;
base = derived1;
cls_cont_used = new;
for (int i = 0; i < 10; i++) begin
rand_result = base.randomize();
rand_result = other.randomize();
rand_result = cont.randomize();
rand_result = der_int.randomize();
rand_result = der_contain.randomize();
if (!(derived.l inside {ONE, TWO, THREE, FOUR})) $stop;
void'(base.randomize());
void'(derived2.randomize());
void'(other.randomize());
void'(cont.randomize());
void'(der_int.randomize());
void'(der_contain.randomize());
if (!(derived1.l 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 (derived1.i.e != 0) $stop;
if (derived1.k != 0) $stop;
if (other.v != 0) $stop;
if (cont.b != null) $stop;
if (der_int.b != 0) $stop;
@ -173,11 +193,13 @@ module t (/*AUTOARG*/);
if (der_contain.cls1.b != 0) $stop;
if (der_contain.b != 0) $stop;
end
`check_rand(derived, derived.i.a);
`check_rand(derived, derived.i.b);
`check_rand(derived, derived.i.c);
`check_rand(derived, derived.j);
`check_rand(derived, derived.l);
`check_rand(derived1, derived1.i.a);
`check_rand(derived1, derived1.i.b);
`check_rand(derived1, derived1.i.c);
`check_rand(derived1, derived1.j);
`check_rand(derived1, derived1.l);
`check_rand(derived2, derived2.i);
`check_rand(derived2, derived2.j);
`check_rand(other, other.w);
`check_rand(other, other.x);
`check_rand(other, other.y);

View File

@ -14,7 +14,7 @@
: ... note: In instance 't'
15 | rand Union uni;
| ^~~
%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:16:13: Unsupported: random member variable with type of a current class
%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:16:13: Unsupported: random member variable with the type of the containing class
: ... note: In instance 't'
16 | rand Cls cls;
| ^~~