address review: brace, exist, dtype and test

This commit is contained in:
Yilou Wang 2026-07-13 22:35:37 +02:00
parent a551b9b693
commit 50c1059374
2 changed files with 109 additions and 32 deletions

View File

@ -4488,10 +4488,8 @@ class RandomizeVisitor final : public VNVisitor {
new AstSub{fl,
new AstExtend{fl, irp->rhsp()->cloneTreePure(false), 64},
new AstExtend{fl, irp->lhsp()->cloneTreePure(false), 64}}};
rangeSizep->dtypeSetUInt64();
}
weightExprp = new AstMul{fl, weightExprp, rangeSizep};
weightExprp->dtypeSetUInt64();
}
}
buckets.push_back({ditemp->rangep(), weightExprp});
@ -4534,8 +4532,9 @@ class RandomizeVisitor final : public VNVisitor {
// Membership test for one bucket: a range comparison or an equality.
static AstNodeExpr* newDistMembershipTerm(AstDist* distp, AstNodeExpr* rangep) {
if (const AstInsideRange* const irp = VN_CAST(rangep, InsideRange))
if (const AstInsideRange* const irp = VN_CAST(rangep, InsideRange)) {
return newDistRangeMembership(distp, irp);
}
FileLine* const fl = distp->fileline();
AstNodeExpr* const eqExprp = distp->exprp()->cloneTreePure(false);
eqExprp->user1(true);
@ -4589,14 +4588,15 @@ class RandomizeVisitor final : public VNVisitor {
// Each direct, static, or sub-object member reference carries a mode bit.
distp->exprp()->foreach([&](const AstNode* nodep) {
const AstNodeVarRef* const refp = VN_CAST(nodep, NodeVarRef);
const AstMemberSel* const mselp = refp ? nullptr : VN_CAST(nodep, MemberSel);
const AstMemberSel* const mselp = VN_CAST(nodep, MemberSel);
if (!refp && !mselp) return;
AstVar* const varp = refp ? refp->varp() : mselp->varp();
const RandomizeMode rmode = {.asInt = varp->user1()};
if (!rmode.usesMode || !gatedVars.insert(varp).second) return;
if (varp->lifetime().isStatic()) {
if (AstNodeExpr* const readp = staticModeRead(varp))
if (AstNodeExpr* const readp = staticModeRead(varp)) {
addModeGate(readp, rmode.index);
}
} else if (mselp) {
AstVar* const memberModep
= getRandModeVarFromClass(VN_AS(varp->user2p(), NodeModule));
@ -4617,8 +4617,8 @@ class RandomizeVisitor final : public VNVisitor {
for (auto& bucket : buckets) {
AstNodeExpr* termp = newDistMembershipTerm(distp, bucket.rangep);
// A weight that is zero only at runtime excludes the bucket's values too.
bool runtimeWeight = false;
bucket.weightExprp->foreach([&](const AstNodeVarRef*) { runtimeWeight = true; });
const bool runtimeWeight
= bucket.weightExprp->exists([](const AstNodeVarRef*) { return true; });
if (runtimeWeight) {
AstNeq* const nzp = new AstNeq{fl, bucket.weightExprp->cloneTreePure(false),
new AstConst{fl, AstConst::Unsized64{}, 0}};
@ -4654,13 +4654,11 @@ class RandomizeVisitor final : public VNVisitor {
new AstExtendS{fl, irp->lhsp()->cloneTreePure(false), 64})
: static_cast<AstNodeExpr*>(
new AstExtend{fl, irp->lhsp()->cloneTreePure(false), 64});
lo64p->dtypeSetUInt64();
AstNodeExpr* const hi64p
= isSigned ? static_cast<AstNodeExpr*>(
new AstExtendS{fl, irp->rhsp()->cloneTreePure(false), 64})
: static_cast<AstNodeExpr*>(
new AstExtend{fl, irp->rhsp()->cloneTreePure(false), 64});
hi64p->dtypeSetUInt64();
rangeSzp = new AstAdd{fl, new AstConst{fl, AstConst::Unsized64{}, 1ULL},
new AstSub{fl, hi64p, lo64p}};
}
@ -4669,7 +4667,6 @@ class RandomizeVisitor final : public VNVisitor {
AstNodeExpr* const offsetp
= new AstCCast{fl, new AstModDiv{fl, rand64p, rangeSzp}, distWidth};
AstNodeExpr* const valuep = new AstAdd{fl, irp->lhsp()->cloneTreePure(false), offsetp};
valuep->dtypeFrom(distp->exprp());
AstNodeExpr* const eqp = new AstEq{fl, distExprCopyp, valuep};
eqp->user1(true);
return eqp;
@ -4735,10 +4732,12 @@ class RandomizeVisitor final : public VNVisitor {
// dist can appear inside an if/else or foreach constraint.
if (AstConstraintIf* const cifp = VN_CAST(itemp, ConstraintIf)) {
if (cifp->thensp())
if (cifp->thensp()) {
lowerDistConstraints(taskp, cifp->thensp(), randModeVarp, foreachp);
if (cifp->elsesp())
}
if (cifp->elsesp()) {
lowerDistConstraints(taskp, cifp->elsesp(), randModeVarp, foreachp);
}
continue;
}
if (AstConstraintForeach* const cfep = VN_CAST(itemp, ConstraintForeach)) {
@ -4940,8 +4939,9 @@ class RandomizeVisitor final : public VNVisitor {
}
if (constrp->itemsp()) expandUniqueElementList(constrp->itemsp());
if (constrp->itemsp())
if (constrp->itemsp()) {
lowerDistConstraints(taskp, constrp->itemsp(), randModeVarp);
}
std::set<AstVar*>& sizeArrays = m_sizeConstrainedArrays[classp];
ConstraintExprVisitor{classp, m_memberMap, constrp->itemsp(),
nullptr, genp, randModeVarp,

View File

@ -15,43 +15,75 @@ typedef int unsigned uint;
class Base;
rand uint delay;
rand uint x;
constraint delay_c {delay inside {[1:100]};}
constraint delay_c {delay inside {[1 : 100]};}
function int rd();
return this.randomize(delay);
endfunction
endclass
class SingleVals extends Base;
constraint c {x dist {5 := 99, 1000000 := 1};}
constraint c {
x dist {
5 := 99,
1000000 := 1
};
}
endclass
class RangeVals extends Base;
constraint c {x dist {[1:10] := 1, [1000:2000] := 9};}
constraint c {
x dist {
[1 : 10] := 1,
[1000 : 2000] := 9
};
}
endclass
class MixVals extends Base;
constraint c {x dist {0 := 1, [100:200] := 5, 9999 := 3};}
constraint c {
x dist {
0 := 1,
[100 : 200] := 5,
9999 := 3
};
}
endclass
class DistInIf extends Base;
rand uint sel;
constraint c {
sel inside {0, 1};
if (sel == 1) x dist {5 := 9, 70 := 1};
else x == 4242;
if (sel == 1)
x dist {
5 := 9,
70 := 1
};
else
x == 4242;
}
endclass
class DistInForeach;
rand uint arr[4];
constraint c {foreach (arr[i]) arr[i] dist {10 := 9, 20 := 1};}
constraint c {
foreach (arr[i])
arr[i] dist {
10 := 9,
20 := 1
};
}
endclass
class StaticVar;
rand uint delay;
static rand uint sx;
constraint delay_c {delay inside {[1:100]};}
constraint c {sx dist {5 := 9, 70 := 1};}
constraint delay_c {delay inside {[1 : 100]};}
constraint c {
sx dist {
5 := 9,
70 := 1
};
}
function int rd();
return this.randomize(delay);
endfunction
@ -60,7 +92,7 @@ endclass
class StaticPlain; // non-dist constraint on a frozen static var
rand uint d;
static rand uint sy;
constraint c {sy inside {[10:20]};}
constraint c {sy inside {[10 : 20]};}
endclass
class Sub;
@ -70,8 +102,13 @@ endclass
class Holder;
rand Sub s;
rand uint delay;
constraint delay_c {delay inside {[1:100]};}
constraint c {s.x dist {5 := 9, 70 := 1};}
constraint delay_c {delay inside {[1 : 100]};}
constraint c {
s.x dist {
5 := 9,
70 := 1
};
}
function new();
s = new;
endfunction
@ -79,17 +116,32 @@ endclass
class MultiVar;
rand uint x, y;
constraint c {(x + y) dist {10 := 9, 1000 := 1};}
constraint c {
(x + y) dist {
10 := 9,
1000 := 1
};
}
endclass
class DupVar;
rand uint x;
constraint c {(x + x) dist {10 := 9, 20 := 1};}
constraint c {
(x + x) dist {
10 := 9,
20 := 1
};
}
endclass
class DupMember;
rand Sub s;
constraint c {(s.x + s.x) dist {10 := 9, 20 := 1};}
constraint c {
(s.x + s.x) dist {
10 := 9,
20 := 1
};
}
function new();
s = new;
endfunction
@ -98,7 +150,12 @@ endclass
class RtWeight;
rand uint x;
uint w;
constraint c {x dist {5 := 9, 70 := w};}
constraint c {
x dist {
5 := 9,
70 := w
};
}
endclass
module t;
@ -124,6 +181,7 @@ module t;
ok = sv.rd();
`checkd(ok, 1);
`checkd(sv.x, 1000000);
if (sv.delay < 1 || sv.delay > 100) `checkd(sv.delay, 0);
end
// Frozen in the high-weight bucket -> succeeds.
@ -246,6 +304,25 @@ module t;
`checkd(h.s.x, 7);
end
// Both the handle and the member frozen.
h = new;
ok = h.randomize();
`checkd(ok, 1);
h.s.rand_mode(0);
h.s.x.rand_mode(0);
h.s.x = 5;
for (int i = 0; i < 8; ++i) begin
ok = h.randomize();
`checkd(ok, 1);
`checkd(h.s.x, 5);
end
h.s.x = 7;
for (int i = 0; i < 8; ++i) begin
ok = h.randomize();
`checkd(ok, 0);
`checkd(h.s.x, 7);
end
// Multi-var dist expression, one var frozen: the active var must still
// satisfy membership (sum wraps mod 2**32, so both values stay reachable).
m = new;
@ -350,7 +427,8 @@ module t;
`checkd(ok, 1);
if (di.sel == 1) begin
if (di.x != 5 && di.x != 70) `checkd(0, 1);
end else begin
end
else begin
`checkd(di.x, 4242);
end
end
@ -360,8 +438,7 @@ module t;
for (int i = 0; i < 16; ++i) begin
ok = df.randomize();
`checkd(ok, 1);
foreach (df.arr[j])
if (df.arr[j] != 10 && df.arr[j] != 20) `checkd(0, 1);
foreach (df.arr[j]) if (df.arr[j] != 10 && df.arr[j] != 20) `checkd(0, 1);
end
$write("*-* All Finished *-*\n");