0

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.

Moberg
  • 5,253
  • 4
  • 38
  • 54

1 Answers1

1

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 srandomonly 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:

urandom_range(), urandom(), random() in verilog

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44