2023-04-01 16:50:27 +02:00
// 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
2023-04-05 02:56:18 +02:00
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
2023-04-01 16:50:27 +02:00
module t ( /*AUTOARG*/ ) ;
Cls ca ;
Cls cb ;
2023-04-05 02:56:18 +02:00
Bar b1 ;
Bar b2 ;
2023-04-01 16:50:27 +02:00
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 ;
2023-04-05 02:56:18 +02:00
b1 = new ;
b2 = new ;
2023-04-01 16:50:27 +02:00
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 ) ;
2023-04-05 02:56:18 +02:00
$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 ) ;
2023-04-01 16:50:27 +02:00
// 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