
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 */
i executed the program using $srandom(1). but i didn’t get same random numbers using $srandom. will you check once the given code is proper. i am using questasim simulation tool
I tried out again using incisive tool and it works. Please check with Questasim support team on this.
Hey Srini,
what is the difference between $srandom and $urandom:
1. as $urandom (i) produce same results as $srandom = 1
2. Further, as far as I have read, for each individual seed, numbers should be different i.e. Seed 1 – 5 unique (not identical) values should be different from seed 2 – 5 unique values but by using $srandom = 1 or $urandom(i) it gives all 5 values of each seed set as exact same values.
Can you please explain what is the scenario here?
class srand_sysfn_class;
rand bit [31:0] addr;
function new();
for(int i =1; i<5;i++) begin
for (int j =0;j<5;j++) begin
addr = $urandom(i);
$display ("addr = %h ",addr);
end
$display("*****************");
end
`default_nettype none;
for(int j = 1;j<5 ;j++) begin
int seed = j;
$display(" seed is set %0d",seed);
void'($urandom(seed));
for(int i = 0;i < 5; i++) begin
addr = $urandom();
$display ("addr = %h ",addr);
end
$display("—————");
end
endfunction
endclass
program p1;
srand_sysfn_class c3 = new();
endprogram
Output:
addr = 2fd9a2ac
addr = 2fd9a2ac
addr = 2fd9a2ac
addr = 2fd9a2ac
addr = 2fd9a2ac
*****************
addr = dfb76d78
addr = dfb76d78
addr = dfb76d78
addr = dfb76d78
addr = dfb76d78
*****************
addr = 9d5ab7e5
addr = 9d5ab7e5
addr = 9d5ab7e5
addr = 9d5ab7e5
addr = 9d5ab7e5
*****************
addr = 3feed2e4
addr = 3feed2e4
addr = 3feed2e4
addr = 3feed2e4
addr = 3feed2e4
*****************
seed is set 1
addr = f377581d
addr = 8ba1adbf
addr = 131ab2c9
addr = 3aae165d
addr = 85e1726a
—————
seed is set 2
addr = b4ec20a3
addr = 17585bbe
addr = b73555d3
addr = 17dd0aa8
addr = 42ce7d9f
—————
seed is set 3
addr = f422e8af
addr = 86446707
addr = ea6fcc63
addr = 76592177
addr = eb04e4bc
—————
seed is set 4
addr = 79d8d00f
addr = 0ea2a3fe
addr = 6f6ffbe6
addr = 0f2f31c3
addr = cdf86a3f
—————
hi sini balakrishnan,can you pls explain that when we use ” solve x befor y ” constraint in randomizing variables,,i am not getting its exact usage,,thankyou