Random seed problem
Tagged: OSVVM random
January 26, 2018 at 04:43 #1424TorstenMember
I have a strange problem with a random variable, which is initialised every time before use with different values, but the variable returns the same “random” value, regardless of the different seed. The variable is located local in a procedure. The relevant snippet of the procedure looks like this:
procedure NetCheck (signal Clk : in std_logic;
signal Fifo : inout t_vai64_if;
RefQueue : inout NetQueue.t_queue;
AlertName : in string;
AlertBaseId : in AlertLogIDType) is
variable v_random : RandomPType;
variable v_wait : time;
v_random.InitSeed(v_random'instance_name & to_string(now));
Log(v_random'instance_name & to_string(now));
Fifo <= ('Z', 'Z', 'Z', (others => 'Z'), 'Z');
v_wait := v_random.RandTime(0 ns, 50 ns);
Log("v_wait: " & to_string(v_wait));
end procedure NetCheck;
I call it in my testbench like this:
-- ipc network path checker process
NetChecker : NetCheck (s_clk, s_net_rx, sv_net_queue, NetChecker'instance_name, C_TESTBENCH_ID);
What I get in my console is this:
# %% Log ALWAYS in Default, :hostifrxswitcht(sim):netcheck[std_logic,t_vai64_if,t_queue,string,integer]:v_random0 ps at 0 ns
# %% Log ALWAYS in Default, v_wait: 50000 ps at 0 ns
# %% Log ALWAYS in Default, :hostifrxswitcht(sim):netcheck[std_logic,t_vai64_if,t_queue,string,integer]:v_random132000 ps at 132 ns
# %% Log ALWAYS in Default, v_wait: 50000 ps at 132 ns
# %% Log ALWAYS in Default, :hostifrxswitcht(sim):netcheck[std_logic,t_vai64_if,t_queue,string,integer]:v_random196000 ps at 196 ns
# %% Log ALWAYS in Default, v_wait: 50000 ps at 196 ns
# %% Log ALWAYS in Default, :hostifrxswitcht(sim):netcheck[std_logic,t_vai64_if,t_queue,string,integer]:v_random260000 ps at 260 ns
# %% Log ALWAYS in Default, v_wait: 50000 ps at 260 ns
This result irritates me, I assumed, that I would get a different value each time the procedure is called, because of the different seed. I use similar code in many of my procedures when I need random and had no problems with this approach until now.
Is this possibly a tool problem or is the problem sitting in front of the computer in this case? 😉
TorstenJanuary 26, 2018 at 07:43 #1426Jim LewisMember
This is an interaction between ieee.math_real.uniform and the seeds. Throw out your first random number and the rest look good.
Exciting issue. I explored this issue with the following similar procedure.
procedure RandProTest is
variable RV : RandomPType;
variable vSeed : RandomSeedType;
variable vTime : time;
variable vInt : integer;
variable vReal : real;
-- RV.InitSeed(RV'instance_name & to_string(now));
RV.InitSeed(now / 1 ns);
print(RV'instance_name & to_string(now));
print("Seed: " & to_string(RV.GetSeed)) ;
vSeed := RV.GetSeed ;
for i in 1 to 5 loop
-- print("Seed: " & to_string(vSeed)) ;
ieee.math_real.uniform(vSeed(vSeed'left), vSeed(vSeed'right), vReal) ;
print("vReal * 100: " & to_string(integer(round(vReal*100.0)))) ;
end loop ;
for i in 1 to 5 loop
-- print("Seed: " & to_string(RV.GetSeed)) ;
vInt := RV.RandInt(0, 100);
print("vInt: " & to_string(vInt));
end loop ;
end procedure RandProTest;
Note if you run this that the first number out for most calls to the procedure are identical. However, after that they are different.
Really quick it started to look an interaction between ieee.math_real.uniform and the seeds, so I called uniform directly in the procedure. I explored seeds some. The seeds generated using strings while different were fairly close numerically. To get some greater differences in the seeds, I tried (now / 1 ns). While these seeds were reasonably different, the first number randomized was mostly the same.
The good news is that the numbers generated after the first number look good.
Long Term Solution:
A better seed hashing function may help. I have thought about doing this in the past, however, it will change everyone’s tests. Hence, I hesitate. I think if it gets changed, it can get changed one time. In addition, based on this test, InitSeed should probably call uniform one time and that would address any deficiencies in the hashing.
Thoughts?January 26, 2018 at 11:20 #1427TorstenMember
Thanks, I get far better results with your workaround. If we change the seed function, we could look what kind of hash functions are used for dictionary types in languages like python. I assume, they use functions which are not cryptographic secure, but have a good uniform distribution and are very fast.
But you are right, with such a change, the generated randim numbers are different than before, so we have to carefully think about it. Maybe we should prefer a workaround with less impact. Maybe we could integrate your workaround in a new procedure? As a fast and short term solution? This is the way, I use until we fix this problem …
- You must be logged in to reply to this topic.