-- -*- Mode: VHDL -*- ------------------------------------------------------------------------------- -- Title : Handle access to the ngCCM I/O over GBT -- Project : ------------------------------------------------------------------------------- -- File : ngCCM.vhd -- Author : Stephen Goadhouse -- Company : Univ. of Virginia, Physics Dept. -- Created : 2012-03-12 -- Last update: 2012-11-16 -- Platform : -- Standard : VHDL'93 ------------------------------------------------------------------------------- -- Description: This code handles logic specific to the ngCCM X1 prototype -- platform. This includes breaking out the pins from the received -- GBT Word. ------------------------------------------------------------------------------- -- Copyright (c) 2012 ------------------------------------------------------------------------------- -- Revisions : -- Date Ver Author Description -- 2012-04-17 0.1 GOADHOUSE Created -- 2012-06-22 1.0 GOADHOUSE Released -- 2012-10-18 2.0 GOADHOUSE Updated and ported to the GLIB -- 2013-11-01 3.0 SAHIN Updated and ported to the GLIB v3, added simultanous control over 14 channels -- 2014-04-05 3.1 SAHIN The changes are ported from GOADHOUSE, the unused parts are commented out -- 2014-12-15 4.0 SAHIN Ported to fc7, major bug fixes, direct the CCM Server for the bkp status bits -- 2015-11-01 4.1 KARAKAYA PRBS generator and error detection module is implemented -- 2016-04-01 4.2 COSTANZA JTAG implementation is ported and improved -- 2016-10-18 4.3 SAHIN Cosmetic changes, -- 2016-11-17 4.4 COSTANZA sfp+ interface -- 2016-12-12 4.5 COSTANZA new JTAG filtering -- 2016-12-12 4.6 COSTANZA reset for the bkp_pwr_good counter -- 2017-01-24 4.7 COSTANZA added partition for bkp commands -- 2017-01-24 4.8 COSTANZA removed redundant partitions ------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; --use ieee.std_logic_unsigned.all; use IEEE.std_logic_misc.all; LIBRARY work; --USE work.ngCCM_package.ALL; USE work.ngFEC_pack.ALL; --USE work.ipbus.ALL; --USE work.prbs_pattern_generator.ALL; ENTITY ngCCM IS PORT ( reset_IN : IN STD_LOGIC; -- reset input reset_OUT : OUT STD_LOGIC; -- reset output for reset chain reset_partition : IN STD_LOGIC_VECTOR(no_partition-1 downto 0); error_counter_reset_i : IN STD_LOGIC; fabric_clk : IN STD_LOGIC; -- Clocks sync'ed to TX and RX GBT components TX_Clock_20MHz : IN STD_LOGIC; RX_Clock_20MHz : IN STD_LOGIC; RX_wordclk : IN STD_LOGIC; -- GBT TX and RX Words TX_Word_o : OUT STD_LOGIC_VECTOR(83 DOWNTO 0); RX_Word_i : IN STD_LOGIC_VECTOR(83 DOWNTO 0); RX_Word_DV_i : IN STD_LOGIC; -- Brcst : IN STD_LOGIC_VECTOR(5 DOWNTO 0); -- brcstStr : IN STD_LOGIC; QIE_RESET : IN STD_LOGIC; WTE : IN STD_LOGIC; -- SFP connection status bits sfp_rx_lost : IN std_logic; sfp_tx_fault : IN std_logic; -- Clock from I2C module that is 6x the I2C clock, SCL and I2C ack -- clk_6x_o : OUT STD_LOGIC; i2c_clk_en : IN STD_LOGIC; -- IPbus interface ipb_clk_i : IN STD_LOGIC; ipb_miso : OUT ipb_out; ngccm_bkp_regs : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); ipb_mosi : IN ipb_in; prescale : IN STD_LOGIC_VECTOR (31 DOWNTO 0); prbs_o : IN STD_LOGIC_VECTOR(set_prbs_tabs(HBHE,20)'high downto 0); TimeoutErrorCnt : OUT STD_LOGIC; TCK_inCnt : OUT STD_LOGIC; TCK_outCnt : OUT STD_LOGIC; -- TCK_counter : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); PRBS_rx_pattern_error_cnt_o : OUT STD_LOGIC; PRBS_rx_pattern_bitwise_error_cnt_o : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); pwr_good_cnt_o : OUT STD_LOGIC; ngCCM_status_o : OUT STD_LOGIC_VECTOR (15 DOWNTO 0) ); END ngCCM; ARCHITECTURE rtl OF ngCCM IS CONSTANT kREG_NGCCM_JTAG : INTEGER := 4; -- Address Offset for ngCCM JTAG Control/Status register -- Split up the different ngCCM I/Os by functionality to make it easier to -- twiddle the bits of only related signals. CONSTANT kREG_NGCCMIO_JTAG : INTEGER := 8; -- Address Offset for ngCCM I/O Actel JTAG CONSTANT kREG_NGCCMIO_SEC_IDEV : INTEGER := 9; -- Address Offset for ngCCM I/O Actel IDEV CONSTANT kREG_NGCCMIO_BKP_IO : INTEGER := 10; -- Address Offset for ngCCM I/O RBX I/O CONSTANT kREG_NGCCMIO_BKP_I2C : INTEGER := 11; -- Address Offset for ngCCM I/O RBX I2C CONSTANT kREG_NGCCMIO_SEC_I2C : INTEGER := 13; -- Address Offset for ngCCM I/O SFP I2C CONSTANT kREG_NGCCMIO_MISC : INTEGER := 14; -- Address Offset for ngCCM I/O Miscellaneous I/O -- CONSTANT kREG_NGCCMI2C_SFP_SR_RXR : INTEGER := (7*16)+1; -- Address Offset for ngCCM I2C SFP Status & Receive -- CONSTANT kREG_NGCCMI2C_SFP_CR_TXR : INTEGER := (7*16)+1; -- Address Offset for ngCCM I2C SFP Control & Transmit COMPONENT CrossClock_RX IS GENERIC ( DataBtoA_SZ : INTEGER; DataAtoB_SZ : INTEGER; WAIT_STATES_A : INTEGER); PORT ( resetA : IN STD_LOGIC; clkA : IN STD_LOGIC; clkA_en : IN STD_LOGIC; sentBtoA_o : OUT STD_LOGIC; strbAtoB_o : OUT STD_LOGIC; DataAtoB_i : IN STD_LOGIC_VECTOR; DataBtoA_o : OUT STD_LOGIC_VECTOR; clkB : IN STD_LOGIC; sendBtoA_i : IN STD_LOGIC; recvAtoB_o : OUT STD_LOGIC; DataBtoA_i : IN STD_LOGIC_VECTOR; DataAtoB_o : OUT STD_LOGIC_VECTOR); END COMPONENT CrossClock_RX; COMPONENT IPbus_local IS GENERIC ( ADDR_MSB : INTEGER := kMSB_ngCCM; WAIT_STATES : INTEGER := kWAIT_ngCCM; WRITE_PULSE_TICKS : INTEGER := kWTICKS_ngCCM); PORT ( reset_local : IN STD_LOGIC; clk_local : IN STD_LOGIC; strobe_local : OUT STD_LOGIC; write_local : OUT STD_LOGIC; addr_local : OUT STD_LOGIC_VECTOR(kMSB_ngCCM DOWNTO 0); DataIn_local : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); DataOut_local : IN STD_LOGIC_VECTOR(31 DOWNTO 0); IPbus_clk : IN STD_LOGIC; IPbus_strobe : IN STD_LOGIC; IPbus_write : IN STD_LOGIC; IPbus_ack : OUT STD_LOGIC; IPbus_addr : IN STD_LOGIC_VECTOR(kMSB_ngCCM DOWNTO 0); IPbus_DataIn : IN STD_LOGIC_VECTOR(31 DOWNTO 0); IPbus_DataOut : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)); END COMPONENT IPbus_local; COMPONENT Sync IS PORT ( clk : IN STD_LOGIC; ce : IN STD_LOGIC; sync_i : IN STD_LOGIC; sync_o : OUT STD_LOGIC); END COMPONENT Sync; COMPONENT SyncRst IS PORT ( clk : IN STD_LOGIC; ce : IN STD_LOGIC; Rst_i : IN STD_LOGIC; Rst_o : OUT STD_LOGIC); END COMPONENT; COMPONENT Agnostic_Counter IS GENERIC ( gCOUNTER_SIZE : INTEGER; gCOUNTER_TERM : STD_LOGIC_VECTOR); PORT ( Clock : IN STD_LOGIC; reset : IN STD_LOGIC; en : IN STD_LOGIC := '1'; q : OUT STD_LOGIC_VECTOR); END COMPONENT Agnostic_Counter; COMPONENT LocalI2CBridge IS PORT ( reset_local : IN STD_LOGIC; clk_local : IN STD_LOGIC; strobe_local : IN STD_LOGIC; write_local : IN STD_LOGIC; addr_local : IN STD_LOGIC_VECTOR(3 DOWNTO 0); DataIn_local : IN STD_LOGIC_VECTOR(31 DOWNTO 0); DataOut_local : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); -- clk_6x_o : OUT STD_LOGIC; wb_ack_o : OUT STD_LOGIC; clk_en : IN STD_LOGIC; prer_scale_i : IN STD_LOGIC_VECTOR (15 downto 0); power_good : IN std_logic; sfp_rx_lost : IN STD_LOGIC; sfp_tx_fault : IN STD_LOGIC; scl_i : IN STD_LOGIC; sda_i : IN STD_LOGIC; scl_o : OUT STD_LOGIC; sda_o : OUT STD_LOGIC); END COMPONENT LocalI2CBridge; COMPONENT LocalJTAGBridge IS PORT ( reset_local : IN STD_LOGIC; clk_local : IN STD_LOGIC; strobe_local : IN STD_LOGIC; write_local : IN STD_LOGIC; addr_local : IN STD_LOGIC_VECTOR(9 DOWNTO 0); DataIn_local : IN STD_LOGIC_VECTOR(31 DOWNTO 0); DataOut_local : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); TimeoutError : OUT STD_LOGIC; jtag_reg_wr : IN STD_LOGIC; jtag_reg_i : IN STD_LOGIC_VECTOR(31 DOWNTO 0); jtag_reg_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); jtag_en_o : OUT STD_LOGIC; ctrl_clk_o : OUT STD_LOGIC; TCK_in_rise : OUT STD_LOGIC; tdo_i : IN STD_LOGIC; tck_i : IN STD_LOGIC; tms_i : IN STD_LOGIC; trst_i : IN STD_LOGIC; tck_o : OUT STD_LOGIC; tdi_o : OUT STD_LOGIC; tms_o : OUT STD_LOGIC; trst_o : OUT STD_LOGIC); END COMPONENT LocalJTAGBridge; COMPONENT glitch_filter IS -- size = number of consecutive dins that must be the same before sending to dout -- DOUT_RST = reset state of dout GENERIC (SIZE : INTEGER; DOUT_RST : STD_LOGIC ); PORT ( din : IN STD_LOGIC; -- data in dout : OUT STD_LOGIC; -- data out rise : OUT STD_LOGIC; -- single pulse when dout is rising fall : OUT STD_LOGIC; -- single pulse when dout is falling clk : IN STD_LOGIC; -- clock -- clk_en : IN STD_LOGIC; -- clock rst_n: IN STD_LOGIC); -- reset - active low END COMPONENT glitch_filter; SIGNAL RX_Word_rx40 : STD_LOGIC_VECTOR(RX_Word_i'high DOWNTO 0); SIGNAL RX_Word_tx40 : STD_LOGIC_VECTOR(RX_Word_i'high DOWNTO 0); SIGNAL gbt_RX_to_TX_data_i : STD_LOGIC_VECTOR(RX_Word_i'high DOWNTO 0); SIGNAL gbt_RX_to_TX_data_o : STD_LOGIC_VECTOR(gbt_RX_to_TX_data_i'range); SIGNAL fetch_RX_data : STD_LOGIC; SIGNAL clr_fetch_RX_data : STD_LOGIC; SIGNAL strobe_local_dly : STD_LOGIC; SIGNAL recv_RX_to_TX_data : STD_LOGIC; SIGNAL recv_RX_to_TX_data_dly : STD_LOGIC; SIGNAL TX_to_RX_unused_o : STD_LOGIC_VECTOR(0 DOWNTO 0); SIGNAL data_in : ngccm_register; -- Local Data In from IPbus SIGNAL data_out : ngccm_register; -- Local Data Out to IPbus type addr is array (no_partition-1 downto 0) of STD_LOGIC_VECTOR(kMSB_ngCCM DOWNTO 0); --# partitions + JTAG SIGNAL addr_local : addr; -- address bus from IPbus SIGNAL strobe_local : STD_LOGIC_VECTOR(no_partition-1 downto 0); -- Strobe signal from IPbus (# part + JTAG) SIGNAL write_local : STD_LOGIC_VECTOR(no_partition-1 downto 0); -- Write signal from IPbus (# part + JTAG) SIGNAL jtag_reset_local : STD_LOGIC_VECTOR(no_partition-1 downto 0); -- Write signal from IPbus (# part + JTAG) -- IPbus registers -- SIGNAL reg_ngccm_status : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccm_jtag_i : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccm_jtag_o : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccmio_jtag : STD_LOGIC_VECTOR(31 DOWNTO 0); --@@@ SIGNAL reg_ngccmio_sec_idev : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccmio_bkp_io : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccmio_bkp_i2c : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccmio_bkp_i2c_mux : STD_LOGIC_VECTOR(31 DOWNTO 0); --@@@ SIGNAL reg_ngccmio_sfp_io : STD_LOGIC_VECTOR(31 DOWNTO 0); -- SIGNAL reg_ngccmio_sec_i2c : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL reg_ngccmio_misc : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL other_data_out : STD_LOGIC_VECTOR(data_out(0)'range); SIGNAL jtag_data_out : STD_LOGIC_VECTOR(data_out(0)'range); SIGNAL i2c_sel_data_out : STD_LOGIC_VECTOR(data_out(0)'range); TYPE i2c_data_typ IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(data_out(0)'range); SIGNAL i2c_data_out : ngccm_register; SIGNAL TX_Reset : STD_LOGIC; SIGNAL RX_Reset : STD_LOGIC; -- signal error_counter_reset : STD_LOGIC; -- signal PRBS_Error_reset : STD_LOGIC; -- SIGNAL prer_scale : STD_LOGIC_VECTOR(15 downto 0); ---!!!! SIGNAL ngccmPinsInReg : ngccm_pin_input_typ; -- Inputs coherently sync'ed via CrossClock SIGNAL ngccmPinsInRx : ngccm_pin_input_typ; -- Inputs still sync'ed to RX 40MHz from GBT RX core SIGNAL ngccmPinsOutReg : ngccm_pin_output_typ; -- SIGNAL heartBeat_Enable : STD_LOGIC; -- SIGNAL heartBeatCntr : STD_LOGIC_VECTOR(25 DOWNTO 0); -- CONSTANT kHEARTBEAT_CNTR_TERM : STD_LOGIC_VECTOR(heartBeatCntr'range) := (OTHERS => '1'); SIGNAL I2CDirectAccess_Enable : STD_LOGIC := '0'; -- if '1', I2C pins will be accessed as bits in I/O registers SIGNAL i2c_scl_i : STD_LOGIC_VECTOR(2*kNUM_I2C_ngCCM-1 DOWNTO 0); SIGNAL i2c_sda_i : STD_LOGIC_VECTOR(2*kNUM_I2C_ngCCM-1 DOWNTO 0); SIGNAL i2c_scl_o : STD_LOGIC_VECTOR(2*kNUM_I2C_ngCCM-1 DOWNTO 0); SIGNAL i2c_sda_o : STD_LOGIC_VECTOR(2*kNUM_I2C_ngCCM-1 DOWNTO 0); SIGNAL i2c_strobe : STD_LOGIC_VECTOR(kNUM_I2C_BUSSES-1 DOWNTO 0); SIGNAL i2c_reset_local : std_logic_vector(kNUM_I2C_BUSSES-1 DOWNTO 0):=(others=>'0'); signal strobe_mux : STD_LOGIC; -- SIGNAL clk_6x : STD_LOGIC_VECTOR(kNUM_I2C_BUSSES-1 DOWNTO 0); signal wb_ack : STD_LOGIC_VECTOR(kNUM_I2C_BUSSES-1 DOWNTO 0); -- Signals used to interface to LocalJTAGBridge SIGNAL jtag_strobe : STD_LOGIC; SIGNAL jtag_ctrl_clk : STD_LOGIC; SIGNAL reg_ngccm_jtag_wr : STD_LOGIC; -- signal when reg_ngccm_jtag_i is being written -- LocalJTAGBridge pins SIGNAL jtag_bridge_tdo_i : STD_LOGIC; SIGNAL jtag_bridge_tck_i : STD_LOGIC; SIGNAL jtag_bridge_tms_i : STD_LOGIC; SIGNAL jtag_bridge_trst_i : STD_LOGIC; SIGNAL jtag_bridge_tck_o : STD_LOGIC; SIGNAL jtag_bridge_tdi_o : STD_LOGIC; SIGNAL jtag_bridge_tms_o : STD_LOGIC; SIGNAL jtag_bridge_trst_o : STD_LOGIC; SIGNAL jtag_sec_en : STD_LOGIC; SIGNAL jtag_sec_en_dly : STD_LOGIC; -- glitch filter output SIGNAL jtag_tdo : STD_LOGIC; SIGNAL jtag_tck : STD_LOGIC; SIGNAL jtag_tms : STD_LOGIC; SIGNAL jtag_trst : STD_LOGIC; SIGNAL sec_jtag_tdo : STD_LOGIC; SIGNAL sec_jtag_tck : STD_LOGIC; SIGNAL sec_jtag_tms : STD_LOGIC; SIGNAL sec_jtag_trst : STD_LOGIC; --Signals for jtag mux SIGNAL ngccm_TRST : STD_LOGIC; SIGNAL sec_ngccm_TRST : STD_LOGIC; SIGNAL sel_sec_jtag : STD_LOGIC; SIGNAL jtag_tck_o : STD_LOGIC; SIGNAL jtag_tdi_o : STD_LOGIC; SIGNAL jtag_tms_o : STD_LOGIC; SIGNAL jtag_trst_o : STD_LOGIC; SIGNAL sec_jtag_tck_o : STD_LOGIC; SIGNAL sec_jtag_tdi_o : STD_LOGIC; SIGNAL sec_jtag_tms_o : STD_LOGIC; SIGNAL sec_jtag_trst_o : STD_LOGIC; --Signal used for prbs -- SIGNAL prbs_o : STD_LOGIC_VECTOR(set_prbs_tabs(HBHE,20)'high downto 0); signal prbs_read_regs : STD_LOGIC_VECTOR(set_prbs_tabs(HBHE,20)'high downto 0):=(others=>'0'); signal prbs_write_regs : STD_LOGIC_VECTOR(set_prbs_tabs(HBHE,20)'high downto 0):=(others=>'0'); --Signal used for pwr_good SIGNAL pwr_good_pre : STD_LOGIC:=('1'); SIGNAL pwr_good_cnt : STD_LOGIC := '0'; SIGNAL qie_reset_q : STD_LOGIC; SIGNAL wte_q : STD_LOGIC; SIGNAL RX_Clock_40MHz : STD_LOGIC; SIGNAL RX_Clock_20MHz_dl : STD_LOGIC_VECTOR (1 DOWNTO 0):=(others=>'0'); -- changed 9/17/2020 SIGNAL TCK_in_rise : STD_LOGIC; --signal TCK_inCounter : unsigned(15 downto 0):=(others=>'0'); SIGNAL jtag_bridge_tck_q : STD_LOGIC; --signal TCK_outCounter : unsigned(15 downto 0):=(others=>'0'); SIGNAL TimeoutError : STD_LOGIC; signal TimeoutErrorCounter : unsigned(31 downto 0):=(others=>'0'); signal TX_Word : std_logic_vector(83 downto 0); signal TX_Word_tmp : std_logic_vector(83 downto 0); --type array8X32U is array (0 to 7) of unsigned(31 downto 0); --signal ngCCM_status_counter : array8X32U := (others => (others => '0')); signal power_good_n : std_logic; signal RX_wordclk_cnt : unsigned(15 downto 0):=(others=>'0'); signal test_comm_cnt : unsigned(15 downto 0):=(others=>'0'); signal test_comm_cnt2 : unsigned(15 downto 0):=(others=>'0'); --attribute mark_debug : string; --attribute mark_debug of RX_word_rx40 : signal is "true"; --attribute mark_debug of TX_word : signal is "true"; --attribute mark_debug of i2c_scl_i : signal is "true"; --attribute mark_debug of i2c_sda_i : signal is "true"; --attribute mark_debug of i2c_scl_o : signal is "true"; --attribute mark_debug of i2c_sda_o : signal is "true"; signal TimeoutErrorCnt_i : std_logic := '0'; signal TCK_inCnt_i : std_logic := '0'; signal TCK_outCnt_i : std_logic := '0'; BEGIN TimeoutErrorCnt <= TimeoutErrorCnt_i; TCK_inCnt <= TCK_inCnt_i; TCK_outCnt <= TCK_outCnt_i; process(fabric_clk) begin if(fabric_clk'event and fabric_clk = '1')then if(TimeoutError = '1')then TimeoutErrorCnt_i <= not TimeoutErrorCnt_i; end if; if(TCK_in_rise = '1')then TCK_inCnt_i <= not TCK_inCnt_i; end if; jtag_bridge_tck_q <= jtag_bridge_tck_o; if(jtag_bridge_tck_o = '1' and jtag_bridge_tck_q = '0')then TCK_outCnt_i <= not TCK_outCnt_i; end if; end if; end process; --TCK_counter <= std_logic_vector(TCK_outCounter) & std_logic_vector(TCK_inCounter); process(RX_wordclk) begin if(RX_wordclk'event and RX_wordclk = '1')then RX_Clock_20MHz_dl <= RX_Clock_20MHz_dl(0) & RX_Clock_20MHz; -- changed 9/17/2020 RX_Clock_40MHz <= RX_Clock_20MHz_dl(1) xor RX_Clock_20MHz_dl(0); -- changed 9/17/2020 end if; end process; -- Loopback reset reset_out <= reset_in; Sync_TX_Reset : SyncRst PORT MAP(clk => fabric_clk, ce => '1', Rst_i => reset_in, Rst_o => TX_Reset); Sync_RX_Reset : SyncRst PORT MAP(clk => RX_wordclk, ce => RX_Clock_40MHz, Rst_i => reset_in, Rst_o => RX_Reset); -- Sync_error_counter_reset : SyncRst PORT MAP(clk => RX_wordclk, ce => RX_Clock_40MHz, Rst_i => error_counter_reset_i, Rst_o => error_counter_reset); --prbs generator -- prbs: entity work.prbs -- generic map(seed => set_initialValue(HBHE,20,inv_prbs_seed(HBHE,20)),inverter=>inv_prbs_seed(HBHE,20),hbhehf=>HBHE) -- port map ( -- prbs_o => prbs_o, -- clk => fabric_clk, -- clk_en => TX_Clock_20MHz, -- reset => TX_Reset -- ); --PRBS_Error_reset <= error_counter_reset or ngccmPinsInRX.test_comm; --gbt_rx_checker gbt_rx_checker: entity work.gbt_rx_checker generic map(seed_length => 20,nobReg => 32) port map( RX_Reset => RX_Reset, -- Error_counter_reset => error_counter_reset, Error_counter_reset => '0', RX_Clock_40MHz => RX_Clock_20MHz, RX_wordclk => RX_wordclk, sfp_rx_lost => sfp_rx_lost, sfp_tx_fault => sfp_tx_fault, PRBS_rx_pattern => prbs_read_regs, PRBS_rx_pattern_error_cnt_o => PRBS_rx_pattern_error_cnt_o, PRBS_rx_pattern_bitwise_error_cnt_o => PRBS_rx_pattern_bitwise_error_cnt_o ); -- purpose: Only copy over RX_Word when data is valid -- map one 20MHz frame received to two 40MHz frames -- type : sequential rx_word_dv_proc: PROCESS (RX_wordclk, RX_Reset) IS BEGIN -- PROCESS rx_word_dv_proc IF RX_Reset = '1' THEN -- asynchronous reset (active high) RX_Word_rx40 <= (OTHERS => '0'); ELSIF rising_edge(RX_wordclk) THEN -- rising clock edge IF (RX_Word_DV_i = '1'and RX_Clock_40MHz = '1') THEN -- changed 9/17/2020 IF (RX_Clock_20MHz = '1') THEN -- rising 20MHz clock edge for i in 0 to 41 loop RX_Word_rx40(2*i) <= RX_Word_i(2*i+1); RX_Word_rx40(2*i+1) <= RX_Word_i(2*i+1); end loop; RX_Word_rx40(83 downto 80) <= RX_Word_i(83 downto 80); RX_Word_rx40(31 downto 16) <= RX_Word_i(31 downto 16); else -- changed 9/17/2020 for i in 0 to 41 loop RX_Word_rx40(2*i) <= RX_Word_i(2*i); RX_Word_rx40(2*i+1) <= RX_Word_i(2*i); end loop; RX_Word_rx40(83 downto 80) <= RX_Word_i(83 downto 80); RX_Word_rx40(31 downto 16) <= RX_Word_i(31 downto 16); END IF; END IF; END IF; END PROCESS rx_word_dv_proc; -- purpose: Capture Writes to the ngCCM I/O registers. Writes to the other registers is handled elsewhere. -- type : sequential -- process(fabric_clk) -- begin -- if(fabric_clk'event and fabric_clk = '1')then -- qie_reset_q <= qie_reset; -- wte_q <= wte; -- end if; -- end process; ngccmPinsOutReg.sec_reset <= '0'; ngccmPinsOutReg.sec_sel_addr <= (OTHERS => '0'); -- select NONE ngccmPinsOutReg.sec_peltier <= (OTHERS => '0'); ngccmPinsOutReg.sec_pwr_enable <= '0'; ngccmio_write_proc : PROCESS (fabric_clk, TX_Reset) IS BEGIN -- PROCESS ngccmio_write_proc IF TX_Reset = '1' THEN -- asynchronous reset (active high) -- ngccmPinsOutReg <= ( -- Primary JTAG connection ngccmPinsOutReg.jtag_tck <= '0'; -- same as board pull-down ngccmPinsOutReg.jtag_tdi <= '1'; -- same as board pull-up ngccmPinsOutReg.jtag_tms <= '1'; -- same as board pull-up ngccmPinsOutReg.jtag_trst <= '0'; -- Keep Sec FPGA JTAG in reset (active low) ngccmPinsOutReg.sel_addr <= (OTHERS => '0'); -- select NONE -- Redundant JTAG connection ngccmPinsOutReg.sec_jtag_tck <= '0'; -- same as board pull-down ngccmPinsOutReg.sec_jtag_tdi <= '1'; -- same as board pull-up ngccmPinsOutReg.sec_jtag_tms <= '1'; -- same as board pull-up ngccmPinsOutReg.sec_jtag_trst <= '0'; -- Keep Sec FPGA JTAG in reset (active low) -- ngccmPinsOutReg.sec_sel_addr <= (OTHERS => '0'); -- select NONE -- Primary Fast Singnals ngccmPinsOutReg.peltier <= (OTHERS => '0'); ngccmPinsOutReg.bkp_reset <= '0'; ngccmPinsOutReg.bkp_reset_qie <= '0'; ngccmPinsOutReg.bkp_wte <= '0'; ngccmPinsOutReg.bkp_pwr_enable <= '1'; -- Redundant Fast Singnals -- ngccmPinsOutReg.sec_peltier <= (OTHERS => '0'); -- ngccmPinsOutReg.sec_reset <= '0'; ngccmPinsOutReg.sec_reset_qie <= '0'; ngccmPinsOutReg.sec_wte <= '0'; -- ngccmPinsOutReg.sec_pwr_enable <= '0'; -- Primary I2C connection -- There is only a single SCL for a grouping of I2C "busses" ngccmPinsOutReg.bkt_scl <= "111"; ngccmPinsOutReg.bkt_sda <= (OTHERS => '1'); -- Redundant I2C connection -- There is only a single SCL for a grouping of I2C "busses" ngccmPinsOutReg.sec_scl <= '1'; ngccmPinsOutReg.sec_sda <= (OTHERS => '1'); -- Debug connection ngccmPinsOutReg.test_comm <= '0'; ngccmPinsOutReg.sec_test_comm <= '0'; ngccmPinsOutReg.prbs_rx <= set_initialValue(HBHE,20,inv_prbs_seed(HBHE,20));--prbs seed reg_ngccm_jtag_wr <= '0'; reg_ngccm_jtag_i <= (OTHERS => '0'); sel_sec_jtag <= '0'; ngccm_trst <= '0'; sec_ngccm_trst <= '0'; ELSIF rising_edge(fabric_clk) THEN -- rising clock edge -- write prbs -- if(TX_Clock_20MHz = '1')then ngccmPinsOutReg.prbs_rx <= prbs_o; -- end if; IF (write_local(BKP_PARTITION) = '1') THEN CASE to_integer(UNSIGNED(addr_local(BKP_PARTITION))) IS WHEN kREG_NGCCMIO_BKP_IO => ngccmPinsOutReg.bkp_reset <= data_in(BKP_PARTITION)(0); ngccmPinsOutReg.bkp_pwr_enable <= data_in(BKP_PARTITION)(2); ngccmPinsOutReg.peltier <= data_in(BKP_PARTITION)(7 downto 4); ngccmPinsOutReg.sel_addr <= data_in(BKP_PARTITION)(15 downto 12); ngccmPinsOutReg.test_comm <= data_in(BKP_PARTITION)(20); sel_sec_jtag <= data_in(BKP_PARTITION)(21); ngccm_trst <= data_in(BKP_PARTITION)(29); sec_ngccm_trst <= data_in(BKP_PARTITION)(30); WHEN OTHERS => NULL; END CASE; END IF; -- This behavior overides any above logic. If I2CDirectAccess_Enable is -- asserted, then the above writing to I/O bits will change the I2C -- signals. Otherwise, they get driven by the internal I2C controller. IF I2CDirectAccess_Enable = '0' THEN -- Primary communication ngccmPinsOutReg.bkt_scl <= i2c_scl_o(1) & i2c_scl_o(1) & i2c_scl_o(1); ngccmPinsOutReg.bkt_sda <= i2c_sda_o(kNUM_I2C_ngCCM-1 downto 0); ngccmPinsOutReg.bkp_wte <= WTE; ngccmPinsOutReg.bkp_reset_qie <= QIE_RESET; -- Redundant communication ngccmPinsOutReg.sec_scl <= i2c_scl_o(kNUM_I2C_ngCCM+1); ngccmPinsOutReg.sec_sda <= i2c_sda_o(2*kNUM_I2C_ngCCM-1 downto kNUM_I2C_ngCCM); ngccmPinsOutReg.sec_wte <= WTE; ngccmPinsOutReg.sec_reset_qie <= QIE_RESET; END IF; -- This behavior overides any above logic. If jtag_en is deasserted -- (ie. JTAG Controller not being used), then the above writing to I/O -- bits will change the JTAG signals. Otherwise, they get driven by the -- internal JTAG controller. IF jtag_sec_en = '1' THEN ngccmPinsOutReg.jtag_tck <= jtag_tck_o; ngccmPinsOutReg.jtag_tdi <= jtag_tdi_o; ngccmPinsOutReg.jtag_tms <= jtag_tms_o; ngccmPinsOutReg.jtag_trst <= jtag_trst_o; ngccmPinsOutReg.sec_jtag_tck <= sec_jtag_tck_o; ngccmPinsOutReg.sec_jtag_tdi <= sec_jtag_tdi_o; ngccmPinsOutReg.sec_jtag_tms <= sec_jtag_tms_o; ngccmPinsOutReg.sec_jtag_trst <= sec_jtag_trst_o; ELSIF (jtag_sec_en_dly = '1' AND jtag_sec_en = '0') THEN -- On the falling edge of jtag_sec_en, make sure that TRst is asserted -- ('0') and the other signals are at sensible levels. ngccmPinsOutReg.jtag_tck <= '1'; ngccmPinsOutReg.jtag_tdi <= '1'; ngccmPinsOutReg.jtag_tms <= '1'; ngccmPinsOutReg.jtag_trst <= '0'; ngccmPinsOutReg.sec_jtag_tck <= '1'; ngccmPinsOutReg.sec_jtag_tdi <= '1'; ngccmPinsOutReg.sec_jtag_tms <= '1'; ngccmPinsOutReg.sec_jtag_trst <= '0'; END IF; reg_ngccm_jtag_wr <= '0'; -- default is '0' -- below logic overwrites some of the registers up IF (write_local(JTAG_PARTITION) = '1') THEN CASE to_integer(UNSIGNED(addr_local(JTAG_PARTITION))) IS WHEN kREG_NGCCM_JTAG => reg_ngccm_jtag_i <= data_in(JTAG_PARTITION); reg_ngccm_jtag_wr <= '1'; WHEN OTHERS => NULL; END CASE; END IF; -- clock jtag_en for falling edge detection jtag_sec_en_dly <= jtag_sec_en; END IF; END PROCESS ngccmio_write_proc; -- Assign the output pins to TX_Word. -- merge two 40MHz Tx frames into one 20MHz Tx frame TX_Word <= ngCCM_Pins_to_GBT_Word(ngccmPinsOutReg); process(fabric_clk) begin if(fabric_clk'event and fabric_clk = '1')then if(TX_Clock_20MHz = '1')then TX_Word_o <= TX_Word_tmp; for i in 0 to 41 loop TX_Word_tmp(2*i) <= TX_Word(2*i); end loop; TX_Word_tmp(31 downto 16) <= TX_Word(31 downto 16); TX_Word_tmp(83 downto 80) <= TX_Word(83 downto 80); else for i in 0 to 41 loop TX_Word_tmp(2*i+1) <= TX_Word(2*i); end loop; TX_Word_tmp(31 downto 16) <= TX_Word(31 downto 16); TX_Word_tmp(83 downto 80) <= TX_Word(83 downto 80); end if; end if; end process; prbs_write_regs <= ngccmPinsOutReg.prbs_rx; -- prbs_write_regs_o <= prbs_write_regs; -- Assign RX_Word_tx40 to the virtual input pins ngccmPinsInReg <= GBT_Word_to_ngCCM_Pins(RX_Word_tx40); -- Combine ngccmPinsInReg into the read REGISTER reg_ngccmio_jtag <= (0 => ngccmPinsInReg.jtag_tck, 1 => ngccmPinsOutReg.jtag_tdi, 2 => ngccmPinsInReg.jtag_tms, 3 => ngccmPinsInReg.jtag_trst, 4 => ngccmPinsInReg.jtag_tdo, 5 => ngccmPinsInReg.sec_jtag_tck, 6 => ngccmPinsOutReg.sec_jtag_tdi, 7 => ngccmPinsInReg.sec_jtag_tms, 8 => ngccmPinsInReg.sec_jtag_trst, 9 => ngccmPinsInReg.sec_jtag_tdo, 10 => ngccm_trst, 11 => sec_ngccm_trst, 15 => sel_sec_jtag, 16 => ngccmPinsOutReg.sec_sel_addr(0), 17 => ngccmPinsOutReg.sec_sel_addr(1), 18 => ngccmPinsOutReg.sec_sel_addr(2), 19 => ngccmPinsOutReg.sec_sel_addr(3), 20 => ngccmPinsInReg.sec_geo_addr(0), 21 => ngccmPinsInReg.sec_geo_addr(1), 22 => ngccmPinsInReg.sec_geo_addr(2), 23 => ngccmPinsInReg.sec_geo_addr(3), 24 => ngccmPinsOutReg.sel_addr(0), 25 => ngccmPinsOutReg.sel_addr(1), 26 => ngccmPinsOutReg.sel_addr(2), 27 => ngccmPinsOutReg.sel_addr(3), 28 => ngccmPinsInReg.geo_addr(0), 29 => ngccmPinsInReg.geo_addr(1), 30 => ngccmPinsInReg.geo_addr(2), 31 => ngccmPinsInReg.geo_addr(3), OTHERS => '0'); reg_ngccmio_bkp_io <= (0 => ngccmPinsInReg.bkp_reset, -- OUT: bkp_reset 1 => ngccmPinsInReg.bkp_wte, -- OUT: bkp_wte 2 => ngccmPinsInReg.bkp_pwr_enable, -- OUT: bkp_pwr_enable 3 => ngccmPinsInReg.bkp_reset_qie, -- OUT: bkp_reset_qie 4 => ngccmPinsInReg.bkp_pwr_good, 16 => ngccmPinsInReg.sec_reset, -- OUT: sec_reset 17 => ngccmPinsInReg.sec_wte, -- OUT: sec_wte 18 => ngccmPinsInReg.sec_pwr_enable, -- OUT: sec_pwr_enable 19 => ngccmPinsInReg.sec_reset_qie, -- OUT: sec_reset_qie 20 => ngccmPinsInReg.sec_pwr_good, OTHERS => '0'); reg_ngccmio_bkp_i2c <= (0 => ngccmPinsInReg.bkt_scl(0), 1 => ngccmPinsInReg.bkt_scl(1), 2 => ngccmPinsInReg.bkt_scl(2), 3 => ngccmPinsInReg.bkt_sda(1), 4 => ngccmPinsInReg.bkt_sda(2), 5 => ngccmPinsInReg.bkt_sda(3), 6 => ngccmPinsInReg.bkt_sda(4), 7 => ngccmPinsInReg.bkt_sda(5), 8 => ngccmPinsInReg.bkt_sda(6), 9 => ngccmPinsInReg.bkt_sda(7), 10 => ngccmPinsInReg.bkt_sda(8), 11 => ngccmPinsInReg.bkt_sda(9), 12 => ngccmPinsInReg.bkt_sda(10), 13 => ngccmPinsInReg.bkt_sda(11), 14 => ngccmPinsInReg.bkt_sda(12), 16 => ngccmPinsInReg.sec_scl, 17 => ngccmPinsInReg.sec_scl, 18 => ngccmPinsInReg.sec_scl, 19 => ngccmPinsInReg.sec_sda(1), 20 => ngccmPinsInReg.sec_sda(2), 21 => ngccmPinsInReg.sec_sda(3), 22 => ngccmPinsInReg.sec_sda(4), 23 => ngccmPinsInReg.sec_sda(5), 24 => ngccmPinsInReg.sec_sda(6), 25 => ngccmPinsInReg.sec_sda(7), 26 => ngccmPinsInReg.sec_sda(8), 27 => ngccmPinsInReg.sec_sda(9), 28 => ngccmPinsInReg.sec_sda(10), 29 => ngccmPinsInReg.sec_sda(11), 30 => ngccmPinsInReg.sec_sda(12), OTHERS => '0'); reg_ngccmio_misc <= (24 => ngccmPinsInReg.ngccm_rev_id(0), 25 => ngccmPinsInReg.ngccm_rev_id(1), 26 => ngccmPinsInReg.ngccm_rev_id(2), 27 => '0', 28 => ngccmPinsInReg.ngccm_neigh_rev_id(0), 29 => ngccmPinsInReg.ngccm_neigh_rev_id(1), 30 => ngccmPinsInReg.ngccm_neigh_rev_id(2), 31 => '0', OTHERS => '0'); ngccm_bkp_regs(0) <= ngccmPinsInReg.bkp_pwr_good; ngccm_bkp_regs(1) <= ngccmPinsInReg.bkp_reset; ngccm_bkp_regs(2) <= ngccmPinsInReg.bkp_wte; ngccm_bkp_regs(3) <= ngccmPinsInReg.bkp_pwr_enable; ngccm_bkp_regs(4) <= ngccmPinsInReg.bkp_reset_qie; ngccm_bkp_regs(5) <= ngccmPinsInReg.ngccm_rev_id(0); ngccm_bkp_regs(6) <= ngccmPinsInReg.ngccm_rev_id(1); ngccm_bkp_regs(7) <= ngccmPinsInReg.ngccm_rev_id(2); ngccm_bkp_regs(8) <= ngccmPinsInReg.ngccm_neigh_rev_id(0); ngccm_bkp_regs(9) <= ngccmPinsInReg.ngccm_neigh_rev_id(1); ngccm_bkp_regs(10) <= ngccmPinsInReg.ngccm_neigh_rev_id(2); ngccm_bkp_regs(11) <= ngccmPinsOutReg.bkp_reset; ngccm_bkp_regs(12) <= ngccmPinsOutReg.bkp_wte; ngccm_bkp_regs(13) <= ngccmPinsOutReg.bkp_pwr_enable; ngccm_bkp_regs(14) <= ngccmPinsOutReg.bkp_reset_qie; ngccm_bkp_regs(18 downto 15) <= ngccmPinsOutReg.peltier; ngccm_bkp_regs(19) <= ngccmPinsOutReg.sec_reset; ngccm_bkp_regs(20) <= ngccmPinsOutReg.sec_wte; ngccm_bkp_regs(21) <= ngccmPinsOutReg.sec_pwr_enable; ngccm_bkp_regs(22) <= ngccmPinsOutReg.sec_reset_qie; ngccm_bkp_regs(26 downto 23) <= ngccmPinsOutReg.sec_peltier; ngccm_bkp_regs( 31 downto 27) <= (others=>'0'); -- these pins are still sync'ed to the GBT RX core RX 40 MHz clock ngccmPinsInRX <= GBT_Word_to_ngCCM_Pins(RX_Word_rx40); --prbs read prbs_read_regs <= ngccmPinsInRX.prbs_tx; -- prbs_read_regs_o <= prbs_read_regs; process(RX_wordclk,RX_Reset) begin if RX_Reset = '1' then pwr_good_pre <= '0'; elsif rising_edge(RX_wordclk) then if(RX_Clock_40MHz = '1')then pwr_good_pre <= ngccmPinsInRX.bkp_pwr_good; end if; end if; end process; process(RX_wordclk) begin if rising_edge(RX_wordclk) then if(RX_Clock_40MHz = '1')then if(pwr_good_pre = '0' and ngccmPinsInRX.bkp_pwr_good = '1')then pwr_good_cnt <= not pwr_good_cnt; end if; end if; end if; end process; pwr_good_cnt_o <= pwr_good_cnt; -- heartBeat_inst : Agnostic_Counter -- GENERIC MAP ( -- gCOUNTER_SIZE => heartBeatCntr'length, -- gCOUNTER_TERM => kHEARTBEAT_CNTR_TERM) -- PORT MAP ( -- Clock => fabric_clk, -- reset => TX_Reset, -- en => heartBeat_Enable, -- use this to save power when not enabled -- q => heartBeatCntr); ------------------------------------------------------------------------- -- Local IPbus interface ------------------------------------------------------------------------- -- purpose: Used to capture data from RX Clock side -- type : sequential strobe_mux <= or_reduce(strobe_local); gbt_fetch_rx_data_proc : PROCESS (fabric_clk, TX_Reset) IS BEGIN -- PROCESS gbt_fetch_rx_data_proc IF TX_Reset = '1' THEN -- asynchronous reset (active high) strobe_local_dly <= '0'; recv_RX_to_TX_data_dly <= '0'; clr_fetch_RX_data <= '0'; ELSIF rising_edge(fabric_clk) THEN -- rising clock edge if(TX_Clock_20MHz = '1')then strobe_local_dly <= strobe_mux; recv_RX_to_TX_data_dly <= recv_RX_to_TX_data; IF (recv_RX_to_TX_data = '1' AND recv_RX_to_TX_data_dly = '0') THEN -- assert clr_fetch_RX_data on rising edge of recv_RX_to_TX_data clr_fetch_RX_data <= '1'; ELSIF (strobe_mux = '0' AND strobe_local_dly = '1') THEN -- deassert clr_fetch_RX_data on falling edge of strobe_local clr_fetch_RX_data <= '0'; END IF; end if; --fetch_RX_data <= strobe_mux AND NOT clr_fetch_RX_data;!!!!!!!! END IF; END PROCESS gbt_fetch_rx_data_proc; -- fetch_RX_data is strobe local modulated with clr_fetch_RX_data. -- fetch_RX_data is combinatorial so as to not lose another clock cycle. fetch_RX_data <= strobe_mux AND NOT clr_fetch_RX_data;--!!!!!!!!!!!1 gbt_RX_to_TX_data_i <= RX_Word_rx40; RX_Word_tx40 <= gbt_RX_to_TX_data_o; CrossClock_DV_cnt : CrossClock_RX GENERIC MAP ( DataBtoA_SZ => 1, DataAtoB_SZ => gbt_RX_to_TX_data_i'length, WAIT_STATES_A => 0) -- it will be the minimum WAIT which is > 0 PORT MAP ( resetA => RX_Reset, clkA => RX_wordclk, clkA_en => RX_Clock_40MHz, sentBtoA_o => OPEN, strbAtoB_o => OPEN, DataAtoB_i => gbt_RX_to_TX_data_i, DataBtoA_o => TX_to_RX_unused_o, clkB => fabric_clk, sendBtoA_i => fetch_RX_data, Recvatob_o => recv_RX_to_TX_data, DataBtoA_i => "0", DataAtoB_o => gbt_RX_to_TX_data_o ); -- NOTE: Local side of IPbus is clocked with TX_Clock_40MHz so -- all RX signals must be sync'ed to TX_Clock_40MHz. -- NOTE: b/c need to use CrossClock to sync from RX_Clock_40MHz -- domain, need to add additional wait states to IPbus_local. IPbus_gen : FOR part IN 0 TO no_partition-1 GENERATE -- skip_SFP_SEC: if(part /= SFP_PARTITION_SEC) generate ipb_miso(part).ipb_err <= '0'; IPbus_local_inst : IPbus_local GENERIC MAP ( ADDR_MSB => kMSB_ngCCM, WAIT_STATES => kWAIT_ngCCM+4, WRITE_PULSE_TICKS => kWTICKS_ngCCM) PORT MAP ( reset_local => TX_Reset, clk_local => fabric_clk, strobe_local => strobe_local(part), write_local => write_local (part), addr_local => addr_local (part), DataIn_local => data_in (part), DataOut_local => data_out(part), IPbus_clk => ipb_clk_i, IPbus_strobe => ipb_mosi(part).ipb_strobe, IPbus_write => ipb_mosi(part).ipb_write, IPbus_ack => ipb_miso(part).ipb_ack, IPbus_addr => ipb_mosi(part).ipb_addr(kMSB_ngCCM DOWNTO 0), IPbus_DataIn => ipb_mosi(part).ipb_wdata, IPbus_DataOut => ipb_miso(part).ipb_rdata); -- end generate SKIP_SFP_SEC; end generate IPbus_gen; data_out(kNUM_I2C_BUSSES-1 downto 0) <= i2c_data_out(kNUM_I2C_BUSSES-1 downto 0); WITH to_integer(UNSIGNED(addr_local(BKP_PARTITION))) SELECT data_out(BKP_PARTITION) <= reg_ngccmio_jtag WHEN kREG_NGCCMIO_JTAG, reg_ngccmio_bkp_io WHEN kREG_NGCCMIO_BKP_IO, reg_ngccmio_bkp_i2c WHEN kREG_NGCCMIO_BKP_I2C, -- reg_ngccmio_sec_i2c WHEN kREG_NGCCMIO_SEC_I2C, reg_ngccmio_misc WHEN kREG_NGCCMIO_MISC, other_data_out WHEN OTHERS; other_data_out <= (others => '0'); WITH to_integer(UNSIGNED(addr_local(JTAG_PARTITION))) SELECT data_out(JTAG_PARTITION) <= reg_ngccm_jtag_o WHEN kREG_NGCCM_JTAG, jtag_data_out WHEN OTHERS; -- Select when I2C data bus to output based on the four addr_local bits 7-4. -- i2c_data_out(0) <= x"DEADCABB"; -- output this if one of the 8 I2C busses is not selected -- i2c_sel_data_out <= i2c_data_out(to_integer(UNSIGNED(addr_local(i2cbus)(7 DOWNTO 4)))); -- reg_ngccm_status <= (0 => heartBeat_Enable, -- 1 => I2CDirectAccess_Enable, -- 3 => jtag_ctrl_clk, -- @@@ for debug -- 4 => ngccmPinsInReg.sec_tck, -- @@@ for debug -- 5 => ngccmPinsOutReg.sec_tdi, -- @@@ for debug -- 6 => ngccmPinsInReg.sec_tms, -- @@@ for debug -- 7 => ngccmPinsInReg.sec_trst, -- @@@ for debug -- 8 => ngccmPinsInReg.sec_tdo, -- @@@ for debug -- OTHERS => '0'); -- heartBeat_Enable <= '1';--!!!!remove this part before the final release I2CDirectAccess_Enable <= '0';--!!!! -------------------------------------------------------------------------------------------- -- I2C bus handling. -------------------------------------------------------------------------------------------- i2c_gen : FOR i2cbus IN 0 TO kNUM_I2C_ngCCM-1 GENERATE -- Set up strobe_local to be muxed to I2C controller per addr_local bits 7-4. i2c_strobe(i2cbus) <= strobe_local(i2cbus) WHEN (to_integer(UNSIGNED(addr_local(i2cbus)(7 DOWNTO 4))) = i2cbus) ELSE '0'; i2c_reset_local(i2cbus) <= TX_Reset or reset_partition(i2cbus); i2c_scl_i(i2cbus) <= ngccmPinsInRx.bkt_scl(0) when i2cbus < 5 else ngccmPinsInRx.bkt_scl(1) when i2cbus < 10 else ngccmPinsInRx.bkt_scl(2); LocalI2CBridge_fe : LocalI2CBridge PORT MAP ( reset_local => i2c_reset_local(i2cbus), clk_local => fabric_clk, strobe_local => i2c_strobe(i2cbus), write_local => write_local(i2cbus), addr_local => addr_local(i2cbus)(3 DOWNTO 0), DataIn_local => data_in(i2cbus), DataOut_local => i2c_data_out(i2cbus), wb_ack_o => wb_ack(i2cbus), clk_en => i2c_clk_en, -- clk_6x_o => clk_6x(i2cbus), prer_scale_i => prescale(15 DOWNTO 0), power_good => power_good_n, sfp_rx_lost => sfp_rx_lost, sfp_tx_fault => sfp_tx_fault, scl_i => i2c_scl_i(i2cbus), sda_i => i2c_sda_i(i2cbus), scl_o => i2c_scl_o(i2cbus), sda_o => i2c_sda_o(i2cbus)); END GENERATE i2c_gen; power_good_n <= not ngccmPinsInReg.bkp_pwr_good; -- The i2c controller within LocalI2CBridge will synchronize these -- inputs to the clock being used songccm_pin_output_typ no need to sync to TX 40MHz -- clock at this level. i2c_sda_i <= ngccmPinsInRx.bkt_sda & ngccmPinsInRx.bkt_sda; -------------------------------------------------------------------------------------------- -- Actel JTAG bus handling. -------------------------------------------------------------------------------------------- -- strobe JTAG data block when get strobe_local and the high addr_local bit is a '1' jtag_strobe <= strobe_local(JTAG_PARTITION) AND addr_local(JTAG_PARTITION)(kMSB_ngCCM); jtag_reset_local(jtag_partition) <= TX_Reset or reset_partition(jtag_partition); LocalJTAGBridge_inst : LocalJTAGBridge PORT MAP ( -- IPbus local interface reset_local => jtag_reset_local(jtag_partition), clk_local => fabric_clk, strobe_local => jtag_strobe, write_local => write_local(JTAG_PARTITION), addr_local => addr_local(JTAG_PARTITION)(9 DOWNTO 0), DataIn_local => data_in(JTAG_PARTITION), DataOut_local => jtag_data_out, TimeoutError => TimeoutError, -- control/status registers jtag_reg_wr => reg_ngccm_jtag_wr, jtag_reg_i => reg_ngccm_jtag_i, jtag_reg_o => reg_ngccm_jtag_o, jtag_en_o => jtag_sec_en, -- output of the divided down clock ctrl_clk_o => jtag_ctrl_clk, TCK_in_rise => TCK_in_rise, -- NOTE: These pins are synchronized to RX 40MHz. The JTAG controller -- within LocalJTAGBridge will sync them to TX 40MHz before using them. tdo_i => jtag_bridge_tdo_i, tck_i => jtag_bridge_tck_i, --tdi_i => jtag_bridge_tdi_i, tms_i => jtag_bridge_tms_i, trst_i => jtag_bridge_trst_i, -- output pins to be written to GBT interface tck_o => jtag_bridge_tck_o, tdi_o => jtag_bridge_tdi_o, tms_o => jtag_bridge_tms_o, trst_o => jtag_bridge_trst_o); -- Glitch filters for JTAG RX signals jtag_tck <= ngccmPinsInRx.jtag_tck; jtag_tdo <= ngccmPinsInRx.jtag_tdo; jtag_tms <= ngccmPinsInRx.jtag_tms; jtag_trst <= ngccmPinsInRx.jtag_trst; sec_jtag_tck <= ngccmPinsInRx.sec_jtag_tck; sec_jtag_tdo <= ngccmPinsInRx.sec_jtag_tdo; sec_jtag_tms <= ngccmPinsInRx.sec_jtag_tms; sec_jtag_trst <= ngccmPinsInRx.sec_jtag_trst; -- ngccmPinsInRx is in the RX_wordclk clock domain, so there should be no glitches to filter. -- glitch_jtag_tck : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.jtag_tck, dout => jtag_tck, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_jtag_tdo : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.jtag_tdo, dout => jtag_tdo, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_jtag_tms : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.jtag_tms, dout => jtag_tms, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_jtag_trst : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '0') -- PORT MAP (din => ngccmPinsInRx.jtag_trst, dout => jtag_trst, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- -- glitch_sec_jtag_tck : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.sec_jtag_tck, dout => sec_jtag_tck, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_sec_jtag_tdo : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.sec_jtag_tdo, dout => sec_jtag_tdo, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_sec_jtag_tms : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '1') -- PORT MAP (din => ngccmPinsInRx.sec_jtag_tms, dout => sec_jtag_tms, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- glitch_sec_jtag_trst : glitch_filter -- GENERIC MAP (SIZE => 2, DOUT_RST => '0') -- PORT MAP (din => ngccmPinsInRx.sec_jtag_trst, dout => sec_jtag_trst, rise => OPEN, fall => OPEN, clk => RX_wordclk, rst_n => not RX_reset); -- purpose: Handle mux of JTAG signals based on SEL_ADDR -- type : combinational -- jtagMuxProc: PROCESS (ngccmPinsOutReg, -- jtag_tck, jtag_tdo, jtag_tms, jtag_trst, -- sec_jtag_tck, sec_jtag_tdo, sec_jtag_tms, sec_jtag_trst, -- jtag_tck_o, jtag_tdi_o, jtag_tms_o, jtag_trst_o) IS -- VARIABLE selAddrNum : INTEGER := to_integer(UNSIGNED(ngccmPinsOutReg.sel_addr)); -- BEGIN -- PROCESS jtagMuxProc -- -- Defaults -- jtag_tck_o <= '1'; -- jtag_tdi_o <= '1'; -- jtag_tms_o <= '1'; -- jtag_trst_o <= '0'; -- sec_jtag_tck_o <= '1'; -- sec_jtag_tdi_o <= '1'; -- sec_jtag_tms_o <= '1'; -- sec_jtag_trst_o <= '0'; -- IF (selAddrNum /= 7) THEN -- IF (sel_sec_jtag = '0') THEN -- -- Connect LocalJTAGBridge to the direct JTAG bits -- -- -- -- NOTE: These pins are synchronized to RX 40MHz. The JTAG controller -- -- within LocalJTAGBridge will sync them to TX 40MHz before using them. -- jtag_bridge_tdo_i <= jtag_tdo; -- jtag_bridge_tck_i <= jtag_tck; -- jtag_bridge_tms_i <= jtag_tms; -- jtag_bridge_trst_i <= jtag_trst; -- -- output pins to be written to GBT interface -- jtag_tck_o <= jtag_bridge_tck_o; -- jtag_tdi_o <= jtag_bridge_tdi_o; -- jtag_tms_o <= jtag_bridge_tms_o; -- if (selAddrNum = 0) THEN -- jtag_trst_o <= '1'; -- ELSE -- jtag_trst_o <= jtag_bridge_trst_o; -- END IF; -- sec_jtag_tck_o <= sec_jtag_tck_o; -- sec_jtag_tdi_o <= sec_jtag_tdi_o; -- sec_jtag_tms_o <= sec_jtag_tms_o; -- sec_jtag_trst_o <= '0'; -- ELSE -- -- Connect LocalJTAGBridge to the redundant path -- -- -- -- NOTE: These pins are synchronized to RX 40MHz. The JTAG controller -- -- within LocalJTAGBridge will sync them to TX 40MHz before using them. -- jtag_bridge_tdo_i <= ngccmPinsInRx.sec_jtag_tdo; -- jtag_bridge_tck_i <= ngccmPinsInRx.sec_jtag_tck; -- jtag_bridge_tms_i <= ngccmPinsInRx.sec_jtag_tms; -- jtag_bridge_trst_i <= ngccmPinsInRx.sec_jtag_trst; -- QIE/Calibration have no TRST - must set a bit in Bridge FPGA via I2C -- -- output pins to be written to GBT interface -- jtag_tck_o <= jtag_tck_o; -- jtag_tdi_o <= jtag_tdi_o; -- jtag_tms_o <= jtag_tms_o; -- jtag_trst_o <= '0'; -- sec_jtag_tck_o <= jtag_bridge_tck_o; -- sec_jtag_tdi_o <= jtag_bridge_tdi_o; -- sec_jtag_tms_o <= jtag_bridge_tms_o; -- if (selAddrNum = 0) THEN -- sec_jtag_trst_o <= '1'; -- ELSE -- sec_jtag_trst_o <= jtag_bridge_trst_o; -- END IF; -- END IF; -- ELSE -- -- Connect LocalJTAGBridge to itself -- jtag_tck_o <= jtag_tck_o; -- jtag_tdi_o <= jtag_tdi_o; -- jtag_tms_o <= jtag_tms_o; -- jtag_trst_o <= '0'; -- sec_jtag_tck_o <= sec_jtag_tck_o; -- sec_jtag_tdi_o <= sec_jtag_tdi_o; -- sec_jtag_tms_o <= sec_jtag_tms_o; -- sec_jtag_trst_o <= '0'; -- END IF; -- END PROCESS jtagMuxProc; jtagMuxProc_A : PROCESS (ngccmPinsOutReg, ngccmPinsInRx, jtag_tck, jtag_tdo, jtag_tms, jtag_trst) VARIABLE selAddrNum : INTEGER := to_integer(UNSIGNED(ngccmPinsOutReg.sel_addr)); BEGIN -- PROCESS jtagMuxProc IF(selAddrNum = 7)THEN jtag_bridge_tdo_i <= '1'; jtag_bridge_tck_i <= '1'; jtag_bridge_tms_i <= '1'; jtag_bridge_trst_i <= '0'; ELSIF(sel_sec_jtag = '0')THEN jtag_bridge_tdo_i <= jtag_tdo; jtag_bridge_tck_i <= jtag_tck; jtag_bridge_tms_i <= jtag_tms; jtag_bridge_trst_i <= jtag_trst; ELSE jtag_bridge_tdo_i <= ngccmPinsInRx.sec_jtag_tdo; jtag_bridge_tck_i <= ngccmPinsInRx.sec_jtag_tck; jtag_bridge_tms_i <= ngccmPinsInRx.sec_jtag_tms; jtag_bridge_trst_i <= ngccmPinsInRx.sec_jtag_trst; -- QIE/Calibration have no TRST - must set a bit in Bridge FPGA via I2C END IF; END PROCESS jtagMuxProc_A; jtagMuxProc_B : PROCESS (ngccmPinsOutReg, jtag_bridge_tck_o, jtag_bridge_tdi_o, jtag_bridge_tms_o, jtag_bridge_trst_o) VARIABLE selAddrNum : INTEGER := to_integer(UNSIGNED(ngccmPinsOutReg.sel_addr)); BEGIN -- PROCESS jtagMuxProc IF(selAddrNum = 7 OR sel_sec_jtag = '1')THEN jtag_tck_o <= '1'; jtag_tdi_o <= '1'; jtag_tms_o <= '1'; jtag_trst_o <= '0'; ELSE jtag_tck_o <= jtag_bridge_tck_o; jtag_tdi_o <= jtag_bridge_tdi_o; jtag_tms_o <= jtag_bridge_tms_o; if(selAddrNum = 0)THEN jtag_trst_o <= '1'; ELSE jtag_trst_o <= jtag_bridge_trst_o; END IF; END IF; END PROCESS jtagMuxProc_B; jtagMuxProc_C : PROCESS (ngccmPinsOutReg, jtag_bridge_tck_o, jtag_bridge_tdi_o, jtag_bridge_tms_o, jtag_bridge_trst_o) VARIABLE selAddrNum : INTEGER := to_integer(UNSIGNED(ngccmPinsOutReg.sel_addr)); BEGIN -- PROCESS jtagMuxProc IF(selAddrNum = 7 OR sel_sec_jtag = '0')THEN sec_jtag_tck_o <= '1'; sec_jtag_tdi_o <= '1'; sec_jtag_tms_o <= '1'; sec_jtag_trst_o <= '0'; ELSE sec_jtag_tck_o <= jtag_bridge_tck_o; sec_jtag_tdi_o <= jtag_bridge_tdi_o; sec_jtag_tms_o <= jtag_bridge_tms_o; if(selAddrNum = 0)THEN sec_jtag_trst_o <= '1'; ELSE sec_jtag_trst_o <= jtag_bridge_trst_o; END IF; END IF; END PROCESS jtagMuxProc_C; ngCCM_status_o(15) <= ngccmPinsInRX.test_comm; ngCCM_status_o(14 downto 9) <= (others => '0'); ngCCM_status_o(8 downto 0) <= prbs_read_regs(8 downto 0); END rtl;