diff --git a/rtl/xoroshiro128plus.vhdl b/rtl/rng_xoroshiro128plus.vhdl similarity index 72% rename from rtl/xoroshiro128plus.vhdl rename to rtl/rng_xoroshiro128plus.vhdl index d3c24a6..758fef0 100644 --- a/rtl/xoroshiro128plus.vhdl +++ b/rtl/rng_xoroshiro128plus.vhdl @@ -4,7 +4,7 @@ -- Author: Joris van Rantwijk -- -- This is a 64-bit random number generator in synthesizable VHDL. --- The generator produces 64 new random bits on every (enabled) clock cycle. +-- The generator can produce 64 new random bits on every clock cycle. -- -- The algorithm "xoroshiro128+" is by David Blackman and Sebastiano Vigna. -- See also http://xoroshiro.di.unimi.it/ @@ -14,8 +14,8 @@ -- to initialize the generator at reset. The generator also supports -- re-seeding at run time. -- --- After reset, at least one clock cycle is needed before valid --- random data appears on the output. +-- After reset and after re-seeding, at least one clock cycle is needed +-- before valid random data appears on the output. -- -- NOTE: This is not a cryptographic random number generator. -- @@ -39,7 +39,7 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; -entity xoroshiro128plus is +entity rng_xoroshiro128plus is generic ( -- Default seed value. @@ -53,29 +53,37 @@ entity xoroshiro128plus is -- Synchronous reset, active high. rst: in std_logic; - -- Clock enable, active high. - enable: in std_logic; - - -- High to re-seed the generator (requires enable = '1'). + -- High to request re-seeding of the generator. reseed: in std_logic; -- New seed value (must be valid when reseed = '1'). newseed: in std_logic_vector(127 downto 0); - -- Output value. - -- A new value appears on every rising clock edge where enable = '1'. - output: out std_logic_vector(63 downto 0) ); + -- High when the user accepts the current random data word + -- and requests new random data for the next clock cycle. + out_ready: in std_logic; + + -- High when valid random data is available on the output. + -- This signal is low during the first clock cycle after reset and + -- after re-seeding, and high in all other cases. + out_valid: out std_logic; + + -- Random output data (valid when out_valid = '1'). + -- A new random word appears after every rising clock edge + -- where out_ready = '1'. + out_data: out std_logic_vector(63 downto 0) ); end entity; -architecture xoroshiro128plus_arch of xoroshiro128plus is +architecture xoroshiro128plus_arch of rng_xoroshiro128plus is -- Internal state of RNG. signal reg_state_s0: std_logic_vector(63 downto 0) := init_seed(63 downto 0); signal reg_state_s1: std_logic_vector(63 downto 0) := init_seed(127 downto 64); -- Output register. + signal reg_valid: std_logic; signal reg_output: std_logic_vector(63 downto 0) := (others => '0'); -- Shift left. @@ -105,16 +113,18 @@ architecture xoroshiro128plus_arch of xoroshiro128plus is begin -- Drive output signal. - output <= reg_output; + out_valid <= reg_valid; + out_data <= reg_output; -- Synchronous process. process (clk) is begin if rising_edge(clk) then - if enable = '1' then + if out_ready = '1' or reg_valid = '0' then -- Prepare output word. + reg_valid <= '1'; reg_output <= std_logic_vector(unsigned(reg_state_s0) + unsigned(reg_state_s1)); @@ -128,18 +138,20 @@ begin reg_state_s1 <= rotl(reg_state_s0, 36) xor rotl(reg_state_s1, 36); - -- Re-seed function. - if reseed = '1' then - reg_state_s0 <= newseed(63 downto 0); - reg_state_s1 <= newseed(127 downto 64); - end if; + end if; + -- Re-seed function. + if reseed = '1' then + reg_state_s0 <= newseed(63 downto 0); + reg_state_s1 <= newseed(127 downto 64); + reg_valid <= '0'; end if; -- Synchronous reset. if rst = '1' then reg_state_s0 <= init_seed(63 downto 0); reg_state_s1 <= init_seed(127 downto 64); + reg_valid <= '0'; reg_output <= (others => '0'); end if;