System Verilog: Random Number System Functions

System Verilog: Random Number System Functions

System Verilog provides system functions - $urandom(),$urandom_range() and $srandom() for generating random numbers.

The $random verilog system function has only one random number generator shared between all threads, but each thread in simulation has its own random number generator for $urandom and $urandom_range. Separate random number generators for each thread helps to improve random stability

$urandom() The $urandom() system function provides a mechanism for generating pseudo-random numbers. The function returns a new unsigned 32-bit random number each time it is called.

function int unsigned $urandom [ (int seed ) ] ;

The seed is an optional argument that determines the sequence of random numbers generated. This generates 32 bit unsigned number, but 2 bits, 4 bits etc. random numbers can be generated as shown below.

class rand_sysfn_class;

rand bit[31:0] addr1; rand bit[63:0] addr2; rand bit [1:0] selb; rand bit [3:0] msel;

function new(); for(int i =0; i<5;i++) begin addr1 = $urandom(); $display ("Addr1 = %h ",addr1);

addr2 ={$urandom(),$urandom()}; $display ("Addr2 = %h ",addr2);

selb = $urandom & 7; //2 bit random number $display ("Selb = %b ",selb);

msel = $urandom & 15; //4 bit random number $display ("msel = %b ",msel);

end endfunction endclass

program p1; rand_sysfn_class c1 = new(); endprogram

/* /////////////////// Addr1 = d7ab96af Addr2 = 20186340ff61aafe Selb = 00 msel = 1011 Addr1 = ebbca2d7 Addr2 = e7f59ecffb84c2f7 Selb = 01 msel = 1111 Addr1 = 96baee2d Addr2 = f0a8dce11e18993c Selb = 01 msel = 0000 Addr1 = 8921cc12 Addr2 = 124f7d245177c3a2 Selb = 01 msel = 1100 Addr1 = 6d4439da Addr2 = 925968242e00b55c Selb = 10 msel = 1100

*/

$urandom_range() The $urandom_range() function returns an unsigned 32 integer within a specified range. Range would be specified using max and min values as shown below

function int unsigned $urandom_range( int unsigned maxval,int unsigned minval = 0 );

In the below code addr1 range is from 32'hFFFF_FF00 to 32'hFFFF_FFFE. So it generated following values in 5 iterations.

Addr1 = ffffff24 -> Addr1 = ffffffeb -> Addr1 = ffffff59 -> Addr1 = ffffff4c -> Addr1 = ffffffbf

class rand_range_sysfn_class; rand bit[31:0] addr1; rand bit[63:0] addr2;

function new(); for(int i =0; i<5;i++) begin addr1 = $urandom_range(32'hFFFF_FFFE,32'hFFFF_FF00); $display ("Addr1 = %h ",addr1);

addr2 ={$urandom_range(32'h0000_FFFF,32'h0000_0000),$urandom_range(32'h0000_000F,32'h0000_0001)}; $display ("Addr2 = %h ",addr2);

end endfunction endclass /////////////////// program p2; rand_range_sysfn_class c2 = new(); endprogram /* Addr1 = ffffff24 Addr2 = 0000fabd00000001 Addr1 = ffffffeb Addr2 = 0000b7a10000000c Addr1 = ffffff59 Addr2 = 00005e060000000f Addr1 = ffffff4c Addr2 = 000088430000000e Addr1 = ffffffbf Addr2 = 0000ba0b0000000a */

srandom() The srandom() method allows manually seeding the RNG of objects or threads.

function void srandom( int seed );

The srandom() method initializes an object’s RNG using the value of the given seed.

In the below code 5 iterations are done without setting a seed using $srandom(). So different random numbers are generated. But once we set srandom(1), RNG will generate same random numbers. This will change once we change the seed.

class srand_sysfn_class; rand bit [31:0] addr;

function new(); for(int i =0; i<5;i++) begin addr = $urandom(); $display ("addr = %h ",addr); end

for(int i =0; i<5;i++) begin $srandom(1); addr = $urandom(); $display ("addr - with srandom = %h ",addr); end endfunction endclass

program p1; srand_sysfn_class c3 = new(); endprogram

/* Without setting a seed using $srandom() addr = d7ab96af addr = ff61aafe addr = 20186340 addr = 5075bfa0 addr = 25afd34b

Setting a seed using $srandom() addr - with srandom = 80010e00 addr - with srandom = 80010e00 addr - with srandom = 80010e00 addr - with srandom = 80010e00 addr - with srandom = 80010e00 */