Seeding random number generator

Discussion in 'VHDL' started by hepmehepme@comcast.net, May 7, 2009.

  1. Guest

    Sorry if this has been covered already. I am developing a testbench
    for a design and I want the behavioral models for external devices to
    use random parameters within the constraints of the data sheets. I
    figured out how to start up a sim with a seed variable in Modelsim,
    but now I'm confused about how to use that seed. Say I have two
    processes, each controlling one aspect of an ADC. Does each process
    have its own random number stream or do they share some global random
    number stream? In other words, does each process access a global seed
    or do they each maintain their own seeds. I was thinking that a global
    seed may be dangerous because it may change in a non-deterministic
    fashion. Here is an example with local seeds. The first process
    controls the ADC convert to busy timing, the second process controls
    the prop delay through a mux. Each takes the initial value for the
    seed from the generic for the testbench and then keeps a local copy of
    the seed. Is this the right way to do this?

    procedure rand_time(
    variable seed1, seed2 : inout positive;
    min, max : in integer;
    result : out time
    ) is
    variable rand : real;
    begin
    uniform(seed1, seed2, rand);
    result := (integer(real(min) + (rand * (real(max)-real(min)) ) ))* 1
    ps;
    end procedure;

    -- ADC busy timing
    convert : process
    variable s1 : integer;
    variable s2 : integer;
    variable t6 : time;
    variable tconv : time;
    variable init : std_logic;
    begin
    -- Init seeds from generic if not already initialized
    if(init /= '1')then
    s1 := gSEED;
    s2 := s1/2 + 50;
    init := '1';
    end if;
    busy_n <= '1';

    wait until falling_edge(convst_n);
    if(cs_n = '0')and(shtdn_n = '1')then
    rand_time(s1, s2, MIN_T6, MAX_T6, t6);
    rand_time(s1, s2, MIN_TCONV, MAX_TCONV, tconv);
    busy_n <= '0' after t6;
    wait for (tconv - t6);
    busy_n <= '1';
    dtemp <= din;
    end if;
    end process convert;

    -- mux timing
    mux : process (en_n, mux_sel)
    variable s1: integer;
    variable s2: integer;
    variable p : time;
    variable init : std_logic;
    begin
    -- Init seeds from generic if not already initialized
    if(init /= '1')then
    s1 := gSEED;
    s2 := s1/2 + 50;
    init := '1';
    end if;

    rand_time(s1, s2, MIN_DELAY, MAX_DELAY, p);

    if(en_n = '1') then
    dout <= (others => 'Z') after p;

    else
    dout(15 downto 12) <= mux_sel after p;
    dout(11 downto 0) <= (others => '0') after p;
    end if;
    end process mux;
     
    , May 7, 2009
    #1
    1. Advertising

  2. Tricky Guest

    There is no Global seed. The seeds are stored in the seed variables
    (s1 and s2 in each process) you have. If you monitored them you'd
    notice that they change every time you call the uniform function, and
    hence why they are of mode "inout".

    So in effect there is no "random number stream" as you put it - just a
    formula that gives you a value based on s1 and s2, and s1 and s2 are
    changed after each call.

    This is useful because it allows repeatability of random streams. You
    can check output by seeding the expected output sequence with the same
    seeds you initialised the input sequence with.
     
    Tricky, May 7, 2009
    #2
    1. Advertising

  3. Tricky Guest


    > procedure rand_time(
    > variable seed1, seed2 : inout positive;
    > min, max : in integer;
    > result : out time
    > ) is
    > variable rand : real;
    > begin
    > uniform(seed1, seed2, rand);
    > result := (integer(real(min) + (rand * (real(max)-real(min)) ) ))* 1
    > ps;
    > end procedure;



    Another point: this function doesnt have the correct probability for
    min and max occuring.
    If n is the probability for any value occuring, the values of Min and
    Max themselves have a probability of n/2. This is because the integer
    conversion function rounds to nearest rather than truncate which means
    min and max only have a 0-0.5 range each, rather than 0-1.0.

    eg:

    Min = 0, Max = 3.

    result Actual output
    before rounding
    0.0-0.5 0
    0.5-1.5 1
    1.5-2.5 2
    2.5-3.0 3

    Therefore 1 and 2 are each twice as likely to occur than 0 and 3.


    I have a very similar procedure for integers, and found the solution
    to the problem thus (thanks to who posted the random testing package
    the other week :) ):

    procedure rand_int( variable seed1, seed2 : inout positive; min, max :
    in integer; result : out integer) is
    variable rand : real;
    variable val_range : real;
    begin
    assert (max >= min) report "Rand_int: Range Error" severity Failure;

    uniform(seed1, seed2, rand);
    val_range := real(Max - Min + 1);
    result := integer( trunc(rand * val_range )) + min;
    end procedure;

    This increases the
     
    Tricky, May 7, 2009
    #3
  4. JimLewis Guest

    You can simplify this greatly by using the packages that I developed.
    They layer on top of procedure uniform.

    Packages and usage notes are available at:
    http://www.synthworks.com/downloads/index.htm

    The presentation focuses on randomizing integers, however,
    time values can be generated by multiplying by 1 ns.
    To inspire you, your process would be:

    Compile packages - directions are in the download

    Use SynthWorks.RandomPkg.all ; -- reference package

    process
    variable RV : RandomPType ; -- declare randomization variable
    begin
    -- Initialize Seed -- done once
    RV.SetSeed( (7, 1) ) ; -- optional if you only are doing one thread
    of randomization
    ...
    p := 1 ns * RV.RandInt(MIN_DELAY, MAX_DELAY) ;


    Cheers,
    Jim
    SynthWorks VHDL Training

    P.S. We teach randomization plus self-checking, transaction-based
    testing,
    and verification data structures (linked-lists, scoreboards,
    memories),
    in our VHDL Testbenches and Verification classes.
    See: http://www.synthworks.com/vhdl_testbench_verification.htm
     
    JimLewis, May 7, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joe
    Replies:
    2
    Views:
    492
    Howard
    Nov 19, 2004
  2. Random Seeding

    , May 15, 2006, in forum: C Programming
    Replies:
    13
    Views:
    633
    Eric Sosman
    May 16, 2006
  3. Jack
    Replies:
    4
    Views:
    421
  4. HumanJHawkins
    Replies:
    2
    Views:
    514
    peter koch
    Nov 30, 2006
  5. Carl Banks

    Re: Seeding the rand() Generator

    Carl Banks, Aug 3, 2009, in forum: Python
    Replies:
    4
    Views:
    479
    Nils Ruettershoff
    Aug 6, 2009
Loading...

Share This Page