try to improve the coverage

This commit is contained in:
Yilou Wang 2025-10-22 16:29:30 +02:00
parent 3f017b4d8c
commit 3dddb90fc5
2 changed files with 28 additions and 19 deletions

View File

@ -245,8 +245,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
const std::vector<AstVar*>& newPath) {
if (!constrp) return;
AstConstraint* cloneConstrp = constrp->cloneTree(false);
if (!cloneConstrp) return;
AstConstraint* const cloneConstrp = constrp->cloneTree(false);
std::string pathPrefix = rootVarRefp->name();
for (AstVar* pathMemberVarp : newPath) {
@ -255,7 +254,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
cloneConstrp->name(pathPrefix + GLOBAL_CONSTRAINT_SEPARATOR + cloneConstrp->name());
cloneConstrp->foreach([&](AstVarRef* varRefp) {
if (!varRefp || !varRefp->varp()) return;
UASSERT(varRefp && varRefp->varp(), "VarRef should be valid in constraint");
AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath);
AstMemberSel* const finalSelp
@ -306,9 +305,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
if (!fromp || !cloneCons) return;
cloneCons->name(fromp->name() + GLOBAL_CONSTRAINT_SEPARATOR + cloneCons->name());
cloneCons->foreach([&](AstVarRef* varRefp) {
if (!varRefp || !varRefp->varp()) return;
UASSERT(varRefp && varRefp->varp(), "VarRef should be valid in constraint");
AstVarRef* const clonedFromp = fromp->cloneTree(false);
if (!clonedFromp) return;
AstMemberSel* const varMemberp
= new AstMemberSel{cloneCons->fileline(), clonedFromp, varRefp->varp()};
varMemberp->user2p(m_classp);
@ -641,8 +639,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
gConsClass->foreachMember(
[&](AstClass* const classp, AstConstraint* const constrp) {
if (!constrp) return;
AstConstraint* cloneConstrp = constrp->cloneTree(false);
if (!cloneConstrp) return;
AstConstraint* const cloneConstrp = constrp->cloneTree(false);
// Name manipulation
nameManipulation(varRefp, cloneConstrp);
m_clonedConstraints.push_back(cloneConstrp);
@ -726,10 +723,9 @@ class ConstraintExprVisitor final : public VNVisitor {
} else if (VN_IS(fromp, MemberSel)) {
// Recursive case: build path from outer levels
return buildMemberPath(VN_AS(fromp, MemberSel)) + "." + memberSelp->name();
} else {
// Fallback: just return member name
return memberSelp->name();
}
memberSelp->v3fatalSrc("Unexpected node type in MemberSel chain");
return "";
}
AstSFormatF* getConstFormat(AstNodeExpr* nodep) {
@ -869,10 +865,6 @@ class ConstraintExprVisitor final : public VNVisitor {
}
membersel = VN_AS(topMemberSel, MemberSel)->cloneTree(false);
smtName = buildMemberPath(membersel);
} else if (VN_IS(nodep->backp(), MemberSel)) {
// Normal case: simple one-level MemberSel
membersel = VN_AS(nodep->backp(), MemberSel)->cloneTree(false);
smtName = membersel->fromp()->name() + "." + membersel->name();
} else {
// No MemberSel: just variable name
smtName = nodep->name();
@ -1156,16 +1148,13 @@ class ConstraintExprVisitor final : public VNVisitor {
// Traverse MemberSel chain to find the root variable reference
AstNode* rootNode = nodep->fromp();
while (VN_IS(rootNode, MemberSel) && !VN_IS(rootNode, NodeVarRef)) {
while (VN_IS(rootNode, MemberSel)) {
rootNode = VN_AS(rootNode, MemberSel)->fromp();
}
// Check if the root variable participates in global constraints
AstVar* const constrainedVar
= VN_IS(rootNode, VarRef)
? VN_AS(rootNode, VarRef)->varp()
: (VN_IS(rootNode, MemberSel) ? VN_AS(rootNode, MemberSel)->varp()
: nullptr);
= VN_IS(rootNode, VarRef) ? VN_AS(rootNode, VarRef)->varp() : nullptr;
if (constrainedVar && constrainedVar->isGlobalConstrained()) {
// Global constraint - unwrap the MemberSel
iterateChildren(nodep);

View File

@ -46,6 +46,8 @@ module t_constraint_global_random;
initial begin
t = new();
// Test 1: Regular randomize() with global constraints
success = t.randomize();
if (success != 1) $stop;
@ -59,6 +61,24 @@ module t_constraint_global_random;
if (t.m1.inner.val < 1 || t.m1.inner.val > 5 ||
t.m2.inner.val < 1 || t.m2.inner.val > 5) $stop;
// Test 2: randomize() with inline constraint on global-constrained members
success = 0;
success = t.randomize() with {
m1.inner.val == 2;
m2.inner.val == 5;
};
if (success != 1) $stop;
// Verify inline constraints
if (t.m1.inner.val != 2) $stop;
if (t.m2.inner.val != 5) $stop;
// Verify global constraints still hold
if (t.m1.x != 3 || t.m2.x != 5) $stop;
if (t.m1.inner.val >= t.m2.inner.val) $stop;
if (t.y <= t.m1.x || t.y >= t.m2.x) $stop;
if (t.m1.inner.val + t.m2.inner.val >= 8) $stop;
$write("*-* All Finished *-*\n");
$finish;
end