I have an always
process running in my testbench that calls $urandom_range()
Is it possible to reseed this while im running my testbench?
I guess it has something to do with srandom
but can't get it to work.
I have an always
process running in my testbench that calls $urandom_range()
Is it possible to reseed this while im running my testbench?
I guess it has something to do with srandom
but can't get it to work.
It is possible to seed the random number generator for the thread (ie that used by $urandom
etc) by calling $urandom
with an integer argument, eg:
$urandom(12345);
You mention srandom
. This is another way to interact with the thread’s random number generator and that is by using the process
class, which is a class declared in the std
package. This process class has a method called srandom
which seeds the current thread from an integer.
To use the process
class, first you need a variable of class process
:
std::process p;
and then you need to assign this variable with the return value of a static method of the process class, called self
:
p = process::self();
If you're not familiar with object-oriented design, don't worry. Trust me. This is what you need to do. Think of these two lines as like some kind of magic spell. Once we have issued this magic spell, we can call the srandom
method to seed the thread’s random number generator, eg:
p.srandom(12345);
So, what’s the difference between srandom
and $urandom?
Or to put it another way:
If I set a seed using the srandom
method of the process class, does that set the thread’s random number generator to the same state as setting the same seed using $urandom
?
There is no difference. Except there is.
What? Let’s put some code (as at the bottom of this answer into) EDA Playground: https://www.edaplayground.com/x/4yN4
Let’s seed our thread’s random number generator using srandom:
p.srandom(9);
then let’s generate four random numbers:
repeat(4) $display( $urandom );
and see what we get:
# KERNEL: 659167701
# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565
Then let's seed our thread's random number generator using $urandom:
$urandom(9);
and again let’s generate four random numbers
repeat(4) $display( $urandom );
and again let’s see what we get:
# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565
# KERNEL: 3967046865
At first glance, it looks like we've generated a different four random numbers. However, on closer inspection, we see that the first number of the second ($urandom
) series is the same as the second number of the first series (srandom
). Why might that be? Well, it's because the call to $urandom
to set the seed not only set the seed, but also generated a random number, whereas the call to srandom
only set the seed.
module M;
initial
begin
string randstate;
std::process p;
p = process::self();
$display("p.srandom(9)");
p.srandom(9);
repeat(4) $display( $urandom );
$display("$urandom(9)");
$urandom(9);
repeat(4) $display( $urandom );
end
endmodule
See also my answer here, which has useful background stuff: