You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
a2i/rel/src/vhdl/work/pcq_abist_bolton_frontend.vhdl

828 lines
36 KiB
VHDL

-- © 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;