fix format problem and simplify comments
This commit is contained in:
parent
e3c597f84d
commit
7bffe11b1d
|
|
@ -2169,8 +2169,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Expand AstConstraintUnique with element-list items into pairwise != constraints.
|
// Expand unique{a,b,c} with explicit elements into pairwise != constraints.
|
||||||
// Whole-array VarRef unique constraints are left untouched for ConstraintExprVisitor.
|
// Whole-array unique{arr} is left for ConstraintExprVisitor's rand_unique handling.
|
||||||
static void expandUniqueElementList(AstNode* itemsp) {
|
static void expandUniqueElementList(AstNode* itemsp) {
|
||||||
AstNode* itemp = itemsp;
|
AstNode* itemp = itemsp;
|
||||||
while (itemp) {
|
while (itemp) {
|
||||||
|
|
@ -2181,14 +2181,13 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect non-array-VarRef items
|
|
||||||
std::vector<AstNodeExpr*> exprItems;
|
std::vector<AstNodeExpr*> exprItems;
|
||||||
bool hasArrayVarRef = false;
|
bool hasArrayVarRef = false;
|
||||||
for (AstNode* rp = uniquep->rangesp(); rp; rp = rp->nextp()) {
|
for (AstNode* rp = uniquep->rangesp(); rp; rp = rp->nextp()) {
|
||||||
if (AstVarRef* const vrp = VN_CAST(rp, VarRef)) {
|
if (AstVarRef* const vrp = VN_CAST(rp, VarRef)) {
|
||||||
if (VN_IS(vrp->varp()->dtypep()->skipRefp(), UnpackArrayDType)) {
|
if (VN_IS(vrp->varp()->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||||
hasArrayVarRef = true;
|
hasArrayVarRef = true;
|
||||||
continue; // Skip whole-array items
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exprItems.push_back(VN_AS(rp, NodeExpr));
|
exprItems.push_back(VN_AS(rp, NodeExpr));
|
||||||
|
|
@ -2201,17 +2200,15 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
AstNodeExpr* const lhsp = exprItems[i]->cloneTree(false);
|
AstNodeExpr* const lhsp = exprItems[i]->cloneTree(false);
|
||||||
AstNodeExpr* const rhsp = exprItems[j]->cloneTree(false);
|
AstNodeExpr* const rhsp = exprItems[j]->cloneTree(false);
|
||||||
AstNeq* const neqp = new AstNeq{fl, lhsp, rhsp};
|
AstNeq* const neqp = new AstNeq{fl, lhsp, rhsp};
|
||||||
neqp->user1(true); // Mark as depending on rand variable
|
neqp->user1(true);
|
||||||
AstConstraintExpr* const cexprp = new AstConstraintExpr{fl, neqp};
|
AstConstraintExpr* const cexprp = new AstConstraintExpr{fl, neqp};
|
||||||
uniquep->addNextHere(cexprp);
|
uniquep->addNextHere(cexprp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasArrayVarRef) {
|
if (!hasArrayVarRef) {
|
||||||
// All items expanded — remove the AstConstraintUnique
|
|
||||||
uniquep->unlinkFrBack();
|
uniquep->unlinkFrBack();
|
||||||
VL_DO_DANGLING(uniquep->deleteTree(), uniquep);
|
VL_DO_DANGLING(uniquep->deleteTree(), uniquep);
|
||||||
}
|
}
|
||||||
// If hasArrayVarRef: keep AstConstraintUnique for whole-array handling
|
|
||||||
}
|
}
|
||||||
itemp = nextp;
|
itemp = nextp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,13 @@
|
||||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||||
// verilog_format: on
|
// verilog_format: on
|
||||||
|
|
||||||
// Test: unique constraint on explicit array element subset
|
// Test unique constraint on explicit array element subsets (IEEE 18.5.9).
|
||||||
// IEEE 1800-2017 Section 18.5.9
|
// bit [3:0] keeps the value space small so collisions are near-certain
|
||||||
//
|
// without proper constraint enforcement.
|
||||||
// Uses bit [3:0] (16 possible values) with 5-element unique subsets
|
|
||||||
// so that without proper constraint enforcement, collisions are
|
|
||||||
// virtually guaranteed across 20 iterations.
|
|
||||||
|
|
||||||
class UniqueElemSubset;
|
class UniqueElemSubset;
|
||||||
rand bit [3:0] arr[10];
|
rand bit [3:0] arr[10];
|
||||||
|
|
||||||
// Unique applied to a subset of array indices
|
|
||||||
constraint unique_subset_con {
|
constraint unique_subset_con {
|
||||||
unique { arr[2], arr[3], arr[4], arr[5], arr[6] };
|
unique { arr[2], arr[3], arr[4], arr[5], arr[6] };
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +34,6 @@ endclass
|
||||||
class UniqueElemFour;
|
class UniqueElemFour;
|
||||||
rand bit [3:0] data[8];
|
rand bit [3:0] data[8];
|
||||||
|
|
||||||
// Unique on 4 explicit elements
|
|
||||||
constraint unique_data_con {
|
constraint unique_data_con {
|
||||||
unique { data[1], data[2], data[3], data[4] };
|
unique { data[1], data[2], data[3], data[4] };
|
||||||
}
|
}
|
||||||
|
|
@ -59,14 +54,12 @@ module t;
|
||||||
UniqueElemFour uef;
|
UniqueElemFour uef;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// Test 1: unique on 5 explicit array elements
|
|
||||||
ues = new();
|
ues = new();
|
||||||
repeat (20) begin
|
repeat (20) begin
|
||||||
`checkd(ues.randomize(), 1)
|
`checkd(ues.randomize(), 1)
|
||||||
`checkd(ues.check_unique(), 1)
|
`checkd(ues.check_unique(), 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
// Test 2: unique on 4 explicit array elements
|
|
||||||
uef = new();
|
uef = new();
|
||||||
repeat (20) begin
|
repeat (20) begin
|
||||||
`checkd(uef.randomize(), 1)
|
`checkd(uef.randomize(), 1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue