---Media interface RX state machine\r
-\r
-LIBRARY IEEE;\r
-USE IEEE.std_logic_1164.ALL;\r
+library ieee;\r
+use ieee.std_logic_1164.all;\r
USE IEEE.numeric_std.all;\r
\r
-library work;\r
-use work.trb_net_std.all;\r
---use work.trb_net_components.all;\r
-use work.med_sync_define_RS.all;\r
-\r
entity main_rx_reset_RS is\r
- generic(\r
- SIM_MODE : integer := 0;\r
- IS_WAP_ZERO : integer := 0;\r
- IS_MODE : integer := c_IS_SLAVE\r
- );\r
- port(\r
- CLEAR : in std_logic; -- async reset, active high\r
- LOCALCLK : in std_logic; -- CDR reference clock\r
- TX_PLL_LOL_IN : in std_logic; -- TX_PLOL form AUX channel\r
- RX_CDR_LOL_IN : in std_logic; -- CDR LOL \r
- RX_LOS_LOW_IN : in std_logic; -- RX LOS\r
- WA_POSITION_IN : in std_logic_vector(3 downto 0);\r
- SFP_LOS_IN : in std_logic; -- SFP LOS signal\r
- RX_PCS_RST_CH_C_OUT : out std_logic;\r
- RX_SERDES_RST_CH_C_OUT : out std_logic;\r
- LINK_RX_READY_OUT : out std_logic; -- RX SerDes is fully operational\r
- MASTER_RESET_OUT : out std_logic; -- can be used as master reset if sourced from Slave port\r
- STATE_OUT : out std_logic_vector(3 downto 0)\r
+ port (\r
+ CLEAR : in std_logic;\r
+ CLK_REF : in std_logic;\r
+ PLL_LOL_IN : in std_logic;\r
+ CDR_LOL_IN : in std_logic;\r
+ CV_IN : in std_logic;\r
+ LSM_IN : in std_logic;\r
+ LOS_IN : in std_logic;\r
+ SD_LOS_IN : in std_logic;\r
+ WAP_ZERO_IN : in std_logic;\r
+ -- outputs\r
+ RX_SERDES_RST_OUT : out std_logic;\r
+ RX_PCS_RST_OUT : out std_logic;\r
+ LINK_RX_READY_OUT : out std_logic;\r
+ STATE_OUT : out std_logic_vector(3 downto 0)\r
);\r
-end entity;\r
+end entity; \r
\r
--- IS_WAP_ZERO could be moved into med_ecpX_sfp_sync...\r
+architecture main_rx_reset_RS_arch of main_rx_reset_RS is\r
\r
-architecture main_rx_reset_arch of main_rx_reset_RS is\r
+ attribute syn_keep : boolean;\r
\r
- -- We use two different timing for simulation and real world.\r
- -- Using SIM_MODE for implementation will most likely kill the link.\r
- constant count2_index : integer := 20 - (SIM_MODE * 12); -- 20 for implementation, 8 for simulation\r
- constant wap_index : integer := 16 - (SIM_MODE * 8); -- 16 for implementation, 8 for simulation\r
+-- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3.\r
+-- Without this piece of code, many things would have been a real pain.\r
\r
- type statetype is ( WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_TIMER1, CHECK_LOL_LOS, WAIT_FOR_TIMER2, CHECK_WAP, NORMAL );\r
+ constant Tshort : unsigned(31 downto 0) := x"0000000a";\r
+-- @200MHz 100ms\r
+ constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
+ constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
+ constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
\r
- signal CURRENT_STATE : statetype; -- current state of lsm\r
- signal NEXT_STATE : statetype; -- next state of lsm\r
+ signal pll_lol_s : std_logic;\r
+ signal cdr_lol_s : std_logic;\r
+ signal cv_s : std_logic;\r
+ signal lsm_s : std_logic;\r
+ signal los_s : std_logic;\r
+ signal sd_los_s : std_logic;\r
\r
- signal tx_pll_lol_q : std_logic; -- synced\r
- signal rx_cdr_lol_q : std_logic; -- synced\r
- signal rx_los_low_q : std_logic; -- synced\r
- signal sfp_los_q : std_logic; -- synced\r
- signal wa_position_q : std_logic_vector(3 downto 0); -- synced\r
- signal rx_lol_los : std_logic;\r
- signal rx_lol_los_int : std_logic;\r
- signal rx_lol_los_del : std_logic;\r
- signal rx_pcs_rst_ch_c_int : std_logic;\r
- signal rx_serdes_rst_ch_c_int : std_logic;\r
+ signal cnt : unsigned(31 downto 0);\r
\r
- signal reset_timer2 : std_logic;\r
- signal counter2 : unsigned(count2_index downto 0);\r
- signal timer2 : std_logic;\r
+ type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, \r
+ APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, \r
+ CHECK_WAP, NORMAL_OP);\r
\r
-begin\r
+ signal rx_sm : rx_sm_state;\r
+ \r
+ attribute syn_keep of rx_sm : signal is true;\r
\r
- GEN_WAP_SYNC : if (IS_WAP_ZERO = 1) generate\r
- -- sync WAP\r
- SYNC_WAP : entity work.signal_sync \r
- generic map( \r
- WIDTH => 4,\r
- DEPTH => 3\r
- )\r
- port map(\r
- RESET => '0',\r
- CLK0 => LOCALCLK, \r
- CLK1 => LOCALCLK,\r
- D_IN => WA_POSITION_IN,\r
- D_OUT => wa_position_q\r
- );\r
- end generate GEN_WAP_SYNC;\r
-\r
- GEN_WAP_FIXED: if (IS_WAP_ZERO = 0) generate\r
- wa_position_q <= x"0";\r
- end generate GEN_WAP_FIXED;\r
-\r
- -- sync SerDes signals\r
- SYNC_SERDES_SIGS : entity work.signal_sync \r
- generic map( \r
- WIDTH => 4,\r
- DEPTH => 3\r
- )\r
- port map(\r
- RESET => '0',\r
- CLK0 => LOCALCLK, \r
- CLK1 => LOCALCLK,\r
- D_IN(0) => TX_PLL_LOL_IN,\r
- D_IN(1) => RX_CDR_LOL_IN,\r
- D_IN(2) => RX_LOS_LOW_IN,\r
- D_IN(3) => SFP_LOS_IN,\r
- D_OUT(0) => tx_pll_lol_q,\r
- D_OUT(1) => rx_cdr_lol_q,\r
- D_OUT(2) => rx_los_low_q,\r
- D_OUT(3) => sfp_los_q\r
- );\r
-\r
- MASTER_RESET_OUT <= sfp_los_q when (IS_MODE = c_IS_SLAVE) else '0';\r
-\r
- rx_lol_los <= rx_cdr_lol_q or rx_los_low_q ;\r
-\r
---timer2 = 400,000 Refclk cycles or 200,000 REFCLKDIV2 cycles\r
---A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set timer2 = bit[19]\r
-\r
- THE_TIMER2_PROC: process( LOCALCLK ) \r
- begin\r
- if( rising_edge(LOCALCLK) ) then\r
- if( reset_timer2 = '1' ) then\r
- counter2 <= (others => '0');\r
- else\r
- if( counter2(count2_index) = '0' ) then\r
- counter2 <= counter2 + 1 ;\r
- end if;\r
- end if;\r
- end if;\r
- end process THE_TIMER2_PROC;\r
+begin\r
\r
- timer2 <= counter2(count2_index);\r
+-- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP.\r
+-- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset.\r
+-- Remark: syncing is done here by one FF only. Might be dangerous.\r
\r
- -- State machine clocked process\r
- THE_FSM_PROC: process( LOCALCLK, CLEAR )\r
+------------------------------------------------------------------\r
+ RX_RESET_PROC : process( CLEAR, CLK_REF )\r
begin\r
if( CLEAR = '1' ) then\r
- CURRENT_STATE <= WAIT_FOR_PLOL;\r
- rx_lol_los_int <= '1';\r
- rx_lol_los_del <= '1';\r
- RX_PCS_RST_CH_C_OUT <= '1';\r
- RX_SERDES_RST_CH_C_OUT <= '0';\r
- else\r
- if( rising_edge(LOCALCLK) ) then\r
- CURRENT_STATE <= NEXT_STATE;\r
- rx_lol_los_del <= rx_lol_los;\r
- rx_lol_los_int <= rx_lol_los_del;\r
- RX_PCS_RST_CH_C_OUT <= rx_pcs_rst_ch_c_int;\r
- RX_SERDES_RST_CH_C_OUT <= rx_serdes_rst_ch_c_int;\r
- end if;\r
- end if;\r
- end process THE_FSM_PROC;\r
-\r
- 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 )\r
- begin\r
- reset_timer2 <= '0';\r
- STATE_OUT <= x"F"; \r
- LINK_RX_READY_OUT <= '0';\r
+ pll_lol_s <= '1';\r
+ cdr_lol_s <= '1';\r
+ cv_s <= '1';\r
+ lsm_s <= '0';\r
+ los_s <= '1';\r
+ sd_los_s <= '1';\r
+\r
+ RX_SERDES_RST_OUT <= '1';\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+ \r
+ rx_sm <= powerup;\r
+ STATE_OUT <= x"f";\r
+ cnt <= (others => '0'); \r
+ elsif( rising_edge(CLK_REF) ) then\r
+ pll_lol_s <= PLL_LOL_IN;\r
+ cdr_lol_s <= CDR_LOL_IN;\r
+ cv_s <= CV_IN; \r
+ lsm_s <= LSM_IN; \r
+ los_s <= LOS_IN; \r
+ sd_los_s <= SD_LOS_IN;\r
\r
- case CURRENT_STATE is\r
- when WAIT_FOR_PLOL =>\r
- rx_pcs_rst_ch_c_int <= '1';\r
- rx_serdes_rst_ch_c_int <= '0';\r
- reset_timer2 <= '1';\r
- if( (tx_pll_lol_q = '1') or (rx_los_low_q = '1') ) then\r
- NEXT_STATE <= WAIT_FOR_PLOL;\r
- else\r
- NEXT_STATE <= RX_SERDES_RESET;\r
- end if;\r
- STATE_OUT <= x"1";\r
-\r
- when RX_SERDES_RESET =>\r
- rx_pcs_rst_ch_c_int <= '1';\r
- rx_serdes_rst_ch_c_int <= '1';\r
- reset_timer2 <= '1';\r
- NEXT_STATE <= WAIT_FOR_TIMER1;\r
- STATE_OUT <= x"2";\r
-\r
- when WAIT_FOR_TIMER1 =>\r
- rx_pcs_rst_ch_c_int <= '1';\r
- rx_serdes_rst_ch_c_int <= '1';\r
- reset_timer2 <= '1';\r
- NEXT_STATE <= CHECK_LOL_LOS;\r
- STATE_OUT <= x"3";\r
-\r
- when CHECK_LOL_LOS =>\r
- rx_pcs_rst_ch_c_int <= '1';\r
- rx_serdes_rst_ch_c_int <= '0';\r
- reset_timer2 <= '1';\r
- NEXT_STATE <= WAIT_FOR_TIMER2;\r
- STATE_OUT <= x"4";\r
-\r
- when WAIT_FOR_TIMER2 =>\r
- rx_pcs_rst_ch_c_int <= '1';\r
- rx_serdes_rst_ch_c_int <= '0';\r
- if( (rx_lol_los_int = rx_lol_los_del) ) then --NO RISING OR FALLING EDGES\r
- if( timer2 = '1' ) then\r
- if( rx_lol_los_int = '1' ) then\r
- NEXT_STATE <= WAIT_FOR_PLOL;\r
- reset_timer2 <= '1';\r
+ case rx_sm is\r
+ when POWERUP =>\r
+ STATE_OUT <= x"0";\r
+ RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+-- if( (pll_lol_s = '1') or (los_s = '1') or (sd_los_s = '1') ) then\r
+ if( (pll_lol_s = '1') or (sd_los_s = '1') ) then\r
+ cnt <= (others => '0');\r
+ else\r
+ if( cnt = Tplol ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= APPLY_CDR_RST;\r
else\r
- NEXT_STATE <= CHECK_WAP;\r
- reset_timer2 <= '1';\r
+ cnt <= cnt + 1;\r
end if;\r
+ end if;\r
+\r
+ when APPLY_CDR_RST =>\r
+ STATE_OUT <= x"1";\r
+ RX_SERDES_RST_OUT <= '1';\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( cnt = Tshort ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= WAIT_CDR_LOCK;\r
else\r
- NEXT_STATE <= WAIT_FOR_TIMER2;\r
+ cnt <= cnt + 1; \r
end if;\r
- else\r
- NEXT_STATE <= CHECK_LOL_LOS; --RESET timer2\r
- reset_timer2 <= '1';\r
- end if;\r
- STATE_OUT <= x"5";\r
-\r
- when CHECK_WAP =>\r
- rx_pcs_rst_ch_c_int <= '0';\r
- rx_serdes_rst_ch_c_int <= '0';\r
- if( std_logic(counter2(wap_index)) = '1' ) then -- may be too long\r
- if( wa_position_q /= x"0" ) then\r
- NEXT_STATE <= WAIT_FOR_PLOL;\r
- reset_timer2 <= '1';\r
+ \r
+ when WAIT_CDR_LOCK =>\r
+ STATE_OUT <= x"2";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( cnt = Tcdr ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= TEST_CDR;\r
else\r
- NEXT_STATE <= NORMAL;\r
- reset_timer2 <= '1';\r
+ cnt <= cnt + 1; \r
end if;\r
- else\r
- NEXT_STATE <= CHECK_WAP;\r
- end if; \r
- STATE_OUT <= x"7";\r
-\r
- when NORMAL =>\r
- rx_pcs_rst_ch_c_int <= '0';\r
- rx_serdes_rst_ch_c_int <= '0';\r
- reset_timer2 <= '1';\r
- if( (rx_lol_los_int = '1') or (wa_position_q /= x"0") ) then\r
- NEXT_STATE <= WAIT_FOR_PLOL;\r
- else\r
+\r
+ when TEST_CDR =>\r
+ STATE_OUT <= x"3";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( cdr_lol_s = '1' ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= APPLY_CDR_RST;\r
+ else\r
+ if( cnt = Tcdr ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= APPLY_RXPCS_RST;\r
+ else\r
+ cnt <= cnt + 1;\r
+ end if;\r
+ end if;\r
+\r
+ when APPLY_RXPCS_RST =>\r
+ STATE_OUT <= x"4";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '1';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( cnt = Tshort ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= WAIT_RXPCS_LOCK;\r
+ else\r
+ cnt <= cnt + 1; \r
+ end if;\r
+\r
+ when WAIT_RXPCS_LOCK =>\r
+ STATE_OUT <= x"5";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( cnt = Tviol ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= TEST_RXPCS;\r
+ else\r
+ cnt <= cnt + 1; \r
+ end if;\r
+\r
+ when TEST_RXPCS =>\r
+ STATE_OUT <= x"6";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ if( (lsm_s = '0') or (cv_s = '1') ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= APPLY_RXPCS_RST;\r
+ else\r
+ if( cnt = Tviol ) then\r
+ cnt <= (others => '0');\r
+ rx_sm <= CHECK_WAP;\r
+ else\r
+ cnt <= cnt + 1;\r
+ end if;\r
+ end if;\r
+\r
+ when CHECK_WAP =>\r
+ STATE_OUT <= x"7";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ cnt <= (others => '0');\r
+ if( WAP_ZERO_IN = '1' ) then\r
+ rx_sm <= NORMAL_OP;\r
+ else\r
+-- rx_sm <= APPLY_RXPCS_RST; -- DOESNT WORK\r
+ rx_sm <= APPLY_CDR_RST;\r
+ end if;\r
+ \r
+ when NORMAL_OP =>\r
+ STATE_OUT <= x"8";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
LINK_RX_READY_OUT <= '1';\r
- NEXT_STATE <= NORMAL;\r
- end if;\r
- STATE_OUT <= x"6";\r
+ cnt <= (others => '0');\r
+ if( (lsm_s = '0') or (cv_s = '1') ) then\r
+ rx_sm <= APPLY_RXPCS_RST; \r
+ end if;\r
\r
- when others =>\r
- NEXT_STATE <= WAIT_FOR_PLOL;\r
- reset_timer2 <= '1';\r
+ when others =>\r
+ -- just in case\r
+ STATE_OUT <= x"f";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ rx_sm <= POWERUP;\r
\r
- end case;\r
+ end case;\r
+ \r
+------------------------------------------------\r
+-- if (pll_lol_s = '1') or (los_s = '1') then\r
+-- if( pll_lol_s = '1' ) then\r
+ if( (pll_lol_s = '1') or (sd_los_s = '1') ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ end if;\r
\r
- end process THE_FSM_DECODE_PROC;\r
+ end if;\r
+ end process rx_reset_proc;\r
\r
end architecture;\r
);\r
port(\r
CLEAR : in std_logic; -- async reset, active high\r
- LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! \r
+ CLK_REF : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! \r
TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A\r
TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B\r
TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C\r
)\r
port map(\r
RESET => '0',\r
- CLK0 => LOCALCLK, \r
- CLK1 => LOCALCLK,\r
+ CLK0 => CLK_REF, \r
+ CLK1 => CLK_REF,\r
D_IN(0) => tx_pll_lol_all, \r
D_IN(1) => TX_CLOCK_AVAIL_IN,\r
D_OUT(0) => tx_pll_lol_all_q,\r
\r
\r
-- Timer\r
- THE_TIMER_PROC: process( LOCALCLK )\r
+ THE_TIMER_PROC: process( CLK_REF )\r
begin\r
- if( rising_edge(LOCALCLK) ) then\r
+ if( rising_edge(CLK_REF) ) then\r
if( reset_timer = '1' ) then\r
counter <= (others => '0');\r
else\r
\r
\r
-- State machine clocked process\r
- THE_FSM_PROC: process( LOCALCLK, CLEAR )\r
+ THE_FSM_PROC: process( CLK_REF, CLEAR )\r
begin\r
if( CLEAR = '1' ) then\r
CURRENT_STATE <= IDLE;\r
TX_PCS_RST_CH_C_OUT <= '1';\r
LINK_TX_READY_OUT <= '0';\r
else \r
- if( rising_edge(LOCALCLK) ) then\r
+ if( rising_edge(CLK_REF) ) then\r
CURRENT_STATE <= NEXT_STATE;\r
TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int;\r
LINK_TX_READY_OUT <= link_tx_ready_int;\r
-- TX serializer is operational "at level" of this signal, \r
-- and gets reset by a transition (according to SerDes Usage Guide).\r
-- Timer1 is used to delay the TX link ready signal by some cycles.\r
- THE_QUAD_SYNC_PROC: process( LOCALCLK, CLEAR )\r
+ THE_QUAD_SYNC_PROC: process( CLK_REF, CLEAR )\r
begin\r
if( CLEAR = '1' ) then\r
sync_tx_quad_trans <= '0';\r
else \r
- if( rising_edge(LOCALCLK) ) then\r
+ if( rising_edge(CLK_REF) ) then\r
if( sync_tx_quad_int = '1' ) then\r
sync_tx_quad_trans <= not sync_tx_quad_trans;\r
end if;\r
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;
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);
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,
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
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
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
-- 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;
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
-- 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;
constant K_RST : std_logic_vector(7 downto 0) := x"fe"; -- K30.7 -- used for reset \r
\r
-- data char for idle\r
-constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5"; -- D5.6\r
-constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2\r
+constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5"; -- D5.6 -- first link phase\r
+constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2 -- second link phase\r
\r
-component rx_rsl is\r
+component main_rx_reset_RS is\r
port (\r
CLEAR : in std_logic;\r
CLK_REF : in std_logic;\r
);\r
port(\r
CLEAR : in std_logic; -- async reset, active high\r
- LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! \r
+ CLK_REF : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! \r
TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A\r
TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B\r
TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C\r
RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);\r
-- link status signals\r
LINK_RX_READY_IN : in std_logic;\r
- LINK_TX_READY_IN : in std_logic;\r
- LINK_HALF_DONE_IN : in std_logic;\r
- LINK_FULL_DONE_IN : in std_logic;\r
+ LINK_HALF_DONE_OUT : out std_logic;\r
+ LINK_FULL_DONE_OUT : out std_logic;\r
-- debug\r
DEBUG_OUT : out std_logic_vector(31 downto 0);\r
STAT_REG_OUT : out std_logic_vector(31 downto 0)\r
);\r
end component;\r
\r
-component rx_lsm_RS is\r
- port(\r
- LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low\r
- CLK_RXI : in std_logic; -- recovered RX clock\r
- RX_K_IN : in std_logic;\r
- RX_DATA_IN : in std_logic_vector(7 downto 0); \r
- LINK_HALF_DONE_OUT : out std_logic;\r
- LINK_FULL_DONE_OUT : out std_logic;\r
- STATE_OUT : out std_logic_vector(3 downto 0)\r
- );\r
-end component;\r
-\r
component tx_control_RS is\r
generic(\r
SIM_MODE : integer := 0;\r
RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);\r
-- link status signals\r
LINK_RX_READY_IN : in std_logic; -- used for synchronous reset\r
- LINK_HALF_DONE_IN : in std_logic; -- unused\r
- LINK_FULL_DONE_IN : in std_logic;\r
+ LINK_HALF_DONE_OUT : out std_logic;\r
+ LINK_FULL_DONE_OUT : out std_logic;\r
-- debug\r
DEBUG_OUT : out std_logic_vector(31 downto 0);\r
STAT_REG_OUT : out std_logic_vector(31 downto 0)\r
signal ce_idle0_ctr : std_logic;\r
signal rst_idle0_ctr : std_logic;\r
signal ctr_idle0 : unsigned(4 downto 0);\r
- signal idle0_detected : std_logic;\r
+ signal idle0_detected : std_logic; -- link_half_done\r
signal ce_idle1_ctr : std_logic;\r
signal rst_idle1_ctr : std_logic;\r
signal ctr_idle1 : unsigned(4 downto 0);\r
- signal idle1_detected : std_logic;\r
+ signal idle1_detected : std_logic; -- link_full_done\r
signal rst_link_state : std_logic;\r
\r
-- attribute syn_keep : boolean;\r
-- Syncing things\r
SYNC_RXI: signal_sync \r
generic map( \r
- WIDTH => 2,\r
+ WIDTH => 1,\r
DEPTH => 3\r
)\r
port map(\r
CLK0 => CLK_RXI, \r
CLK1 => CLK_RXI,\r
D_IN(0) => LINK_RX_READY_IN,\r
- D_IN(1) => LINK_FULL_DONE_IN,\r
- D_OUT(0) => link_rx_ready_qrx,\r
- D_OUT(1) => link_full_done_qrx\r
+ D_OUT(0) => link_rx_ready_qrx\r
);\r
\r
-- Syncing things\r
RESET => '0',\r
CLK0 => CLK_SYS, \r
CLK1 => CLK_SYS,\r
- D_IN(0) => LINK_FULL_DONE_IN,\r
+ D_IN(0) => idle1_detected,\r
D_OUT(0) => link_full_done_qsys\r
);\r
\r
\r
ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty;\r
\r
- ct_fifo_reset <= not link_full_done_qrx;\r
+ ct_fifo_reset <= not idle1_detected;\r
\r
----------------------------------------------------------------------\r
-- Read incoming data\r
RX_RST_OUT <= rx_rst_i when rising_edge(CLK_RXI);\r
RX_RST_WORD_OUT <= rx_rst_word_i when rising_edge(CLK_RXI);\r
\r
+ LINK_HALF_DONE_OUT <= idle0_detected;\r
+ LINK_FULL_DONE_OUT <= idle1_detected;\r
+\r
----------------------------------------------------------------------\r
-- Debug and Status\r
---------------------------------------------------------------------- \r
+++ /dev/null
-LIBRARY IEEE;\r
-USE IEEE.std_logic_1164.ALL;\r
-USE IEEE.numeric_std.all;\r
-\r
-library work;\r
-use work.med_sync_define_RS.all;\r
-\r
-entity rx_lsm_RS is\r
- port(\r
- LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low\r
- CLK_RXI : in std_logic; -- recovered RX clock\r
- RX_K_IN : in std_logic;\r
- RX_DATA_IN : in std_logic_vector(7 downto 0); \r
- LINK_HALF_DONE_OUT : out std_logic;\r
- LINK_FULL_DONE_OUT : out std_logic;\r
- STATE_OUT : out std_logic_vector(3 downto 0)\r
- );\r
-end entity;\r
-\r
-architecture rx_lsm_arch of rx_lsm_RS is\r
-\r
- type statetype is ( IDLE, KF, DFT, DFS );\r
-\r
- signal CURRENT_STATE : statetype; -- current state of lsm\r
- signal NEXT_STATE : statetype; -- next state of lsm\r
- \r
- signal reset_ctr_t : std_logic;\r
- signal ce_ctr_t : std_logic;\r
- signal ce_ctr_t_q : std_logic;\r
- signal ctr_t : unsigned(4 downto 0);\r
- signal ctr_t_done : std_logic;\r
- signal reset_ctr_s : std_logic;\r
- signal ce_ctr_s : std_logic;\r
- signal ce_ctr_s_q : std_logic;\r
- signal ctr_s : unsigned(4 downto 0);\r
- signal ctr_s_done : std_logic;\r
- signal link_toggling_int : std_logic;\r
- signal link_steady_int : std_logic;\r
- \r
-begin\r
-\r
- THE_CTR_T_PROC: process( CLK_RXI, LINK_RX_READY_IN ) \r
- begin\r
- if( LINK_RX_READY_IN = '0' ) then\r
- ctr_t <= (others => '0');\r
- elsif( rising_edge(CLK_RXI) ) then\r
- if( reset_ctr_t = '1' ) then\r
- ctr_t <= (others => '0');\r
- elsif( (ctr_t_done = '0') and (ce_ctr_t_q = '1') ) then\r
- ctr_t <= ctr_t + 1 ;\r
- end if;\r
- end if;\r
- end process THE_CTR_T_PROC;\r
-\r
- ctr_t_done <= ctr_t(4);\r
-\r
- THE_CTR_S_PROC: process( CLK_RXI, LINK_RX_READY_IN ) \r
- begin\r
- if( LINK_RX_READY_IN = '0' ) then\r
- ctr_s <= (others => '0');\r
- elsif( rising_edge(CLK_RXI) ) then\r
- if( reset_ctr_s = '1' ) then\r
- ctr_s <= (others => '0');\r
- 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\r
- ctr_s <= ctr_s + 1 ;\r
- end if;\r
- end if;\r
- end process THE_CTR_S_PROC;\r
-\r
- ctr_s_done <= ctr_s(4);\r
-\r
- -- toggling idles sequence detected\r
- THE_TOGGLE_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
- begin\r
- if( LINK_RX_READY_IN = '0' ) then\r
- link_toggling_int <= '0';\r
- elsif( rising_edge(CLK_RXI) ) then\r
- if( (ce_ctr_t_q = '1') and (ctr_t_done = '1') ) then\r
- link_toggling_int <= '1';\r
- end if; \r
- end if;\r
- end process THE_TOGGLE_DETECTED_PROC;\r
-\r
- LINK_HALF_DONE_OUT <= link_toggling_int;\r
-\r
- -- steady idles sequence detected\r
- THE_STEADY_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
- begin\r
- if( LINK_RX_READY_IN = '0' ) then\r
- link_steady_int <= '0';\r
- elsif( rising_edge(CLK_RXI) ) then\r
- if( (ce_ctr_s_q = '1') and (ctr_s_done = '1') ) then\r
- link_steady_int <= '1';\r
- end if; \r
- end if;\r
- end process THE_STEADY_DETECTED_PROC;\r
-\r
- LINK_FULL_DONE_OUT <= link_steady_int;\r
-\r
- -- State machine clocked process\r
- THE_FSM_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
- begin\r
- if( LINK_RX_READY_IN = '0' ) then\r
- CURRENT_STATE <= IDLE;\r
- ce_ctr_t_q <= '0';\r
- ce_ctr_s_q <= '0';\r
- elsif( rising_edge(CLK_RXI) ) then\r
- CURRENT_STATE <= NEXT_STATE;\r
- ce_ctr_t_q <= ce_ctr_t;\r
- ce_ctr_s_q <= ce_ctr_s;\r
- end if;\r
- end process THE_FSM_PROC;\r
-\r
- -- State machine decoding processs\r
- THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN )\r
- begin\r
- reset_ctr_t <= '0';\r
- reset_ctr_s <= '0';\r
- ce_ctr_t <= '0';\r
- ce_ctr_s <= '0';\r
- STATE_OUT <= x"F";\r
-\r
- case CURRENT_STATE is\r
-\r
- when IDLE =>\r
- STATE_OUT <= x"0";\r
- reset_ctr_t <= '1';\r
- reset_ctr_s <= '1';\r
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
- NEXT_STATE <= KF;\r
- else\r
- NEXT_STATE <= IDLE;\r
- end if;\r
-\r
- when KF =>\r
- STATE_OUT <= x"1";\r
- if ( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then\r
- NEXT_STATE <= DFS;\r
- ce_ctr_s <= '1';\r
- elsif( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE0) ) then\r
- NEXT_STATE <= DFT;\r
- ce_ctr_t <= '1';\r
- else\r
- NEXT_STATE <= IDLE;\r
- end if;\r
-\r
- when DFT =>\r
- STATE_OUT <= x"2";\r
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
- NEXT_STATE <= KF;\r
- else\r
- NEXT_STATE <= IDLE;\r
- end if;\r
-\r
- when DFS =>\r
- STATE_OUT <= x"3";\r
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
- NEXT_STATE <= KF;\r
- else\r
- NEXT_STATE <= IDLE;\r
- end if;\r
-\r
- when others =>\r
- STATE_OUT <= x"f";\r
- NEXT_STATE <= IDLE;\r
-\r
- end case;\r
-\r
- end process THE_FSM_DECODE_PROC;\r
-\r
-end architecture;\r
+++ /dev/null
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-USE IEEE.numeric_std.all;\r
-\r
-entity rx_rsl is\r
- port (\r
- CLEAR : in std_logic;\r
- CLK_REF : in std_logic;\r
- PLL_LOL_IN : in std_logic;\r
- CDR_LOL_IN : in std_logic;\r
- CV_IN : in std_logic;\r
- LSM_IN : in std_logic;\r
- LOS_IN : in std_logic;\r
- SD_LOS_IN : in std_logic;\r
- WAP_ZERO_IN : in std_logic;\r
- -- outputs\r
- RX_SERDES_RST_OUT : out std_logic;\r
- RX_PCS_RST_OUT : out std_logic;\r
- LINK_RX_READY_OUT : out std_logic;\r
- STATE_OUT : out std_logic_vector(3 downto 0)\r
- );\r
-end rx_rsl; \r
-\r
-architecture rx_rsl_arc of rx_rsl is\r
-\r
- attribute syn_keep : boolean;\r
-\r
--- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3.\r
--- Without this piece of code, many things would have been a real pain.\r
-\r
- constant Tshort : unsigned(31 downto 0) := x"0000000a";\r
--- @200MHz 100ms\r
- constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
- constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
- constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00"; \r
-\r
- signal pll_lol_s : std_logic;\r
- signal cdr_lol_s : std_logic;\r
- signal cv_s : std_logic;\r
- signal lsm_s : std_logic;\r
- signal los_s : std_logic;\r
- signal sd_los_s : std_logic;\r
-\r
- signal cnt : unsigned(31 downto 0);\r
-\r
- type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, \r
- APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, \r
- CHECK_WAP, NORMAL_OP);\r
-\r
- signal rx_sm : rx_sm_state;\r
- \r
- attribute syn_keep of rx_sm : signal is true;\r
-\r
-begin\r
-\r
--- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP.\r
--- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset.\r
--- Remark: syncing is done here by one FF only. Might be dangerous.\r
-\r
-------------------------------------------------------------------\r
-RX_RESET_PROC : process( CLEAR, CLK_REF )\r
-begin\r
- if( CLEAR = '1' ) then\r
- pll_lol_s <= '1';\r
- cdr_lol_s <= '1';\r
- cv_s <= '1';\r
- lsm_s <= '0';\r
- los_s <= '1';\r
- sd_los_s <= '1';\r
-\r
- RX_SERDES_RST_OUT <= '1';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- \r
- rx_sm <= powerup;\r
- STATE_OUT <= x"f";\r
- cnt <= (others => '0'); \r
- elsif( rising_edge(CLK_REF) ) then\r
- pll_lol_s <= PLL_LOL_IN;\r
- cdr_lol_s <= CDR_LOL_IN;\r
- cv_s <= CV_IN; \r
- lsm_s <= LSM_IN; \r
- los_s <= LOS_IN; \r
- sd_los_s <= SD_LOS_IN;\r
- \r
- case rx_sm is\r
- when POWERUP =>\r
- STATE_OUT <= x"0";\r
- RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
--- if( (pll_lol_s = '1') or (los_s = '1') or (sd_los_s = '1') ) then\r
- if( (pll_lol_s = '1') or (sd_los_s = '1') ) then\r
- cnt <= (others => '0');\r
- else\r
- if( cnt = Tplol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_CDR_RST;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
-\r
- when APPLY_CDR_RST =>\r
- STATE_OUT <= x"1";\r
- RX_SERDES_RST_OUT <= '1';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tshort ) then\r
- cnt <= (others => '0');\r
- rx_sm <= WAIT_CDR_LOCK;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
- \r
- when WAIT_CDR_LOCK =>\r
- STATE_OUT <= x"2";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tcdr ) then\r
- cnt <= (others => '0');\r
- rx_sm <= TEST_CDR;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when TEST_CDR =>\r
- STATE_OUT <= x"3";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cdr_lol_s = '1' ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_CDR_RST;\r
- else\r
- if( cnt = Tcdr ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_RXPCS_RST;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
-\r
- when APPLY_RXPCS_RST =>\r
- STATE_OUT <= x"4";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tshort ) then\r
- cnt <= (others => '0');\r
- rx_sm <= WAIT_RXPCS_LOCK;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when WAIT_RXPCS_LOCK =>\r
- STATE_OUT <= x"5";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tviol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= TEST_RXPCS;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when TEST_RXPCS =>\r
- STATE_OUT <= x"6";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- if( (lsm_s = '0') or (cv_s = '1') ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_RXPCS_RST;\r
- else\r
- if( cnt = Tviol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= CHECK_WAP;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
-\r
- when CHECK_WAP =>\r
- STATE_OUT <= x"7";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- cnt <= (others => '0');\r
- if( WAP_ZERO_IN = '1' ) then\r
- rx_sm <= NORMAL_OP;\r
- else\r
--- rx_sm <= APPLY_RXPCS_RST; -- DOESNT WORK\r
- rx_sm <= APPLY_CDR_RST;\r
- end if;\r
- \r
- when NORMAL_OP =>\r
- STATE_OUT <= x"8";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '1';\r
- cnt <= (others => '0');\r
- if( (lsm_s = '0') or (cv_s = '1') ) then\r
- rx_sm <= APPLY_RXPCS_RST; \r
- end if;\r
-\r
- when others =>\r
- -- just in case\r
- STATE_OUT <= x"f";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- rx_sm <= POWERUP;\r
-\r
- end case;\r
- \r
-------------------------------------------------\r
--- if (pll_lol_s = '1') or (los_s = '1') then\r
--- if( pll_lol_s = '1' ) then\r
- if( (pll_lol_s = '1') or (sd_los_s = '1') ) then\r
- rx_sm <= POWERUP; \r
- cnt <= (others => '0');\r
- end if;\r
-\r
- end if;\r
-end process rx_reset_proc;\r
-\r
-end rx_rsl_arc;\r
+++ /dev/null
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-USE IEEE.numeric_std.all;\r
-\r
-entity rx_rsl is\r
- port (\r
- CLEAR : in std_logic;\r
- CLK_REF : in std_logic;\r
- PLL_LOL_IN : in std_logic;\r
- CDR_LOL_IN : in std_logic;\r
- CV_IN : in std_logic;\r
- LSM_IN : in std_logic;\r
- LOS_IN : in std_logic;\r
- WAP_ZERO_IN : in std_logic;\r
- -- outputs\r
- RX_SERDES_RST_OUT : out std_logic;\r
- RX_PCS_RST_OUT : out std_logic;\r
- LINK_RX_READY_OUT : out std_logic;\r
- STATE_OUT : out std_logic_vector(3 downto 0)\r
- );\r
-end rx_rsl; \r
-\r
-architecture rx_rsl_arc of rx_rsl is\r
-\r
- attribute syn_keep : boolean;\r
-\r
--- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3.\r
--- Without this piece of code, many things would have been a real pain.\r
-\r
- constant Tshort : unsigned(31 downto 0) := x"0000000a";\r
--- @200MHz 100ms\r
- constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
- constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
- constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
-\r
- signal pll_lol_s : std_logic;\r
- signal cdr_lol_s : std_logic;\r
- signal cv_s : std_logic;\r
- signal lsm_s : std_logic;\r
- signal los_s : std_logic;\r
-\r
- signal cnt : unsigned(31 downto 0);\r
-\r
- type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, \r
- CHECK_WAP, APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, \r
- TEST_RXPCS, NORMAL_OP);\r
-\r
- signal rx_sm : rx_sm_state;\r
- \r
- attribute syn_keep of rx_sm : signal is true;\r
-\r
-begin\r
-\r
--- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP.\r
--- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset.\r
--- Remark: syncing is done here by one FF only. Might be dangerous.\r
-\r
-------------------------------------------------------------------\r
-RX_RESET_PROC : process( CLEAR, CLK_REF )\r
-begin\r
- if( CLEAR = '1' ) then\r
- pll_lol_s <= '1';\r
- cdr_lol_s <= '1';\r
- cv_s <= '1';\r
- lsm_s <= '0';\r
- los_s <= '1';\r
-\r
- RX_SERDES_RST_OUT <= '1';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- \r
- rx_sm <= powerup;\r
- STATE_OUT <= x"f";\r
- cnt <= (others => '0'); \r
- elsif( rising_edge(CLK_REF) ) then\r
- pll_lol_s <= PLL_LOL_IN;\r
- cdr_lol_s <= CDR_LOL_IN;\r
- cv_s <= CV_IN; \r
- lsm_s <= LSM_IN; \r
- los_s <= LOS_IN; \r
- \r
- case rx_sm is\r
- when POWERUP =>\r
- STATE_OUT <= x"0";\r
- RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( (pll_lol_s = '1') or (los_s = '1') ) then\r
- cnt <= (others => '0');\r
- else\r
- if( cnt = Tplol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_CDR_RST;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
-\r
- when APPLY_CDR_RST =>\r
- STATE_OUT <= x"1";\r
- RX_SERDES_RST_OUT <= '1';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tshort ) then\r
- cnt <= (others => '0');\r
- rx_sm <= WAIT_CDR_LOCK;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
- \r
- when WAIT_CDR_LOCK =>\r
- STATE_OUT <= x"2";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tcdr ) then\r
- cnt <= (others => '0');\r
- rx_sm <= TEST_CDR;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when TEST_CDR =>\r
- STATE_OUT <= x"3";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cdr_lol_s = '1' ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_CDR_RST;\r
- else\r
- if( cnt = Tcdr ) then\r
- cnt <= (others => '0');\r
- rx_sm <= CHECK_WAP;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
-\r
- -- THIS STATE CAN BE ASSIMILATED INTO TEST_CDR\r
- when CHECK_WAP => \r
- STATE_OUT <= x"4";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1'; -- really?\r
- LINK_RX_READY_OUT <= '0';\r
- cnt <= (others => '0');\r
- if( WAP_ZERO_IN = '1' ) then\r
- rx_sm <= NORMAL_OP;\r
- else\r
- rx_sm <= APPLY_CDR_RST;\r
- end if;\r
-\r
- when APPLY_RXPCS_RST =>\r
- STATE_OUT <= x"5";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '1';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tshort ) then\r
- cnt <= (others => '0');\r
- rx_sm <= WAIT_RXPCS_LOCK;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when WAIT_RXPCS_LOCK =>\r
- STATE_OUT <= x"6";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- if( cnt = Tviol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= TEST_RXPCS;\r
- else\r
- cnt <= cnt + 1; \r
- end if;\r
-\r
- when TEST_RXPCS =>\r
- STATE_OUT <= x"7";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- if( (lsm_s = '0') or (cv_s = '1') ) then\r
- cnt <= (others => '0');\r
- rx_sm <= APPLY_RXPCS_RST;\r
- else\r
- if( cnt = Tviol ) then\r
- cnt <= (others => '0');\r
- rx_sm <= NORMAL_OP;\r
- else\r
- cnt <= cnt + 1;\r
- end if;\r
- end if;\r
- \r
- when NORMAL_OP =>\r
- STATE_OUT <= x"8";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '1';\r
- cnt <= (others => '0');\r
- if( (lsm_s = '0') or (cv_s = '1') ) then\r
- rx_sm <= APPLY_RXPCS_RST; \r
- end if;\r
-\r
- when others =>\r
- -- just in case\r
- STATE_OUT <= x"f";\r
- RX_SERDES_RST_OUT <= '0';\r
- RX_PCS_RST_OUT <= '0';\r
- LINK_RX_READY_OUT <= '0';\r
- rx_sm <= POWERUP;\r
-\r
- end case;\r
- \r
-------------------------------------------------\r
--- if (pll_lol_s = '1') or (los_s = '1') then\r
- if( pll_lol_s = '1' ) then\r
- rx_sm <= POWERUP; \r
- cnt <= (others => '0');\r
- end if;\r
-\r
- end if;\r
-end process rx_reset_proc;\r
-\r
-end rx_rsl_arc;\r