The system function $random
provides a way to generate random numbers in Verilog. Each time it is called, the function returns a new 32-bit random number, which is a signed integer that can be either positive or negative.
Syntax
$random([seed]);
The seed argument controls the output of the $random
function, ensuring that different seeds produce distinct random streams. This seed argument can be a reg
, an integer
, or a time
variable. It is important to assign a value to this variable before calling $random
.
module tb;
reg [3:0] val;
reg [31:0] seed; // prefer 32b value
initial begin
for (integer i = 0; i < 10; i += 1) begin
seed = 5;
val = $random(seed) % 3;
$display ("i=%0d seed=%0d val=0x%0h val=%0d", i, seed, val, val);
end
end
endmodule
The same seed returns the same value over multiple iterations.
xcelium> run i=0 seed=345346 val=0xe val=14 i=1 seed=345346 val=0xe val=14 i=2 seed=345346 val=0xe val=14 i=3 seed=345346 val=0xe val=14 i=4 seed=345346 val=0xe val=14 i=5 seed=345346 val=0xe val=14 i=6 seed=345346 val=0xe val=14 i=7 seed=345346 val=0xe val=14 i=8 seed=345346 val=0xe val=14 i=9 seed=345346 val=0xe val=14 xmsim: *W,RNQUIE: Simulation is complete.
However, $random
provides different values if the seed argument is not given.
module tb;
reg [3:0] val;
reg [31:0] seed; // prefer 32b value
initial begin
for (integer i = 0; i < 10; i += 1) begin
val = $random(seed) % 3;
$display ("i=%0d seed=%0d val=0x%0h val=%0d", i, seed, val, val);
end
end
endmodule
xcelium> run i=0 seed=2450862598 val=0x2 val=2 i=1 seed=1082744015 val=0xf val=15 i=2 seed=75814084 val=0x0 val=0 i=3 seed=837833973 val=0xe val=14 i=4 seed=2260302130 val=0x0 val=0 i=5 seed=3336541963 val=0x2 val=2 i=6 seed=851608272 val=0xe val=14 i=7 seed=154620049 val=0x0 val=0 i=8 seed=2163466526 val=0x0 val=0 i=9 seed=2262289159 val=0x1 val=1 xmsim: *W,RNQUIE: Simulation is complete.
Full Range Example
For the expression ($random % N) where N is greater than 0, it returns a number in the following range [(-b + 1) : (b - 1)].
module tb;
reg [3:0] val;
initial begin
for (integer i = 0; i < 10; i += 1) begin
val = $random % 2;
$display ("val=0x%0h val=%0d", val, val);
end
end
endmodule
The randomization example shown above gave values between -1:1 because N=2 in the example above. Note that val being 15 in signed format means that its value is -1.
xcelium> run val=0x0 val=0 val=0xf val=15 val=0xf val=15 val=0xf val=15 val=0x1 val=1 val=0x1 val=1 val=0xf val=15 val=0x0 val=0 val=0x1 val=1 val=0x1 val=1 xmsim: *W,RNQUIE: Simulation is complete.
Positive Range Example
To remove the negative values in the previous example and to get a range from 0:N, a concatenation operator should be added.
module tb;
reg [3:0] val;
initial begin
for (integer i = 0; i < 10; i += 1) begin
val = {$random} % 2;
$display ("val=0x%0h val=%0d", val, val);
end
end
endmodule
xcelium> run val=0x0 val=0 val=0x1 val=1 val=0x1 val=1 val=0x1 val=1 val=0x1 val=1 val=0x1 val=1 val=0x1 val=1 val=0x0 val=0 val=0x1 val=1 val=0x1 val=1 xmsim: *W,RNQUIE: Simulation is complete.