Fix inline constraints creating class random generator (#5280)
This commit is contained in:
parent
298faa84ee
commit
2bd2b9324f
|
|
@ -2338,17 +2338,40 @@ public:
|
|||
// 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) {
|
||||
void foreachMember(const Callable& f) {
|
||||
using T_Node = typename FunctionArgNoPointerNoCV<Callable, 1>::type;
|
||||
static_assert(
|
||||
vlstd::is_invocable<Callable, AstClass*, T_Node*>::value
|
||||
&& std::is_base_of<AstNode, T_Node>::value,
|
||||
"Callable 'f' must have a signature compatible with 'void(AstClass*, T_Node*)', "
|
||||
"with 'T_Node' being a subtype of 'AstNode'");
|
||||
if (AstClassExtends* const extendsp = this->extendsp()) {
|
||||
extendsp->classp()->foreachMember(visit);
|
||||
extendsp->classp()->foreachMember(f);
|
||||
}
|
||||
for (AstNode* stmtp = stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (T_Node* memberp = AstNode::privateCast<T_Node, decltype(stmtp)>(stmtp)) {
|
||||
visit(this, memberp);
|
||||
f(this, memberp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Same as above, but stops after first match
|
||||
template <typename Callable>
|
||||
bool existsMember(const Callable& p) const {
|
||||
using T_Node = typename FunctionArgNoPointerNoCV<Callable, 1>::type;
|
||||
static_assert(vlstd::is_invocable_r<bool, Callable, const AstClass*, const T_Node*>::value
|
||||
&& std::is_base_of<AstNode, T_Node>::value,
|
||||
"Predicate 'p' must have a signature compatible with 'bool(const AstClass*, "
|
||||
"const T_Node*)', with 'T_Node' being a subtype of 'AstNode'");
|
||||
if (AstClassExtends* const extendsp = this->extendsp()) {
|
||||
if (extendsp->classp()->existsMember(p)) return true;
|
||||
}
|
||||
for (AstNode* stmtp = stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (T_Node* memberp = AstNode::privateCast<T_Node, decltype(stmtp)>(stmtp)) {
|
||||
if (p(this, memberp)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
class AstClassPackage final : public AstNodeModule {
|
||||
// The static information portion of a class (treated similarly to a package)
|
||||
|
|
|
|||
|
|
@ -552,15 +552,22 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
std::map<std::string, AstCDType*> m_randcDtypes; // RandC data type deduplication
|
||||
|
||||
// METHODS
|
||||
AstVar* getCreateRandomGenerator(AstClass* classp) {
|
||||
if (classp->user3p()) return VN_AS(classp->user3p(), Var);
|
||||
if (classp->extendsp()) return getCreateRandomGenerator(classp->extendsp()->classp());
|
||||
void createRandomGenerator(AstClass* const classp) {
|
||||
if (classp->user3p()) return;
|
||||
if (classp->extendsp()) {
|
||||
createRandomGenerator(classp->extendsp()->classp());
|
||||
return;
|
||||
}
|
||||
AstVar* const genp = new AstVar{classp->fileline(), VVarType::MEMBER, "constraint",
|
||||
classp->findBasicDType(VBasicDTypeKwd::RANDOM_GENERATOR)};
|
||||
genp->user2p(classp);
|
||||
classp->addMembersp(genp);
|
||||
classp->user3p(genp);
|
||||
return genp;
|
||||
}
|
||||
AstVar* getRandomGenerator(AstClass* const classp) {
|
||||
if (classp->user3p()) return VN_AS(classp->user3p(), Var);
|
||||
if (classp->extendsp()) return getRandomGenerator(classp->extendsp()->classp());
|
||||
return nullptr;
|
||||
}
|
||||
AstTask* getCreateConstraintSetupFunc(AstClass* classp) {
|
||||
if (classp->user2p()) return VN_AS(classp->user2p(), Task);
|
||||
|
|
@ -572,6 +579,14 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
classp->user2p(setupAllTaskp);
|
||||
return setupAllTaskp;
|
||||
}
|
||||
void createRandomizeClassVars(AstNetlist* const netlistp) {
|
||||
netlistp->foreach([&](AstClass* const classp) {
|
||||
if (classp->existsMember(
|
||||
[&](const AstClass*, const AstConstraint*) { return true; })) {
|
||||
createRandomGenerator(classp);
|
||||
}
|
||||
});
|
||||
}
|
||||
AstVar* enumValueTabp(AstEnumDType* const nodep) {
|
||||
if (nodep->user2p()) return VN_AS(nodep->user2p(), Var);
|
||||
UINFO(9, "Construct Venumvaltab " << nodep << endl);
|
||||
|
|
@ -756,27 +771,26 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
FileLine* fl = nodep->fileline();
|
||||
|
||||
AstNodeExpr* beginValp = nullptr;
|
||||
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);
|
||||
}
|
||||
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());
|
||||
});
|
||||
AstVar* genp = getRandomGenerator(nodep);
|
||||
if (genp) {
|
||||
nodep->foreachMember([&](AstClass* const classp, AstConstraint* const constrp) {
|
||||
AstTask* taskp = VN_AS(constrp->user2p(), Task);
|
||||
if (!taskp) {
|
||||
taskp = newSetupConstraintTask(classp, constrp->name());
|
||||
constrp->user2p(taskp);
|
||||
}
|
||||
AstTaskRef* const setupTaskRefp
|
||||
= new AstTaskRef{constrp->fileline(), taskp->name(), nullptr};
|
||||
setupTaskRefp->taskp(taskp);
|
||||
setupTaskRefp->classOrPackagep(classp);
|
||||
|
||||
AstTask* const setupAllTaskp = getCreateConstraintSetupFunc(nodep);
|
||||
|
||||
setupAllTaskp->addStmtsp(setupTaskRefp->makeStmt());
|
||||
|
||||
ConstraintExprVisitor{m_memberMap, constrp->itemsp(), nullptr, genp};
|
||||
if (constrp->itemsp()) taskp->addStmtsp(constrp->itemsp()->unlinkFrBackWithNext());
|
||||
});
|
||||
randomizep->addStmtsp(implementConstraintsClear(fl, genp));
|
||||
AstTask* setupAllTaskp = getCreateConstraintSetupFunc(nodep);
|
||||
AstTaskRef* const setupTaskRefp = new AstTaskRef{fl, setupAllTaskp->name(), nullptr};
|
||||
|
|
@ -926,13 +940,13 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
UASSERT_OBJ(classp, m_modp, "Module not class, should have failed in V3Width");
|
||||
}
|
||||
if (classp->user1()) {
|
||||
// We need to first ensure that the class randomizer is instantiated if needed
|
||||
// We need to first ensure that the class constraints are transformed
|
||||
// NOTE: This is safe only because AstClass visit function overwrites all
|
||||
// nesting-dependent state variables
|
||||
iterate(classp);
|
||||
}
|
||||
|
||||
AstVar* const classGenp = getCreateRandomGenerator(classp);
|
||||
AstVar* const classGenp = getRandomGenerator(classp);
|
||||
AstVar* const localGenp
|
||||
= new AstVar{nodep->fileline(), VVarType::BLOCKTEMP, "randomizer",
|
||||
classp->findBasicDType(VBasicDTypeKwd::RANDOM_GENERATOR)};
|
||||
|
|
@ -1007,6 +1021,7 @@ public:
|
|||
// CONSTRUCTORS
|
||||
explicit RandomizeVisitor(AstNetlist* nodep)
|
||||
: m_inlineUniqueNames("__Vrandwith") {
|
||||
createRandomizeClassVars(nodep);
|
||||
iterate(nodep);
|
||||
nodep->foreach([&](AstConstraint* constrp) {
|
||||
VL_DO_DANGLING(pushDeletep(constrp->unlinkFrBack()), constrp);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@
|
|||
{"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": [],"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": []},
|
||||
{"type":"VAR","name":"constraint","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","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": []}
|
||||
],"activesp": [],"extendsp": []}
|
||||
],"activesp": []}
|
||||
],"filesp": [],
|
||||
|
|
@ -56,28 +57,29 @@
|
|||
{"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":"(MB)","loc":"d,25:21,25:22","dtypep":"(MB)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(OB)","loc":"d,25:21,25:22","dtypep":"(OB)","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":"(NB)","loc":"d,15:18,15:19","ascending":true,
|
||||
{"type":"RANGE","name":"","addr":"(PB)","loc":"d,15:18,15:19","ascending":true,
|
||||
"leftp": [
|
||||
{"type":"CONST","name":"32'h0","addr":"(OB)","loc":"d,15:19,15:20","dtypep":"(MB)"}
|
||||
{"type":"CONST","name":"32'h0","addr":"(QB)","loc":"d,15:19,15:20","dtypep":"(OB)"}
|
||||
],
|
||||
"rightp": [
|
||||
{"type":"CONST","name":"32'h1","addr":"(PB)","loc":"d,15:19,15:20","dtypep":"(MB)"}
|
||||
{"type":"CONST","name":"32'h1","addr":"(RB)","loc":"d,15:19,15:20","dtypep":"(OB)"}
|
||||
]}
|
||||
]},
|
||||
{"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":"CLASSREFDTYPE","name":"Packet","addr":"(H)","loc":"d,69:4,69:10","dtypep":"(H)","generic":false,"classp":"(O)","classOrPackagep":"(O)","paramsp": []},
|
||||
{"type":"BASICDTYPE","name":"VlRandomizer","addr":"(NB)","loc":"d,7:1,7:6","dtypep":"(NB)","keyword":"VlRandomizer","generic":true,"rangep": []}
|
||||
]},
|
||||
{"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0",
|
||||
"modulep": [
|
||||
{"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": [],
|
||||
{"type":"MODULE","name":"@CONST-POOL@","addr":"(SB)","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":"(RB)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(QB)","varsp": [],"blocksp": [],"inlinesp": []}
|
||||
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(TB)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(SB)","varsp": [],"blocksp": [],"inlinesp": []}
|
||||
],"activesp": []}
|
||||
]}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -48,22 +48,24 @@
|
|||
</assign>
|
||||
</func>
|
||||
<func loc="d,7,1,7,6" name="new" dtype_id="7"/>
|
||||
<var loc="d,7,1,7,6" name="constraint" dtype_id="8" vartype="VlRandomizer" origName="constraint"/>
|
||||
</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="8" name="logic" left="31" right="0"/>
|
||||
<basicdtype loc="d,25,21,25,22" id="9" 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'h0" dtype_id="8"/>
|
||||
<const loc="d,15,19,15,20" name="32'h1" dtype_id="8"/>
|
||||
<const loc="d,15,19,15,20" name="32'h0" dtype_id="9"/>
|
||||
<const loc="d,15,19,15,20" name="32'h1" dtype_id="9"/>
|
||||
</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="8" name="VlRandomizer"/>
|
||||
</typetable>
|
||||
</netlist>
|
||||
</verilator_xml>
|
||||
|
|
|
|||
|
|
@ -23,5 +23,10 @@ if (!$Self->have_solver) {
|
|||
);
|
||||
}
|
||||
|
||||
for my $file (glob_all("$Self->{obj_dir}/$Self->{vm_prefix}*Baz*.cpp")) {
|
||||
# Check that "Baz" has no constrained random generator
|
||||
file_grep_not($file, "this->__PVT__constraint");
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue