From a91f6fec178a1010a074b9f4b605d380f9677a0e Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Wed, 15 Dec 2021 14:12:48 +0100 Subject: [PATCH] cleanup for files, DLM ping works --- media_interfaces/sync/main_rx_reset_RS.vhd | 413 +++++++++--------- media_interfaces/sync/main_tx_reset_RS.vhd | 18 +- media_interfaces/sync/med_sync_control_RS.vhd | 50 +-- media_interfaces/sync/med_sync_define_RS.vhd | 25 +- media_interfaces/sync/rx_control_RS.vhd | 21 +- media_interfaces/sync/rx_lsm_RS.vhd | 171 -------- media_interfaces/sync/rx_rsl.vhd | 230 ---------- media_interfaces/sync/rx_rsl_WRONG.vhd | 224 ---------- 8 files changed, 250 insertions(+), 902 deletions(-) delete mode 100644 media_interfaces/sync/rx_lsm_RS.vhd delete mode 100644 media_interfaces/sync/rx_rsl.vhd delete mode 100644 media_interfaces/sync/rx_rsl_WRONG.vhd diff --git a/media_interfaces/sync/main_rx_reset_RS.vhd b/media_interfaces/sync/main_rx_reset_RS.vhd index 9c52c39..2626171 100644 --- a/media_interfaces/sync/main_rx_reset_RS.vhd +++ b/media_interfaces/sync/main_rx_reset_RS.vhd @@ -1,243 +1,230 @@ ---Media interface RX state machine - -LIBRARY IEEE; -USE IEEE.std_logic_1164.ALL; +library ieee; +use ieee.std_logic_1164.all; USE IEEE.numeric_std.all; -library work; -use work.trb_net_std.all; ---use work.trb_net_components.all; -use work.med_sync_define_RS.all; - entity main_rx_reset_RS is - generic( - SIM_MODE : integer := 0; - IS_WAP_ZERO : integer := 0; - IS_MODE : integer := c_IS_SLAVE - ); - port( - CLEAR : in std_logic; -- async reset, active high - LOCALCLK : in std_logic; -- CDR reference clock - TX_PLL_LOL_IN : in std_logic; -- TX_PLOL form AUX channel - RX_CDR_LOL_IN : in std_logic; -- CDR LOL - RX_LOS_LOW_IN : in std_logic; -- RX LOS - WA_POSITION_IN : in std_logic_vector(3 downto 0); - SFP_LOS_IN : in std_logic; -- SFP LOS signal - RX_PCS_RST_CH_C_OUT : out std_logic; - RX_SERDES_RST_CH_C_OUT : out std_logic; - LINK_RX_READY_OUT : out std_logic; -- RX SerDes is fully operational - MASTER_RESET_OUT : out std_logic; -- can be used as master reset if sourced from Slave port - STATE_OUT : out std_logic_vector(3 downto 0) + port ( + CLEAR : in std_logic; + CLK_REF : in std_logic; + PLL_LOL_IN : in std_logic; + CDR_LOL_IN : in std_logic; + CV_IN : in std_logic; + LSM_IN : in std_logic; + LOS_IN : in std_logic; + SD_LOS_IN : in std_logic; + WAP_ZERO_IN : in std_logic; + -- outputs + RX_SERDES_RST_OUT : out std_logic; + RX_PCS_RST_OUT : out std_logic; + LINK_RX_READY_OUT : out std_logic; + STATE_OUT : out std_logic_vector(3 downto 0) ); -end entity; +end entity; --- IS_WAP_ZERO could be moved into med_ecpX_sfp_sync... +architecture main_rx_reset_RS_arch of main_rx_reset_RS is -architecture main_rx_reset_arch of main_rx_reset_RS is + attribute syn_keep : boolean; - -- 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); -- 20 for implementation, 8 for simulation - constant wap_index : integer := 16 - (SIM_MODE * 8); -- 16 for implementation, 8 for simulation +-- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3. +-- Without this piece of code, many things would have been a real pain. - type statetype is ( WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_TIMER1, CHECK_LOL_LOS, WAIT_FOR_TIMER2, CHECK_WAP, NORMAL ); + constant Tshort : unsigned(31 downto 0) := x"0000000a"; +-- @200MHz 100ms + constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; + constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; + constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - signal CURRENT_STATE : statetype; -- current state of lsm - signal NEXT_STATE : statetype; -- next state of lsm + signal pll_lol_s : std_logic; + signal cdr_lol_s : std_logic; + signal cv_s : std_logic; + signal lsm_s : std_logic; + signal los_s : std_logic; + signal sd_los_s : std_logic; - signal tx_pll_lol_q : std_logic; -- synced - signal rx_cdr_lol_q : std_logic; -- synced - signal rx_los_low_q : std_logic; -- synced - signal sfp_los_q : std_logic; -- synced - signal wa_position_q : std_logic_vector(3 downto 0); -- synced - signal rx_lol_los : std_logic; - signal rx_lol_los_int : std_logic; - signal rx_lol_los_del : std_logic; - signal rx_pcs_rst_ch_c_int : std_logic; - signal rx_serdes_rst_ch_c_int : std_logic; + signal cnt : unsigned(31 downto 0); - signal reset_timer2 : std_logic; - signal counter2 : unsigned(count2_index downto 0); - signal timer2 : std_logic; + type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, + APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, + CHECK_WAP, NORMAL_OP); -begin + signal rx_sm : rx_sm_state; + + attribute syn_keep of rx_sm : signal is true; - GEN_WAP_SYNC : if (IS_WAP_ZERO = 1) generate - -- sync WAP - SYNC_WAP : entity work.signal_sync - generic map( - WIDTH => 4, - DEPTH => 3 - ) - port map( - RESET => '0', - CLK0 => LOCALCLK, - CLK1 => LOCALCLK, - D_IN => WA_POSITION_IN, - D_OUT => wa_position_q - ); - end generate GEN_WAP_SYNC; - - GEN_WAP_FIXED: if (IS_WAP_ZERO = 0) generate - wa_position_q <= x"0"; - end generate GEN_WAP_FIXED; - - -- sync SerDes signals - SYNC_SERDES_SIGS : entity work.signal_sync - generic map( - WIDTH => 4, - DEPTH => 3 - ) - port map( - RESET => '0', - CLK0 => LOCALCLK, - CLK1 => LOCALCLK, - D_IN(0) => TX_PLL_LOL_IN, - D_IN(1) => RX_CDR_LOL_IN, - D_IN(2) => RX_LOS_LOW_IN, - D_IN(3) => SFP_LOS_IN, - D_OUT(0) => tx_pll_lol_q, - D_OUT(1) => rx_cdr_lol_q, - D_OUT(2) => rx_los_low_q, - D_OUT(3) => sfp_los_q - ); - - MASTER_RESET_OUT <= sfp_los_q when (IS_MODE = c_IS_SLAVE) else '0'; - - rx_lol_los <= rx_cdr_lol_q or rx_los_low_q ; - ---timer2 = 400,000 Refclk cycles or 200,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; +begin - timer2 <= counter2(count2_index); +-- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP. +-- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset. +-- Remark: syncing is done here by one FF only. Might be dangerous. - -- State machine clocked process - THE_FSM_PROC: process( LOCALCLK, CLEAR ) +------------------------------------------------------------------ + RX_RESET_PROC : process( CLEAR, CLK_REF ) begin if( CLEAR = '1' ) then - CURRENT_STATE <= WAIT_FOR_PLOL; - rx_lol_los_int <= '1'; - rx_lol_los_del <= '1'; - RX_PCS_RST_CH_C_OUT <= '1'; - RX_SERDES_RST_CH_C_OUT <= '0'; - else - if( rising_edge(LOCALCLK) ) then - CURRENT_STATE <= NEXT_STATE; - rx_lol_los_del <= rx_lol_los; - rx_lol_los_int <= rx_lol_los_del; - RX_PCS_RST_CH_C_OUT <= rx_pcs_rst_ch_c_int; - RX_SERDES_RST_CH_C_OUT <= rx_serdes_rst_ch_c_int; - end if; - end if; - end process THE_FSM_PROC; - - THE_FSM_DECODE_PROC: process( CURRENT_STATE, tx_pll_lol_q, rx_los_low_q, rx_lol_los_int, timer2, wa_position_q, rx_lol_los_del ) - begin - reset_timer2 <= '0'; - STATE_OUT <= x"F"; - LINK_RX_READY_OUT <= '0'; + pll_lol_s <= '1'; + cdr_lol_s <= '1'; + cv_s <= '1'; + lsm_s <= '0'; + los_s <= '1'; + sd_los_s <= '1'; + + RX_SERDES_RST_OUT <= '1'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + + rx_sm <= powerup; + STATE_OUT <= x"f"; + cnt <= (others => '0'); + elsif( rising_edge(CLK_REF) ) then + pll_lol_s <= PLL_LOL_IN; + cdr_lol_s <= CDR_LOL_IN; + cv_s <= CV_IN; + lsm_s <= LSM_IN; + los_s <= LOS_IN; + sd_los_s <= SD_LOS_IN; - case CURRENT_STATE is - when WAIT_FOR_PLOL => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - reset_timer2 <= '1'; - if( (tx_pll_lol_q = '1') or (rx_los_low_q = '1') ) then - NEXT_STATE <= WAIT_FOR_PLOL; - else - NEXT_STATE <= RX_SERDES_RESET; - end if; - STATE_OUT <= x"1"; - - when RX_SERDES_RESET => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '1'; - reset_timer2 <= '1'; - NEXT_STATE <= WAIT_FOR_TIMER1; - STATE_OUT <= x"2"; - - when WAIT_FOR_TIMER1 => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '1'; - reset_timer2 <= '1'; - NEXT_STATE <= CHECK_LOL_LOS; - STATE_OUT <= x"3"; - - when CHECK_LOL_LOS => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - reset_timer2 <= '1'; - NEXT_STATE <= WAIT_FOR_TIMER2; - STATE_OUT <= x"4"; - - when WAIT_FOR_TIMER2 => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - if( (rx_lol_los_int = rx_lol_los_del) ) then --NO RISING OR FALLING EDGES - if( timer2 = '1' ) then - if( rx_lol_los_int = '1' ) then - NEXT_STATE <= WAIT_FOR_PLOL; - reset_timer2 <= '1'; + case rx_sm is + when POWERUP => + STATE_OUT <= x"0"; + RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; +-- if( (pll_lol_s = '1') or (los_s = '1') or (sd_los_s = '1') ) then + if( (pll_lol_s = '1') or (sd_los_s = '1') ) then + cnt <= (others => '0'); + else + if( cnt = Tplol ) then + cnt <= (others => '0'); + rx_sm <= APPLY_CDR_RST; else - NEXT_STATE <= CHECK_WAP; - reset_timer2 <= '1'; + cnt <= cnt + 1; end if; + end if; + + when APPLY_CDR_RST => + STATE_OUT <= x"1"; + RX_SERDES_RST_OUT <= '1'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tshort ) then + cnt <= (others => '0'); + rx_sm <= WAIT_CDR_LOCK; else - NEXT_STATE <= WAIT_FOR_TIMER2; + cnt <= cnt + 1; end if; - else - NEXT_STATE <= CHECK_LOL_LOS; --RESET timer2 - reset_timer2 <= '1'; - end if; - STATE_OUT <= x"5"; - - when CHECK_WAP => - rx_pcs_rst_ch_c_int <= '0'; - rx_serdes_rst_ch_c_int <= '0'; - if( std_logic(counter2(wap_index)) = '1' ) then -- may be too long - if( wa_position_q /= x"0" ) then - NEXT_STATE <= WAIT_FOR_PLOL; - reset_timer2 <= '1'; + + when WAIT_CDR_LOCK => + STATE_OUT <= x"2"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tcdr ) then + cnt <= (others => '0'); + rx_sm <= TEST_CDR; else - NEXT_STATE <= NORMAL; - reset_timer2 <= '1'; + cnt <= cnt + 1; end if; - else - NEXT_STATE <= CHECK_WAP; - end if; - STATE_OUT <= x"7"; - - when NORMAL => - rx_pcs_rst_ch_c_int <= '0'; - rx_serdes_rst_ch_c_int <= '0'; - reset_timer2 <= '1'; - if( (rx_lol_los_int = '1') or (wa_position_q /= x"0") ) then - NEXT_STATE <= WAIT_FOR_PLOL; - else + + when TEST_CDR => + STATE_OUT <= x"3"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cdr_lol_s = '1' ) then + cnt <= (others => '0'); + rx_sm <= APPLY_CDR_RST; + else + if( cnt = Tcdr ) then + cnt <= (others => '0'); + rx_sm <= APPLY_RXPCS_RST; + else + cnt <= cnt + 1; + end if; + end if; + + when APPLY_RXPCS_RST => + STATE_OUT <= x"4"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tshort ) then + cnt <= (others => '0'); + rx_sm <= WAIT_RXPCS_LOCK; + else + cnt <= cnt + 1; + end if; + + when WAIT_RXPCS_LOCK => + STATE_OUT <= x"5"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tviol ) then + cnt <= (others => '0'); + rx_sm <= TEST_RXPCS; + else + cnt <= cnt + 1; + end if; + + when TEST_RXPCS => + STATE_OUT <= x"6"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + if( (lsm_s = '0') or (cv_s = '1') ) then + cnt <= (others => '0'); + rx_sm <= APPLY_RXPCS_RST; + else + if( cnt = Tviol ) then + cnt <= (others => '0'); + rx_sm <= CHECK_WAP; + else + cnt <= cnt + 1; + end if; + end if; + + when CHECK_WAP => + STATE_OUT <= x"7"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + cnt <= (others => '0'); + if( WAP_ZERO_IN = '1' ) then + rx_sm <= NORMAL_OP; + else +-- rx_sm <= APPLY_RXPCS_RST; -- DOESNT WORK + rx_sm <= APPLY_CDR_RST; + end if; + + when NORMAL_OP => + STATE_OUT <= x"8"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; LINK_RX_READY_OUT <= '1'; - NEXT_STATE <= NORMAL; - end if; - STATE_OUT <= x"6"; + cnt <= (others => '0'); + if( (lsm_s = '0') or (cv_s = '1') ) then + rx_sm <= APPLY_RXPCS_RST; + end if; - when others => - NEXT_STATE <= WAIT_FOR_PLOL; - reset_timer2 <= '1'; + when others => + -- just in case + STATE_OUT <= x"f"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + rx_sm <= POWERUP; - end case; + end case; + +------------------------------------------------ +-- if (pll_lol_s = '1') or (los_s = '1') then +-- if( pll_lol_s = '1' ) then + if( (pll_lol_s = '1') or (sd_los_s = '1') ) then + rx_sm <= POWERUP; + cnt <= (others => '0'); + end if; - end process THE_FSM_DECODE_PROC; + end if; + end process rx_reset_proc; end architecture; diff --git a/media_interfaces/sync/main_tx_reset_RS.vhd b/media_interfaces/sync/main_tx_reset_RS.vhd index 8f568fa..63652cd 100644 --- a/media_interfaces/sync/main_tx_reset_RS.vhd +++ b/media_interfaces/sync/main_tx_reset_RS.vhd @@ -10,7 +10,7 @@ entity main_tx_reset_RS is ); port( CLEAR : in std_logic; -- async reset, active high - LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! + CLK_REF : 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 @@ -65,8 +65,8 @@ begin ) port map( RESET => '0', - CLK0 => LOCALCLK, - CLK1 => LOCALCLK, + CLK0 => CLK_REF, + CLK1 => CLK_REF, D_IN(0) => tx_pll_lol_all, D_IN(1) => TX_CLOCK_AVAIL_IN, D_OUT(0) => tx_pll_lol_all_q, @@ -75,9 +75,9 @@ begin -- Timer - THE_TIMER_PROC: process( LOCALCLK ) + THE_TIMER_PROC: process( CLK_REF ) begin - if( rising_edge(LOCALCLK) ) then + if( rising_edge(CLK_REF) ) then if( reset_timer = '1' ) then counter <= (others => '0'); else @@ -92,14 +92,14 @@ begin -- State machine clocked process - THE_FSM_PROC: process( LOCALCLK, CLEAR ) + THE_FSM_PROC: process( CLK_REF, CLEAR ) begin if( CLEAR = '1' ) then CURRENT_STATE <= IDLE; TX_PCS_RST_CH_C_OUT <= '1'; LINK_TX_READY_OUT <= '0'; else - if( rising_edge(LOCALCLK) ) then + if( rising_edge(CLK_REF) ) then CURRENT_STATE <= NEXT_STATE; TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int; LINK_TX_READY_OUT <= link_tx_ready_int; @@ -173,12 +173,12 @@ begin -- 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 ) + THE_QUAD_SYNC_PROC: process( CLK_REF, CLEAR ) begin if( CLEAR = '1' ) then sync_tx_quad_trans <= '0'; else - if( rising_edge(LOCALCLK) ) then + if( rising_edge(CLK_REF) ) then if( sync_tx_quad_int = '1' ) then sync_tx_quad_trans <= not sync_tx_quad_trans; end if; diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index 6d76f83..fc2755f 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -79,6 +79,7 @@ architecture med_sync_control_arch of med_sync_control_RS is signal sd_los_q : std_logic; signal reset_i : std_logic; + signal link_tx_ready_i : std_logic; signal link_rx_ready_i : std_logic; signal link_half_done_i : std_logic; signal link_full_done_i : std_logic; @@ -94,8 +95,9 @@ architecture med_sync_control_arch of med_sync_control_RS is signal is_wap_zero_i : std_logic; signal debug_tx_control_i : std_logic_vector(31 downto 0); signal debug_rx_control_i : std_logic_vector(31 downto 0); - signal rx_lsm_state : std_logic_vector(3 downto 0); + signal link_full_done_qsys : std_logic; + signal link_half_done_qsys : std_logic; signal link_rx_ready_qsys : std_logic; signal link_tx_ready_qsys : std_logic; signal link_status : std_logic_vector(3 downto 0); @@ -141,12 +143,15 @@ begin reset_i <= (RESET or sd_los_q) when (IS_MODE = c_IS_SLAVE) else (RESET); +-- for syncing later + link_tx_ready_i <= LINK_TX_READY_IN; + ------------------------------------------------- -- Reset RX FSM ------------------------------------------------- - THE_RX_RST_FSM: rx_rsl + THE_MAIN_RX_RST: main_rx_reset_RS port map( - CLEAR => '0', --GLOBAL_RESET_IN, + CLEAR => '0', CLK_REF => CLK_REF, PLL_LOL_IN => TX_PLL_LOL_IN, CDR_LOL_IN => RX_CDR_LOL_IN, @@ -206,9 +211,9 @@ begin RX_RST_OUT => RX_RST_OUT, RX_RST_WORD_OUT => RX_RST_WORD_OUT, -- - LINK_RX_READY_IN => link_rx_ready_i, - LINK_HALF_DONE_IN => link_half_done_i, - LINK_FULL_DONE_IN => link_full_done_i, + LINK_RX_READY_IN => link_rx_ready_i, -- internally synced + LINK_HALF_DONE_OUT => link_half_done_i, -- CLK_RXI based + LINK_FULL_DONE_OUT => link_full_done_i, -- CLK_RXI based -- DEBUG_OUT => debug_rx_control_i, STAT_REG_OUT => STAT_RX_CONTROL @@ -216,17 +221,6 @@ begin DEBUG_RX_CONTROL <= debug_rx_control_i; - THE_RX_LSM: rx_lsm_RS - port map( - LINK_RX_READY_IN => link_rx_ready_i, - CLK_RXI => CLK_RXI, - RX_K_IN => RX_K_IN, - RX_DATA_IN => RX_DATA_IN, - LINK_HALF_DONE_OUT => link_half_done_i, -- CLK_RXI based - LINK_FULL_DONE_OUT => link_full_done_i, -- CLK_RXI based - STATE_OUT => rx_lsm_state --open - ); - -- clocks for media interface media_med2int_i.clk_half <= CLK_RXHALF; -- goes to clock and reset handler media_med2int_i.clk_full <= CLK_RXI; -- goes to clock and reset handler @@ -259,10 +253,10 @@ begin SEND_RST_IN => TX_RST_IN, SEND_RST_WORD_IN => TX_RST_WORD_IN, -- link status signals, internally synced - 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_FULL_DONE_IN => link_full_done_i, + LINK_TX_READY_IN => link_tx_ready_i, -- internally synced + LINK_RX_READY_IN => link_rx_ready_i, -- internally synced + LINK_HALF_DONE_IN => link_half_done_i, -- internally synced + LINK_FULL_DONE_IN => link_full_done_i, -- internally synced -- debug DEBUG_OUT => debug_tx_control_i, STAT_REG_OUT => STAT_TX_CONTROL @@ -274,7 +268,7 @@ begin -- WordSync is taken from RX in case of SP to sync the MPs in a hub. -- In case of a root MP it is taken from MP to sync DLM sending. - -- NB: a root MP nees WORD_SYNC_IN set to '1' for operation. + -- NB: a root MP needs WORD_SYNC_IN set to '1' for operation. -- MB: a root MP provides WORD_SYNC_OUT for DLM transmission timing. WORD_SYNC_OUT <= word_sync_rx_i when (IS_MODE = c_IS_SLAVE) else word_sync_tx_i; @@ -322,16 +316,20 @@ begin SYNC_MEDIA_SIGS : entity work.signal_sync generic map( - WIDTH => 6, + WIDTH => 8, DEPTH => 3 ) port map( RESET => '0', CLK0 => CLK_SYS, CLK1 => CLK_SYS, - D_IN(5) => LINK_TX_READY_IN, + D_IN(7) => link_full_done_i, + D_IN(6) => link_half_done_i, + D_IN(5) => link_tx_ready_i, D_IN(4) => link_rx_ready_i, D_IN(3 downto 0) => link_status, + D_OUT(7) => link_full_done_qsys, + D_OUT(6) => link_half_done_qsys, D_OUT(5) => link_tx_ready_qsys, D_OUT(4) => link_rx_ready_qsys, D_OUT(3 downto 0) => link_status_qsys @@ -339,8 +337,8 @@ begin -- TEST_LINE signals DEBUG_OUT(31 downto 12) <= (others => '0'); - DEBUG_OUT(11) <= link_full_done_i; - DEBUG_OUT(10) <= link_half_done_i; + DEBUG_OUT(11) <= link_full_done_qsys; + DEBUG_OUT(10) <= link_half_done_qsys; DEBUG_OUT(9) <= '0'; DEBUG_OUT(8) <= link_rx_ready_qsys; DEBUG_OUT(7) <= link_tx_ready_qsys; diff --git a/media_interfaces/sync/med_sync_define_RS.vhd b/media_interfaces/sync/med_sync_define_RS.vhd index cabf0ec..db4545e 100644 --- a/media_interfaces/sync/med_sync_define_RS.vhd +++ b/media_interfaces/sync/med_sync_define_RS.vhd @@ -22,10 +22,10 @@ constant K_EOP : std_logic_vector(7 downto 0) := x"fd"; -- K29.7 -- reserved constant K_RST : std_logic_vector(7 downto 0) := x"fe"; -- K30.7 -- used for reset -- data char for idle -constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5"; -- D5.6 -constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2 +constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5"; -- D5.6 -- first link phase +constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2 -- second link phase -component rx_rsl is +component main_rx_reset_RS is port ( CLEAR : in std_logic; CLK_REF : in std_logic; @@ -80,7 +80,7 @@ component main_tx_reset_RS is ); port( CLEAR : in std_logic; -- async reset, active high - LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! + CLK_REF : 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 @@ -117,27 +117,14 @@ component rx_control_RS is RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); -- link status signals LINK_RX_READY_IN : in std_logic; - LINK_TX_READY_IN : in std_logic; - LINK_HALF_DONE_IN : in std_logic; - LINK_FULL_DONE_IN : in std_logic; + LINK_HALF_DONE_OUT : out std_logic; + LINK_FULL_DONE_OUT : out std_logic; -- debug DEBUG_OUT : out std_logic_vector(31 downto 0); STAT_REG_OUT : out std_logic_vector(31 downto 0) ); end component; -component rx_lsm_RS is - port( - LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low - CLK_RXI : in std_logic; -- recovered RX clock - RX_K_IN : in std_logic; - RX_DATA_IN : in std_logic_vector(7 downto 0); - LINK_HALF_DONE_OUT : out std_logic; - LINK_FULL_DONE_OUT : out std_logic; - STATE_OUT : out std_logic_vector(3 downto 0) - ); -end component; - component tx_control_RS is generic( SIM_MODE : integer := 0; diff --git a/media_interfaces/sync/rx_control_RS.vhd b/media_interfaces/sync/rx_control_RS.vhd index d89be82..9237d4d 100644 --- a/media_interfaces/sync/rx_control_RS.vhd +++ b/media_interfaces/sync/rx_control_RS.vhd @@ -30,8 +30,8 @@ entity rx_control_RS is RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); -- link status signals LINK_RX_READY_IN : in std_logic; -- used for synchronous reset - LINK_HALF_DONE_IN : in std_logic; -- unused - LINK_FULL_DONE_IN : in std_logic; + LINK_HALF_DONE_OUT : out std_logic; + LINK_FULL_DONE_OUT : out std_logic; -- debug DEBUG_OUT : out std_logic_vector(31 downto 0); STAT_REG_OUT : out std_logic_vector(31 downto 0) @@ -79,11 +79,11 @@ architecture rx_control_arch of rx_control_RS is signal ce_idle0_ctr : std_logic; signal rst_idle0_ctr : std_logic; signal ctr_idle0 : unsigned(4 downto 0); - signal idle0_detected : std_logic; + signal idle0_detected : std_logic; -- link_half_done signal ce_idle1_ctr : std_logic; signal rst_idle1_ctr : std_logic; signal ctr_idle1 : unsigned(4 downto 0); - signal idle1_detected : std_logic; + signal idle1_detected : std_logic; -- link_full_done signal rst_link_state : std_logic; -- attribute syn_keep : boolean; @@ -101,7 +101,7 @@ begin -- Syncing things SYNC_RXI: signal_sync generic map( - WIDTH => 2, + WIDTH => 1, DEPTH => 3 ) port map( @@ -109,9 +109,7 @@ begin CLK0 => CLK_RXI, CLK1 => CLK_RXI, D_IN(0) => LINK_RX_READY_IN, - D_IN(1) => LINK_FULL_DONE_IN, - D_OUT(0) => link_rx_ready_qrx, - D_OUT(1) => link_full_done_qrx + D_OUT(0) => link_rx_ready_qrx ); -- Syncing things @@ -124,7 +122,7 @@ begin RESET => '0', CLK0 => CLK_SYS, CLK1 => CLK_SYS, - D_IN(0) => LINK_FULL_DONE_IN, + D_IN(0) => idle1_detected, D_OUT(0) => link_full_done_qsys ); @@ -173,7 +171,7 @@ begin ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty; - ct_fifo_reset <= not link_full_done_qrx; + ct_fifo_reset <= not idle1_detected; ---------------------------------------------------------------------- -- Read incoming data @@ -341,6 +339,9 @@ begin RX_RST_OUT <= rx_rst_i when rising_edge(CLK_RXI); RX_RST_WORD_OUT <= rx_rst_word_i when rising_edge(CLK_RXI); + LINK_HALF_DONE_OUT <= idle0_detected; + LINK_FULL_DONE_OUT <= idle1_detected; + ---------------------------------------------------------------------- -- Debug and Status ---------------------------------------------------------------------- diff --git a/media_interfaces/sync/rx_lsm_RS.vhd b/media_interfaces/sync/rx_lsm_RS.vhd deleted file mode 100644 index d9ab08c..0000000 --- a/media_interfaces/sync/rx_lsm_RS.vhd +++ /dev/null @@ -1,171 +0,0 @@ -LIBRARY IEEE; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.all; - -library work; -use work.med_sync_define_RS.all; - -entity rx_lsm_RS is - port( - LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low - CLK_RXI : in std_logic; -- recovered RX clock - RX_K_IN : in std_logic; - RX_DATA_IN : in std_logic_vector(7 downto 0); - LINK_HALF_DONE_OUT : out std_logic; - LINK_FULL_DONE_OUT : out std_logic; - STATE_OUT : out std_logic_vector(3 downto 0) - ); -end entity; - -architecture rx_lsm_arch of rx_lsm_RS is - - type statetype is ( IDLE, KF, DFT, DFS ); - - signal CURRENT_STATE : statetype; -- current state of lsm - signal NEXT_STATE : statetype; -- next state of lsm - - signal reset_ctr_t : std_logic; - signal ce_ctr_t : std_logic; - signal ce_ctr_t_q : std_logic; - signal ctr_t : unsigned(4 downto 0); - signal ctr_t_done : std_logic; - signal reset_ctr_s : std_logic; - signal ce_ctr_s : std_logic; - signal ce_ctr_s_q : std_logic; - signal ctr_s : unsigned(4 downto 0); - signal ctr_s_done : std_logic; - signal link_toggling_int : std_logic; - signal link_steady_int : std_logic; - -begin - - THE_CTR_T_PROC: process( CLK_RXI, LINK_RX_READY_IN ) - begin - if( LINK_RX_READY_IN = '0' ) then - ctr_t <= (others => '0'); - elsif( rising_edge(CLK_RXI) ) then - if( reset_ctr_t = '1' ) then - ctr_t <= (others => '0'); - elsif( (ctr_t_done = '0') and (ce_ctr_t_q = '1') ) then - ctr_t <= ctr_t + 1 ; - end if; - end if; - end process THE_CTR_T_PROC; - - ctr_t_done <= ctr_t(4); - - THE_CTR_S_PROC: process( CLK_RXI, LINK_RX_READY_IN ) - begin - if( LINK_RX_READY_IN = '0' ) then - ctr_s <= (others => '0'); - elsif( rising_edge(CLK_RXI) ) then - if( reset_ctr_s = '1' ) then - ctr_s <= (others => '0'); - elsif( (ctr_s_done = '0') and (ce_ctr_s_q = '1') and (ctr_t_done = '1') ) then -- added to make sure correct sequence is done - ctr_s <= ctr_s + 1 ; - end if; - end if; - end process THE_CTR_S_PROC; - - ctr_s_done <= ctr_s(4); - - -- toggling idles sequence detected - THE_TOGGLE_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN ) - begin - if( LINK_RX_READY_IN = '0' ) then - link_toggling_int <= '0'; - elsif( rising_edge(CLK_RXI) ) then - if( (ce_ctr_t_q = '1') and (ctr_t_done = '1') ) then - link_toggling_int <= '1'; - end if; - end if; - end process THE_TOGGLE_DETECTED_PROC; - - LINK_HALF_DONE_OUT <= link_toggling_int; - - -- steady idles sequence detected - THE_STEADY_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN ) - begin - if( LINK_RX_READY_IN = '0' ) then - link_steady_int <= '0'; - elsif( rising_edge(CLK_RXI) ) then - if( (ce_ctr_s_q = '1') and (ctr_s_done = '1') ) then - link_steady_int <= '1'; - end if; - end if; - end process THE_STEADY_DETECTED_PROC; - - LINK_FULL_DONE_OUT <= link_steady_int; - - -- State machine clocked process - THE_FSM_PROC: process( CLK_RXI, LINK_RX_READY_IN ) - begin - if( LINK_RX_READY_IN = '0' ) then - CURRENT_STATE <= IDLE; - ce_ctr_t_q <= '0'; - ce_ctr_s_q <= '0'; - elsif( rising_edge(CLK_RXI) ) then - CURRENT_STATE <= NEXT_STATE; - ce_ctr_t_q <= ce_ctr_t; - ce_ctr_s_q <= ce_ctr_s; - end if; - end process THE_FSM_PROC; - - -- State machine decoding processs - THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN ) - begin - reset_ctr_t <= '0'; - reset_ctr_s <= '0'; - ce_ctr_t <= '0'; - ce_ctr_s <= '0'; - STATE_OUT <= x"F"; - - case CURRENT_STATE is - - when IDLE => - STATE_OUT <= x"0"; - reset_ctr_t <= '1'; - reset_ctr_s <= '1'; - if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then - NEXT_STATE <= KF; - else - NEXT_STATE <= IDLE; - end if; - - when KF => - STATE_OUT <= x"1"; - if ( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then - NEXT_STATE <= DFS; - ce_ctr_s <= '1'; - elsif( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE0) ) then - NEXT_STATE <= DFT; - ce_ctr_t <= '1'; - else - NEXT_STATE <= IDLE; - end if; - - when DFT => - STATE_OUT <= x"2"; - if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then - NEXT_STATE <= KF; - else - NEXT_STATE <= IDLE; - end if; - - when DFS => - STATE_OUT <= x"3"; - if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then - NEXT_STATE <= KF; - else - NEXT_STATE <= IDLE; - end if; - - when others => - STATE_OUT <= x"f"; - NEXT_STATE <= IDLE; - - end case; - - end process THE_FSM_DECODE_PROC; - -end architecture; diff --git a/media_interfaces/sync/rx_rsl.vhd b/media_interfaces/sync/rx_rsl.vhd deleted file mode 100644 index dfce0cc..0000000 --- a/media_interfaces/sync/rx_rsl.vhd +++ /dev/null @@ -1,230 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -USE IEEE.numeric_std.all; - -entity rx_rsl is - port ( - CLEAR : in std_logic; - CLK_REF : in std_logic; - PLL_LOL_IN : in std_logic; - CDR_LOL_IN : in std_logic; - CV_IN : in std_logic; - LSM_IN : in std_logic; - LOS_IN : in std_logic; - SD_LOS_IN : in std_logic; - WAP_ZERO_IN : in std_logic; - -- outputs - RX_SERDES_RST_OUT : out std_logic; - RX_PCS_RST_OUT : out std_logic; - LINK_RX_READY_OUT : out std_logic; - STATE_OUT : out std_logic_vector(3 downto 0) - ); -end rx_rsl; - -architecture rx_rsl_arc of rx_rsl is - - attribute syn_keep : boolean; - --- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3. --- Without this piece of code, many things would have been a real pain. - - constant Tshort : unsigned(31 downto 0) := x"0000000a"; --- @200MHz 100ms - constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - - signal pll_lol_s : std_logic; - signal cdr_lol_s : std_logic; - signal cv_s : std_logic; - signal lsm_s : std_logic; - signal los_s : std_logic; - signal sd_los_s : std_logic; - - signal cnt : unsigned(31 downto 0); - - type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, - APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, - CHECK_WAP, NORMAL_OP); - - signal rx_sm : rx_sm_state; - - attribute syn_keep of rx_sm : signal is true; - -begin - --- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP. --- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset. --- Remark: syncing is done here by one FF only. Might be dangerous. - ------------------------------------------------------------------- -RX_RESET_PROC : process( CLEAR, CLK_REF ) -begin - if( CLEAR = '1' ) then - pll_lol_s <= '1'; - cdr_lol_s <= '1'; - cv_s <= '1'; - lsm_s <= '0'; - los_s <= '1'; - sd_los_s <= '1'; - - RX_SERDES_RST_OUT <= '1'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - - rx_sm <= powerup; - STATE_OUT <= x"f"; - cnt <= (others => '0'); - elsif( rising_edge(CLK_REF) ) then - pll_lol_s <= PLL_LOL_IN; - cdr_lol_s <= CDR_LOL_IN; - cv_s <= CV_IN; - lsm_s <= LSM_IN; - los_s <= LOS_IN; - sd_los_s <= SD_LOS_IN; - - case rx_sm is - when POWERUP => - STATE_OUT <= x"0"; - RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; --- if( (pll_lol_s = '1') or (los_s = '1') or (sd_los_s = '1') ) then - if( (pll_lol_s = '1') or (sd_los_s = '1') ) then - cnt <= (others => '0'); - else - if( cnt = Tplol ) then - cnt <= (others => '0'); - rx_sm <= APPLY_CDR_RST; - else - cnt <= cnt + 1; - end if; - end if; - - when APPLY_CDR_RST => - STATE_OUT <= x"1"; - RX_SERDES_RST_OUT <= '1'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tshort ) then - cnt <= (others => '0'); - rx_sm <= WAIT_CDR_LOCK; - else - cnt <= cnt + 1; - end if; - - when WAIT_CDR_LOCK => - STATE_OUT <= x"2"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= TEST_CDR; - else - cnt <= cnt + 1; - end if; - - when TEST_CDR => - STATE_OUT <= x"3"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cdr_lol_s = '1' ) then - cnt <= (others => '0'); - rx_sm <= APPLY_CDR_RST; - else - if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= APPLY_RXPCS_RST; - else - cnt <= cnt + 1; - end if; - end if; - - when APPLY_RXPCS_RST => - STATE_OUT <= x"4"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tshort ) then - cnt <= (others => '0'); - rx_sm <= WAIT_RXPCS_LOCK; - else - cnt <= cnt + 1; - end if; - - when WAIT_RXPCS_LOCK => - STATE_OUT <= x"5"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tviol ) then - cnt <= (others => '0'); - rx_sm <= TEST_RXPCS; - else - cnt <= cnt + 1; - end if; - - when TEST_RXPCS => - STATE_OUT <= x"6"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - if( (lsm_s = '0') or (cv_s = '1') ) then - cnt <= (others => '0'); - rx_sm <= APPLY_RXPCS_RST; - else - if( cnt = Tviol ) then - cnt <= (others => '0'); - rx_sm <= CHECK_WAP; - else - cnt <= cnt + 1; - end if; - end if; - - when CHECK_WAP => - STATE_OUT <= x"7"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - cnt <= (others => '0'); - if( WAP_ZERO_IN = '1' ) then - rx_sm <= NORMAL_OP; - else --- rx_sm <= APPLY_RXPCS_RST; -- DOESNT WORK - rx_sm <= APPLY_CDR_RST; - end if; - - when NORMAL_OP => - STATE_OUT <= x"8"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '1'; - cnt <= (others => '0'); - if( (lsm_s = '0') or (cv_s = '1') ) then - rx_sm <= APPLY_RXPCS_RST; - end if; - - when others => - -- just in case - STATE_OUT <= x"f"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - rx_sm <= POWERUP; - - end case; - ------------------------------------------------- --- if (pll_lol_s = '1') or (los_s = '1') then --- if( pll_lol_s = '1' ) then - if( (pll_lol_s = '1') or (sd_los_s = '1') ) then - rx_sm <= POWERUP; - cnt <= (others => '0'); - end if; - - end if; -end process rx_reset_proc; - -end rx_rsl_arc; diff --git a/media_interfaces/sync/rx_rsl_WRONG.vhd b/media_interfaces/sync/rx_rsl_WRONG.vhd deleted file mode 100644 index 019a903..0000000 --- a/media_interfaces/sync/rx_rsl_WRONG.vhd +++ /dev/null @@ -1,224 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -USE IEEE.numeric_std.all; - -entity rx_rsl is - port ( - CLEAR : in std_logic; - CLK_REF : in std_logic; - PLL_LOL_IN : in std_logic; - CDR_LOL_IN : in std_logic; - CV_IN : in std_logic; - LSM_IN : in std_logic; - LOS_IN : in std_logic; - WAP_ZERO_IN : in std_logic; - -- outputs - RX_SERDES_RST_OUT : out std_logic; - RX_PCS_RST_OUT : out std_logic; - LINK_RX_READY_OUT : out std_logic; - STATE_OUT : out std_logic_vector(3 downto 0) - ); -end rx_rsl; - -architecture rx_rsl_arc of rx_rsl is - - attribute syn_keep : boolean; - --- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3. --- Without this piece of code, many things would have been a real pain. - - constant Tshort : unsigned(31 downto 0) := x"0000000a"; --- @200MHz 100ms - constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; - - signal pll_lol_s : std_logic; - signal cdr_lol_s : std_logic; - signal cv_s : std_logic; - signal lsm_s : std_logic; - signal los_s : std_logic; - - signal cnt : unsigned(31 downto 0); - - type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, - CHECK_WAP, APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, - TEST_RXPCS, NORMAL_OP); - - signal rx_sm : rx_sm_state; - - attribute syn_keep of rx_sm : signal is true; - -begin - --- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP. --- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset. --- Remark: syncing is done here by one FF only. Might be dangerous. - ------------------------------------------------------------------- -RX_RESET_PROC : process( CLEAR, CLK_REF ) -begin - if( CLEAR = '1' ) then - pll_lol_s <= '1'; - cdr_lol_s <= '1'; - cv_s <= '1'; - lsm_s <= '0'; - los_s <= '1'; - - RX_SERDES_RST_OUT <= '1'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - - rx_sm <= powerup; - STATE_OUT <= x"f"; - cnt <= (others => '0'); - elsif( rising_edge(CLK_REF) ) then - pll_lol_s <= PLL_LOL_IN; - cdr_lol_s <= CDR_LOL_IN; - cv_s <= CV_IN; - lsm_s <= LSM_IN; - los_s <= LOS_IN; - - case rx_sm is - when POWERUP => - STATE_OUT <= x"0"; - RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( (pll_lol_s = '1') or (los_s = '1') ) then - cnt <= (others => '0'); - else - if( cnt = Tplol ) then - cnt <= (others => '0'); - rx_sm <= APPLY_CDR_RST; - else - cnt <= cnt + 1; - end if; - end if; - - when APPLY_CDR_RST => - STATE_OUT <= x"1"; - RX_SERDES_RST_OUT <= '1'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tshort ) then - cnt <= (others => '0'); - rx_sm <= WAIT_CDR_LOCK; - else - cnt <= cnt + 1; - end if; - - when WAIT_CDR_LOCK => - STATE_OUT <= x"2"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= TEST_CDR; - else - cnt <= cnt + 1; - end if; - - when TEST_CDR => - STATE_OUT <= x"3"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cdr_lol_s = '1' ) then - cnt <= (others => '0'); - rx_sm <= APPLY_CDR_RST; - else - if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= CHECK_WAP; - else - cnt <= cnt + 1; - end if; - end if; - - -- THIS STATE CAN BE ASSIMILATED INTO TEST_CDR - when CHECK_WAP => - STATE_OUT <= x"4"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; -- really? - LINK_RX_READY_OUT <= '0'; - cnt <= (others => '0'); - if( WAP_ZERO_IN = '1' ) then - rx_sm <= NORMAL_OP; - else - rx_sm <= APPLY_CDR_RST; - end if; - - when APPLY_RXPCS_RST => - STATE_OUT <= x"5"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '1'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tshort ) then - cnt <= (others => '0'); - rx_sm <= WAIT_RXPCS_LOCK; - else - cnt <= cnt + 1; - end if; - - when WAIT_RXPCS_LOCK => - STATE_OUT <= x"6"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - if( cnt = Tviol ) then - cnt <= (others => '0'); - rx_sm <= TEST_RXPCS; - else - cnt <= cnt + 1; - end if; - - when TEST_RXPCS => - STATE_OUT <= x"7"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - if( (lsm_s = '0') or (cv_s = '1') ) then - cnt <= (others => '0'); - rx_sm <= APPLY_RXPCS_RST; - else - if( cnt = Tviol ) then - cnt <= (others => '0'); - rx_sm <= NORMAL_OP; - else - cnt <= cnt + 1; - end if; - end if; - - when NORMAL_OP => - STATE_OUT <= x"8"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '1'; - cnt <= (others => '0'); - if( (lsm_s = '0') or (cv_s = '1') ) then - rx_sm <= APPLY_RXPCS_RST; - end if; - - when others => - -- just in case - STATE_OUT <= x"f"; - RX_SERDES_RST_OUT <= '0'; - RX_PCS_RST_OUT <= '0'; - LINK_RX_READY_OUT <= '0'; - rx_sm <= POWERUP; - - end case; - ------------------------------------------------- --- if (pll_lol_s = '1') or (los_s = '1') then - if( pll_lol_s = '1' ) then - rx_sm <= POWERUP; - cnt <= (others => '0'); - end if; - - end if; -end process rx_reset_proc; - -end rx_rsl_arc; -- 2.43.0