Tests: Fix side-effects in checkd randomize

This commit is contained in:
Wilson Snyder 2026-08-14 20:59:19 -04:00
parent d6b206cc7d
commit 6d6d15e003
30 changed files with 349 additions and 151 deletions

View File

@ -40,25 +40,28 @@ module t;
static Derived d = new();
static GrandChild g = new();
int sum_check;
int randomize_result;
// Test single-level inheritance with .sum()
repeat (5) begin
`checkd(d.randomize(), 1)
`checkd(d.arr.size(), 4)
randomize_result = d.randomize();
`checkd(randomize_result, 1);
`checkd(d.arr.size(), 4);
sum_check = 0;
foreach (d.arr[i]) sum_check += d.arr[i];
`checkd(sum_check, 200)
`checkd(d.base_val inside {[1:100]}, 1)
`checkd(sum_check, 200);
`checkd(d.base_val inside {[1:100]}, 1);
end
// Test multi-level inheritance with reduction on fixed array
repeat (5) begin
bit [7:0] or_check;
`checkd(g.randomize(), 1)
`checkd(g.arr.size(), 4)
randomize_result = g.randomize();
`checkd(randomize_result, 1);
`checkd(g.arr.size(), 4);
sum_check = 0;
foreach (g.arr[i]) sum_check += g.arr[i];
`checkd(sum_check, 200)
`checkd(sum_check, 200);
or_check = 0;
foreach (g.extra[i]) or_check |= g.extra[i];
if (or_check == 0) begin

View File

@ -74,6 +74,7 @@ module t;
static ClsIf obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
int randomize_result;
obj.gate = 1'b1;
seen_zero = 0;
seen_nonzero = 0;
@ -81,7 +82,8 @@ module t;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: if: value out of dist range: %0d\n", `__FILE__, `__LINE__,
@ -113,6 +115,7 @@ module t;
static ClsImpl obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
int randomize_result;
obj.gate = 1'b1;
seen_zero = 0;
seen_nonzero = 0;
@ -120,7 +123,8 @@ module t;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: ->: value out of dist range: %0d\n", `__FILE__, `__LINE__,
@ -152,6 +156,7 @@ module t;
static ClsImplChained obj = new();
int seen_zero, seen_nonzero;
int this_zero, this_nonzero, mixed;
int randomize_result;
obj.gateA = 1'b1;
obj.gateB = 1'b1;
seen_zero = 0;
@ -160,7 +165,8 @@ module t;
repeat (100) begin
this_zero = 0;
this_nonzero = 0;
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: ->->: value out of dist range: %0d\n", `__FILE__, `__LINE__,

View File

