---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: -- Design Name: -- Module Name: ChlngLFSR_Norm - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- -- =================================================================================================== -- See comments in ChlngLFSR_Norm.vhd. This one implements the n-Ahead functionality. -- =================================================================================================== library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity ChlngLFSR_nAhead_Norm is generic( CLFSR_LEN_NB: integer := 4); 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); advance_grp: in std_logic; ready: out std_logic; PRN: out std_logic_vector(CLFSR_LEN_NB-1 downto 0) ); end ChlngLFSR_nAhead_Norm; ARCHITECTURE beh of ChlngLFSR_nAhead_Norm 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. LFSR4_B: entity work.LFSR4_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_next, 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, advance_grp) 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'); -- 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. We can optionally reset the 4 bit LFSRs, with 'advance_grp' included in -- the following if stmt, in which case the same order of comparisons is used in each region. The second -- one rotates comparisons and generates all 16 comparisons (only 15 of them within any one region). -- You can optionally take out 'advance_grp' in the if stmt if you want to just continuously cycle through -- the 4-bit LFSRs). ********* 'advance_grp == 1' IS ALSO INCLUDED IN ChlngLFSR_NormReg.vhd. -- Need to remember if 'init_seed' was asserted below. init_seed_next <= init_seed or advance_grp; if ( init_seed_next = '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 RegionSizeMinus1, which in this case is 15. -- This check is not necessary here. 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; -- Can NOT use '_next' here b/c this is used in BitGenDriver.vhd to set inc_n_ahead, which causes an oscillation -- see comment -- regarding n_ahead_setting in ChlngLFSR_NormReg.vhd 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;