System Verilog: Random Number System Functions
Last modified 2017-01-30
Sini
System Verilog provides system functions - $urandom(),$urandomrange() 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 $urandomrange. 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 randsysfnclass;
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; randsysfnclass 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
*/
$urandomrange() The $urandomrange() 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 $urandomrange( int unsigned maxval,int unsigned minval = 0 );
In the below code addr1 range is from 32'hFFFFFF00 to 32'hFFFFFFFE. So it generated following values in 5 iterations.
Addr1 = ffffff24 -> Addr1 = ffffffeb -> Addr1 = ffffff59 -> Addr1 = ffffff4c -> Addr1 = ffffffbf
class randrangesysfnclass; rand bit[31:0] addr1; rand bit[63:0] addr2;
function new(); for(int i =0; i<5;i++) begin addr1 = $urandomrange(32'hFFFFFFFE,32'hFFFFFF00); $display ("Addr1 = %h ",addr1);
addr2 ={$urandomrange(32'h0000FFFF,32'h00000000),$urandomrange(32'h0000000F,32'h00000001)}; $display ("Addr2 = %h ",addr2);
end endfunction endclass /////////////////// program p2; randrangesysfnclass 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 srandsysfnclass; 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; srandsysfnclass 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 */