refine the code and improve the branch coverage

This commit is contained in:
Yilou Wang 2025-10-22 22:15:06 +02:00
parent 514a1c6050
commit 8a85bf6c81
2 changed files with 35 additions and 35 deletions

View File

@ -2122,7 +2122,8 @@ 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 setGlobalConstrained(bool flag) { m_globalConstrained = flag; } void globalConstrained(bool flag) { m_globalConstrained = flag; }
bool globalConstrained() const { return m_globalConstrained; }
// 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; }
@ -2187,7 +2188,6 @@ public:
bool isTrace() const { return m_trace; } bool isTrace() const { return m_trace; }
bool isRand() const { return m_rand.isRand(); } bool isRand() const { return m_rand.isRand(); }
bool isRandC() const { return m_rand.isRandC(); } bool isRandC() const { return m_rand.isRandC(); }
bool isGlobalConstrained() const { return m_globalConstrained; }
bool isConst() const VL_MT_SAFE { return m_isConst; } bool isConst() const VL_MT_SAFE { return m_isConst; }
bool isStatic() const VL_MT_SAFE { return m_isStatic; } bool isStatic() const VL_MT_SAFE { return m_isStatic; }
bool isLatched() const { return m_isLatched; } bool isLatched() const { return m_isLatched; }

View File

@ -209,18 +209,18 @@ class RandomizeMarkVisitor final : public VNVisitor {
} }
// Mark nested MemberSel chain variables as globally constrained // Mark nested MemberSel chain variables as globally constrained
void markNestedGlobalConstrainedRecurse(AstNode* nodep) { void markNestedGlobalConstrainedRecurse(AstNode* nodep) {
if (!nodep) return; UASSERT(nodep, "Node should not be null");
if (VN_IS(nodep, VarRef)) { if (VN_IS(nodep, VarRef)) {
AstVar* const varp = VN_AS(nodep, VarRef)->varp(); AstVar* const varp = VN_AS(nodep, VarRef)->varp();
if (varp->isGlobalConstrained()) return; if (varp->globalConstrained()) return;
varp->setGlobalConstrained(true); varp->globalConstrained(true);
} else if (VN_IS(nodep, MemberSel)) { } else if (VN_IS(nodep, MemberSel)) {
AstMemberSel* const memberSelp = VN_AS(nodep, MemberSel); AstMemberSel* const memberSelp = VN_AS(nodep, MemberSel);
if (memberSelp->varp()) { if (memberSelp->varp()) {
AstVar* const varp = memberSelp->varp(); AstVar* const varp = memberSelp->varp();
if (varp->isGlobalConstrained()) return; if (varp->globalConstrained()) return;
varp->setGlobalConstrained(true); varp->globalConstrained(true);
} }
markNestedGlobalConstrainedRecurse(memberSelp->fromp()); markNestedGlobalConstrainedRecurse(memberSelp->fromp());
} }
@ -241,7 +241,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
// Process a single constraint during nested constraint cloning // Process a single constraint during nested constraint cloning
void processNestedConstraint(AstConstraint* const constrp, AstVarRef* rootVarRefp, void processNestedConstraint(AstConstraint* const constrp, AstVarRef* rootVarRefp,
const std::vector<AstVar*>& newPath) { const std::vector<AstVar*>& newPath) {
if (!constrp) return; UASSERT(constrp, "Constraint should not be null");
AstConstraint* const cloneConstrp = constrp->cloneTree(false); AstConstraint* const cloneConstrp = constrp->cloneTree(false);
@ -271,26 +271,25 @@ class RandomizeMarkVisitor final : public VNVisitor {
if (!classp) return; if (!classp) return;
for (AstNode* memberNodep = classp->membersp(); memberNodep; for (AstNode* memberNodep = classp->membersp(); memberNodep;
memberNodep = memberNodep->nextp()) { memberNodep = memberNodep->nextp()) {
if (AstVar* memberVarp = VN_CAST(memberNodep, Var)) { AstVar* const memberVarp = VN_CAST(memberNodep, Var);
if (memberVarp->rand().isRandomizable()) { if (!memberVarp) continue;
const AstClassRefDType* memberClassRefp if (!memberVarp->rand().isRandomizable()) continue;
= VN_CAST(memberVarp->dtypep()->skipRefp(), ClassRefDType); const AstClassRefDType* const memberClassRefp
if (memberClassRefp && memberClassRefp->classp()) { = VN_CAST(memberVarp->dtypep()->skipRefp(), ClassRefDType);
AstClass* nestedClassp = memberClassRefp->classp(); if (!memberClassRefp || !memberClassRefp->classp()) continue;
std::vector<AstVar*> newPath = pathToClass; AstClass* nestedClassp = memberClassRefp->classp();
newPath.push_back(memberVarp);
// Replace all variable references inside the cloned constraint with proper
// member selections
nestedClassp->foreachMember(
[&](AstClass* const containingClassp, AstConstraint* const constrp) {
processNestedConstraint(constrp, rootVarRefp, newPath);
});
cloneNestedConstraintsRecurse(rootVarRefp, nestedClassp, newPath); std::vector<AstVar*> newPath = pathToClass;
} newPath.push_back(memberVarp);
} // Replace all variable references inside the cloned constraint with proper
} // member selections
nestedClassp->foreachMember(
[&](AstClass* const containingClassp, AstConstraint* const constrp) {
processNestedConstraint(constrp, rootVarRefp, newPath);
});
cloneNestedConstraintsRecurse(rootVarRefp, nestedClassp, newPath);
} }
} }
@ -300,7 +299,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
} }
void nameManipulation(AstVarRef* fromp, AstConstraint* cloneCons) { void nameManipulation(AstVarRef* fromp, AstConstraint* cloneCons) {
if (!fromp || !cloneCons) return; UASSERT(fromp && cloneCons, "Parameters should not be null");
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) {
UASSERT(varRefp && varRefp->varp(), "VarRef should be valid in constraint"); UASSERT(varRefp && varRefp->varp(), "VarRef should be valid in constraint");
@ -321,7 +320,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
// Clear processed variables for each new class context // Clear processed variables for each new class context
m_processedVars.clear(); m_processedVars.clear();
iterateChildrenConst(nodep); iterateChildrenConst(nodep);
for (AstConstraint* constrp : m_clonedConstraints) { m_classp->addStmtsp(constrp); } for (AstConstraint* const constrp : m_clonedConstraints) m_classp->addStmtsp(constrp);
m_clonedConstraints.clear(); m_clonedConstraints.clear();
if (nodep->extendsp()) { if (nodep->extendsp()) {
// Save pointer to derived class // Save pointer to derived class
@ -596,8 +595,9 @@ class RandomizeMarkVisitor final : public VNVisitor {
} }
backp = backp->backp(); backp = backp->backp();
} }
} else } else {
nodep->user2p(m_modp); nodep->user2p(m_modp);
}
if (randObject && nodep->varp() if (randObject && nodep->varp()
&& nodep->varp()->rand().isRandomizable()) { // Process global constraints && nodep->varp()->rand().isRandomizable()) { // Process global constraints
if (m_classp && m_classp->user1() == IS_RANDOMIZED) { if (m_classp && m_classp->user1() == IS_RANDOMIZED) {
@ -624,7 +624,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
= VN_CAST(varRefp->dtypep()->skipRefp(), ClassRefDType); = VN_CAST(varRefp->dtypep()->skipRefp(), ClassRefDType);
if (!classRefp || !classRefp->classp()) return; if (!classRefp || !classRefp->classp()) return;
if (nodep->user1() && varRefp->varp()->isGlobalConstrained()) { if (nodep->user1() && varRefp->varp()->globalConstrained()) {
AstClass* gConsClass = classRefp->classp(); AstClass* gConsClass = classRefp->classp();
AstVar* const objVar = varRefp->varp(); // The object variable (e.g., obj1, obj2) AstVar* const objVar = varRefp->varp(); // The object variable (e.g., obj1, obj2)
@ -849,7 +849,7 @@ class ConstraintExprVisitor final : public VNVisitor {
} }
// Check if this variable is marked as globally constrained // Check if this variable is marked as globally constrained
bool isGlobalConstrained = nodep->varp()->isGlobalConstrained(); bool isGlobalConstrained = nodep->varp()->globalConstrained();
AstMemberSel* membersel = nullptr; AstMemberSel* membersel = nullptr;
std::string smtName; std::string smtName;
@ -893,7 +893,7 @@ class ConstraintExprVisitor final : public VNVisitor {
// For global constraints: always call write_var with full path even if varp->user3() is // For global constraints: always call write_var with full path even if varp->user3() is
// set For normal constraints: only call write_var if varp->user3() is not set // set For normal constraints: only call write_var if varp->user3() is not set
if (!varp->user3() || (membersel && nodep->varp()->isGlobalConstrained())) { if (!varp->user3() || (membersel && nodep->varp()->globalConstrained())) {
// For global constraints, delete nodep here after processing // For global constraints, delete nodep here after processing
if (membersel && isGlobalConstrained) { VL_DO_DANGLING(pushDeletep(nodep), nodep); } if (membersel && isGlobalConstrained) { VL_DO_DANGLING(pushDeletep(nodep), nodep); }
AstCMethodHard* const methodp = new AstCMethodHard{ AstCMethodHard* const methodp = new AstCMethodHard{
@ -1150,7 +1150,7 @@ class ConstraintExprVisitor final : public VNVisitor {
// Check if the root variable participates in global constraints // Check if the root variable participates in global constraints
AstVar* const constrainedVar AstVar* const constrainedVar
= VN_IS(rootNode, VarRef) ? VN_AS(rootNode, VarRef)->varp() : nullptr; = VN_IS(rootNode, VarRef) ? VN_AS(rootNode, VarRef)->varp() : nullptr;
if (constrainedVar && constrainedVar->isGlobalConstrained()) { if (constrainedVar && constrainedVar->globalConstrained()) {
// Global constraint - unwrap the MemberSel // Global constraint - unwrap the MemberSel
iterateChildren(nodep); iterateChildren(nodep);
nodep->replaceWith(nodep->fromp()->unlinkFrBack()); nodep->replaceWith(nodep->fromp()->unlinkFrBack());
@ -2177,12 +2177,12 @@ class RandomizeVisitor final : public VNVisitor {
return; return;
} }
AstFunc* const memberFuncp AstFunc* const memberFuncp
= memberVarp->isGlobalConstrained() = memberVarp->globalConstrained()
? V3Randomize::newRandomizeFunc(m_memberMap, classRefp->classp(), ? V3Randomize::newRandomizeFunc(m_memberMap, classRefp->classp(),
BASIC_RANDOMIZE_FUNC_NAME) BASIC_RANDOMIZE_FUNC_NAME)
: V3Randomize::newRandomizeFunc(m_memberMap, classRefp->classp()); : V3Randomize::newRandomizeFunc(m_memberMap, classRefp->classp());
AstMethodCall* const callp AstMethodCall* const callp
= memberVarp->isGlobalConstrained() = memberVarp->globalConstrained()
? new AstMethodCall{fl, ? new AstMethodCall{fl,
new AstVarRef{fl, classp, memberVarp, new AstVarRef{fl, classp, memberVarp,
VAccess::WRITE}, VAccess::WRITE},