-- © IBM Corp. 2020 -- Licensed under the Apache License, Version 2.0 (the "License"), as modified by -- the terms below; you may not use the files in this repository except in -- compliance with the License as modified. -- You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -- -- Modified Terms: -- -- 1) For the purpose of the patent license granted to you in Section 3 of the -- License, the "Work" hereby includes implementations of the work of authorship -- in physical form. -- -- 2) Notwithstanding any terms to the contrary in the License, any licenses -- necessary for implementation of the Work that are available from OpenPOWER -- via the Power ISA End User License Agreement (EULA) are explicitly excluded -- hereunder, and may be obtained from OpenPOWER under the terms and conditions -- of the EULA. -- -- Unless required by applicable law or agreed to in writing, the reference design -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License -- for the specific language governing permissions and limitations under the License. -- -- Additional rights, including the ability to physically implement a softcore that -- is compliant with the required sections of the Power ISA Specification, are -- available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be -- obtained (along with the Power ISA) here: https://openpowerfoundation.org. -- -- Description: Pervasive ABIST ASIC Bolt-On -- --***************************************************************************** library ieee; use ieee.std_logic_1164.all; library ibm; use ibm.std_ulogic_support.all; use ibm.std_ulogic_function_support.all; use ibm.std_ulogic_unsigned.all; library support; use support.power_logic_pkg.all; library tri; use tri.tri_latches_pkg.all; entity pcq_abist_bolton_frontend is generic( expand_type : integer := 2; -- 0 = ibm (Umbra), 1 = non-ibm, 2 = ibm (MPG) num_backends : integer := 44); port( vdd : inout power_logic; gnd : inout power_logic; nclk : in clk_logic; -- BISTCNTL interface bcreset : in std_ulogic; bcdata : in std_ulogic; bcshcntl : in std_ulogic; bcshdata : in std_ulogic; bcexe : in std_ulogic; bcsysrepair : in std_ulogic; bo_enable : in std_ulogic; bo_go : in std_ulogic; -- daisy chain donein : in std_ulogic; sdin : in std_ulogic; doneout : out std_ulogic; sdout : out std_ulogic; diagloop_out : out std_ulogic; waitin : in std_ulogic; failin : in std_ulogic; waitout : out std_ulogic; failout : out std_ulogic; -- abist engine abist_done : in std_ulogic; -- bist engine done abist_start_test_int : out std_ulogic; -- start bist abist_start_test : in std_ulogic; -- start bist abist_si : out std_ulogic; -- to SI of bist engine (reg write) abist_mode_dc : in std_ulogic; abist_mode_dc_int : out std_ulogic; -- back ends bo_unload : out std_ulogic; bo_load : out std_ulogic; bo_repair : out std_ulogic; -- load repair reg bo_reset : out std_ulogic; -- reset backends bo_shdata : out std_ulogic; -- shift data for timing and signature write and diag loop bo_select : out std_ulogic_vector(0 to num_backends-1); -- select for mask and hier writes bo_fail : in std_ulogic_vector(0 to num_backends-1); -- fail/no-fix bo_diagout : in std_ulogic_vector(0 to num_backends-1); -- to diag mux -- thold / scan lbist_ac_mode_dc : in std_ulogic; ck_bo_sl_thold_6 : in std_ulogic; ck_bo_sl_thold_0 : in std_ulogic; -- local thold ck_bo_sg_0 : in std_ulogic; -- local scan gate lcb_mpw1_dc_b : in std_ulogic; lcb_mpw2_dc_b : in std_ulogic; lcb_delay_lclkr_dc : in std_ulogic; lcb_clkoff_dc_b : in std_ulogic; lcb_act_dis_dc : in std_ulogic; scan_in : in std_ulogic; -- scan in for frontend regs scan_out : out std_ulogic; -- scan out for frontend regs -- top level thold / sg outputs, may be again overrided in leaves bo_pc_abst_sl_thold_6 : out std_ulogic; -- thold to abist registers bo_pc_pc_abst_sl_thold_6 : out std_ulogic; -- thold to bist engine bo_pc_ary_nsl_thold_6 : out std_ulogic; -- thold to arrays bo_pc_func_sl_thold_6 : out std_ulogic; -- thold to staging latches bo_pc_time_sl_thold_6 : out std_ulogic; -- thold to timing regs bo_pc_repr_sl_thold_6 : out std_ulogic; -- thold to repair regs bo_pc_sg_6 : out std_ulogic); -- scan enable to all registers, -- actual shifting controlled by tholds -- synopsys translate_off -- synopsys translate_on end pcq_abist_bolton_frontend; architecture pcq_abist_bolton_frontend of pcq_abist_bolton_frontend is --===================================================================== -- Types and Constants --===================================================================== subtype Rstate is integer range 0 to 13; subtype Tstate is std_ulogic_vector(Rstate); subtype Renum is integer range 0 to 11; subtype Tenum is std_ulogic_vector(Renum); subtype Rinstruction is integer range 0 to 19; subtype Tinstruction is std_ulogic_vector(Rinstruction); subtype Rmode is integer range Rinstruction'right-19 to Rinstruction'right-17; subtype Tmode is std_ulogic_vector(Rmode); constant Rkind : integer := Rinstruction'right-16; constant Rloop : integer := Rinstruction'right-10; constant Raccumulate : integer := Rinstruction'right-7; constant RFARR : integer := Rinstruction'right-1; constant Rmfctmode : integer := Rinstruction'right; subtype Tkind is std_ulogic; subtype Raddr is integer range Rinstruction'right-15 to Rinstruction'right-4; subtype Taddr is std_ulogic_vector(Raddr); subtype Rw_addr is integer range Rinstruction'right-3 to Rinstruction'right; subtype Tw_addr is std_ulogic_vector(0 to 3); subtype Rr_addr is integer range Rinstruction'right-7 to Rinstruction'right; subtype Tr_addr is std_ulogic_vector(0 to 7); subtype Tshuttle is std_ulogic_vector(bo_fail'range); subtype Tmemmask is Tshuttle; subtype Tcounter is std_ulogic_vector(0 to 11); subtype Tdiagptr is std_ulogic_vector(0 to 7); constant Rdiagptr_enable : integer := 0; -- bit set to 0: diag rotate disabled, no arrays selected during hierarchical writes constant Rdiagptr_override : integer := 7; -- bit set to 0: bits 1-7 select array for diag/hierarchical write; bit set to 1: all arrays selected for hier. write subtype Rbackend_select is integer range 1 to 6; subtype Tdiagdecr is std_ulogic_vector(0 to 31); subtype Rdiagdecr is integer range Tdiagdecr'right-29 to Tdiagdecr'right; constant Rdiagdecr_enable : integer := Tdiagdecr'right-30; constant Rdiagdecr_evs : integer := Tdiagdecr'right-31; constant type_num : std_ulogic_vector(0 to 11) := X"129"; constant fareg_length : Tcounter := X"020"; constant max_sticky_length : Tcounter := X"240"; constant warmup_length : Tcounter := X"010"; constant scan_offset_0 : integer := 0; constant scan_offset_1 : integer := scan_offset_0 + 7; constant scan_offset_2 : integer := scan_offset_1 + 3; constant scan_offset_3 : integer := scan_offset_2 + Tstate'length + 3; constant scan_offset_4 : integer := scan_offset_3 + Tenum'length; constant scan_offset_5 : integer := scan_offset_4 + Tinstruction'length; constant scan_offset_6 : integer := scan_offset_5 + Tshuttle'length; constant scan_offset_7 : integer := scan_offset_6 + Tcounter'length; constant scan_offset_8 : integer := scan_offset_7 + Tdiagptr'length; constant scan_offset_9 : integer := scan_offset_8 + 1; constant scan_offset_10 : integer := scan_offset_9 + Tmemmask'length; constant scan_offset_11 : integer := scan_offset_10 + 1; constant scan_offset_12 : integer := scan_offset_11 + Tdiagdecr'length; constant scan_offset_13 : integer := scan_offset_12 + 2; constant scan_offset_14 : integer := scan_offset_13 + bo_fail'length; subtype Tint_scan is std_ulogic_vector(0 to scan_offset_14-1); type sul_bool is array(boolean) of std_ulogic; constant pos : sul_bool := ( false => '0' , true => '1'); --===================================================================== -- State Machine Constants --===================================================================== constant SC_IDLE : integer := 0; constant SC_ENUM : integer := 1; constant SC_WRITE : integer := 2; constant SC_READ : integer := 3; constant SC_IRLOAD : integer := 4; constant SC_DIAGROT : integer := 5; constant SC_0 : integer := 6; constant SC_1 : integer := 7; constant SC_2 : integer := 8; constant SC_3PRE : integer := 9; constant SC_3 : integer := 10; constant SC_4 : integer := 11; constant SC_RUNBST : integer := 12; constant SC_CLEAR : integer := 13; constant SM_IDLE : Tstate := "10000000000000"; constant SM_ENUM : Tstate := "01000000000000"; constant SM_WRITE : Tstate := "00100000000000"; constant SM_READ : Tstate := "00010000000000"; constant SM_IRLOAD : Tstate := "00001000000000"; constant SM_DIAGROT : Tstate := "00000100000000"; constant SM_0 : Tstate := "00000010000000"; constant SM_1 : Tstate := "00000001000000"; constant SM_2 : Tstate := "00000000100000"; constant SM_3PRE : Tstate := "00000000010000"; constant SM_3 : Tstate := "00000000001000"; constant SM_4 : Tstate := "00000000000100"; constant SM_RUNBST : Tstate := "00000000000010"; constant SM_CLEAR : Tstate := "00000000000001"; constant MODE_RUN : Tmode := "000"; constant MODE_ENUM : Tmode := "001"; constant MODE_READ : Tmode := "010"; constant MODE_WRITE : Tmode := "011"; constant ADDR_BISTMASK : Tw_addr := X"0"; -- control reg 0 constant ADDR_MEMMASK : Tw_addr := X"1"; -- control reg 1 constant ADDR_DIAGPTR : Tw_addr := X"2"; -- control reg 2 constant ADDR_RBISTMASK : Tr_addr := X"00"; -- read control reg 0 constant ADDR_RMEMMASK : Tr_addr := X"01"; -- read control reg 1 constant ADDR_RDIAGPTR : Tr_addr := X"02"; -- read control reg 2 constant ADDR_ABIST : Tw_addr := X"B"; -- control reg B constant ADDR_TIMING : Tw_addr := X"C"; -- control reg C constant ADDR_SIGNATURE : Tw_addr := X"D"; -- control reg D constant ADDR_DIAGCOUNT : Tw_addr := X"E"; -- control reg E constant ADDR_RDIAGCOUNT : Tr_addr := X"0E"; -- read control reg E constant ADDR_TYPE : Tr_addr := X"10"; -- status reg 0 constant ADDR_ENUM : Tr_addr := X"11"; -- status reg 1 constant ADDR_BISTDONE : Tr_addr := X"12"; -- status reg 2 constant ADDR_WAIT : Tr_addr := X"13"; -- status reg 3 constant ADDR_FAIL : Tr_addr := X"14"; -- status reg 4 --===================================================================== -- Signal Declarations --===================================================================== signal state_q, state_d : Tstate; signal instruction_d, instruction_q : Tinstruction; signal shift_instruction, shift_write : std_ulogic; signal shuttle_select, shuttle_d, shuttle_q : Tshuttle; signal shift_shuttle : std_ulogic; -- signal enum_d, enum_q : Tenum; signal clear_enum, count_enum : std_ulogic; signal mode : Tmode; signal kind : Tkind; signal addr : Taddr; signal w_reg_addr : Tw_addr; signal r_reg_addr : Tr_addr; signal reg_select : std_ulogic; signal s_idle, s_enum, s_write, s_read, s_irload, s_diagrot, s_0, s_1, s_2, s_3pre, s_3, s_4, s_runbst, s_clear : std_ulogic; signal s_3pre_delayed, s_3_delayed, s_4_delayed : std_ulogic; signal bistmask_d, bistmask_q, shift_bistmask : std_ulogic; signal bistdone_q, bistdone_d : std_ulogic; signal memmask_d, memmask_q : Tmemmask; signal shift_memmask : std_ulogic; signal done_d, done_q, wait_d, wait_q, fail_d, fail_q : std_ulogic; signal bcshctrl_ff, bcdata_ff, bcshdata_ff, bcexe_ff, bcreset_ff, bo_go_ff, bcsysrepair_ff : std_ulogic; signal write_signature, write_timing : std_ulogic; signal int_scan_in, int_scan_out : Tint_scan; signal ck_bo_sl_thold_0_b : std_ulogic; signal force_func : std_ulogic; signal count_d, count_q : Tcounter; signal count_done : std_ulogic; signal diagptr_q, diagptr_d : Tdiagptr; signal shift_diagptr : std_ulogic; signal diagmux_and : std_ulogic_vector(bo_diagout'range); signal bo_select_int : std_ulogic_vector(bo_select'range); signal sg_int : std_ulogic; signal diagdecr_q, diagdecr_d : Tdiagdecr; signal shift_diagcount, diagdecr_zero : std_ulogic; signal diagloop_out_d, diagloop_out_int : std_ulogic; signal write_abist_q, write_abist_d : std_ulogic; signal bo_fail_ff, bo_fail_pre : std_ulogic_vector(0 to num_backends-1); begin sg_int <= '0' when bo_enable = '1' else ck_bo_sg_0; --===================================================================== -- Shuttle and Diagloop --===================================================================== shift_shuttle <= bcshdata_ff and ((s_idle and pos(mode = MODE_READ)) or (s_idle and pos(mode = MODE_RUN)) or s_diagrot or s_read) and bo_enable; shuttle : process (bistdone_q, bistmask_q, bo_fail_ff, diagdecr_q, diagptr_q, enum_q, memmask_q, r_reg_addr) is begin shuttle_select <= (others => '0'); case r_reg_addr is when ADDR_RBISTMASK => shuttle_select(Tshuttle'right) <= bistmask_q; when ADDR_RMEMMASK => shuttle_select <= memmask_q; when ADDR_RDIAGPTR => shuttle_select(Tshuttle'right-diagptr_q'right to Tshuttle'right) <= diagptr_q; when ADDR_RDIAGCOUNT=> shuttle_select(Tshuttle'right-Tdiagdecr'right to Tshuttle'right) <= diagdecr_q; when ADDR_TYPE => shuttle_select(Tshuttle'right-type_num'right to Tshuttle'right) <= type_num; when ADDR_ENUM => shuttle_select(Tshuttle'right-Tenum'right to Tshuttle'right) <= enum_q; when ADDR_BISTDONE => shuttle_select(Tshuttle'right) <= bistdone_q; when ADDR_FAIL => shuttle_select <= bo_fail_ff; when others => null; end case; end process; shuttle_d <= shuttle_q(1 to shuttle_q'right) & sdin when (shift_shuttle and not s_diagrot) = '1' else shuttle_q(1 to shuttle_q'right) & diagloop_out_int when (shift_shuttle and s_diagrot) = '1' else shuttle_select; sdout <= shuttle_q(shuttle_d'left); diagmux : for i in bo_diagout'range generate begin diagmux_and(i) <= bo_diagout(i) and bo_select_int(i); end generate; diagloop_out_int <= or_reduce(diagmux_and) and diagptr_q(Rdiagptr_enable) and s_diagrot; diagloop_out_d <= diagloop_out_int and not lbist_ac_mode_dc; --===================================================================== -- Instruction register & universal registers --===================================================================== shift_instruction <= bcshctrl_ff and (s_idle or s_irload) and bo_enable; instruction_d <= instruction_q(1 to instruction_q'right) & bcdata_ff; abist_si <= bcdata_ff and not bcreset_ff; shift_write <= ((s_idle and pos(mode = MODE_WRITE)) or s_write) and bcshdata_ff and bo_enable; shift_diagptr <= shift_write and reg_select and pos(w_reg_addr = ADDR_DIAGPTR) and bo_enable; diagptr_d <= diagptr_q(1 to diagptr_q'right) & bcdata_ff; shift_diagcount <= shift_write and reg_select and pos(w_reg_addr = ADDR_DIAGCOUNT) and bo_enable; diagdecr_d <= diagdecr_q(1 to diagdecr_q'right) & bcdata_ff when shift_diagcount = '1' else diagdecr_q(diagdecr_q'left to Rdiagdecr'left-1) & (diagdecr_q(Rdiagdecr) - 1) when s_runbst = '1' and diagdecr_q(Rdiagdecr_enable) = '1' else diagdecr_q; diagdecr_zero <= pos(diagdecr_q(Rdiagdecr) = 0) and diagdecr_q(Rdiagdecr_enable); shift_bistmask <= shift_write and reg_select and pos(w_reg_addr = ADDR_BISTMASK) and bo_enable; bistmask_d <= bcdata_ff; shift_memmask <= shift_write and reg_select and pos(w_reg_addr = ADDR_MEMMASK) and bo_enable; memmask_d <= memmask_q(1 to memmask_q'right) & bcdata_ff; write_timing <= shift_write and reg_select and pos(w_reg_addr = ADDR_TIMING); write_signature <= shift_write and reg_select and pos(w_reg_addr = ADDR_SIGNATURE); write_abist_d <= shift_write and reg_select and pos(w_reg_addr = ADDR_ABIST) and not lbist_ac_mode_dc; --===================================================================== -- Backend selection from diagptr --===================================================================== bo_select_decoder : for i in bo_select'range generate begin bo_select_int(i) <= (diagptr_q(Rdiagptr_override) or pos(diagptr_q(Rbackend_select) = i)) and diagptr_q(Rdiagptr_enable); end generate; bo_select <= (others => '0') when lbist_ac_mode_dc = '1' else bo_select_int when (shift_write and reg_select) = '1' else not memmask_q; bo_repair <= s_4 and not lbist_ac_mode_dc; bo_unload <= (s_3 or s_3pre) and not lbist_ac_mode_dc; bo_reset <= bcreset_ff or s_clear or (s_runbst and abist_done) or (s_3pre and count_done) or (s_3 and count_done) or lbist_ac_mode_dc; -- reset fail/nofix bits during warmup, reset counters at end of a state bo_shdata <= '0' when lbist_ac_mode_dc = '1' else shuttle_d(shuttle_d'left) when s_diagrot = '1' else bcdata_ff and not bcreset_ff; bo_load <= (write_signature) and not lbist_ac_mode_dc; bo_fail_pre <= (others => '0') when lbist_ac_mode_dc = '1' else bo_fail; --===================================================================== -- Counters --===================================================================== count_done <= pos(count_q = X"000"); bistdone_d <= '0' when s_0 = '1' or s_clear = '1' else '1' when (s_4 = '1' and count_done = '1') or diagdecr_zero = '1' else bistdone_q; --===================================================================== -- Enumeration counter --===================================================================== clear_enum <= s_idle and bcexe_ff and pos(mode = MODE_ENUM); count_enum <= s_enum; enum_d <= (others => '0') when clear_enum = '1' else enum_q + 1 when count_enum = '1' else enum_q; --===================================================================== -- Daisy Chain FFs --===================================================================== done_d <= donein and (bistmask_q or bistdone_q or (s_idle and pos(mode = MODE_ENUM)) or s_enum); wait_d <= waitin and bistdone_q and diagdecr_q(Rdiagdecr_evs); fail_d <= failin or (not bistmask_q and s_idle and or_reduce(bo_fail_ff and memmask_q)); --===================================================================== -- Thold/SG Decoder --===================================================================== bo_pc_abst_sl_thold_6 <= ck_bo_sl_thold_6 when (bcreset_ff or s_3_delayed or s_clear)='1' else '0' when (s_1 or s_2 or s_runbst)='1' and diagdecr_zero='0' else '1'; bo_pc_ary_nsl_thold_6 <= not(bcreset_ff or s_2 or s_runbst); bo_pc_func_sl_thold_6 <= not(s_0 or s_1 or s_2 or s_runbst); bo_pc_time_sl_thold_6 <= ck_bo_sl_thold_6 when (write_timing)='1' else '1'; -- not during reset bo_pc_repr_sl_thold_6 <= ck_bo_sl_thold_6 when (s_4_delayed or s_3pre_delayed)='1' else '1'; -- not during reset bo_pc_sg_6 <= bcreset_ff or write_abist_q or write_timing or s_4_delayed or s_3_delayed or s_3pre_delayed or s_clear; abist_start_test_int <= s_runbst and not abist_done when bo_enable='1' else abist_start_test; bo_pc_pc_abst_sl_thold_6 <= ck_bo_sl_thold_6 when write_abist_q='1' else '0' when (s_1 or s_2 or bcreset_ff or s_runbst)='1' else '1'; abist_mode_dc_int <= s_0 or s_1 or s_2 or s_runbst when bo_enable='1' else abist_mode_dc; --===================================================================== -- State Transitions --===================================================================== trans : process (abist_done, bcexe_ff, bcreset_ff, bcshctrl_ff, bcshdata_ff, bo_go_ff, count_done, count_q, diagdecr_q(Rdiagdecr_evs), diagdecr_zero, done_q, instruction_q(Raccumulate), instruction_q(RFARR), instruction_q(Rloop), mode, state_q, bcsysrepair_ff) is begin state_d <= state_q; count_d <= count_q - 1; case state_q is when SM_IDLE => if (bcshctrl_ff = '1') then state_d <= SM_IRLOAD; else case mode is when MODE_ENUM => if bcexe_ff = '1' then state_d <= SM_ENUM; end if; when MODE_READ => if bcshdata_ff = '1' then state_d <= SM_READ; end if; when MODE_WRITE => if bcshdata_ff = '1' then state_d <= SM_WRITE; end if; when MODE_RUN => if bo_go_ff = '1' then if instruction_q(Raccumulate)='1' then state_d <= SM_0; count_d <= warmup_length; else state_d <= SM_CLEAR; count_d <= max_sticky_length; end if; elsif bcshdata_ff = '1' then state_d <= SM_DIAGROT; end if; when others => null; end case; end if; when SM_IRLOAD => if (bcshctrl_ff = '0') then state_d <= SM_IDLE; end if; when SM_ENUM => if (done_q = '1') then state_d <= SM_IDLE; end if; when SM_READ => if (bcshdata_ff = '0') then state_d <= SM_IDLE; end if; when SM_WRITE => if (bcshdata_ff = '0') then state_d <= SM_IDLE; end if; when SM_DIAGROT => if (bcshdata_ff = '0') then state_d <= SM_IDLE; end if; when SM_CLEAR => if (count_done = '1') then state_d <= SM_0; count_d <= warmup_length; end if; when SM_0 => if (count_done = '1') then state_d <= SM_1; count_d <= warmup_length; end if; when SM_1 => if (count_done = '1') then state_d <= SM_2; end if; when SM_2 => if (bcexe_ff = '1') then state_d <= SM_RUNBST; end if; when SM_RUNBST => if (abist_done = '1') then state_d <= SM_3PRE; end if; if diagdecr_zero = '1' then state_d <= SM_IDLE; end if; count_d <= fareg_length; when SM_3PRE => if (count_done = '1') then state_d <= SM_3; count_d <= max_sticky_length; end if; when SM_3 => if (count_done = '1') then if (diagdecr_q(Rdiagdecr_evs) = '0' or instruction_q(RFARR)='1' or bcsysrepair_ff='1') then state_d <= SM_4; else state_d <= SM_IDLE; end if; count_d <= fareg_length; end if; when SM_4 => if (count_done = '1') then if instruction_q(Rloop) = '1' then state_d <= SM_0; else state_d <= SM_IDLE; end if; end if; when others => state_d <= SM_IDLE; end case; if bcreset_ff = '1' then state_d <= SM_IDLE; end if; end process; --===================================================================== -- Latches --===================================================================== input_reg: entity tri.tri_boltreg_p generic map (width => scan_offset_1 - scan_offset_0, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_0 to scan_offset_1-1), scout => int_scan_out(scan_offset_0 to scan_offset_1-1), din(0) => bcdata, din(1) => bcshcntl, din(2) => bcshdata, din(3) => bcexe, din(4) => bcreset, din(5) => bo_go, din(6) => bcsysrepair, dout(0) => bcdata_ff, dout(1) => bcshctrl_ff, dout(2) => bcshdata_ff, dout(3) => bcexe_ff, dout(4) => bcreset_ff, dout(5) => bo_go_ff, dout(6) => bcsysrepair_ff); daisy_reg: entity tri.tri_boltreg_p generic map (width => scan_offset_2 - scan_offset_1, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_1 to scan_offset_2-1), scout => int_scan_out(scan_offset_1 to scan_offset_2-1), din(0) => done_d, din(1) => wait_d, din(2) => fail_d, dout(0) => done_q, dout(1) => wait_q, dout(2) => fail_q ); doneout <= done_q; waitout <= wait_q; failout <= fail_q; state_reg: entity tri.tri_boltreg_p generic map (width => scan_offset_3 - scan_offset_2, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_2 to scan_offset_3-1), scout => int_scan_out(scan_offset_2 to scan_offset_3-1), din(Tstate'range) => state_d, din(Tstate'right + 1) => s_3pre, din(Tstate'right + 2) => s_3, din(Tstate'right + 3) => s_4, dout(Tstate'range) => state_q, dout(Tstate'right + 1) => s_3pre_delayed, dout(Tstate'right + 2) => s_3_delayed, dout(Tstate'right + 3) => s_4_delayed); s_idle <= state_q(SC_IDLE); s_enum <= state_q(SC_ENUM); s_write <= state_q(SC_WRITE); s_read <= state_q(SC_READ); s_irload <= state_q(SC_IRLOAD); s_diagrot <= state_q(SC_DIAGROT); s_0 <= state_q(SC_0); s_1 <= state_q(SC_1); s_2 <= state_q(SC_2); s_3pre <= state_q(SC_3PRE); s_3 <= state_q(SC_3); s_4 <= state_q(SC_4); s_runbst <= state_q(SC_RUNBST); s_clear <= state_q(SC_CLEAR); enum_reg: entity tri.tri_boltreg_p generic map (width => enum_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_3 to scan_offset_4-1), scout => int_scan_out(scan_offset_3 to scan_offset_4-1), din => enum_d, dout => enum_q ); instr_reg: entity tri.tri_boltreg_p generic map (width => instruction_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => shift_instruction, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_4 to scan_offset_5-1), scout => int_scan_out(scan_offset_4 to scan_offset_5-1), din => instruction_d, dout => instruction_q ); mode <= instruction_q(Rmode); kind <= instruction_q(Rkind); addr <= instruction_q(Raddr); w_reg_addr <= instruction_q(Rw_addr); r_reg_addr <= instruction_q(Rr_addr); reg_select <= '1' when addr = X"000" or (kind = '1' and addr = type_num) or (kind = '0' and addr = enum_q) else '0'; shuttle_reg: entity tri.tri_boltreg_p generic map (width => shuttle_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_5 to scan_offset_6-1), scout => int_scan_out(scan_offset_5 to scan_offset_6-1), din => shuttle_d, dout => shuttle_q ); count_reg: entity tri.tri_boltreg_p generic map (width => count_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_6 to scan_offset_7-1), scout => int_scan_out(scan_offset_6 to scan_offset_7-1), din => count_d, dout => count_q ); diagptr_reg: entity tri.tri_boltreg_p generic map (width => diagptr_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => shift_diagptr, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_7 to scan_offset_8-1), scout => int_scan_out(scan_offset_7 to scan_offset_8-1), din => diagptr_d, dout => diagptr_q ); bistmask_reg: entity tri.tri_boltreg_p generic map (width => 1, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => shift_bistmask, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_8 to scan_offset_9-1), scout => int_scan_out(scan_offset_8 to scan_offset_9-1), din(0) => bistmask_d, dout(0) => bistmask_q ); memmask_reg: entity tri.tri_boltreg_p generic map (width => memmask_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => shift_memmask, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_9 to scan_offset_10-1), scout => int_scan_out(scan_offset_9 to scan_offset_10-1), din => memmask_d, dout => memmask_q ); bistdone_reg: entity tri.tri_boltreg_p generic map (width => 1, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_10 to scan_offset_11-1), scout => int_scan_out(scan_offset_10 to scan_offset_11-1), din(0) => bistdone_d, dout(0) => bistdone_q ); diagdecr_reg: entity tri.tri_boltreg_p generic map (width => diagdecr_d'length, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_11 to scan_offset_12-1), scout => int_scan_out(scan_offset_11 to scan_offset_12-1), din => diagdecr_d, dout => diagdecr_q ); out_reg: entity tri.tri_boltreg_p generic map (width => scan_offset_13 - scan_offset_12, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_12 to scan_offset_13-1), scout => int_scan_out(scan_offset_12 to scan_offset_13-1), din(0) => diagloop_out_d, din(1) => write_abist_d, dout(0) => diagloop_out, dout(1) => write_abist_q ); fail_reg: entity tri.tri_boltreg_p generic map (width => scan_offset_14 - scan_offset_13, init => 0, expand_type => expand_type) port map (vd => vdd, gd => gnd, nclk => nclk, act => bo_enable, thold_b => ck_bo_sl_thold_0_b, sg => sg_int, forcee => force_func, delay_lclkr => lcb_delay_lclkr_dc, mpw1_b => lcb_mpw1_dc_b, mpw2_b => lcb_mpw2_dc_b, scin => int_scan_in(scan_offset_13 to scan_offset_14-1), scout => int_scan_out(scan_offset_13 to scan_offset_14-1), din => bo_fail_pre, dout => bo_fail_ff ); int_scan_in(0) <= scan_in and not bo_enable; int_scan_in(1 to int_scan_in'right) <= int_scan_out(0 to int_scan_out'right-1); scan_out <= int_scan_out(int_scan_out'right); --===================================================================== -- Thold/SG Staging --===================================================================== lcbor_func: entity tri.tri_lcbor generic map (expand_type => expand_type ) port map ( clkoff_b => lcb_clkoff_dc_b, thold => ck_bo_sl_thold_0, sg => sg_int, act_dis => lcb_act_dis_dc, forcee => force_func, thold_b => ck_bo_sl_thold_0_b ); ----------------------------------------------------------------------- end pcq_abist_bolton_frontend;