Random seed problem

Why OSVVM?ForumsOSVVMRandom seed problem

Tagged: 

This topic has 2 voices, contains 2 replies, and was last updated by Avatar of Torsten M. Torsten M. 26 days ago.

Viewing 3 posts - 1 through 3 (of 3 total)
Author Posts
Author Posts
January 26, 2018 at 04:43 #1424
Avatar of Torsten M.
Torsten M.

Hi everyone,

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;
begin
    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? ;)

Best regards,
Torsten

  • This reply was modified 27 days ago by Avatar of Torsten M. Torsten M..
January 26, 2018 at 07:43 #1426
Avatar of Jim Lewis
Jim Lewis

Hi Torsten

Short Answer:

This is an interaction between ieee.math_real.uniform and the seeds.  Throw out your first random number and the rest look good.

Long Answer:

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;
  begin
--      RV.InitSeed(RV'instance_name & to_string(now));
--      RV.InitSeed(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 #1427
Avatar of Torsten M.
Torsten M.

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 …

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.