David
David

Reputation: 27

System Verilog: randomization per instance at initial

I want to simulate a multiple latches with random starting conditions, but I want each instance to have its own initial condition

This is a simplified version of the code. I would like the value to be different in both of the instances, without changing the interface

module random_usage();
  integer addr1;
  real data;
  initial begin
    addr1 = $urandom();
    data  = $urandom();
 
    $display("addr1=%0d, data=%0d",addr1,data);
  end
endmodule

module tb();
    integer seed = 1;
    random_usage a();
    random_usage b();
    initial
    begin
        #5;
        seed  = $get_initial_random_seed();
        $display("seed=%0d", seed);
    end

endmodule

What I have seen so far:

Instance specific $urandom in system-verilog

solution doesn't work in initial condition, or even when you feed the same clock

https://www.systemverilog.io/randomization

I have modules, so i don't know how to apply the solutions, or even if it will work here

https://www.reddit.com/r/FPGA/comments/jd0dmu/system_verilog_force_randomization_different_per/

seems to be the same question, and there is no straight solution, but the last person gave a VCS flag. I am using VCS, but i have not been able to get the flag to work

Upvotes: 0

Views: 734

Answers (1)

dave_59
dave_59

Reputation: 42698

The IEEE 1800-2017 SystemVerilog LRM section 18.14.1 Random stability properties says rather naively that each instances gets seeded with the same initialization seed.

Most tools now have a switch changing that behavior by using the hierarchical path name to seed each instance. Some tools have even made that the default. If you want tool independent behavior, you can use this package:

package seed_instance;

int initial_seed = $urandom;

function automatic void srandom(string path);
  static int hash[int];
  int hash_value = initial_seed;
  process p = process::self();
  for(int i=0;i<path.len();i++)
    hash_value+=path[i]*(i*7);
  if (!hash.exists(hash_value))
    hash[hash_value] = hash_value;
  else
    hash[hash_value]+=$urandom; // next seed
  p.srandom(hash[hash_value]);
endfunction

endpackage
  
module random_usage();
  integer addr1;
  real data;
  initial begin
    seed_instance::srandom($sformatf("%m"));
    addr1 = $urandom();
    data  = $urandom();
 
    $display("1: addr1=%0d, data=%0d",addr1,data);
  end
  
   initial begin
    seed_instance::srandom($sformatf("%m"));
    addr1 = $urandom();
    data  = $urandom();
 
     $display("2: addr1=%0d, data=%0d",addr1,data);
  end
endmodule

module tb();
    integer seed = 1;
    random_usage a();
    random_usage b();
endmodule

Upvotes: 1

Related Questions