Tests: Check dist bucket draw is per-element in foreach (#8023)

This commit is contained in:
BRDR LIFE 2026-08-01 13:07:55 -04:00 committed by GitHub
parent 7e116ca601
commit a3e7f5103d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 51 additions and 6 deletions

View File

@ -6,10 +6,19 @@
// Test that dist constraints nested inside if / -> inside foreach produce
// values only within the declared distribution and cover all buckets.
//
// The bucket draw must also be made PER ELEMENT, not once per solve and then
// shared by every element. Counting buckets across all solves cannot tell those
// apart: a single hoisted draw still hits both buckets over 100 solves, it just
// never mixes them inside one solve. So each block also counts solves in which
// at least one element landed in each bucket. With dist {0 := 3, [1:4] := 1}
// over 4 elements a per-element draw mixes in about 86 of 100 solves, whereas a
// hoisted draw can never mix and gives exactly 0.
// verilog_format: off
`define stop $stop
`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 check_mixed(what,gotv) do if ((gotv) == 0) begin $write("%%Error: %s:%0d: dist inside foreach+%s: bucket draw is not per-element, no solve mixed buckets\n", `__FILE__,`__LINE__, what); `stop; end while(0);
// verilog_format: on
// foreach (a[i]) if (gate) a[i] dist {...}
@ -64,10 +73,14 @@ module t;
begin
static ClsIf obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
obj.gate = 1'b1;
seen_zero = 0;
seen_nonzero = 0;
mixed = 0;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
@ -75,9 +88,16 @@ module t;
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
else seen_nonzero++;
if (obj.a[i] == 0) begin
seen_zero++;
this_zero++;
end
else begin
seen_nonzero++;
this_nonzero++;
end
end
if (this_zero > 0 && this_nonzero > 0) mixed++;
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write(
@ -85,16 +105,21 @@ module t;
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
`check_mixed("if", mixed)
end
// Test -> (implication) form
begin
static ClsImpl obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
obj.gate = 1'b1;
seen_zero = 0;
seen_nonzero = 0;
mixed = 0;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
@ -102,9 +127,16 @@ module t;
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
else seen_nonzero++;
if (obj.a[i] == 0) begin
seen_zero++;
this_zero++;
end
else begin
seen_nonzero++;
this_nonzero++;
end
end
if (this_zero > 0 && this_nonzero > 0) mixed++;
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write(
@ -112,17 +144,22 @@ module t;
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
`check_mixed("->", mixed)
end
// Test doubly-nested -> (chained implication) form
begin
static ClsImplChained obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
obj.gateA = 1'b1;
obj.gateB = 1'b1;
seen_zero = 0;
seen_nonzero = 0;
mixed = 0;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
@ -130,9 +167,16 @@ module t;
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
else seen_nonzero++;
if (obj.a[i] == 0) begin
seen_zero++;
this_zero++;
end
else begin
seen_nonzero++;
this_nonzero++;
end
end
if (this_zero > 0 && this_nonzero > 0) mixed++;
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write(
@ -140,6 +184,7 @@ module t;
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
`check_mixed("->->", mixed)
end
$write("*-* All Finished *-*\n");