mirror of
https://github.com/verilator/verilator.git
synced 2026-09-02 02:38:15 +02:00
Fix inline constraints creating class random generator (#5280)
This commit is contained in:
+41
-26
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user