---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 17:06:55 10/21/2011 -- Design Name: -- Module Name: ProcessInputParams - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- -- =================================================================================================== -- =================================================================================================== library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; -- This state machine responsible for processing input parameters. Most of them are simply remapped -- to signals. Some are asserted for only once clock cycle, e.g., signal to start the engine. entity ProcessInputParams is Generic( CTRL_REG_WIDTH_NB: integer := 32; XOR_INSPECTION_NUM_FFS_NB: integer := 5; MAX_NUM_SAMS_NB: integer := 8; LC_LFSR_LEN_NB: integer := 32; PHASE_SHIFT_LEN_NB: integer := 11); Port ( Clk: in std_logic; RESET: in std_logic; CtrlRegA: in std_logic_vector(CTRL_REG_WIDTH_NB-1 downto 0); RESET_IN_SOFT: out std_logic; TOP_start_engine: out std_logic; REBEL_target_FF: out std_logic_vector(XOR_INSPECTION_NUM_FFS_NB-1 downto 0); DEBUG_print_snapshots: out std_logic; DEBUG_print_PNs: out std_logic; DEBUG_processor_done_reading: out std_logic; TOP_log_n_num_sams: out std_logic_vector(MAX_NUM_SAMS_NB-1 downto 0); TOP_back_or_forward_search: out std_logic; LC_LFSR_seed: out std_logic_vector(LC_LFSR_LEN_NB-1 downto 0); TOP_PUFNum_range_threshold: out std_logic_vector(PHASE_SHIFT_LEN_NB-1 downto 0); TOP_phase_shift_inc_dec: out std_logic_vector(PHASE_SHIFT_LEN_NB-1 downto 0); TOP_skip_path: out std_logic; TOP_enrollment: out std_logic; TOP_regeneration: out std_logic; TOP_authentication: out std_logic ); end ProcessInputParams; architecture beh of ProcessInputParams is type start_stop_state_type is (idle, wait_reset); signal start_stop_state_reg, start_stop_state_next: start_stop_state_type; type debug_state_type is (idle, wait_done_reset); signal debug_state_reg, debug_state_next: debug_state_type; begin -- Function specified in low order 2 bits: Note: AuthenticationE and R are still Authentication within the VHDL -- code. The C code, however, distinguishes between them only to allow bit flips to be counted and reported on -- from two runs of authentication. -- "00": Enrollment -- "01": Regeneration -- "10": AuthenticationE -- "11": AuthenticationR TOP_enrollment <= '1' when CtrlRegA(1 downto 0) = "00" else '0'; TOP_regeneration <= '1' when CtrlRegA(1 downto 0) = "01" else '0'; TOP_authentication <= '1' when CtrlRegA(1) = '1' else '0'; -- This refers to the REBEL FF to which the transition must propagate, where 0 specifies the insertion point itself. -- CAN NOT BE LARGER THAN XOR_INSPECTION_NUM_FFS (16). This is true because the rightmost PUT output (labeled 0) has -- 16 FFs to its right that define the 'extended' delay chain. REBEL_target_FF <= "0" & CtrlRegA(5 downto 2); -- Whether only a backwards sweep is performed (0) or both a forward (first) and backward (second) sweep is performed -- during enrollment. TOP_back_or_forward_search <= CtrlRegA(6); -- Log of the number of samples -- 0 indicates 1 sample. TOP_log_n_num_sams <= "00000" & CtrlRegA(9 downto 7); -- Can be all 0 -- inserted the zero-handling LFSR recently. LC_LFSR_seed <= "000000000000000000000000" & CtrlRegA(17 downto 10); -- Each phase shift increment (at 50 MHz) is 17.86 ps. This allows increments and decrements of multipl FPAs between each -- consecutive LC test in the sweep. MUST be set to a value > 0. TOP_phase_shift_inc_dec <= "0000000" & CtrlRegA(21 downto 18) when unsigned(CtrlRegA(21 downto 18)) > to_unsigned(0, 4) else "00000000001"; -- User specified range tolerance, which is enforced in LCTest_Base only during enrollment and only if the user has not -- specified 15, in which case, it is disabled. TOP_PUFNum_range_threshold <= "0000000" & CtrlRegA(25 downto 22); -- If set to '1', the current path is NOT tested. During regeneration, we need to skip paths that during enrollment were -- not valid. Setting this to '1' and starting the engine causes the LFSR to advance (when needed) and the REBEL_Config_ins_point -- to be updated but not test is carried out. Need to do it this way in case the next start sequence is issued by the C program BEFORE -- the LCTest_Driver.vhd state machine returns to idle (don't think that happens but this ensures we don't miss the skip request). TOP_skip_path <= CtrlRegA(26); -- DEBUG, print PNs DEBUG_print_PNs <= CtrlRegA(27); -- DEBUG, print snapshots DEBUG_print_snapshots <= CtrlRegA(28); -- Soft RESET. RESET_IN_SOFT <= CtrlRegA(31); -- State machine to start the engine and wait for completion process(Clk, RESET) begin if (RESET = '1') then start_stop_state_reg <= idle; debug_state_reg <= idle; elsif (Clk'event and Clk = '1') then start_stop_state_reg <= start_stop_state_next; debug_state_reg <= debug_state_next; end if; end process; -- ================================================================================================================ -- This state machine allows the user to start the engine by writing a '1' to the 'start' bit, but does not -- allow the engine to be started again until the user writes a '0' to this bit AND the process finishes. process (start_stop_state_reg, CtrlRegA) begin start_stop_state_next <= start_stop_state_reg; TOP_start_engine <= '0'; case start_stop_state_reg is -- ===================== -- User writes a '1' to the start bit. Assert the TOP_start_engine flag for 1 cycle and then wait for the user -- to write a '0' again. NOTE: We MUST start the engine as SOON as CtrlRegA(30) becomes 1 since we may also -- be SKIPPING the testing of this path (CtrlRegA(26) above), which is checked simultaneously. when idle => if ( CtrlRegA(30) = '1' ) then TOP_start_engine <= '1'; start_stop_state_next <= wait_reset; end if; -- ===================== -- Return to idle if the 'start_engine' bit written by the user becomes '0'. when wait_reset => if ( CtrlRegA(30) = '0' ) then start_stop_state_next <= idle; end if; end case; end process; -- ================================================================================================================ -- This state machine monitors the bit that the processor writes to indicate it is done reading the debug data. process (debug_state_reg, CtrlRegA) begin debug_state_next <= debug_state_reg; DEBUG_processor_done_reading <= '0'; case debug_state_reg is -- ===================== -- Wait for the processor to write a '1' indicating it has read the debug data. when idle => if ( CtrlRegA(29) = '1' ) then debug_state_next <= wait_done_reset; end if; -- ===================== -- Wait for the processor to write a '0' before signaling the engine to continue. when wait_done_reset => if ( CtrlRegA(29) = '0' ) then DEBUG_processor_done_reading <= '1'; debug_state_next <= idle; end if; end case; end process; end beh;