follow comments and refine

This commit is contained in:
Yilou Wang 2026-03-02 23:10:36 +01:00
parent 69b485012f
commit ec027b5fa3
4 changed files with 40 additions and 13 deletions

View File

@ -3534,7 +3534,14 @@ class RandomizeVisitor final : public VNVisitor {
buckets.push_back({ditemp->rangep(), weightExprp});
}
if (buckets.empty()) continue;
if (buckets.empty()) {
// All weights are zero: dist is vacuously true (unconstrained)
AstConstraintExpr* const truep
= new AstConstraintExpr{fl, new AstConst{fl, AstConst::BitTrue{}}};
constrExprp->replaceWith(truep);
VL_DO_DANGLING(pushDeletep(constrExprp), constrExprp);
continue;
}
// Build totalWeight expression: w[0] + w[1] + ... + w[N-1]
AstNodeExpr* totalWeightExprp = nullptr;
@ -3556,6 +3563,7 @@ class RandomizeVisitor final : public VNVisitor {
totalVarp->noSubst(true);
totalVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
totalVarp->funcLocal(true);
totalVarp->isInternal(true);
taskp->addStmtsp(totalVarp);
taskp->addStmtsp(
new AstAssign{fl, new AstVarRef{fl, totalVarp, VAccess::WRITE}, totalWeightExprp});
@ -3567,6 +3575,7 @@ class RandomizeVisitor final : public VNVisitor {
bucketVarp->noSubst(true);
bucketVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
bucketVarp->funcLocal(true);
bucketVarp->isInternal(true);
taskp->addStmtsp(bucketVarp);
AstNodeExpr* randp = new AstRand{fl, nullptr, false};
@ -3629,16 +3638,16 @@ class RandomizeVisitor final : public VNVisitor {
if (chainp) {
constrExprp->replaceWith(chainp);
VL_DO_DANGLING(constrExprp->deleteTree(), constrExprp);
VL_DO_DANGLING(pushDeletep(constrExprp), constrExprp);
}
// Clean up nodes used only as clone templates (never inserted into tree)
for (auto& bucket : buckets) {
VL_DO_DANGLING(bucket.weightExprp->deleteTree(), bucket.weightExprp);
VL_DO_DANGLING(pushDeletep(bucket.weightExprp), bucket.weightExprp);
}
VL_DO_DANGLING(runningSump->deleteTree(), runningSump);
VL_DO_DANGLING(pushDeletep(runningSump), runningSump);
// Last cumSum is unused (last bucket is unconditional default)
VL_DO_DANGLING(cumSums.back()->deleteTree(), cumSums.back());
pushDeletep(cumSums.back());
}
}
@ -3658,6 +3667,7 @@ class RandomizeVisitor final : public VNVisitor {
void visit(AstClass* nodep) override {
VL_RESTORER(m_modp);
VL_RESTORER(m_randCaseNum);
VL_RESTORER(m_distNum);
m_modp = nodep;
m_randCaseNum = 0;
m_distNum = 0;

View File

@ -25,6 +25,11 @@ class DistZeroWeight;
constraint c { x dist { 8'd0 := 0, 8'd1 := 1, 8'd2 := 1 }; }
endclass
class DistAllZeroWeight;
rand bit [7:0] x;
constraint c { x dist { 8'd0 := 0, 8'd1 := 0, 8'd2 := 0 }; }
endclass
class DistVarWeight;
rand bit [7:0] x;
int w1, w2;
@ -42,6 +47,7 @@ module t;
DistScalar sc;
DistRange rg;
DistZeroWeight zw;
DistAllZeroWeight azw;
DistVarWeight vw;
DistVarWeightRange vwr;
int count_high;
@ -58,7 +64,7 @@ module t;
if (sc.x == 8'd255) count_high++;
else `checkd(sc.x, 0);
end
`check_range(count_high, 1200, 1800);
`check_range(count_high, total * 60 / 100, total * 90 / 100);
// :/ range weights: expect ~75% in [10:19]
rg = new;
@ -71,7 +77,7 @@ module t;
`stop;
end
end
`check_range(count_range_high, 1200, 1800);
`check_range(count_range_high, total * 60 / 100, total * 90 / 100);
// Zero weight: value 0 must never appear
zw = new;
@ -84,6 +90,12 @@ module t;
`check_range(zw.x, 1, 2);
end
// All-zero weights: dist constraint is effectively unconstrained, randomize succeeds
azw = new;
repeat (20) begin
`checkd(azw.randomize(), 1);
end
// Variable := scalar weights: w1=1, w2=3 => expect ~75% for value 255
vw = new;
vw.w1 = 1;
@ -94,7 +106,7 @@ module t;
if (vw.x == 8'd255) count_high++;
else `checkd(vw.x, 0);
end
`check_range(count_high, 1200, 1800);
`check_range(count_high, total * 60 / 100, total * 90 / 100);
// Variable :/ range weights: w1=1, w2=3 => expect ~75% in [10:19]
vwr = new;
@ -109,7 +121,7 @@ module t;
`stop;
end
end
`check_range(count_range_high, 1200, 1800);
`check_range(count_range_high, total * 60 / 100, total * 90 / 100);
$write("*-* All Finished *-*\n");
$finish;

View File

@ -9,8 +9,13 @@
import vltest_bootstrap
test.scenarios('vlt')
test.scenarios('simulator')
test.lint()
if not test.have_solver:
test.skip("No constraint solver installed")
test.compile()
test.execute()
test.passes()

View File

@ -11,7 +11,7 @@ class Packet;
rand bit if_4;
rand bit iff_5_6;
/*rand*/ int array[2]; // 2,4,6 // TODO: add rand when supported
rand int array[2]; // 2,4,6
constraint empty {}
@ -58,7 +58,7 @@ module t;
automatic int v;
automatic bit if_4 = '0;
// TODO not testing constrained values
p = new;
v = p.randomize();
if (v != 1) $stop;
v = p.randomize() with {};