address review: brace, exist, dtype and test
This commit is contained in:
parent
a551b9b693
commit
50c1059374
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue