---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: -- Design Name: -- Module Name: ChlngLFSR_NoNorm - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- -- =================================================================================================== -- See comments in ChlngLFSR_NoNorm.vhd. This one implements the n-Ahead functionality. -- =================================================================================================== library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity ChlngLFSR_nAhead_NoNorm is generic( CLFSR_LEN_NB: integer := 12); port( Clk: in std_logic; RESET: in std_logic; start: in std_logic; init_seed: in std_logic; next_seq: in std_logic; seed_in: in std_logic_vector(CLFSR_LEN_NB-1 downto 0); RegionSizeMinus1: in std_logic_vector(CLFSR_LEN_NB-1 downto 0); set_n_ahead_val: in std_logic; inc_n_ahead: in std_logic; val_to_set: in std_logic_vector(CLFSR_LEN_NB-1 downto 0); n_ahead_setting: out std_logic_vector(CLFSR_LEN_NB-1 downto 0); ready: out std_logic; PRN: out std_logic_vector(CLFSR_LEN_NB-1 downto 0) ); end ChlngLFSR_nAhead_NoNorm; ARCHITECTURE beh of ChlngLFSR_nAhead_NoNorm is type state_type is (idle, check_PRN); signal state_reg, state_next: state_type; signal ready_reg, ready_next: std_logic; signal init_seed_reg, init_seed_next: std_logic; signal n_ahead_setting_reg, n_ahead_setting_next: unsigned(CLFSR_LEN_NB-1 downto 0); signal n_ahead_cnt_reg, n_ahead_cnt_next: unsigned(CLFSR_LEN_NB-1 downto 0); signal LFSR_out: std_logic_vector(CLFSR_LEN_NB-1 downto 0); signal set_seed: std_logic; signal gen_bit: std_logic; begin -- LFSR primitive, n bit polynomial LFSR12_B: entity work.LFSR12_wZERO(beh) generic map(LFSR_LEN_NB=>CLFSR_LEN_NB) port map (Clk=>Clk, RESET=>RESET, set_seed=>set_seed, gen_bit=>gen_bit, seed=>seed_in, LFSR_out=>LFSR_out); -- State and register logic process(Clk, RESET) begin if ( RESET = '1' ) then state_reg <= idle; init_seed_reg <= '0'; n_ahead_setting_reg <= (CLFSR_LEN_NB-1 downto 1 =>'0') & (0=>'1'); n_ahead_cnt_reg <= (others => '0'); ready_reg <= '1'; elsif ( Clk'event and Clk = '1' ) then state_reg <= state_next; init_seed_reg <= init_seed_next; n_ahead_setting_reg <= n_ahead_setting_next; n_ahead_cnt_reg <= n_ahead_cnt_next; ready_reg <= ready_next; end if; end process; -- Combo logic for state machine process (state_reg, init_seed, init_seed_reg, next_seq, start, LFSR_out, ready_reg, set_n_ahead_val, inc_n_ahead, val_to_set, n_ahead_setting_reg, n_ahead_cnt_reg, RegionSizeMinus1) begin state_next <= state_reg; ready_next <= ready_reg; init_seed_next <= init_seed_reg; n_ahead_setting_next <= n_ahead_setting_reg; n_ahead_cnt_next <= n_ahead_cnt_reg; set_seed <= '0'; gen_bit <= '0'; case state_reg is -- ======================= when idle => ready_next <= '1'; -- One or the other of these can occur but not both simultaneously (controlled by BitGenDriver). THIS ONLY -- SETS the n_ahead value, it does NOT cause n_head skipping to occur. This happens ONLY when 'init_seed' -- is set. if ( set_n_ahead_val = '1' ) then n_ahead_setting_next <= unsigned(val_to_set); elsif ( inc_n_ahead = '1' ) then n_ahead_setting_next <= n_ahead_setting_reg + 1; end if; -- Start the LFSR to generate PRN. if ( start = '1' ) then ready_next <= '0'; -- Initialize n_ahead_cnt for use when 'init_seed' is set to '1'. n_ahead_cnt_next <= (others => '0'); -- Handles case where we assert 'init_seed' and 'start', and both are released. Need to remember if -- 'init_seed' was asserted below. init_seed_next <= init_seed; -- Load the seed into the LFSR in this cycle and commence 'n_ahead' skipping in the following state -- if n_head_setting is not 0. if ( init_seed = '1' ) then set_seed <= '1'; state_next <= check_PRN; -- Enable the LFSR to generate the next bit. elsif ( next_seq = '1' ) then gen_bit <= '1'; state_next <= check_PRN; end if; end if; -- ======================= -- We need to run the LFSR until a value less than or equal to the 'RegionSizeMinus1' is produced AND we've moved -- ahead the requested number of numbers (if any). when check_PRN => -- Check that the generated number is less than the number of SMCs available. NOTE that RegionSizeMinus1 is always -- 1 less than a power of two, e.g., is 4095 for an CUBE size of 4096 SMCs. if ( unsigned(LFSR_out) <= unsigned(RegionSizeMinus1) ) then -- If next_seq is set to '1' (init_seed_reg is 0) or if init_seed_reg is 1 but n_ahead_setting is 0, then we -- are done since we have successfully produced a value. if ( init_seed_reg = '0' or n_ahead_setting_reg = 0 ) then ready_next <= '1'; state_next <= idle; -- Handle case where init_seed is 1 AND n_ahead_setting_reg is NOT 0. This combination indicates that we need to move -- ahead n_ahead numbers in the sequence as determined by the n_ahead_settings_reg. Keep incrementing until we reach the -- required number of n_ahead_cnts, e.g., if n_ahead_setting_reg is 1, then skip one 'valid' number. KEEP THIS INSIDE of -- the bounding 'if stmt' b/c the move ahead counter needs to be incremented ONLY on 'valid' numbers in the sequence. else n_ahead_cnt_next <= n_ahead_cnt_reg + 1; if ( n_ahead_cnt_reg = n_ahead_setting_reg ) then ready_next <= '1'; state_next <= idle; else gen_bit <= '1'; end if; end if; -- If LFSR has invalid value, generate next one and check again. else gen_bit <= '1'; end if; end case; end process; n_ahead_setting <= std_logic_vector(n_ahead_setting_reg); -- Set the PRN to the output of the LFSR PRN <= LFSR_out; ready <= ready_reg; end beh;