jeudi 29 décembre 2016

Scaling down a 128 bit Xorshift. - PRNG in vhdl

Im trying to figure out a way of generating random values (pseudo random will do) in vhdl using vivado (meaning that I can't use the math_real library).

These random values will determine the number of counts a prescaler will run for which will then in turn generate random timing used for the application.

This means that the values generated do not need to have a very specific value as I can always tweak the speed the prescaler runs at. Generally speaking I am looking for values between 1000 - 10,000, but a bit larger might do as well.

I found following code online which implements a 128 bit xorshift and does seem to work very well. The only problem is that the values are way too large and converting to an integer is pointless as the max value for an unsigned integer is 2^32.

This is the code:

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

entity XORSHIFT_128 is
    port (
        CLK : in std_logic;
        RESET : in std_logic;
        OUTPUT : out std_logic_vector(127 downto 0)
    );
end XORSHIFT_128;

architecture Behavioral of XORSHIFT_128 is
    signal STATE : unsigned(127 downto 0) := to_unsigned(1, 128);

begin
    OUTPUT <= std_logic_vector(STATE);

    Update : process(CLK) is
        variable tmp : unsigned(31 downto 0);
    begin
        if(rising_edge(CLK)) then
            if(RESET = '1') then
                STATE <= (others => '0');
            end if;
            tmp := (STATE(127 downto 96) xor (STATE(127 downto 96) sll 11));
            STATE <= STATE(95 downto 0) &
                ((STATE(31 downto 0) xor (STATE(31 downto 0) srl 19)) xor (tmp xor (tmp srl 8)));
        end if;
    end process;
end Behavioral;

For the past couple of hours I have been trying to downscale this 128 bit xorshift PRNG to an 8 bit, 16 bit or even 32 bit PRNG but every time again I get either no output or my simulation (testbench) freezes after one cycle.

I've tried just dividing the value which does work in a way, but the size of the output of the 128 bit xorshift is so large that it makes it a very unwieldy way of going about the situation.

Any ideas or pointers would be very welcome.




Aucun commentaire:

Enregistrer un commentaire