Reputation: 27
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
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