Random seed problem

Why OSVVM™? Forums OSVVM Random seed problem

Tagged: 

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #1424
    Torsten
    Member

    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

    #1426
    Jim Lewis
    Member

    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?

    #1427
    Torsten
    Member

    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.