Jump to content

Randomization in an initial block


Recommended Posts

I have a module defined as follows...

module dut();

   int i;

   initial begin
      i = $urandom_range(0, 500);
      $display("The value of i is %1d", i);
   end

endmodule // dut

I'm trying to randomize the value assigned to the variable i.  My top level module is

module top_tb;

   dut dut_a();
   dut dut_b();
   dut dut_c();

endmodule

When I simulate this, the output shows the same value for all three instances.

# The value of i is 3
# The value of i is 3
# The value of i is 3

This is a simple example.  I've tried other approaches, including placing the random variable inside a class, declaring a new object of that class inside the initial block and then randomizing the object.  That yields the same result, all the values are the same in the different instances.  I've added time before the randomization via a #10 statement.  Same result.

 

It seems to be related to the initial block.  So how does the SystemVerilog random functions work in regards to an initial block and non-initial blocks?  There some part of how those functions work that I'm not understanding.  How could I set a different random value inside each dut instance within the initial block?

 

gb

Link to comment
Share on other sites

This is the correct functionality. There is a random number generator (RNG) for every module instance in your design, and it is seeded with a RNG from the module instance it starts from. All all modules instances start out with identical seeds. Every thread that starts inside a module instance grabs a new RNG. Threads in parallel blocks get seeded in declaration order, not in the indeterminate order they might actually start. Objects that get constructed get seeded with an RNG from the thread calling the constructor.

 

This random stability model has a few problems that the UNM attempts to correct by using a path name as an initial seed. You just need to make sure your path names are unique enough to generate distinctive seeds. A good paper to read on this topic is: Random Stability, Don't leave it to chance.

Link to comment
Share on other sites

  • 3 years later...

It is possible to set RNG seed for each process in a module (always_.., initial, etc.). To do this it is necessary to have a process handler:

module dut();

   int i;
   process P1;

   initial begin
      P1 = process::self();
      #2;
      i = $urandom_range(0, 500);
      $display("The value of i is %1d", i);
   end

endmodule // dut

Now you can set seed for each process individually:

module top_tb;

   initial begin
      #1;  // Wait process handlers to be created

      // Set seeds
      dut_a.P1.srandom($urandom);
      dut_b.P1.srandom($urandom);
      dut_c.P1.srandom($urandom);
   end

   dut dut_a();
   dut dut_b();
   dut dut_c();

endmodule

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...