---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: -- Design Name: -- Module Name: REBELController - 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; -- The REBEL controller is responsible for scanning in the configuration information and -- scanning out the results from the launch capture test. This path is always configured -- in path insertion mode -- (11) followed by a 0 (if leftmost FF is insertion point) or a -- 1 otherwise. The parameter 'insertion point' identifies the PUT output to be monitored -- FFs are numbered from left to right in the design, starting at REBEL_LENGTH_NB-1 on the -- left. So insertion point 0 refers to rightmost PUT. entity REBELController is Generic( DESIGN_WIDTH_LB: integer := 8; DESIGN_WIDTH_NB: integer := 256; REBEL_LENGTH_LB: integer := 9; REBEL_LENGTH_NB: integer := 272); port( Clk: in std_logic; RESET: in std_logic; do_config: in std_logic; dummy_bit: in std_logic; insertion_point: in std_logic_vector(REBEL_LENGTH_LB-1 downto 0); ready: out std_logic; ScanEn: out std_logic; scan_bit: out std_logic); end REBELController; architecture beh of REBELController is constant NUM_REBEL_HEADER_BITS_LB: integer := 2; constant NUM_REBEL_HEADER_BITS_NB: integer := 3; type state_type is (idle, load_REBEL_FFs, load_REBEL_header, completed); signal state_reg, state_next: state_type; signal scnt_reg, scnt_next: unsigned(REBEL_LENGTH_LB-1 downto 0); -- Number of header bits is only 3 so we don't need a three bit register to count up to three, but who cares. signal hcnt_reg, hcnt_next: unsigned(NUM_REBEL_HEADER_BITS_LB-1 downto 0); signal ready_reg, ready_next: std_logic; signal insertion_point_ext: std_logic_vector(REBEL_LENGTH_LB-1 downto 0); signal insertion_point_modified: unsigned(REBEL_LENGTH_LB-1 downto 0); begin -- Modify the insertion point to suit the algorithm described below. NOTE: although insertion_point -- can NEVER be larger than the DESIGN_WIDTH_NB, this is NOT true of the modified insertion point. -- For example, IT IS TRUE that insertion_point_modified can take on values larger than DESIGN_WIDTH_NB -- IN FACT, upto REBEL_LENGTH_NB + 1, for the case insertion_point is 7, we get 16 here -- SO WE NEED 1 EXTRA -- BIT BEYOND REBEL_LENGTH. insertion_point_ext <= insertion_point; insertion_point_modified <= unsigned(insertion_point_ext) + (REBEL_LENGTH_NB - DESIGN_WIDTH_NB) + 1; -- state and register logic process(Clk, RESET) begin if (RESET = '1') then state_reg <= idle; scnt_reg <= to_unsigned(0, REBEL_LENGTH_LB); hcnt_reg <= to_unsigned(0, NUM_REBEL_HEADER_BITS_LB); ready_reg <= '1'; elsif (Clk'event and Clk = '1') then state_reg <= state_next; scnt_reg <= scnt_next; hcnt_reg <= hcnt_next; ready_reg <= ready_next; end if; end process; -- Combo logic for state machine, iteration cnter and shift operations in data path process (state_reg, scnt_reg, hcnt_reg, do_config, insertion_point, insertion_point_modified, dummy_bit, ready_reg) begin ready_next <= ready_reg; state_next <= state_reg; scnt_next <= scnt_reg; hcnt_next <= hcnt_reg; ScanEn <= '0'; scan_bit <= '0'; -- ===================== case state_reg is when idle => ready_next <= '1'; -- Start a scan operation if ( do_config = '1' ) then ready_next <= '0'; -- Reset the counter scnt_next <= to_unsigned(0, REBEL_LENGTH_LB); state_next <= load_REBEL_FFs; end if; -- ===================== -- Start loading REBEL FFs right-most to left-most FF. when load_REBEL_FFs => -- Control scan enable to 1 and keep it there until the scan operation completes ScanEn <= '1'; -- Count up with cnter tracking output FFs in design, i.e., right-most FF is numbered 0 -- remember the REBEL -- row scan chain is loaded in reverse order. scnt_next <= scnt_reg + 1; -- If scnt_reg becomes equal to the insertion FF + 8 + 1, output a '0' (this makes the next FF to the right the insertion -- point). For example, if we want to insert the PUT output 0 (rightmost FF in design), then insertion_point is 0, -- insertion_point_modified is 0 + 8 + 1 = 9. scnt_reg is 0 (on first iteration), so we wait until 10th iteration (scnt_reg -- is 9) to insert the '0'. NOTE: insertion_point_modified can be set to the value 16 (for DESIGN_WIDTH_NB = 8 and for -- left-most insertion point) and is a 9-bit quantity (to allow upto 272) -- in which case this equality is never satisfied. if ( scnt_reg = insertion_point_modified ) then scan_bit <= '0'; -- While the cnter is less than the insertion point + 8 + 1, output 'dummy_bit' to scan chain. NOTE: These bits will be -- overwritten by the output of the path-under-test once flush delay mode is entered. For example, if we choose insertion -- point 1 (second FF from right in design), then output 'dummy_val' upto and including when scnt_reg is 9. Above case will -- be true when scnt_reg is 10. NOTE: leftmost insertion point is handled in the load_REBEL_header state below. elsif ( scnt_reg < insertion_point_modified ) then scan_bit <= dummy_bit; -- Else output '1s' else scan_bit <= '1'; end if; -- Exit if scnt_reg reaches the number of PUTs in the design if ( scnt_reg = REBEL_LENGTH_NB-1 ) then state_next <= load_REBEL_header; hcnt_next <= to_unsigned(0, NUM_REBEL_HEADER_BITS_LB); end if; -- ===================== -- Load the REBEL header info -- 3 bits. in reverse order when load_REBEL_header => -- Keep scan enable high -- hcnt_reg is initialized in previous state ScanEn <= '1'; hcnt_next <= hcnt_reg + 1; -- Set up header as mixed mode. The rightmost bit of the header is a FF to allow the leftmost PUT to be the insertion point. if ( hcnt_reg = 0 ) then if ( unsigned(insertion_point) = DESIGN_WIDTH_NB-1 ) then scan_bit <= '0'; else scan_bit <= '1'; end if; -- "11" is mixed mode in REBEL else scan_bit <= '1'; end if; -- Exit if hcnt_reg reaches the number of header bits in the design if ( hcnt_reg = NUM_REBEL_HEADER_BITS_NB-1 ) then state_next <= completed; end if; when completed => ready_next <= '1'; state_next <= idle; end case; end process; ready <= ready_reg; end beh;