平时在产生随机数时,大家可能会用到$random(), $urandom()和$urandom_range()函数,但要注意的是,这几个函数返回的是32-bit随机数。
- $random: 当被调用时,返回1个有符号的随机数,可以选择性地使用seed去决定随机数序列的产生。函数定义为:$random [ ( seed ) ]。
- $urandom: 当被调用时,返回1个32-bit无符号伪随机数,可以选择性地使用seed去决定随机数序列的产生。函数定义为:function int unsigned $urandom [ (int seed ) ] ;
- $urandom_range(): 当被调用时,返回指定范围(minval~maxval)内的1个32-bit无符号伪随机数。函数定义为:function int unsigned $urandom_range( int unsigned maxval, int unsigned minval = 0 ); 如果User在使用时,maxval小于minval,这些参数在sv内会自动反转,使得第一个参数肯定不小于第二个参数。
当然还有$dist_uniform, $dist_normal, $dist_exponential, $dist_poisson, $dist_chi_square, $dist_t, $dist_erlang等其它随机函数。
假如我们需要给1个64-bit变量(var_64b)产生随机数时,要注意不能只是简单的使用var_64b=$random(),这样会导致高32-bit其实并没有被随机化,有时候还挺难发现的。
当赋值时,等号两边位宽不一致时,原则如下:
- 如果右边的宽度大于左边的宽度,那么右边的MSBs会被丢弃掉,EDA tools可以决定是否报warming或error。
- 如果右边的宽度小于左边的宽度,那么右边将会扩展。如果右边是无符号数,高位将补0。如果右边是有符号数,高位将根据符号位扩展。如果是正数,那么是0;如果是负数,那么是1。
综上所述,写了个例子如下:
bit [63:0] t_addr;
for (int i=0; i<10; i++) begin
t_addr = $urandom();
$display("The $urandom() value(no sign extended) assigns to t_addr is: 'h%h", t_addr);
end
for (int i=0; i<10; i++) begin
t_addr = $random();
$display("The $random() value(sign extended) assigns to t_addr is: 'h%h", t_addr);
end
执行结果如下:
The $urandom() value(no sign extended) assigns to t_addr is: 'h00000000494cac73
The $urandom() value(no sign extended) assigns to t_addr is: 'h0000000090fac4f2
The $urandom() value(no sign extended) assigns to t_addr is: 'h000000009754de91
The $urandom() value(no sign extended) assigns to t_addr is: 'h00000000caebd7aa
The $urandom() value(no sign extended) assigns to t_addr is: 'h00000000b75e03d0
The $urandom() value(no sign extended) assigns to t_addr is: 'h00000000890f6354
The $urandom() value(no sign extended) assigns to t_addr is: 'h0000000021edc6c8
The $urandom() value(no sign extended) assigns to t_addr is: 'h00000000539f210a
The $urandom() value(no sign extended) assigns to t_addr is: 'h000000009133fcf2
The $urandom() value(no sign extended) assigns to t_addr is: 'h000000004e232cb8
The $random() value(sign extended) assigns to t_addr is: 'h0000000012153524
The $random() value(sign extended) assigns to t_addr is: 'hffffffffc0895e81
The $random() value(sign extended) assigns to t_addr is: 'hffffffff8484d609
The $random() value(sign extended) assigns to t_addr is: 'hffffffffb1f05663
The $random() value(sign extended) assigns to t_addr is: 'h0000000006b97b0d
The $random() value(sign extended) assigns to t_addr is: 'h0000000046df998d
The $random() value(sign extended) assigns to t_addr is: 'hffffffffb2c28465
The $random() value(sign extended) assigns to t_addr is: 'hffffffff89375212
The $random() value(sign extended) assigns to t_addr is: 'h0000000000f3e301
The $random() value(sign extended) assigns to t_addr is: 'h0000000006d7cd0d