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