@ -226,6 +226,7 @@ endclass
module t;
initial begin
int randomize_result;
// dist inside if + foreach stays in range and reaches both buckets
begin
static ClsIf obj = new();
@ -234,7 +235,8 @@ module t;
seen_zero = 0;
seen_nonzero = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[4'd0 : 4'd4]}), 1'b1);
if (obj.a[i] == 0) seen_zero++;
@ -253,7 +255,8 @@ module t;
seen_zero = 0;
seen_nonzero = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[4'd0 : 4'd4]}), 1'b1);
if (obj.a[i] == 0) seen_zero++;
@ -265,7 +268,8 @@ module t;
obj.gate = 1'b0;
seen_else = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[4'd8 : 4'd11]}), 1'b1);
seen_else++;
@ -283,7 +287,8 @@ module t;
seen_zero = 0;
seen_nonzero = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[4'd0 : 4'd4]}), 1'b1);
if (obj.a[i] == 0) seen_zero++;
@ -302,7 +307,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize() with {sel == 1'b1;}, 1);
randomize_result = obj.randomize() with {sel == 1'b1;};
`checkd(randomize_result, 1);
`checkd(obj.sel, 1'b1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[3'd0 : 3'd5]}), 1'b1);
@ -323,7 +329,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[3'd0 : 3'd5]}), 1'b1);
`checkd(obj.b[i], 3'd7);
@ -344,7 +351,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.m[i]) begin
foreach (obj.m[i][j]) begin
`checkd((obj.m[i][j] inside {[3'd0 : 3'd5]}), 1'b1);
@ -367,7 +375,8 @@ module t;
seen_mixed = 0;
repeat (100) begin
int seen_lo, seen_hi;
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
seen_lo = 0;
seen_hi = 0;
foreach (obj.a[i]) begin
@ -388,7 +397,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`checkd(obj.q.size(), 4);
foreach (obj.q[i]) begin
`checkd((obj.q[i] inside {[3'd0 : 3'd5]}), 1'b1);
@ -409,7 +419,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`checkd(obj.d.size(), 4);
foreach (obj.d[i]) begin
`checkd((obj.d[i] inside {[3'd0 : 3'd5]}), 1'b1);
@ -432,7 +443,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[3'd0 : 3'd5]}), 1'b1);
if (obj.a[i] <= 1) seen_low++;
@ -452,7 +464,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.m[i]) begin
foreach (obj.m[i][j]) begin
`checkd((obj.m[i][j] inside {[3'd0 : 3'd5]}), 1'b1);
@ -475,7 +488,8 @@ module t;
seen_low = 0;
seen_high = 0;
repeat (100) begin
`checkd(obj.randomize(), 1);
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
`checkd((obj.a[i] inside {[3'd0 : 3'd5]}), 1'b1);
if (obj.a[i] <= 1) seen_low++;

View File

@ -122,12 +122,14 @@ module t;
automatic VarItems vi = new;
automatic RandItems ri = new;
automatic ColonEqItems ce = new;
int randomize_result;
nlo = 0;
nmid = 0;
nhi = 0;
for (int i = 0; i < `N; i++) begin
`checkd(li.randomize(), 1)
randomize_result = li.randomize();
`checkd(randomize_result, 1);
tally(li.x);
end
`check_hist
@ -136,7 +138,8 @@ module t;
nmid = 0;
nhi = 0;
for (int i = 0; i < `N; i++) begin
`checkd(vb.randomize(), 1)
randomize_result = vb.randomize();
`checkd(randomize_result, 1);
tally(vb.x);
end
`check_hist
@ -145,7 +148,8 @@ module t;
nmid = 0;
nhi = 0;
for (int i = 0; i < `N; i++) begin
`checkd(vi.randomize(), 1)
randomize_result = vi.randomize();
`checkd(randomize_result, 1);
tally(vi.x);
end
`check_hist
@ -153,7 +157,8 @@ module t;
neqy = 0;
nnine = 0;
for (int i = 0; i < `N; i++) begin
`checkd(ri.randomize(), 1)
randomize_result = ri.randomize();
`checkd(randomize_result, 1);
if (ri.x == 9) nnine++;
else if (ri.x == ri.y) neqy++;
else `stop;
@ -163,7 +168,8 @@ module t;
nten = 0;
for (int i = 0; i < `N; i++) begin
`checkd(ce.randomize(), 1)
randomize_result = ce.randomize();
`checkd(randomize_result, 1);
// x is bit [3:0], so only the upper bound can fail
if (ce.x > 10) `stop;
if (ce.x == 10) nten++;

View File

@ -81,6 +81,7 @@ module t;
parameter int TOL_PCT = 30; // +-% tolerance on expected counts
initial begin
int randomize_result;
// --- T1: scalar uniform [0:9] ---
// 10 values, expected N/10 each
@ -89,7 +90,8 @@ module t;
int cnt[10];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
if (obj.x > 4'd9) begin
$write("%%Error: x=%0d outside valid range [0:9]\n", obj.x);
`stop;
@ -106,7 +108,8 @@ module t;
int cnt[5];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
if (obj.a[i] > 3'd4) begin
$write("%%Error: a[%0d]=%0d outside valid range [0:4]\n", i, obj.a[i]);
@ -127,7 +130,8 @@ module t;
int cnt[10];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
foreach (obj.a[i]) begin
if (obj.a[i] > 4'd9) begin
$write("%%Error: a[%0d]=%0d outside valid range [0:9]\n", i, obj.a[i]);
@ -148,7 +152,8 @@ module t;
int cnt[10];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
if (obj.x < -9 || obj.x > 0) begin
$write("%%Error: x=%0d outside valid range [-9:0]\n", obj.x);
`stop;
@ -165,7 +170,8 @@ module t;
int cnt[16];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
if (obj.x < 4'd2 || obj.x > 4'd7) begin
$write("%%Error: x=%0d outside valid range [2:7]\n", obj.x);
`stop;
@ -182,7 +188,8 @@ module t;
int cnt[16];
foreach (cnt[v]) cnt[v] = 0;
repeat (N) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
if (obj.x < 4'd1 || obj.x > 4'd7) begin
$write("%%Error: x=%0d outside valid range [1:7]\n", obj.x);
`stop;

View File

@ -53,6 +53,7 @@ module t;
int count_high;
int count_range_high;
int total;
int randomize_result;
total = 2000;
@ -60,7 +61,8 @@ module t;
sc = new;
count_high = 0;
repeat (total) begin
`checkd(sc.randomize(), 1);
randomize_result = sc.randomize();
`checkd(randomize_result, 1);
if (sc.x == 8'd255) count_high++;
else `checkd(sc.x, 0);
end
@ -70,7 +72,8 @@ module t;
rg = new;
count_range_high = 0;
repeat (total) begin
`checkd(rg.randomize(), 1);
randomize_result = rg.randomize();
`checkd(randomize_result, 1);
if (rg.x >= 8'd10 && rg.x <= 8'd19) count_range_high++;
else if (rg.x > 8'd9) begin
$write("%%Error: x=%0d outside valid range [0:19]\n", rg.x);
@ -82,7 +85,8 @@ module t;
// Zero weight: value 0 must never appear
zw = new;
repeat (total) begin
`checkd(zw.randomize(), 1);
randomize_result = zw.randomize();
`checkd(randomize_result, 1);
if (zw.x == 8'd0) begin
$write("%%Error: zero-weight value 0 was selected\n");
`stop;
@ -93,7 +97,8 @@ module t;
// All-zero weights: dist constraint is effectively unconstrained, randomize succeeds
azw = new;
repeat (20) begin
`checkd(azw.randomize(), 1);
randomize_result = azw.randomize();
`checkd(randomize_result, 1);
end
// Variable := scalar weights: w1=1, w2=3 => expect ~75% for value 255
@ -102,7 +107,8 @@ module t;
vw.w2 = 3;
count_high = 0;
repeat (total) begin
`checkd(vw.randomize(), 1);
randomize_result = vw.randomize();
`checkd(randomize_result, 1);
if (vw.x == 8'd255) count_high++;
else `checkd(vw.x, 0);
end
@ -114,7 +120,8 @@ module t;
vwr.w2 = 3;
count_range_high = 0;
repeat (total) begin
`checkd(vwr.randomize(), 1);
randomize_result = vwr.randomize();
`checkd(randomize_result, 1);
if (vwr.x >= 8'd10 && vwr.x <= 8'd19) count_range_high++;
else if (vwr.x > 8'd9) begin
$write("%%Error: x=%0d outside valid range [0:19]\n", vwr.x);

View File

@ -72,37 +72,43 @@ module t;
static AndTest t_and = new();
static OrTest t_or = new();
static ProductTest t_prod = new();
int randomize_result;
repeat (10) begin
bit [7:0] exp;
int i;
// Test xor
`checkd(t_xor.randomize(), 1)
randomize_result = t_xor.randomize();
`checkd(randomize_result, 1);
exp = 0;
foreach (t_xor.data[i]) exp ^= t_xor.data[i];
`checkh(t_xor.result, exp)
// Test sum
`checkd(t_sum.randomize(), 1)
randomize_result = t_sum.randomize();
`checkd(randomize_result, 1);
exp = 0;
foreach (t_sum.data[i]) exp += t_sum.data[i];
`checkh(t_sum.result, exp)
// Test and
`checkd(t_and.randomize(), 1)
randomize_result = t_and.randomize();
`checkd(randomize_result, 1);
exp = 8'hff;
foreach (t_and.data[i]) exp &= t_and.data[i];
`checkh(t_and.result, exp)
// Test or
`checkd(t_or.randomize(), 1)
randomize_result = t_or.randomize();
`checkd(randomize_result, 1);
exp = 0;
foreach (t_or.data[i]) exp |= t_or.data[i];
`checkh(t_or.result, exp)
// Test product
`checkd(t_prod.randomize(), 1)
randomize_result = t_prod.randomize();
`checkd(randomize_result, 1);
exp = 8'd1;
foreach (t_prod.data[i]) exp *= t_prod.data[i];
`checkh(t_prod.result, exp)

View File

@ -7,6 +7,7 @@
// verilator lint_off
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%d exp=%d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
`define check_range(gotv, minv, maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); `stop; end while(0);
// verilog_format: on
@ -87,13 +88,17 @@ module t;
IndepClass indep;
initial begin
int randomize_result;
indep = new;
ext0 = new;
ext1 = new;
repeat (10) begin
`checkh(ext0.randomize(), 1);
`checkh(ext0.randomize(), 1);
`checkh(ext0.randomize_gpr(indep), 1);
randomize_result = ext0.randomize();
`checkd(randomize_result, 1);
randomize_result = ext0.randomize();
`checkd(randomize_result, 1);
randomize_result = ext0.randomize_gpr(indep);
`checkd(randomize_result, 1);
`checkh(indep.val0 inside {ext0.arr}, 1);
`checkh(indep.val1, 'hDEADBEEF);

View File

@ -29,10 +29,12 @@ endclass
module t;
initial begin
int randomize_result;
static RandArrayIndexTest obj = new();
repeat (20) begin
`checkd(obj.randomize(), 1)
`checkd(obj.selected_value, obj.data[obj.idx])
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`checkd(obj.selected_value, obj.data[obj.idx]);
`check_range(obj.selected_value, 8'd10, 8'd50)
end
$write("*-* All Finished *-*\n");

View File

@ -67,42 +67,46 @@ module t;
Simple s;
MultiLevel m;
int ok;
int randomize_result;
// Test 1: Packet with conditional constraints
p = new;
repeat (20) begin
`checkd(p.randomize(), 1)
`check_range(p.mode, 0, 3)
if (p.mode == 0) `checkd(p.data, 0)
randomize_result = p.randomize();
`checkd(randomize_result, 1);
`check_range(p.mode, 0, 3);
if (p.mode == 0) `checkd(p.data, 0);
if (p.mode == 1) begin
`check_range(p.data, 1, 15)
`check_range(p.data, 1, 15);
end
if (p.mode >= 2) begin
ok = (p.data < 8'h80) ? 1 : 0;
`checkd(ok, 1)
`checkd(ok, 1);
end
end
// Test 2: Simple range constraints
s = new;
repeat (20) begin
`checkd(s.randomize(), 1)
`check_range(s.x, 1, 5)
randomize_result = s.randomize();
`checkd(randomize_result, 1);
`check_range(s.x, 1, 5);
ok = (s.y > s.x) ? 1 : 0;
`checkd(ok, 1)
`checkd(ok, 1);
ok = (s.y < 4'hf) ? 1 : 0;
`checkd(ok, 1)
`checkd(ok, 1);
end
// Test 3: Multi-level chain
m = new;
repeat (20) begin
`checkd(m.randomize(), 1)
`check_range(m.a, 1, 3)
randomize_result = m.randomize();
`checkd(randomize_result, 1);
`check_range(m.a, 1, 3);
ok = (m.b > m.a && m.b < 8) ? 1 : 0;
`checkd(ok, 1)
`checkd(ok, 1);
ok = (m.c > m.b && m.c < 4'hf) ? 1 : 0;
`checkd(ok, 1)
`checkd(ok, 1);
end
$write("*-* All Finished *-*\n");

View File

@ -143,6 +143,7 @@ endclass
module t_constraint_struct_unref;
initial begin
int randomize_result;
C c;
D d;
E e;
@ -205,37 +206,44 @@ module t_constraint_struct_unref;
plain2.inr.b = 4'hA;
plain2.x = 4'hB;
for (int i = 0; i < 300; i++) begin
`checkd(c.randomize(), 1);
randomize_result = c.randomize();
`checkd(randomize_result, 1);
`checkd((c.u.size inside {[0 : 2]}), 1'b1);
`checkd((c.p.size inside {[0 : 2]}), 1'b1);
`checkd(c.u.fixed, 4'hA);
uid[c.u.id]++;
pid[c.p.id]++;
iid[c.u.inner.inner_id]++;
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
`checkd((d.z < 5), 1'b1);
`checkd(d.m.id, 4'h1);
`checkd(d.m.size, 3'h2);
`checkd(d.m.inner.inner_id, 4'h3);
`checkd(d.m.fixed, 4'h4);
zid[d.z]++;
`checkd(e.randomize(), 1);
randomize_result = e.randomize();
`checkd(randomize_result, 1);
`checkd((e.o.inr.a < 3), 1'b1);
bid[e.o.inr.b]++; // unreferenced nested member
xid[e.o.x]++; // unreferenced outer member
`checkd(f.randomize(), 1);
randomize_result = f.randomize();
`checkd(randomize_result, 1);
`checkd((f.s.r < 5), 1'b1);
wid[f.s.wi]++; // unreferenced rand member with initializer
cid[f.s.cyc]++; // unreferenced randc member
`checkd(g.randomize(), 1);
randomize_result = g.randomize();
`checkd(randomize_result, 1);
`checkd((g.o.g < 5), 1'b1);
e0id[g.o.es[0].f]++; // unreferenced array-of-struct element
e1id[g.o.es[1].f]++;
`checkd(h.randomize(), 1);
randomize_result = h.randomize();
`checkd(randomize_result, 1);
`checkd((h.o.sub.rv < 5), 1'b1);
`checkd(h.o.sub.kv, 4'hC);
hid[h.o.hv]++;
`checkd(iarr.randomize(), 1);
randomize_result = iarr.randomize();
`checkd(randomize_result, 1);
foreach (iarr.cfgs[k]) begin
`checkd((iarr.cfgs[k].subs[0].ed[0] != iarr.flip), 1'b1);
`checkd(iarr.cfgs[k].subs[0].ec, 1'b1);

View File

@ -0,0 +1,60 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Primitive C++ style checker
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0.
# SPDX-FileCopyrightText: 2024 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('dist')
def get_source_files():
git_files = test.run_capture("cd " + test.root + " && git ls-files")
if test.verbose:
print("MF " + git_files)
files = {}
for filename in git_files.split():
if filename == '':
continue
files[filename] = True
return files
def check_pattern(filename, contents, pattern, message):
lineno = 1
buf = contents
while True:
m = re.match(r'^(.*?)(' + pattern + ')(.*)', buf, re.DOTALL)
if not m:
break
lineno += m.group(1).count("\n")
ln = m.group(2)
buf = m.group(3)
test.error_keep_going(filename + ":" + str(lineno) + ": " + message + ": " + ln)
#####
if not os.path.exists(test.root + "/.git"):
test.skip("Not in a git repository")
### Must trim output before and after our file list
files = get_source_files()
for filename in sorted(files.keys()):
filename = os.path.join(test.root, filename)
if not os.path.exists(filename): # git file might be deleted but not yet staged
continue
if not re.search(r'test_regress/t/.*\.v$', filename):
continue
contents = test.file_contents(filename)
check_pattern(filename, contents, r'`check[a-z]+\([^\n]*?randomize\(',
"check macros have side effects, suggest assign to randomize_result variable and check that")
test.passes()

View File

@ -24,6 +24,7 @@ class test;
task run_phase;
process p;
uint8_t result;
int randomize_result;
string randstate;
// Pass 1: seed process, create object, randomize, record result
@ -32,14 +33,16 @@ class test;
d = new;
// Save randstate AFTER d=new (d=new advances process RNG per IEEE 18.14.1)
randstate = p.get_randstate();
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
result = d.x;
// Pass 2: same seed -> same sequence -> same result
p.srandom(100);
d = new;
`checks(p.get_randstate(), randstate);
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
`checkd(d.x, result);
// Pass 3: same seed, with intervening task call -> same result
@ -47,7 +50,8 @@ class test;
other_task();
d = new;
`checks(p.get_randstate(), randstate);
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
`checkd(d.x, result);
endtask

View File

@ -27,19 +27,23 @@ module t;
begin
process p;
D d;
int randomize_result;
p = process::self();
p.srandom(42);
d = new;
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
result_a = d.x;
end
begin
process p;
D d;
int randomize_result;
p = process::self();
p.srandom(42);
d = new;
`checkd(d.randomize(), 1);
randomize_result = d.randomize();
`checkd(randomize_result, 1);
result_b = d.x;
end
join

View File

@ -34,12 +34,14 @@ endclass
module t;
initial begin
static Foo foo = new;
int randomize_result;
`checkd(foo.bar0.size(), 1);
`checkd(foo.bar1.size(), 1);
`checkd(foo.bar0[0].x, 0);
`checkd(foo.bar1[0].x, 0);
repeat (100) begin
`checkd(foo.randomize(), 1);
randomize_result = foo.randomize();
`checkd(randomize_result, 1);
`checkd(foo.bar0.size(), 1);
`checkd(foo.bar1.size(), 1);
// Noting prevents x == 0 but it is pretty safe to assume that it won't be a zero (1/2^32)

View File

@ -38,12 +38,14 @@ module t;
AllColorsClass ac;
int color_seen[5];
int first_seq, all_same, this_seq;
int randomize_result;
// Test 1: randc enum with exclusion constraint
// Values must be valid enum members (0-4) and not BLACK (4)
c = new;
repeat (40) begin
`checkd(c.randomize(), 1);
randomize_result = c.randomize();
`checkd(randomize_result, 1);
`checkd(c.color <= BLACK, 1);
`checkd(c.color == BLACK, 0);
end
@ -57,13 +59,15 @@ module t;
this_seq = 0;
for (int j = 0; j < 4; j++) color_seen[j] = 0;
repeat (40) begin
`checkd(ac.randomize(), 1);
randomize_result = ac.randomize();
`checkd(randomize_result, 1);
`checkd(ac.color <= WHITE, 1);
color_seen[ac.color] = 1;
end
// Record first 4 values for sequence comparison
repeat (4) begin
`checkd(ac.randomize(), 1);
randomize_result = ac.randomize();
`checkd(randomize_result, 1);
this_seq = this_seq * 8 + int'(ac.color);
end
`checkd(color_seen[0], 1);

View File

@ -70,6 +70,7 @@ module t;
initial begin
// Scenario A: solomatnikov reproducer
static p_c_seq seq = new();
int randomize_result;
seq.req = new();
repeat (5) begin
seq.body();
@ -81,9 +82,10 @@ module t;
begin
automatic q_derived qd = new();
repeat (5) begin
`checkd(qd.randomize(), 1)
`checkd(qd.q.size(), 3)
foreach (qd.q[i]) `checkd(qd.q[i], i * 10)
randomize_result = qd.randomize();
`checkd(randomize_result, 1);
`checkd(qd.q.size(), 3);
foreach (qd.q[i]) `checkd(qd.q[i], i * 10);
end
end

View File

@ -55,19 +55,22 @@ module t;
initial begin
automatic derived_c d = new();
automatic grandchild_c g = new();
int randomize_result;
// Test derived class this.randomize()
repeat (20) begin
`checkd(d.do_randomize(), 1)
`checkd(d.cfg.enabled, 1)
`checkd(d.watchdog >= 32'd50 && d.watchdog <= 32'd200, 1)
randomize_result = d.do_randomize();
`checkd(randomize_result, 1);
`checkd(d.cfg.enabled, 1);
`checkd(d.watchdog >= 32'd50 && d.watchdog <= 32'd200, 1);
end
// Test deep inheritance this.randomize()
repeat (20) begin
`checkd(g.do_rand_deep(), 1)
`checkd(g.cfg.enabled, 1)
`checkd(g.watchdog >= 32'd50 && g.watchdog <= 32'd200, 1)
randomize_result = g.do_rand_deep();
`checkd(randomize_result, 1);
`checkd(g.cfg.enabled, 1);
`checkd(g.watchdog >= 32'd50 && g.watchdog <= 32'd200, 1);
end
$write("*-* All Finished *-*\n");

View File

@ -29,8 +29,10 @@ module t;
initial begin
static item it = new;
int randomize_result;
repeat (20) begin
`checkd(it.randomize(), 1);
randomize_result = it.randomize();
`checkd(randomize_result, 1);
foreach (it.arr[i]) begin
`checkd(it.arr[i] <= 32'd15, 1);
end

View File

@ -43,33 +43,37 @@ endclass
module t;
initial begin
int randomize_result;
OuterClass obj;
obj = new;
// Test 1: Normal randomize
repeat (20) begin
`checkd(obj.randomize(), 1)
`check_range(obj.nested.val1, 8'd10, 8'd50)
`check_range(obj.nested.val2, 8'd60, 8'd100)
`check_range(obj.nested.val3, 8'd110, 8'd150)
`check_range(obj.outer_val, 8'd1, 8'd20)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`check_range(obj.nested.val1, 8'd10, 8'd50);
`check_range(obj.nested.val2, 8'd60, 8'd100);
`check_range(obj.nested.val3, 8'd110, 8'd150);
`check_range(obj.outer_val, 8'd1, 8'd20);
end
// Test 2: rand_mode(0) on val1 -- must hold assigned value
void'(obj.nested.val1.rand_mode(0));
obj.nested.val1 = 8'd42;
repeat (20) begin
`checkd(obj.randomize(), 1)
`checkd(obj.nested.val1, 8'd42)
`check_range(obj.nested.val2, 8'd60, 8'd100)
`check_range(obj.nested.val3, 8'd110, 8'd150)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`checkd(obj.nested.val1, 8'd42);
`check_range(obj.nested.val2, 8'd60, 8'd100);
`check_range(obj.nested.val3, 8'd110, 8'd150);
end
// Test 3: rand_mode(0) on val2 as well
void'(obj.nested.val2.rand_mode(0));
obj.nested.val2 = 8'd77;
repeat (20) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1)
`checkd(obj.nested.val1, 8'd42)
`checkd(obj.nested.val2, 8'd77)
`check_range(obj.nested.val3, 8'd110, 8'd150)
@ -79,9 +83,10 @@ module t;
void'(obj.nested.val1.rand_mode(1));
void'(obj.nested.val2.rand_mode(1));
repeat (20) begin
`checkd(obj.randomize(), 1)
`check_range(obj.nested.val1, 8'd10, 8'd50)
`check_range(obj.nested.val2, 8'd60, 8'd100)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`check_range(obj.nested.val1, 8'd10, 8'd50);
`check_range(obj.nested.val2, 8'd60, 8'd100);
end
$write("*-* All Finished *-*\n");

View File

@ -51,16 +51,18 @@ endclass
module t;
initial begin
static top_test_c obj = new();
int randomize_result;
repeat (10) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
// Two-level cross-object soft: parent's soft overrides child's
`checkd(obj.cfg.sub_a.timeout, 32'd5000)
`checkd(obj.cfg.sub_a.timeout, 32'd5000);
// One-level cross-object soft: parent's soft overrides child's
`checkd(obj.extra_cfg.timeout, 32'd9999)
`checkd(obj.extra_cfg.enabled, 1'b1)
`checkd(obj.extra_cfg.timeout, 32'd9999);
`checkd(obj.extra_cfg.enabled, 1'b1);
// Hard constraint propagation still works
`checkd(obj.cfg.enabled, 1'b1)
`checkd(obj.cfg.sub_a.enabled, 1'b1)
`checkd(obj.cfg.enabled, 1'b1);
`checkd(obj.cfg.sub_a.enabled, 1'b1);
end
$write("*-* All Finished *-*\n");
$finish;

View File

@ -32,12 +32,14 @@ endclass
module t;
initial begin
int randomize_result;
SoftRelax obj;
obj = new;
repeat (20) begin
`checkd(obj.randomize(), 1)
`checkd(obj.a, 8'd80)
`check_range(obj.b, 8'd101, 8'd199)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`checkd(obj.a, 8'd80);
`check_range(obj.b, 8'd101, 8'd199);
end
$write("*-* All Finished *-*\n");
$finish;

View File

@ -42,13 +42,16 @@ module t;
initial begin
static solve_before_soft_c o1 = new();
static conflicting_soft_c o2 = new();
int randomize_result;
repeat (20) begin
`checkd(o1.randomize(), 1)
`checkd(o1.m, 32'd7)
randomize_result = o1.randomize();
`checkd(randomize_result, 1);
`checkd(o1.m, 32'd7);
end
repeat (20) begin
`checkd(o2.randomize(), 1)
`checkd(o2.a, 32'd9)
randomize_result = o2.randomize();
`checkd(randomize_result, 1);
`checkd(o2.a, 32'd9);
end
$write("*-* All Finished *-*\n");
$finish;

View File

@ -83,10 +83,12 @@ module t;
initial begin
static item it = new;
static Packet pkt = new;
int randomize_result;
// Test 1: solve...before with conditional constraints
repeat (20) begin
`checkd(it.randomize(), 1);
randomize_result = it.randomize();
`checkd(randomize_result, 1);
if (it.mode == 0) begin
foreach (it.data[i]) begin
`checkh(it.data[i], 8'h00);
@ -96,7 +98,8 @@ module t;
// Test 2: solve...before with unpacked/packed struct array members
repeat (20) begin
`checkd(pkt.randomize(), 1);
randomize_result = pkt.randomize();
`checkd(randomize_result, 1);
foreach (pkt.pdata[i]) begin
`checkd(pkt.pdata[i] inside {8'h10, 8'h20, 8'h30, 8'h40, 8'h50}, 1);
end
@ -104,7 +107,8 @@ module t;
// Test 3: solve...before with static array index (non-foreach)
repeat (20) begin
`checkd(it.randomize(), 1);
randomize_result = it.randomize();
`checkd(randomize_result, 1);
end
$write("*-* All Finished *-*\n");

View File

@ -67,6 +67,7 @@ module t;
endclass
initial begin
int randomize_result;
OuterObj obj;
TopObj top;
obj = new();
@ -74,14 +75,16 @@ module t;
// Test direct sub-object enum (one level deep)
repeat (20) begin
`checkd(obj.randomize(), 1)
randomize_result = obj.randomize();
`checkd(randomize_result, 1);
`check_enum_color(obj.inner.color)
`check_enum_state(obj.inner.state)
end
// Test nested sub-object enum (two levels deep)
repeat (20) begin
`checkd(top.randomize(), 1)
randomize_result = top.randomize();
`checkd(randomize_result, 1);
`check_enum_color(top.mid.inner.color)
`check_enum_state(top.mid.inner.state)
end

View File

@ -64,21 +64,25 @@ module t;
UniqueElemSingle uesgl;
initial begin
int randomize_result;
ues = new();
repeat (20) begin
`checkd(ues.randomize(), 1)
`checkd(ues.check_unique(), 1)
randomize_result = ues.randomize();
`checkd(randomize_result, 1);
`checkd(ues.check_unique(), 1);
end
uef = new();
repeat (20) begin
`checkd(uef.randomize(), 1)
`checkd(uef.check_unique(), 1)
randomize_result = uef.randomize();
`checkd(randomize_result, 1);
`checkd(uef.check_unique(), 1);
end
uesgl = new();
repeat (5) begin
`checkd(uesgl.randomize(), 1)
randomize_result = uesgl.randomize();
`checkd(randomize_result, 1);
end
$write("*-* All Finished *-*\n");

View File

@ -19,7 +19,7 @@ class std_randomize_class;
bit [31:0] old_data;
bit [63:0] old_data_x_4;
function bit std_randomize();
function void std_randomize();
int success;
bit valid;
@ -31,7 +31,7 @@ class std_randomize_class;
valid = (success == 1) && !(addr == old_addr || data == old_data) && data_x_4 == old_data_x_4;
return valid;
`checkd(valid, 1);
endfunction
endclass
@ -74,54 +74,66 @@ module t_scope_std_randomize;
std_randomize_class test;
initial begin
int randomize_result;
// Test class member randomization
test = new();
test.old_addr = test.addr;
test.old_data = test.data;
test.old_data_x_4 = test.data_x_4;
`checkd(std::randomize(test.addr, test.data), 1);
randomize_result = std::randomize(test.addr, test.data);
`checkd(randomize_result, 1);
if (test.addr == test.old_addr && test.data == test.old_data) $stop;
`checkd(test.data_x_4, test.old_data_x_4);
// Test function-based randomization
`checkd(run(), 1);
`checkd(test.std_randomize(), 1);
test.std_randomize();
// Test array randomization with constraints
`checkd(std::randomize(limit) with { foreach (limit[i]) { limit[i] < 32'd100;}}, 1);
randomize_result = std::randomize(limit) with { foreach (limit[i]) { limit[i] < 32'd100;}};
`checkd(randomize_result, 1);
foreach (limit[i]) if (limit[i] >= 32'd100) $stop;
`checkd(std::randomize(limit_7bits) with { foreach (limit_7bits[i]) { limit_7bits[i] < 7'd10;}}, 1);
randomize_result = std::randomize(limit_7bits) with { foreach (limit_7bits[i]) { limit_7bits[i] < 7'd10;}};
`checkd(randomize_result, 1);
foreach (limit_7bits[i]) if (limit_7bits[i] >= 7'd10) $stop;
`checkd(std::randomize(limit_15bits) with { foreach (limit_15bits[i]) { limit_15bits[i] < 15'd1000;}}, 1);
randomize_result = std::randomize(limit_15bits) with { foreach (limit_15bits[i]) { limit_15bits[i] < 15'd1000;}};
`checkd(randomize_result, 1);
foreach (limit_15bits[i]) if (limit_15bits[i] >= 15'd1000) $stop;
`checkd(std::randomize(limit_31bits) with { foreach (limit_31bits[i]) { limit_31bits[i] < 31'd100000;}}, 1);
randomize_result = std::randomize(limit_31bits) with { foreach (limit_31bits[i]) { limit_31bits[i] < 31'd100000;}};
`checkd(randomize_result, 1);
foreach (limit_31bits[i]) if (limit_31bits[i] >= 31'd100000) $stop;
`checkd(std::randomize(limit_63bits) with { foreach (limit_63bits[i]) { limit_63bits[i] < 63'd10000000000;}}, 1);
randomize_result = std::randomize(limit_63bits) with { foreach (limit_63bits[i]) { limit_63bits[i] < 63'd10000000000;}};
`checkd(randomize_result, 1);
foreach (limit_63bits[i]) if (limit_63bits[i] >= 63'd10000000000) $stop;
`checkd(std::randomize(limit_95bits) with { foreach (limit_95bits[i]) { limit_95bits[i] < 95'd1000000000000;}}, 1);
randomize_result = std::randomize(limit_95bits) with { foreach (limit_95bits[i]) { limit_95bits[i] < 95'd1000000000000;}};
`checkd(randomize_result, 1);
foreach (limit_95bits[i]) if (limit_95bits[i] >= 95'd1000000000000) $stop;
foreach (limit_63bits[i]) begin
`checkd(std::randomize(limit_63bits[i]) with { limit_63bits[i] >= 63'd50; limit_63bits[i] < 63'd100;}, 1);
randomize_result = std::randomize(limit_63bits[i]) with { limit_63bits[i] >= 63'd50; limit_63bits[i] < 63'd100;};
`checkd(randomize_result, 1);
if ((limit_63bits[i] < 63'd50) || (limit_63bits[i] >= 63'd100)) `stop;
end
foreach (limit_95bits[i]) begin
`checkd(std::randomize(limit_95bits[i]) with { limit_95bits[i] >= 95'd50; limit_95bits[i] < 95'd1000;}, 1);
randomize_result = std::randomize(limit_95bits[i]) with { limit_95bits[i] >= 95'd50; limit_95bits[i] < 95'd1000;};
`checkd(randomize_result, 1);
if (limit_95bits[i] < 95'd50 || limit_95bits[i] >= 95'd1000) $stop;
end
// Test mixed argument types (VarRef + MemberSel + ArraySel) with interdependent constraints
`checkd(std::randomize(addr, test.addr, limit_31bits[0]) with {
randomize_result = std::randomize(addr, test.addr, limit_31bits[0]) with {
addr > 8'd10; addr < 8'd50;
test.addr > addr; test.addr < 8'd100;
limit_31bits[0] > 31'(test.addr); limit_31bits[0] < 31'd200;
}, 1);
};
`checkd(randomize_result, 1);
if (addr <= 8'd10 || addr >= 8'd50) `stop;
if (test.addr <= addr || test.addr >= 8'd100) `stop;
if (limit_31bits[0] <= 31'(test.addr) || limit_31bits[0] >= 31'd200) `stop;

View File

@ -18,17 +18,21 @@ module t_std_randomize_assoc;
bit [7:0] assoc_byte[string];
initial begin
int randomize_result;
// Test 1: std::randomize with int-keyed associative array (no constraints)
assoc_int[0] = 0;
assoc_int[1] = 0;
assoc_int[2] = 0;
`checkd(std::randomize(assoc_int), 1);
randomize_result = std::randomize(assoc_int);
`checkd(randomize_result, 1);
// Test 2: std::randomize with string-keyed associative array
assoc_byte["a"] = 0;
assoc_byte["b"] = 0;
assoc_byte["c"] = 0;
`checkd(std::randomize(assoc_byte), 1);
randomize_result = std::randomize(assoc_byte);
`checkd(randomize_result, 1);
// Test 3: Multiple randomizations produce different values
begin
@ -36,7 +40,8 @@ module t_std_randomize_assoc;
repeat (5) begin
assoc_int[0] = 0;
assoc_int[1] = 0;
`checkd(std::randomize(assoc_int), 1);
randomize_result = std::randomize(assoc_int);
`checkd(randomize_result, 1);
if (assoc_int[0] != 0) non_zero++;
if (assoc_int[1] != 0) non_zero++;
end

View File

@ -23,33 +23,39 @@ module t_std_randomize_queue;
int i;
initial begin
int randomize_result;
// Test 1: std::randomize with queue (no constraints)
q8 = {8'd0, 8'd0, 8'd0};
`checkd(std::randomize(q8), 1);
randomize_result = std::randomize(q8);
`checkd(randomize_result, 1);
// Test 2: std::randomize with queue and constraints
q8 = {8'd0, 8'd0, 8'd0, 8'd0};
`checkd(std::randomize(q8) with {
randomize_result = std::randomize(q8) with {
foreach (q8[j]) q8[j] > 8'd10 && q8[j] < 8'd100;
}, 1);
};
`checkd(randomize_result, 1);
foreach (q8[j]) begin
if (q8[j] <= 8'd10 || q8[j] >= 8'd100) `stop;
end
// Test 3: std::randomize with 32-bit queue
q32 = {32'd0, 32'd0, 32'd0};
`checkd(std::randomize(q32) with {
randomize_result = std::randomize(q32) with {
foreach (q32[k]) q32[k] < 32'd1000;
}, 1);
};
`checkd(randomize_result, 1);
foreach (q32[k]) begin
if (q32[k] >= 32'd1000) `stop;
end
// Test 4: std::randomize with dynamic array
dyn8 = new[3];
`checkd(std::randomize(dyn8) with {
randomize_result = std::randomize(dyn8) with {
foreach (dyn8[m]) dyn8[m] inside {[1:50]};
}, 1);
};
`checkd(randomize_result, 1);
foreach (dyn8[m]) begin
if (dyn8[m] < 1 || dyn8[m] > 50) `stop;
end
@ -59,7 +65,8 @@ module t_std_randomize_queue;
begin
automatic int non_zero = 0;
repeat (5) begin
`checkd(std::randomize(q8), 1);
randomize_result = std::randomize(q8);
`checkd(randomize_result, 1);
foreach (q8[n]) if (q8[n] != 0) non_zero++;
end
// With 15 random 8-bit values, expect most non-zero

View File

@ -35,9 +35,11 @@ endclass
module t;
Top top;
initial begin
int randomize_result;
top = new;
`checkd(top.randomize(), 1);
randomize_result = top.randomize();
`checkd(randomize_result, 1);
`checkd(top.s.num, 0);
$write("*-* All Finished *-*\n");