From 11d68c55b7d6b4a7d132cf2c4da939a8e29a9096 Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Fri, 26 Nov 2021 21:24:58 +0100 Subject: [PATCH] wrong reset connection fixed --- media_interfaces/med_ecp3_sfp_sync_all_RS.vhd | 161 ++++---- media_interfaces/sync/main_tx_reset_RS.vhd | 364 +++++++++--------- media_interfaces/sync/med_sync_control_RS.vhd | 128 +++--- 3 files changed, 329 insertions(+), 324 deletions(-) diff --git a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd index 003ad80..bcd3206 100644 --- a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd @@ -10,9 +10,9 @@ use work.trb_net_std.all; use work.med_sync_define_RS.all; entity med_ecp3_sfp_sync_all_RS is - generic( + generic( SIM_MODE : integer := 0; - IS_MODE : int_array_t(0 to 3) := (c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED); + IS_MODE : int_array_t(0 to 3) := (c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED); IS_WAP_ZERO : integer := 1 ); port( @@ -32,19 +32,19 @@ entity med_ecp3_sfp_sync_all_RS is RX_RST_OUT : out std_logic; -- RST received RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); TX_RST_IN : in std_logic; - TX_RST_WORD_IN : in std_logic_vector(7 downto 0); + TX_RST_WORD_IN : in std_logic_vector(7 downto 0); WORD_SYNC_IN : in std_logic; WORD_SYNC_OUT : out std_logic; MASTER_CLK_IN : in std_logic; -- recovered RX clock in (only master ports in quad) - MASTER_CLK_OUT : out std_logic; -- recovered RX clock out (slave port in quad) + MASTER_CLK_OUT : out std_logic; -- recovered RX clock out (slave port in quad) MASTER_RESET_OUT : out std_logic; - DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- disable SFP transmitter - LINK_TX_READY_IN : in std_logic; -- TX PLLs are operational - TX_PLL_LOL_OUT : out std_logic; -- status signal of TX PLL + DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- disable SFP transmitter + LINK_TX_READY_IN : in std_logic; -- TX PLLs are operational + TX_PLL_LOL_OUT : out std_logic; -- status signal of TX PLL TX_RESET_OUT : out std_logic; SYNC_TX_PLL_IN : in std_logic; -- bit0 alignment for TX Serializer RST_QUAD_IN : in std_logic; - RST_TX_SERDES_IN : in std_logic; + RST_TX_PCS_IN : in std_logic; --SFP Connection SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) SD_LOS_IN : in std_logic_vector(3 downto 0); -- SFP Loss Of Signal ('0' = OK, '1' = no signal) @@ -53,8 +53,9 @@ entity med_ecp3_sfp_sync_all_RS is BUS_RX : in CTRLBUS_RX; BUS_TX : out CTRLBUS_TX; -- Status and control port - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') + STAT_DEBUG : out std_logic_vector(63 downto 0); + CTRL_DEBUG : in std_logic_vector(63 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end entity; @@ -69,7 +70,6 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is attribute syn_hier : string; attribute syn_hier of med_ecp3_sfp_sync_all_RS_arch : architecture is "hard"; - signal clk_200_i : std_logic; signal clk_rx_full : std_logic_vector(3 downto 0); signal clk_rx_half : std_logic_vector(3 downto 0); signal clk_tx_full : std_logic_vector(3 downto 0); @@ -84,11 +84,8 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal rst_n : std_logic; signal rx_serdes_rst : std_logic_vector(3 downto 0); - signal tx_serdes_rst : std_logic_vector(3 downto 0); - signal tx_pcs_rst : std_logic_vector(3 downto 0); signal rx_pcs_rst : std_logic_vector(3 downto 0); signal rst_qd : std_logic_vector(3 downto 0); - signal serdes_rst_qd : std_logic_vector(3 downto 0); signal rx_los_low : std_logic_vector(3 downto 0); signal lsm_status : std_logic_vector(3 downto 0); @@ -103,7 +100,6 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal sci_write_i : std_logic; signal wa_position : std_logic_vector(15 downto 0) := x"FFFF"; - signal wa_position_sel : std_logic_vector(3 downto 0); signal stat_rx_control_i : std_logic_vector(4*32-1 downto 0); signal stat_tx_control_i : std_logic_vector(4*32-1 downto 0); @@ -111,6 +107,8 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal debug_tx_control_i : std_logic_vector(4*32-1 downto 0); signal stat_fsm_reset_i : std_logic_vector(4*32-1 downto 0); + signal debug_i : std_logic_vector(4*32-1 downto 0); + signal hdinp, hdinn, hdoutp, hdoutn : std_logic_vector(3 downto 0); attribute nopad : string; attribute nopad of hdinp, hdinn, hdoutp, hdoutn : signal is "true"; @@ -120,26 +118,26 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal powerup_ch : std_logic_vector(3 downto 0); signal tx_ref_clk_i : std_logic; - + signal tx_dlm_word_i : std_logic_vector(7 downto 0); signal tx_dlm_i : std_logic; - + signal tx_rst_word_i : std_logic_vector(4*8-1 downto 0); signal tx_rst_i : std_logic_vector(3 downto 0); - + signal rx_rst_word_i : std_logic_vector(4*8-1 downto 0); signal rx_rst_i : std_logic_vector(3 downto 0); - + signal master_reset_i : std_logic_vector(3 downto 0); signal tx_reset_i : std_logic_vector(3 downto 0); signal quad_mode : integer range 0 to 100; begin - --- unused = 0 --- master = 1 --- slave = 8 + +-- unused = 0 +-- master = 1 +-- slave = 8 ------------------------------------------------- -- check settings of media interface @@ -151,21 +149,21 @@ begin assert not (quad_mode > 11) report "Error: multi slave QUAD detected" severity error; -- notify user on status - assert not ((quad_mode >= 1) and (quad_mode <= 4)) report "Note: QUAD with only master ports detected" severity note; + assert not ((quad_mode >= 1) and (quad_mode <= 4)) report "Note: QUAD with only master ports detected" severity note; assert not (quad_mode = 8) report "Note: QUAD with one slave port detected" severity note; - assert not ((quad_mode >= 9) and (quad_mode <= 11)) report "Note: mixed master/slave QUAD detected" severity note; + assert not ((quad_mode >= 9) and (quad_mode <= 11)) report "Note: mixed master/slave QUAD detected" severity note; ------------------------------------------------- -- only used SerDes are activated ------------------------------------------------- - powerup_ch(3) <= '0' when IS_MODE(3) = c_IS_UNUSED else '1'; - powerup_ch(2) <= '0' when IS_MODE(2) = c_IS_UNUSED else '1'; - powerup_ch(1) <= '0' when IS_MODE(1) = c_IS_UNUSED else '1'; - powerup_ch(0) <= '0' when IS_MODE(0) = c_IS_UNUSED else '1'; +-- powerup_ch(3) <= '0' when IS_MODE(3) = c_IS_UNUSED else '1'; +-- powerup_ch(2) <= '0' when IS_MODE(2) = c_IS_UNUSED else '1'; +-- powerup_ch(1) <= '0' when IS_MODE(1) = c_IS_UNUSED else '1'; +-- powerup_ch(0) <= '0' when IS_MODE(0) = c_IS_UNUSED else '1'; ------------------------------------------------- -- SFPs are disabled on unused SerDes channels -------------------------------------------------- +------------------------------------------------- -- we can include the LINK_TX_READY_IN signal here for master ports SD_TXDIS_OUT(3) <= DESTROY_LINK_IN(3) when IS_MODE(3) = c_IS_MASTER else '1' when IS_MODE(3) = c_IS_UNUSED else @@ -188,16 +186,16 @@ begin clk_rx_full(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else clk_rx_full(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else '0'; - + ------------------------------------------------- -- master reset ------------------------------------------------- - MASTER_RESET_OUT <= master_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else + MASTER_RESET_OUT <= master_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else master_reset_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else master_reset_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else master_reset_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else - '0'; - + '0'; + ------------------------------------------------- -- reset komma ------------------------------------------------- @@ -206,13 +204,13 @@ begin rx_rst_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else rx_rst_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else '0'; - + RX_RST_WORD_OUT <= rx_rst_word_i(7 downto 0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else rx_rst_word_i(15 downto 8) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else rx_rst_word_i(23 downto 16) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else rx_rst_word_i(31 downto 24) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else - '0'; - + x"00"; + ------------------------------------------------- -- TX PLL reset ------------------------------------------------- @@ -248,7 +246,7 @@ begin rx_serdes_rst_ch0_c => rx_serdes_rst(0), sb_felb_ch0_c => '0', sb_felb_rst_ch0_c => '0', - tx_pcs_rst_ch0_c => tx_pcs_rst(0), + tx_pcs_rst_ch0_c => RST_TX_PCS_IN, -- was wrong tx_pwrup_ch0_c => powerup_ch(0), -- new rx_pcs_rst_ch0_c => rx_pcs_rst(0), rx_pwrup_ch0_c => powerup_ch(0), -- new @@ -279,7 +277,7 @@ begin rx_serdes_rst_ch1_c => rx_serdes_rst(1), sb_felb_ch1_c => '0', sb_felb_rst_ch1_c => '0', - tx_pcs_rst_ch1_c => tx_pcs_rst(1), + tx_pcs_rst_ch1_c => RST_TX_PCS_IN, -- was wrong tx_pwrup_ch1_c => powerup_ch(1), -- new rx_pcs_rst_ch1_c => rx_pcs_rst(1), rx_pwrup_ch1_c => powerup_ch(1), -- new @@ -310,7 +308,7 @@ begin rx_serdes_rst_ch2_c => rx_serdes_rst(2), sb_felb_ch2_c => '0', sb_felb_rst_ch2_c => '0', - tx_pcs_rst_ch2_c => tx_pcs_rst(2), + tx_pcs_rst_ch2_c => RST_TX_PCS_IN, -- was wrong tx_pwrup_ch2_c => powerup_ch(2), -- new rx_pcs_rst_ch2_c => rx_pcs_rst(2), rx_pwrup_ch2_c => powerup_ch(2), -- new @@ -341,7 +339,7 @@ begin rx_serdes_rst_ch3_c => rx_serdes_rst(3), sb_felb_ch3_c => '0', sb_felb_rst_ch3_c => '0', - tx_pcs_rst_ch3_c => tx_pcs_rst(3), + tx_pcs_rst_ch3_c => RST_TX_PCS_IN, -- was wrong tx_pwrup_ch3_c => powerup_ch(3), -- new rx_pcs_rst_ch3_c => rx_pcs_rst(3), rx_pwrup_ch3_c => powerup_ch(3), -- new @@ -366,7 +364,7 @@ begin tx_serdes_rst_c => '0', tx_pll_lol_qd_s => TX_PLL_LOL_OUT, rst_qd_c => RST_QUAD_IN, - serdes_rst_qd_c => RST_TX_SERDES_IN, + serdes_rst_qd_c => '0', -- was wrong tx_sync_qd_c => SYNC_TX_PLL_IN ); @@ -374,63 +372,67 @@ begin gen_control : for i in 0 to 3 generate gen_used_control : if (IS_MODE(i) = c_IS_SLAVE) or (IS_MODE(i) = c_IS_MASTER) generate THE_MED_CONTROL : entity work.med_sync_control_RS - generic map( + generic map( SIM_MODE => SIM_MODE, IS_WAP_ZERO => IS_WAP_ZERO, IS_MODE => IS_MODE(i) ) port map( -- clocks and resets - CLK_SYS => SYSCLK, - CLK_RXI => clk_rx_full(i), - CLK_RXHALF => clk_rx_half(i), - CLK_TXI => clk_tx_full(i), - CLK_REF => CLK_REF_FULL, - RESET => RESET, + CLK_SYS => SYSCLK, + CLK_RXI => clk_rx_full(i), + CLK_RXHALF => clk_rx_half(i), + CLK_TXI => clk_tx_full(i), + CLK_REF => CLK_REF_FULL, + RESET => RESET, CLEAR => CLEAR, -- Media Interface - MEDIA_MED2INT => MEDIA_MED2INT(i), + MEDIA_MED2INT => MEDIA_MED2INT(i), MEDIA_INT2MED => MEDIA_INT2MED(i), -- status signals from SerDes - SFP_LOS_IN => SD_LOS_IN(i), - RX_CDR_LOL_IN => rx_cdr_lol(i), - RX_LOS_IN => rx_los_low(i), - WA_POSITION_IN => wa_position(i*4+3 downto i*4), + SFP_LOS_IN => SD_LOS_IN(i), + RX_CDR_LOL_IN => rx_cdr_lol(i), + RX_LOS_IN => rx_los_low(i), + WA_POSITION_IN => wa_position(i*4+3 downto i*4), LINK_TX_READY_IN => LINK_TX_READY_IN, -- control signals to SerDes - RX_SERDES_RST => rx_serdes_rst(i), + RX_SERDES_RST => rx_serdes_rst(i), RX_PCS_RST => rx_pcs_rst(i), -- SerDes data streams - TX_DATA_OUT => tx_data(i*8+7 downto i*8), - TX_K_OUT => tx_k(i), - RX_DATA_IN => rx_data(i*8+7 downto i*8), - RX_K_IN => rx_k(i), + TX_DATA_OUT => tx_data(i*8+7 downto i*8), + TX_K_OUT => tx_k(i), + RX_DATA_IN => rx_data(i*8+7 downto i*8), + RX_K_IN => rx_k(i), -- ports for synchronous operation WORD_SYNC_IN => WORD_SYNC_IN, WORD_SYNC_OUT => WORD_SYNC_OUT, - TX_DLM_IN => tx_dlm_i, - TX_DLM_WORD_IN => tx_dlm_word_i, - TX_RST_IN => tx_rst_i(i), + TX_DLM_IN => tx_dlm_i, + TX_DLM_WORD_IN => tx_dlm_word_i, + TX_RST_IN => tx_rst_i(i), TX_RST_WORD_IN => tx_rst_word_i(i*8+7 downto i*8), - RX_DLM_OUT => RX_DLM_OUT(i), - RX_DLM_WORD_OUT => RX_DLM_WORD_OUT(i*8+7 downto i*8), - RX_RST_OUT => rx_rst_i(i), - RX_RST_WORD_OUT => rx_rst_word_i(i*8+7 downto i*8), - MASTER_RESET_OUT => master_reset_i(i), - TX_RESET_OUT => tx_reset_i(i), + RX_DLM_OUT => RX_DLM_OUT(i), + RX_DLM_WORD_OUT => RX_DLM_WORD_OUT(i*8+7 downto i*8), + RX_RST_OUT => rx_rst_i(i), + RX_RST_WORD_OUT => rx_rst_word_i(i*8+7 downto i*8), + MASTER_RESET_OUT => master_reset_i(i), + TX_RESET_OUT => tx_reset_i(i), -- Status and debug signals - STAT_TX_CONTROL => stat_tx_control_i(i*32+31 downto i*32), - STAT_RX_CONTROL => stat_rx_control_i(i*32+31 downto i*32), + STAT_TX_CONTROL => stat_tx_control_i(i*32+31 downto i*32), + STAT_RX_CONTROL => stat_rx_control_i(i*32+31 downto i*32), DEBUG_TX_CONTROL => debug_tx_control_i(i*32+31 downto i*32), - DEBUG_RX_CONTROL => debug_rx_control_i(i*32+31 downto i*32), - STAT_RESET => stat_fsm_reset_i(i*32+31 downto i*32), - DEBUG_OUT => open + DEBUG_RX_CONTROL => debug_rx_control_i(i*32+31 downto i*32), + STAT_RESET => stat_fsm_reset_i(i*32+31 downto i*32), + DEBUG_OUT => debug_i(i*32+31 downto i*32) ); - - cv_cnt(i) <= cv_cnt(i) + 1 when rx_error(i) = '1' and rising_edge(clk_rx_full(i)); + + powerup_ch(i) <= '1'; + cv_cnt(i) <= cv_cnt(i) + 1 when rx_error(i) = '1' and rising_edge(clk_rx_full(i)); end generate; - gen_not_used : if IS_MODE(i) = c_IS_UNUSED generate + gen_not_used : if (IS_MODE(i) = c_IS_UNUSED) generate + powerup_ch(i) <= '0'; -- keep in power down + rx_serdes_rst(i) <= '1'; -- keep in reset + rx_pcs_rst(i) <= '1'; -- keep in reset MEDIA_MED2INT(i).dataready <= '0'; MEDIA_MED2INT(i).tx_read <= '1'; MEDIA_MED2INT(i).stat_op <= x"0007"; @@ -468,8 +470,9 @@ end generate; cv_cnt_sys <= cv_cnt when rising_edge(SYSCLK); - STAT_DEBUG(13 downto 0) <= debug_tx_control_i(13 downto 0); - STAT_DEBUG(15 downto 14) <= debug_tx_control_i(17 downto 16); - + STAT_DEBUG(63 downto 0) <= (others => '0'); + + DEBUG_OUT <= debug_i(3*32+31 downto 3*32); + end architecture; diff --git a/media_interfaces/sync/main_tx_reset_RS.vhd b/media_interfaces/sync/main_tx_reset_RS.vhd index 683bda2..f5dedd2 100644 --- a/media_interfaces/sync/main_tx_reset_RS.vhd +++ b/media_interfaces/sync/main_tx_reset_RS.vhd @@ -1,44 +1,44 @@ ---Media interface TX state machine - -LIBRARY IEEE; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.all; - -entity main_tx_reset_RS is - generic( - SIM_MODE : integer := 0 - ); - port( - CLEAR : in std_logic; -- async reset, active high - LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! - TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A - TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B - TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C +--Media interface TX state machine + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.all; + +entity main_tx_reset_RS is + generic( + SIM_MODE : integer := 0 + ); + port( + CLEAR : in std_logic; -- async reset, active high + LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! + TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A + TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B + TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D - TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed) - RST_QD_C_OUT : out std_logic; -- full QUAD reset + TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed) + RST_QD_C_OUT : out std_logic; -- full QUAD reset TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0 - LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now - STATE_OUT : out std_logic_vector(3 downto 0) - ); -end entity; - -architecture main_tx_reset_RS_arch of main_tx_reset_RS is + LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now + STATE_OUT : out std_logic_vector(3 downto 0) + ); +end entity; + +architecture main_tx_reset_RS_arch of main_tx_reset_RS is -- We use two different timing for simulation and real world. - -- Using SIM_MODE for implementation will most likely kill the link. - constant count2_index : integer := 20 - (SIM_MODE * 12); -- end of timer2 - constant count1_index : integer := 3; -- end of timer1 - - type statetype is ( QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, SYNC_ALL, NORMAL ); - - signal CURRENT_STATE : statetype; -- current state of lsm - signal NEXT_STATE : statetype; -- next state of lsm + -- Using SIM_MODE for implementation will most likely kill the link. + constant count2_index : integer := 19 - (SIM_MODE * 12); -- end of timer2 + constant count1_index : integer := 3; -- end of timer1 + + type statetype is ( QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, SYNC_ALL, NORMAL ); + + signal CURRENT_STATE : statetype; -- current state of lsm + signal NEXT_STATE : statetype; -- next state of lsm - signal tx_pcs_rst_ch_c_int : std_logic; + signal tx_pcs_rst_ch_c_int : std_logic; signal rst_qd_c_int : std_logic; - signal sync_tx_quad_int : std_logic; + signal sync_tx_quad_int : std_logic; signal link_tx_ready_int : std_logic; signal sync_tx_quad_trans : std_logic; @@ -46,194 +46,194 @@ architecture main_tx_reset_RS_arch of main_tx_reset_RS is signal tx_pll_lol_all_q : std_logic; -- synced signal tx_clock_avail_q : std_logic; -- synced - signal counter1 : unsigned(count1_index downto 0); - signal timer1 : std_logic; - signal reset_timer1 : std_logic; + signal counter1 : unsigned(count1_index downto 0); + signal timer1 : std_logic; + signal reset_timer1 : std_logic; - signal counter2 : unsigned(count2_index downto 0); - signal timer2 : std_logic; - signal reset_timer2 : std_logic; + signal counter2 : unsigned(count2_index downto 0); + signal timer2 : std_logic; + signal reset_timer2 : std_logic; -begin +begin -- all four QUADs need to be ready tx_pll_lol_all <= TX_PLL_LOL_QD_A_IN or TX_PLL_LOL_QD_B_IN or TX_PLL_LOL_QD_C_IN or TX_PLL_LOL_QD_D_IN; --- synchronize, just to be on the safe side +-- synchronize, just to be on the safe side SYNC_SFP_SIGS : entity work.signal_sync generic map( WIDTH => 2, DEPTH => 3 - ) - port map( - RESET => '0', - CLK0 => LOCALCLK, - CLK1 => LOCALCLK, - D_IN(0) => tx_pll_lol_all, - D_IN(1) => TX_CLOCK_AVAIL_IN, + ) + port map( + RESET => '0', + CLK0 => LOCALCLK, + CLK1 => LOCALCLK, + D_IN(0) => tx_pll_lol_all, + D_IN(1) => TX_CLOCK_AVAIL_IN, D_OUT(0) => tx_pll_lol_all_q, - D_OUT(1) => tx_clock_avail_q - ); - --- TIMER1 = 20ns; --- Fastest REFLCK = 312 MHZ, or 3 ns. We need 8 REFCLK cycles. --- A 3 bit counter ([2:0]) counts 8 cycles, so a 4 bit ([3:0]) counter will do if we set TIMER1 = bit[3] - --- Timer 1 - THE_TIMER1_PROC: process( LOCALCLK ) - begin - if( rising_edge(LOCALCLK) ) then - if( reset_timer1 = '1' ) then - counter1 <= (others => '0'); - else - if( counter1(count1_index) = '0' ) then - counter1 <= counter1 + 1 ; - end if; - end if; - end if; - end process THE_TIMER1_PROC; + D_OUT(1) => tx_clock_avail_q + ); + +-- TIMER1 = 20ns; +-- Fastest REFLCK = 312 MHZ, or 3 ns. We need 8 REFCLK cycles. +-- A 3 bit counter ([2:0]) counts 8 cycles, so a 4 bit ([3:0]) counter will do if we set TIMER1 = bit[3] + +-- Timer 1 + THE_TIMER1_PROC: process( LOCALCLK ) + begin + if( rising_edge(LOCALCLK) ) then + if( reset_timer1 = '1' ) then + counter1 <= (others => '0'); + else + if( counter1(count1_index) = '0' ) then + counter1 <= counter1 + 1 ; + end if; + end if; + end if; + end process THE_TIMER1_PROC; timer1 <= counter1(count1_index); - --- TIMER2 = 1,400,000 UI; --- WORST CASE CYCLES is with smallest multipier factor. --- This would be with X8 clock multiplier in DIV2 mode --- IN this casse, 1 UI = 2/8 REFCLK CYCLES. --- SO 1,400,000 UI = 1,400,000/4 = 350,000 REFCLKDIV2 CYCLES --- A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set TIMER2 = bit[19] - - THE_TIMER2_PROC: process( LOCALCLK ) - begin - if( rising_edge(LOCALCLK) ) then - if( reset_timer2 = '1' ) then - counter2 <= (others => '0'); - else - if( counter2(count2_index) = '0' ) then - counter2 <= counter2 + 1 ; - end if; - end if; - end if; - end process THE_TIMER2_PROC; + +-- TIMER2 = 1,400,000 UI; +-- WORST CASE CYCLES is with smallest multipier factor. +-- This would be with X8 clock multiplier in DIV2 mode +-- IN this casse, 1 UI = 2/8 REFCLK CYCLES. +-- SO 1,400,000 UI = 1,400,000/4 = 350,000 REFCLK CYCLES +-- A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set TIMER2 = bit[19] + + THE_TIMER2_PROC: process( LOCALCLK ) + begin + if( rising_edge(LOCALCLK) ) then + if( reset_timer2 = '1' ) then + counter2 <= (others => '0'); + else + if( counter2(count2_index) = '0' ) then + counter2 <= counter2 + 1 ; + end if; + end if; + end if; + end process THE_TIMER2_PROC; timer2 <= counter2(count2_index); - --- State machine clocked process - THE_FSM_PROC: process( LOCALCLK, CLEAR ) - begin - if( CLEAR = '1' ) then - CURRENT_STATE <= QUAD_RESET; - TX_PCS_RST_CH_C_OUT <= '1'; + +-- State machine clocked process + THE_FSM_PROC: process( LOCALCLK, CLEAR ) + begin + if( CLEAR = '1' ) then + CURRENT_STATE <= QUAD_RESET; + TX_PCS_RST_CH_C_OUT <= '1'; RST_QD_C_OUT <= '1'; LINK_TX_READY_OUT <= '0'; - else - if( rising_edge(LOCALCLK) ) then - CURRENT_STATE <= NEXT_STATE; - TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int; + else + if( rising_edge(LOCALCLK) ) then + CURRENT_STATE <= NEXT_STATE; + TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int; RST_QD_C_OUT <= rst_qd_c_int; LINK_TX_READY_OUT <= link_tx_ready_int; - end if; - end if; - end process THE_FSM_PROC; - - THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer1, timer2, tx_pll_lol_all_q, tx_clock_avail_q ) - begin - reset_timer1 <= '0'; - reset_timer2 <= '0'; - rst_qd_c_int <= '0'; + end if; + end if; + end process THE_FSM_PROC; + + THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer1, timer2, tx_pll_lol_all_q, tx_clock_avail_q ) + begin + reset_timer1 <= '0'; + reset_timer2 <= '0'; + rst_qd_c_int <= '0'; tx_pcs_rst_ch_c_int <= '0'; sync_tx_quad_int <= '0'; - link_tx_ready_int <= '0'; - STATE_OUT <= x"F"; - - case CURRENT_STATE is - - when QUAD_RESET => - STATE_OUT <= x"1"; - tx_pcs_rst_ch_c_int <= '1'; - rst_qd_c_int <= '1'; + link_tx_ready_int <= '0'; + STATE_OUT <= x"F"; + + case CURRENT_STATE is + + when QUAD_RESET => + STATE_OUT <= x"1"; + tx_pcs_rst_ch_c_int <= '1'; + rst_qd_c_int <= '1'; reset_timer1 <= '1'; - reset_timer2 <= '1'; - NEXT_STATE <= WAIT_FOR_TIMER1; - - when WAIT_FOR_TIMER1 => - STATE_OUT <= x"2"; - tx_pcs_rst_ch_c_int <= '1'; + reset_timer2 <= '1'; + NEXT_STATE <= WAIT_FOR_TIMER1; + + when WAIT_FOR_TIMER1 => + STATE_OUT <= x"2"; + tx_pcs_rst_ch_c_int <= '1'; rst_qd_c_int <= '1'; - reset_timer2 <= '1'; - if( timer1 = '1' ) then - NEXT_STATE <= CHECK_PLOL; - else - NEXT_STATE <= WAIT_FOR_TIMER1; - end if; - - when CHECK_PLOL => - STATE_OUT <= x"3"; + reset_timer2 <= '1'; + if( timer1 = '1' ) then + NEXT_STATE <= CHECK_PLOL; + else + NEXT_STATE <= WAIT_FOR_TIMER1; + end if; + + when CHECK_PLOL => + STATE_OUT <= x"3"; tx_pcs_rst_ch_c_int <= '1'; - reset_timer1 <= '1'; - reset_timer2 <= '1'; - NEXT_STATE <= WAIT_FOR_TIMER2; - - when WAIT_FOR_TIMER2 => + reset_timer1 <= '1'; + reset_timer2 <= '1'; + NEXT_STATE <= WAIT_FOR_TIMER2; + + when WAIT_FOR_TIMER2 => STATE_OUT <= x"4"; - reset_timer1 <= '1'; - tx_pcs_rst_ch_c_int <= '1'; - if( timer2 = '1' ) then - if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then - NEXT_STATE <= QUAD_RESET; - else - NEXT_STATE <= SYNC_ALL; - sync_tx_quad_int <= '1'; - end if; - else - NEXT_STATE <= WAIT_FOR_TIMER2; - end if; - - when SYNC_ALL => + reset_timer1 <= '1'; + tx_pcs_rst_ch_c_int <= '1'; + if( timer2 = '1' ) then + if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then + NEXT_STATE <= QUAD_RESET; + else + NEXT_STATE <= SYNC_ALL; + sync_tx_quad_int <= '1'; + end if; + else + NEXT_STATE <= WAIT_FOR_TIMER2; + end if; + + when SYNC_ALL => STATE_OUT <= x"5"; - reset_timer2 <= '1'; - if( timer1 = '1' ) then - NEXT_STATE <= NORMAL; - else + reset_timer2 <= '1'; + if( timer1 = '1' ) then + NEXT_STATE <= NORMAL; + else NEXT_STATE <= SYNC_ALL; - end if; - - when NORMAL => - STATE_OUT <= x"6"; + end if; + + when NORMAL => + STATE_OUT <= x"6"; tx_pcs_rst_ch_c_int <= '0'; link_tx_ready_int <= '1'; reset_timer1 <= '1'; - reset_timer2 <= '1'; - if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then - NEXT_STATE <= QUAD_RESET; - else - NEXT_STATE <= NORMAL; - end if; - + reset_timer2 <= '1'; + if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then + NEXT_STATE <= QUAD_RESET; + else + NEXT_STATE <= NORMAL; + end if; + when others => - STATE_OUT <= x"f"; - NEXT_STATE <= QUAD_RESET; - - end case; - - end process THE_FSM_DECODE_PROC; + STATE_OUT <= x"f"; + NEXT_STATE <= QUAD_RESET; + + end case; + + end process THE_FSM_DECODE_PROC; -- TX serializer is operational "at level" of this signal, -- and gets reset by a transition (according to SerDes Usage Guide). -- Timer1 is used to delay the TX link ready signal by some cycles. - THE_QUAD_SYNC_PROC: process( LOCALCLK, CLEAR ) - begin + THE_QUAD_SYNC_PROC: process( LOCALCLK, CLEAR ) + begin if( CLEAR = '1' ) then - sync_tx_quad_trans <= '0'; - else + sync_tx_quad_trans <= '0'; + else if( rising_edge(LOCALCLK) ) then if( sync_tx_quad_int = '1' ) then sync_tx_quad_trans <= not sync_tx_quad_trans; - end if; - end if; - end if; - end process THE_QUAD_SYNC_PROC; + end if; + end if; + end if; + end process THE_QUAD_SYNC_PROC; SYNC_TX_QUAD_OUT <= sync_tx_quad_trans; -end architecture; +end architecture; diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index 0df56ac..16266a6 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -4,16 +4,16 @@ USE IEEE.numeric_std.all; library work; use work.trb_net_std.all; ---use work.trb_net_components.all; +--use work.trb_net_components.all; use work.med_sync_define_RS.all; entity med_sync_control_RS is - generic( + generic( SIM_MODE : integer := 0; -- 0 for simulation, 1 for implementation IS_WAP_ZERO : integer := 1; -- should be 1 for synchronous operation IS_MODE : integer := c_IS_UNUSED ); - port( + port( -- clocks and resets CLK_SYS : in std_logic; -- FPGA fabric system clock CLK_RXI : in std_logic; -- recovered RX clock, from SerDes RX channel @@ -21,25 +21,25 @@ entity med_sync_control_RS is CLK_TXI : in std_logic; -- TX clock, from SerDes TX channel CLK_REF : in std_logic; -- SerDes reference clock RESET : in std_logic; - CLEAR : in std_logic; - -- Media Interface + CLEAR : in std_logic; + -- Media Interface MEDIA_MED2INT : out MED2INT; -- Media Interface IN - MEDIA_INT2MED : in INT2MED; -- Media Interface OUT + MEDIA_INT2MED : in INT2MED; -- Media Interface OUT -- status signals from SerDes SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal RX_CDR_LOL_IN : in std_logic; -- SerDes RX CDR status RX_LOS_IN : in std_logic; -- SerDes RX input signal status - WA_POSITION_IN : in std_logic_vector(3 downto 0); -- WordAlignment Position - LINK_TX_READY_IN : in std_logic; - -- control signals to SerDes + WA_POSITION_IN : in std_logic_vector(3 downto 0); -- WordAlignment Position + LINK_TX_READY_IN : in std_logic; + -- control signals to SerDes RX_SERDES_RST : out std_logic; -- reset RX (SerDes + CDR) - RX_PCS_RST : out std_logic; -- reset RX (PCS) + RX_PCS_RST : out std_logic; -- reset RX (PCS) -- SerDes data streams TX_DATA_OUT : out std_logic_vector(7 downto 0); -- data to TX SerDes TX_K_OUT : out std_logic; -- komma designator to TS SerDes RX_DATA_IN : in std_logic_vector(7 downto 0); -- data from RX SerDes - RX_K_IN : in std_logic; -- komma designator from RX SerDes - -- ports for synchronous operation + RX_K_IN : in std_logic; -- komma designator from RX SerDes + -- ports for synchronous operation WORD_SYNC_IN : in std_logic; -- sync signal for Byte/Word Alignment WORD_SYNC_OUT : out std_logic; TX_DLM_IN : in std_logic; -- transmit one DLM komma @@ -50,8 +50,8 @@ entity med_sync_control_RS is RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0); RX_RST_OUT : out std_logic; -- one RST komma received RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); - MASTER_RESET_OUT : out std_logic; -- master reset for FPGA - TX_RESET_OUT : out std_logic; -- reset main TX reset FSM + MASTER_RESET_OUT : out std_logic; -- master reset for FPGA + TX_RESET_OUT : out std_logic; -- reset main TX reset FSM -- Status and debug signals STAT_TX_CONTROL : out std_logic_vector(31 downto 0); STAT_RX_CONTROL : out std_logic_vector(31 downto 0); @@ -101,7 +101,7 @@ begin CLK1 => CLK_SYS, D_IN(0) => SFP_LOS_IN, D_OUT(0) => sd_los_qsys - ); + ); -- keep central TX reset FSM idle while no clock is present TX_RESET_OUT <= (CLEAR or RESET or not link_rx_ready_i) when (IS_MODE = c_IS_SLAVE) @@ -118,25 +118,25 @@ begin ------------------------------------------------- THE_RX_RST_FSM: main_rx_reset_RS -- OK generic map( - SIM_MODE => SIM_MODE, - IS_WAP_ZERO => IS_WAP_ZERO, + SIM_MODE => SIM_MODE, + IS_WAP_ZERO => IS_WAP_ZERO, IS_MODE => IS_MODE ) port map( - CLEAR => reset_rx_fsm_i, - LOCALCLK => CLK_REF, - TX_PLL_LOL_IN => '0', -- TX and RX channel are independent - RX_CDR_LOL_IN => RX_CDR_LOL_IN, -- internally synced - RX_LOS_LOW_IN => RX_LOS_IN, -- internally synced - WA_POSITION_IN => WA_POSITION_IN, -- internally synced - SFP_LOS_IN => SFP_LOS_IN, -- internally synced - RX_PCS_RST_CH_C_OUT => rx_pcs_rst_i, - RX_SERDES_RST_CH_C_OUT => rx_serdes_rst_i, - LINK_RX_READY_OUT => link_rx_ready_i, - MASTER_RESET_OUT => MASTER_RESET_OUT, -- not necessary??? + CLEAR => reset_rx_fsm_i, + LOCALCLK => CLK_REF, + TX_PLL_LOL_IN => '0', -- TX and RX channel are independent + RX_CDR_LOL_IN => RX_CDR_LOL_IN, -- internally synced + RX_LOS_LOW_IN => RX_LOS_IN, -- internally synced + WA_POSITION_IN => WA_POSITION_IN, -- internally synced + SFP_LOS_IN => SFP_LOS_IN, -- internally synced + RX_PCS_RST_CH_C_OUT => rx_pcs_rst_i, + RX_SERDES_RST_CH_C_OUT => rx_serdes_rst_i, + LINK_RX_READY_OUT => link_rx_ready_i, + MASTER_RESET_OUT => MASTER_RESET_OUT, -- not necessary??? STATE_OUT => rx_fsm_state ); - + -- reset signals for RX SerDes need to be sync'ed to real RX clock SYNC_RST_SIGS: entity work.signal_sync generic map( WIDTH => 2 ) @@ -149,7 +149,7 @@ begin D_OUT(0) => RX_PCS_RST, D_OUT(1) => RX_SERDES_RST ); - + ------------------------------------------------- -- RX Data ------------------------------------------------- @@ -161,42 +161,42 @@ begin CLK_RXI => CLK_RXI, CLK_SYS => CLK_SYS, RESET => reset_i, - + RX_DATA_OUT => media_med2int_i.data, RX_PACKET_NUMBER_OUT => media_med2int_i.packet_num, RX_WRITE_OUT => media_med2int_i.dataready, - + RX_DATA_IN => RX_DATA_IN, RX_K_IN => RX_K_IN, WORD_SYNC_OUT => WORD_SYNC_OUT, - + RX_DLM_OUT => RX_DLM_OUT, RX_DLM_WORD_OUT => RX_DLM_WORD_OUT, RX_RST_OUT => RX_RST_OUT, RX_RST_WORD_OUT => RX_RST_WORD_OUT, - - LINK_RX_READY_IN => link_rx_ready_i, + + LINK_RX_READY_IN => link_rx_ready_i, LINK_TX_READY_IN => LINK_TX_READY_IN, - LINK_HALF_DONE_IN => link_half_done_i, + LINK_HALF_DONE_IN => link_half_done_i, LINK_FULL_DONE_IN => link_full_done_i, - + DEBUG_OUT => DEBUG_RX_CONTROL, STAT_REG_OUT => STAT_RX_CONTROL ); - + THE_RX_LSM: rx_lsm_RS port map( - LINK_RX_READY_IN => link_rx_ready_i, - RXCLK => CLK_RXI, - RX_K_IN => RX_K_IN, - RX_DATA_IN => RX_DATA_IN, - LINK_HALF_DONE_OUT => link_half_done_i, - LINK_FULL_DONE_OUT => link_full_done_i, + LINK_RX_READY_IN => link_rx_ready_i, + RXCLK => CLK_RXI, + RX_K_IN => RX_K_IN, + RX_DATA_IN => RX_DATA_IN, + LINK_HALF_DONE_OUT => link_half_done_i, + LINK_FULL_DONE_OUT => link_full_done_i, STATE_OUT => open ); - + -- clocks for media interface media_med2int_i.clk_half <= CLK_RXHALF; media_med2int_i.clk_full <= CLK_RXI; @@ -204,34 +204,34 @@ begin ------------------------------------------------- -- TX Data ------------------------------------------------- - + THE_TX_CONTROL: tx_control_RS generic map( - SIM_MODE => SIM_MODE, - IS_MODE => IS_MODE + SIM_MODE => SIM_MODE, + IS_MODE => IS_MODE ) port map( CLK_TX => CLK_TXI, CLK_SYS => CLK_SYS, - RESET => reset_i, + RESET => reset_i, -- Media Interface TX_DATA_IN => MEDIA_INT2MED.data, TX_PACKET_NUMBER_IN => MEDIA_INT2MED.packet_num, TX_WRITE_IN => MEDIA_INT2MED.dataready, TX_READ_OUT => media_med2int_i.tx_read, -- SerDes data stream - TX_DATA_OUT => TX_DATA_OUT, + TX_DATA_OUT => TX_DATA_OUT, TX_K_OUT => TX_K_OUT, -- synchronous signals - WORD_SYNC_IN => WORD_SYNC_IN, + WORD_SYNC_IN => WORD_SYNC_IN, SEND_DLM_IN => TX_DLM_IN, - SEND_DLM_WORD_IN => TX_DLM_WORD_IN, + SEND_DLM_WORD_IN => TX_DLM_WORD_IN, SEND_RST_IN => TX_RST_IN, - SEND_RST_WORD_IN => TX_RST_WORD_IN, + SEND_RST_WORD_IN => TX_RST_WORD_IN, -- link status signals, internally synced - LINK_TX_READY_IN => LINK_TX_READY_IN, + LINK_TX_READY_IN => LINK_TX_READY_IN, LINK_RX_READY_IN => link_rx_ready_i, - LINK_HALF_DONE_IN => link_half_done_i, + LINK_HALF_DONE_IN => link_half_done_i, LINK_FULL_DONE_IN => link_full_done_i, -- debug DEBUG_OUT => DEBUG_TX_CONTROL, @@ -248,8 +248,8 @@ begin led_tx <= (MEDIA_INT2MED.dataready or led_tx or sd_los_qsys) and not timer(20) when rising_edge(CLK_SYS); ROC_TIMER_PROC: process( CLK_SYS, RESET ) - begin - if ( RESET = '1' ) then + begin + if ( RESET = '1' ) then timer <= (others => '0'); elsif( rising_edge(CLK_SYS) ) then timer <= timer + 1 ; @@ -278,12 +278,14 @@ begin media_med2int_i.stat_op(4) <= '0'; media_med2int_i.stat_op(3 downto 0) <= x"0" when link_half_done_i = '1' and link_full_done_i = '1' else x"7"; --- TEST_LINE signals - DEBUG_OUT(0) <= link_rx_ready_i; - DEBUG_OUT(1) <= link_half_done_i; - DEBUG_OUT(2) <= link_full_done_i; - - DEBUG_OUT(31 downto 3) <= (others => '0'); +-- TEST_LINE signals + DEBUG_OUT(0) <= link_rx_ready_i; + DEBUG_OUT(1) <= link_half_done_i; + DEBUG_OUT(2) <= link_full_done_i; + DEBUG_OUT(3) <= RX_CDR_LOL_IN; + DEBUG_OUT(4) <= RX_LOS_IN; + + DEBUG_OUT(31 downto 4) <= (others => '0'); -- DEBUG_OUT <= (others => '0'); end architecture; -- 2.43.0