This commit is contained in:
parent
358c5a7d72
commit
77f6b85d1f
|
|
@ -2115,7 +2115,7 @@ public:
|
||||||
void setIgnoreSchedWrite() { m_ignoreSchedWrite = true; }
|
void setIgnoreSchedWrite() { m_ignoreSchedWrite = true; }
|
||||||
bool dfgMultidriven() const { return m_dfgMultidriven; }
|
bool dfgMultidriven() const { return m_dfgMultidriven; }
|
||||||
void setDfgMultidriven() { m_dfgMultidriven = true; }
|
void setDfgMultidriven() { m_dfgMultidriven = true; }
|
||||||
void isGlobalConstrained(bool flag) { m_globalCons = true; }
|
void setGlobalConstrained(bool flag) { m_globalCons = flag; }
|
||||||
// METHODS
|
// METHODS
|
||||||
void name(const string& name) override { m_name = name; }
|
void name(const string& name) override { m_name = name; }
|
||||||
void tag(const string& text) override { m_tag = text; }
|
void tag(const string& text) override { m_tag = text; }
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
bool m_globalConsProcessed = false;
|
bool m_globalConsProcessed = false;
|
||||||
AstWith* m_astWithp = nullptr;
|
AstWith* m_astWithp = nullptr;
|
||||||
std::vector<AstConstraint*> m_clonedConstraints;
|
std::vector<AstConstraint*> m_clonedConstraints;
|
||||||
|
std::unordered_set<const AstClass*> m_processedClasses;
|
||||||
|
|
||||||
// Constants for global constraint processing
|
// Constants for global constraint processing
|
||||||
static constexpr const char* GLOBAL_CONSTRAINT_SEPARATOR = "__DT__";
|
static constexpr const char* GLOBAL_CONSTRAINT_SEPARATOR = "__DT__";
|
||||||
|
|
@ -207,11 +208,24 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void nameManipulation(AstVarRef* fromp, AstConstraint* cloneCons) {
|
void nameManipulation(AstVarRef* fromp, AstConstraint* cloneCons) {
|
||||||
|
if (!fromp || !cloneCons) {
|
||||||
|
UINFO(9, "Invalid parameters in nameManipulation\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Iterate through all variable references and replace them with member selections.
|
// Iterate through all variable references and replace them with member selections.
|
||||||
cloneCons->name(fromp->name() + GLOBAL_CONSTRAINT_SEPARATOR + cloneCons->name());
|
cloneCons->name(fromp->name() + GLOBAL_CONSTRAINT_SEPARATOR + cloneCons->name());
|
||||||
cloneCons->foreach([&](AstVarRef* varRefp) {
|
cloneCons->foreach([&](AstVarRef* varRefp) {
|
||||||
|
if (!varRefp || !varRefp->varp()) {
|
||||||
|
UINFO(9, "Invalid variable reference in constraint\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AstVarRef* clonedFromp = fromp->cloneTree(false);
|
||||||
|
if (!clonedFromp) {
|
||||||
|
UINFO(9, "Failed to clone variable reference in nameManipulation\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
AstMemberSel* varMemberp = new AstMemberSel{cloneCons->fileline(),
|
AstMemberSel* varMemberp = new AstMemberSel{cloneCons->fileline(),
|
||||||
fromp->cloneTree(false), varRefp->varp()};
|
clonedFromp, varRefp->varp()};
|
||||||
varMemberp->user2p(m_classp);
|
varMemberp->user2p(m_classp);
|
||||||
varRefp->replaceWith(varMemberp);
|
varRefp->replaceWith(varMemberp);
|
||||||
VL_DO_DANGLING(varRefp->deleteTree(), varRefp);
|
VL_DO_DANGLING(varRefp->deleteTree(), varRefp);
|
||||||
|
|
@ -223,6 +237,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
VL_RESTORER(m_modp);
|
VL_RESTORER(m_modp);
|
||||||
m_modp = m_classp = nodep;
|
m_modp = m_classp = nodep;
|
||||||
m_globalConsProcessed = false;
|
m_globalConsProcessed = false;
|
||||||
|
// Clear processed classes for each new class context
|
||||||
|
m_processedClasses.clear();
|
||||||
iterateChildrenConst(nodep);
|
iterateChildrenConst(nodep);
|
||||||
for (int i = 0; i < m_clonedConstraints.size(); i++) {
|
for (int i = 0; i < m_clonedConstraints.size(); i++) {
|
||||||
m_classp->addStmtsp(m_clonedConstraints[i]);
|
m_classp->addStmtsp(m_clonedConstraints[i]);
|
||||||
|
|
@ -507,7 +523,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
m_classp->user1(IS_RANDOMIZED_WITH_GLOBAL_CONSTRAINTS);
|
m_classp->user1(IS_RANDOMIZED_WITH_GLOBAL_CONSTRAINTS);
|
||||||
else if (m_classp->user1() == IS_RANDOMIZED_INLINE)
|
else if (m_classp->user1() == IS_RANDOMIZED_INLINE)
|
||||||
m_classp->user1(IS_RANDOMIZED_INLINE_WITH_GLOBAL_CONSTRAINTS);
|
m_classp->user1(IS_RANDOMIZED_INLINE_WITH_GLOBAL_CONSTRAINTS);
|
||||||
VN_AS(nodep->fromp(), VarRef)->varp()->isGlobalConstrained(true); // not needed
|
// Mark the object variable as participating in global constraints
|
||||||
|
VN_AS(nodep->fromp(), VarRef)->varp()->setGlobalConstrained(true);
|
||||||
|
|
||||||
// Global constraint processing algorithm:
|
// Global constraint processing algorithm:
|
||||||
// 1. Detect globally constrained object variables in randomized classes
|
// 1. Detect globally constrained object variables in randomized classes
|
||||||
|
|
@ -516,25 +533,40 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
// 4. Insert cloned constraints into current class for solver processing
|
// 4. Insert cloned constraints into current class for solver processing
|
||||||
// 5. Use basic randomization for non-constrained variables to avoid recursion
|
// 5. Use basic randomization for non-constrained variables to avoid recursion
|
||||||
|
|
||||||
if (!m_globalConsProcessed) { // Only process once per object's global constraints
|
// Extract and validate components early to avoid repeated type checks
|
||||||
// TODO: Should be a vector to check if each class is
|
AstVarRef* const varRefp = VN_CAST(nodep->fromp(), VarRef);
|
||||||
// processed
|
if (!varRefp || !varRefp->varp()) return;
|
||||||
if (nodep->user1() && VN_IS(nodep->fromp()->dtypep()->skipRefp(), ClassRefDType)
|
|
||||||
&& VN_AS(nodep->fromp(), VarRef)->varp()->isGlobalConstrained()) {
|
const AstClassRefDType* const classRefp =
|
||||||
AstClass* gConsClass
|
VN_CAST(varRefp->dtypep()->skipRefp(), ClassRefDType);
|
||||||
= VN_AS(nodep->fromp()->dtypep()->skipRefp(), ClassRefDType)->classp();
|
if (!classRefp || !classRefp->classp()) return;
|
||||||
|
|
||||||
|
if (nodep->user1() && varRefp->varp()->isGlobalConstrained()) {
|
||||||
|
AstClass* gConsClass = classRefp->classp();
|
||||||
|
|
||||||
|
// Use class-specific processing to allow multiple object processing
|
||||||
|
if (m_processedClasses.find(gConsClass) == m_processedClasses.end()) {
|
||||||
|
|
||||||
gConsClass->foreachMember(
|
gConsClass->foreachMember(
|
||||||
[&](AstClass* const classp, AstConstraint* const constrp) {
|
[&](AstClass* const classp, AstConstraint* const constrp) {
|
||||||
|
if (!constrp) {
|
||||||
|
UINFO(9, "Null constraint found in class " << classp->name() << "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
AstConstraint* cloneConstrp = constrp->cloneTree(false);
|
AstConstraint* cloneConstrp = constrp->cloneTree(false);
|
||||||
|
if (!cloneConstrp) {
|
||||||
|
UINFO(9, "Failed to clone constraint " << constrp->name() << "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Name manipulation
|
// Name manipulation
|
||||||
nameManipulation(VN_AS(nodep->fromp(), VarRef), cloneConstrp);
|
nameManipulation(varRefp, cloneConstrp);
|
||||||
m_clonedConstraints.push_back(cloneConstrp);
|
m_clonedConstraints.push_back(cloneConstrp);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mark this class as processed
|
||||||
|
m_processedClasses.insert(gConsClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_globalConsProcessed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstNodeModule* nodep) override {
|
void visit(AstNodeModule* nodep) override {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue