Search code examples
vhdluniform

Random Generator using UNIFORM


I am trying to generate a random number for a little game and I tried to use the UNIFORM function from the package MATH_REAL.

I get a value when I test my code, but it never changes. I tried to make the code happen at every rising_edge but it didn't change anything. I couldn't find or think of an effective fix.

I think I know that problem is simply that my random number is generated only once, but I couldn't figure out a way to change this.

Here is what I implemented (my variation with the clock) :

    rand: process (count1) 
        variable seed1, seed2 : positive;
        variable rand : real;
        variable int_rand : integer range 1 to 5;
    begin
        if rst_i='1' then
            count1 <= 1;
        elsif rising_edge(clk_i) then
            UNIFORM(seed1, seed2, rand);
            int_rand := INTEGER(TRUNC(rand*5.0));
            count1 <= int_rand;
        end if;
    end process;

The value of count1 is then used in another process. The above code gives the same simulation results as simply :

    rand: process (count1) 
        variable seed1, seed2 : positive;
        variable rand : real;
        variable int_rand : integer range 1 to 5;
    begin
        UNIFORM(seed1, seed2, rand);
        int_rand := INTEGER(TRUNC(rand*5.0));
        count1 <= int_rand;
    end process;

Is there a simple way to ensure more that a random number is generated more than once?


Solution

  • When the purpose is to generate a random number on count1 for every rising edge of clk_i, then update the sensitivity list for the process to (assuming async reset by rst_i):

    rand: process (rst_i, clk_i)
    

    This will make the process reexecute at every change of rst_i or clk_i, where the sensitivity list of count1 reexecutes at change of count1 only.

    Note that variable int_rand : integer range 1 to 5; should be range 0 to 4, since uniform result is > 0.0 and < 1.0.

    An interesting behavior is, that a sensitivity list of rand: process (count1) as for the second process, without the if guarding generation on count1, will actually make the process reexecute several times start of simulation, until the generated count1 value is identical to the previous count1 value, in which case the is no change on count1 to trigger reexecution of the process, and then process is then not executed any more.