---------------------------------------------------------------------------------- -- 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: -- ---------------------------------------------------------------------------------- -- =================================================================================================== -- This module controls the random values used to generate a specific challenge. When 'init_seed' is '1', -- the seed is placed into the LFSR_reg on the first cycle when 'start' is asserted. If 'init_seed' is '0', -- then a second signal, 'next_seq', is examined. If '1', then the LFSR is advanced one clock. -- The maximal LFSR generate 2^n values (INCLUDING the all zero case). The number of sense voltages in -- our PUF however may not be a power of two. The number is given by 'TOP_NUM_SMCS'. Here, I choose an -- LFSR length that meets the requirement that TOP_NUM_SMCS <= 2^n and skip all values that are greater -- than TOP_NUM_SMCS. This ensures that all values are visited (eventually). -- My initial plan is to use a 12-bit LFSR which can generate upto 4096 numbers. My array will have 4096 SMCs -- To generate more than 4095 pairings, I create two instantiations of this module. For the first 4095 number -- generations, I set the second copy 1 generation ahead of the first. Assuming no pseudo-randomness, the -- numbers generated for a 3-bit LFSR would be -- 1 2 3 4 5 6 7: First copy -- 2 3 4 5 6 7 1: Second copy -- I would limit this to 2^3-2 = 6 sequences, the 2^n-1 = 7 default minus 1 (the 1-ahead value). -- Then the next 2-ahead sequence would be -- 1 2 3 4 5 6 7: First copy (same sequence) -- 3 4 5 6 7 1 2 -- I would limit this to 2^3-3 = 5 sequences, the 2^n-1 = 7 default minus 2 (the 2-ahead value). This strategy -- allows me to use all the original base entropy first before starting to reuse the base entropy. -- See PUF_DOCUMENTATION for more details here. -- =================================================================================================== library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity ChlngLFSR_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); ready: out std_logic; PRN: out std_logic_vector(CLFSR_LEN_NB-1 downto 0) ); end ChlngLFSR_NoNorm; ARCHITECTURE beh of ChlngLFSR_NoNorm is type state_type is (idle, check_PRN); signal state_reg, state_next: state_type; signal ready_reg, ready_next: std_logic; 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 LFSR12_A: 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; ready_reg <= '1'; elsif ( Clk'event and Clk = '1' ) then state_reg <= state_next; ready_reg <= ready_next; end if; end process; -- Combo logic for state machine process (state_reg, init_seed, next_seq, start, LFSR_out, ready_reg, RegionSizeMinus1) begin state_next <= state_reg; ready_next <= ready_reg; set_seed <= '0'; gen_bit <= '0'; case state_reg is -- ======================= when idle => ready_next <= '1'; -- Start the LFSR to generate PRN. if ( start = '1' ) then ready_next <= '0'; -- Load the seed into the LFSR (which is stored in a register by ManageParams.vhd at startup). 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 when check_PRN => -- Check that the generated number is less than the number of SMCs - 1 available. if ( unsigned(LFSR_out) <= unsigned(RegionSizeMinus1) ) then ready_next <= '1'; state_next <= idle; -- If LFSR has invalid value, generate next one and check again. else gen_bit <= '1'; end if; end case; end process; -- Set the PRN to the output of the LFSR PRN <= LFSR_out; ready <= ready_reg; end beh;