verilator/test_regress/t/t_randomize_srandom.v
2023-04-04 20:56:18 -04:00

155 lines
3.6 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define stop $stop
`define checkeq(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 checkne(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)
class Cls;
bit [63:0] m_sum;
rand int m_r;
function void hash_init();
m_sum = 64'h5aef0c8d_d70a4497;
endfunction
function void hash(int res);
$display(" res %x", res);
m_sum = {32'h0, res} ^ {m_sum[62:0], m_sum[63] ^ m_sum[2] ^ m_sum[0]};
endfunction
function bit [63:0] test1();
Cls o;
// Affected by srandom
$display(" init for randomize");
hash_init;
// TODO: Support this.randomize()
o = this;
void'(o.randomize());
hash(m_r);
void'(o.randomize());
hash(m_r);
return m_sum;
endfunction
function bit [63:0] test2(int seed);
$display(" init for seeded randomize");
hash_init;
this.srandom(seed);
void'(this.randomize());
hash(m_r);
return m_sum;
endfunction
function bit [63:0] test3(int seed);
$display(" init for seeded randomize");
hash_init;
srandom(seed);
void'(randomize());
hash(m_r);
return m_sum;
endfunction
endclass
class Foo;
endclass
class Bar extends Foo;
bit [63:0] m_sum;
rand int m_r;
function void hash_init();
m_sum = 64'h5aef0c8d_d70a4497;
endfunction
function void hash(int res);
$display(" res %x", res);
m_sum = {32'h0, res} ^ {m_sum[62:0], m_sum[63] ^ m_sum[2] ^ m_sum[0]};
endfunction
function void this_srandom(int seed);
this.srandom(seed);
endfunction
function bit [63:0] test2;
$display(" init for seeded randomize");
hash_init;
$display("%d", m_r);
hash(m_r);
return m_sum;
endfunction
endclass
module t(/*AUTOARG*/);
Cls ca;
Cls cb;
Bar b1;
Bar b2;
bit [63:0] sa;
bit [63:0] sb;
initial begin
// Each class gets different seed from same thread,
// so the randomization should be different
$display("New");
ca = new;
cb = new;
b1 = new;
b2 = new;
sa = ca.test1();
sb = cb.test1();
`checkne(sa, sb); // Could false-fail 2^-32
// Seed the classes to be synced
$display("Seed");
ca.srandom(123);
cb.srandom(123);
sa = ca.test1();
sb = cb.test1();
`checkeq(sa, sb);
// Check using this
$display("this.srandom");
sa = ca.test2(1);
sb = cb.test2(2);
`checkne(sa, sb);
sa = ca.test2(3);
sb = cb.test2(3);
`checkeq(sa, sb);
$display("this.srandom - Bar class");
b1.this_srandom(1);
b2.this_srandom(2);
void'(b1.randomize());
void'(b2.randomize());
sa = b1.test2;
sb = b2.test2;
`checkne(sa, sb);
b1.this_srandom(3);
b2.this_srandom(3);
void'(b1.randomize());
void'(b2.randomize());
sa = b1.test2;
sb = b2.test2;
`checkeq(sa, sb);
// Check using direct call
$display("srandom");
sa = ca.test3(1);
sb = cb.test3(2);
`checkne(sa, sb);
sa = ca.test3(3);
sb = cb.test3(3);
`checkeq(sa, sb);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule