Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Random number generator function is same for each call

Status
Not open for further replies.

wtr

Full Member level 5
Joined
May 1, 2014
Messages
299
Helped
29
Reputation
58
Reaction score
25
Trophy points
1,308
Activity points
4,108
Hello all,

See the following


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function get_slv_no (W : integer) return std_logic_vector is
    variable seed1 : positive ;
    variable seed2 : positive ;
    variable re1   : integer;
    variable re2   : real ;
    -- variable num   : std_logic_vector (15 downto 0) ;
    variable num_t : std_logic_vector (W-1 downto 0) ;
begin
    for I in 1 to W/16 loop
        uniform (seed1,seed2,re2);
        re1 := integer (re2 * real(2**16 -1)); 
        num_t(16*I-1 downto 16*(I-1)) := std_logic_vector ( to_unsigned (re1,16));
    end loop;
    return num_t;
end function;




Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
test : process is
  begin
    wait for 10 ns;
    num32 <= get_slv_no(num32'length);
    wait for 10 ns;
    num64 <= get_slv_no(num64'length);
    wait for 10 ns;
    num512 <= get_slv_no(num512'length);
    wait for 10 ns;
    num512 <= get_slv_no(num512'length);
    wait for 10 ns;
    num512 <= get_slv_no(num512'length);
    wait for 10 ns;
    num32 <= (others => '0');
    wait for 10 ns;
    num32 <= get_slv_no(num32'length);
    wait for 10 ns;
    num32 <= get_slv_no(num32'length);
    wait for 10 ns;
    report "" severity failure;
end process;



The random number generator can do one random number, however when called again later in the sequence it does not generate a different number.
Is this because my seed is re-initialised each time?

If I externally change the seed in, then I can manipulate it accordingly. Is there a way I can somehow link the seed to the run time?

Regards,
Wes
 

Thats because your seeds always start at 1 every time you call the function.
If you note the uniform procedure definition, you'll see the seeds are defined as inout. This means the seeds are modified during every call of the uniform procedure and written back to their source.
So you will need to do the same - make this funciton into a procedure with inout seeds and have the seed variables stored in the "test" process in the testbench:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
procedure get_slv_no ( variable seed1, seed2 : inout positive; 
                       signal              s : out   std_logic_vector) is  
  variable r        : real;
  variable randi    : integer;
  alias s_a         : std_logic_vector(s'length-1 downto 0) is s;     -- to fix the range
                    
  variable rembits  : natural;
  variable highos   : natural;
begin
    rembits := s_a'length rem 32;
    highos  := s_a'length - rembits;
  
    for I in 0 to s_a'length/32 - 1 loop
        uniform (seed1,seed2,r);
        randi := integer ( trunc( (r - 0.5)*2.0 * ( real(integer'high) ) + 0.5) ); 
        s_a((i+1)*32 -1 downto I*32) <= std_logic_vector ( to_signed (randi,32));
    end loop;
    
    -- assign MSBs not divisible by 32
    uniform(seed1, seed2, r);
    randi := integer( trunc( (r - 0.5)*2.0 * ( real( 2**rembits-1 ) + 0.5 ) ) ); 
    s_a(s_a'high downto highos) <= std_logic_vector( to_signed(randi, rembits) );
    
end procedure;
 
 
 
 
test : process is
  variable seed1, seed2 : positive := G_RANDOM_SEED; -- it can be useful to set the seed via a generic to allow different random sequences on different runs
  begin
    wait for 10 ns;
    get_slv_no(seed1, seed2, num32);
  -- etc



- - - Updated - - -

PS. You may want to look into OSVVM, as it has some very powerful random number generation tools, and is available in most simulators

https://osvvm.org/
 

I can see that a procedure allows for the inout of the seeds, however do you know of a function based way to do this? Would I need to manually drive the seed?
 

you could do it via an impure function that had the seeds in scope. The problem with a self contained function is that the seed variables are removed when the function returns.


Code VHDL - [expand]
1
2
3
4
5
6
impure function some_random return real is
  variable r : real
begin
  uniform(seed1, seed2, r);  --note - seed1 and seed2 must be in scope of the "some_random" function
  return r;
end function;



The problem here is the function cannot live in a normal package because seed1/2 must be variables, and you are not allowed variables in a package (2008: unless the package is declared inside a region that allows variables, like a process or function)

You could of course have it as a function from a protected type - then the seeds could live inside the protected type, and the protected type lives in a package. But if you're going to do this, you might as well look at osvvm.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top