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?
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:
procedure get_slv_no (variable seed1, seed2 :inoutpositive;signal s :outstd_logic_vector)isvariable r :real;variable randi :integer;alias s_a :std_logic_vector(s'length-1downto0)is s;-- to fix the rangevariable rembits :natural;variable highos :natural;begin
rembits := s_a'lengthrem32;
highos := s_a'length- rembits;for I in0to s_a'length/32-1loop
uniform (seed1,seed2,r);
randi :=integer( trunc((r -0.5)*2.0*(real(integer'high))+0.5));
s_a((i+1)*32-1downto I*32)<=std_logic_vector( to_signed (randi,32));endloop;-- 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'highdownto highos)<=std_logic_vector( to_signed(randi, rembits));endprocedure;
test :processisvariable seed1, seed2 :positive:= G_RANDOM_SEED;-- it can be useful to set the seed via a generic to allow different random sequences on different runsbeginwaitfor10ns;
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
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
impurefunction some_random returnrealisvariable r :realbegin
uniform(seed1, seed2, r);--note - seed1 and seed2 must be in scope of the "some_random" functionreturn r;endfunction;
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.