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_rx_ready_qsys : std_logic;
RX_RST_WORD_OUT => RX_RST_WORD_OUT,
--
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_FULL_DONE_IN => link_full_done_i,
--
- DEBUG_OUT => DEBUG_RX_CONTROL,
+ 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,
);
-- TEST_LINE signals
- DEBUG_OUT(3 downto 0) <= rx_fsm_state;
- DEBUG_OUT(4) <= RX_LOS_IN;
- DEBUG_OUT(5) <= RX_CDR_LOL_IN;
- DEBUG_OUT(6) <= TX_PLL_LOL_IN;
- DEBUG_OUT(7) <= LINK_TX_READY_IN;
- DEBUG_OUT(8) <= link_rx_ready_i;
- DEBUG_OUT(9) <= is_wap_zero_i;
- DEBUG_OUT(10) <= link_half_done_i;
+ DEBUG_OUT(31 downto 12) <= (others => '0');
DEBUG_OUT(11) <= link_full_done_i;
- DEBUG_OUT(15 downto 12) <= debug_tx_control_i(3 downto 0);
- DEBUG_OUT(19 downto 16) <= rx_lsm_state;
- DEBUG_OUT(20) <= word_sync_rx_i;
- DEBUG_OUT(21) <= word_sync_tx_i;
- DEBUG_OUT(31 downto 22) <= (others => '0');
+ DEBUG_OUT(10) <= link_half_done_i;
+ DEBUG_OUT(9) <= '0';
+ DEBUG_OUT(8) <= link_rx_ready_qsys;
+ DEBUG_OUT(7) <= link_tx_ready_qsys;
+ DEBUG_OUT(6 downto 2) <= (others => '0');
+ DEBUG_OUT(1 downto 0) <= debug_rx_control_i(1 downto 0);
-- DEBUG_OUT <= (others => '0');
-- Some remarks on the SerDes issue:
RX_RST_OUT : out std_logic;\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; -- unused\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
-- debug\r
\r
architecture rx_control_arch of rx_control_RS is\r
\r
- type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, GET_RST);\r
+ type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, GET_RST,\r
+ GET_UNKNOWN);\r
\r
signal rx_state : rx_state_t;\r
signal rx_state_bits : std_logic_vector(3 downto 0);\r
signal link_full_done_qrx : std_logic;\r
signal link_full_done_qsys : std_logic;\r
\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 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 rst_link_state : std_logic;\r
+ \r
-- attribute syn_keep : boolean;\r
-- attribute syn_preserve : boolean; \r
--- attribute syn_keep of sync_k_i : signal is true;\r
--- attribute syn_preserve of sync_k_i : signal is true;\r
+-- attribute syn_noprune : boolean;\r
+-- attribute syn_keep of idle0_detected : signal is true;\r
+-- attribute syn_preserve of idle0_detected : signal is true;\r
+-- attribute syn_noprune of idle0_detected : signal is true;\r
+-- attribute syn_keep of idle1_detected : signal is true;\r
+-- attribute syn_preserve of idle1_detected : signal is true;\r
+-- attribute syn_noprune of idle1_detected : signal is true;\r
\r
begin\r
\r
ct_fifo_write <= '0';\r
rx_dlm_i <= '0';\r
rx_rst_i <= '0';\r
- sync_k_i <= '0'; \r
+ sync_k_i <= '0';\r
+ ce_idle0_ctr <= '0';\r
+ ce_idle1_ctr <= '0';\r
+ rst_idle0_ctr <= '0';\r
+ rst_idle1_ctr <= '0';\r
+ rst_link_state <= '0';\r
\r
case rx_state is\r
when SLEEP =>\r
+ -- we wait for a known IDLE komma\r
rx_state_bits <= x"1";\r
rx_data(7 downto 0) <= reg_rx_data_in;\r
+ rst_idle0_ctr <= '1';\r
+ rst_idle1_ctr <= '1';\r
+ rst_link_state <= '1';\r
if( (reg_rx_k_in = '1') and (reg_rx_data_in = K_IDLE) ) then\r
rx_state <= WAIT_1;\r
sync_k_i <= '1';\r
end if;\r
\r
when WAIT_1 =>\r
+ -- and skip the data byte\r
rx_state <= FIRST;\r
\r
when FIRST =>\r
rx_state <= GET_DLM;\r
when K_RST =>\r
rx_state <= GET_RST;\r
- when others => null;\r
+ when others =>\r
+ rx_state <= GET_UNKNOWN;\r
end case;\r
else\r
rx_state <= GET_DATA;\r
end if;\r
\r
- when GET_IDLE =>\r
+ when GET_UNKNOWN =>\r
rx_state_bits <= x"3";\r
rx_state <= FIRST;\r
+ \r
+ when GET_IDLE =>\r
+ rx_state_bits <= x"4";\r
+ rx_state <= FIRST;\r
next_sop <= '1';\r
+ case reg_rx_data_in is\r
+ when D_IDLE0 =>\r
+ -- first link establishment phase\r
+ ce_idle0_ctr <= '1';\r
+ rst_idle1_ctr <= '1';\r
+ when D_IDLE1 =>\r
+ -- second link establishment phase\r
+ ce_idle1_ctr <= '1';\r
+ rst_idle0_ctr <= '1';\r
+ when others =>\r
+ -- all other cases\r
+ rst_idle0_ctr <= '1';\r
+ rst_idle1_ctr <= '1';\r
+ end case;\r
\r
when GET_DATA =>\r
- rx_state_bits <= x"4";\r
- -- rx_state <= FIRST\r
- if reg_rx_k_in = '0' then\r
+ rx_state_bits <= x"5";\r
+ rx_state <= FIRST;\r
+ if reg_rx_k_in = '0' then\r
next_sop <= '0';\r
rx_data(15 downto 8)<= reg_rx_data_in;\r
rx_data(16) <= next_sop;\r
rx_data(17) <= '0';\r
ct_fifo_write <= '1';\r
- rx_state <= FIRST;\r
- else -- not needed?\r
- rx_state <= FIRST; -- not needed? \r
end if;\r
\r
when GET_DLM =>\r
- rx_state_bits <= x"5";\r
+ rx_state_bits <= x"6";\r
rx_dlm_i <= '1';\r
rx_dlm_word_i <= reg_rx_data_in;\r
rx_state <= FIRST;\r
\r
when GET_RST =>\r
- rx_state_bits <= x"6";\r
+ rx_state_bits <= x"7";\r
rx_rst_i <= '1';\r
rx_rst_word_i <= reg_rx_data_in;\r
rx_state <= FIRST;\r
reg_rx_data_in <= RX_DATA_IN when rising_edge(CLK_RXI);\r
reg_rx_k_in <= RX_K_IN when rising_edge(CLK_RXI);\r
\r
+-- Counter for link establishment\r
+ THE_CTR_IDLE0_PROC: process( CLK_RXI ) \r
+ begin\r
+ if( rising_edge(CLK_RXI) ) then\r
+ if ( rst_idle0_ctr = '1' ) then\r
+ ctr_idle0 <= (others => '0');\r
+ elsif( ce_idle0_ctr = '1' ) then\r
+ ctr_idle0 <= ctr_idle0 + 1 ;\r
+ end if;\r
+ end if;\r
+ end process THE_CTR_IDLE0_PROC;\r
+\r
+ THE_CTR_IDLE1_PROC: process( CLK_RXI ) \r
+ begin\r
+ if( rising_edge(CLK_RXI) ) then\r
+ if ( rst_idle1_ctr = '1' ) then\r
+ ctr_idle1 <= (others => '0');\r
+ elsif( ce_idle1_ctr = '1' ) then\r
+ ctr_idle1 <= ctr_idle1 + 1 ;\r
+ end if;\r
+ end if;\r
+ end process THE_CTR_IDLE1_PROC;\r
+\r
+-- IDLE detection for link establishment\r
+ THE_IDLE0_DETECTED_PROC: process( CLK_RXI )\r
+ begin\r
+ if( rising_edge(CLK_RXI) ) then\r
+ if ( rst_link_state = '1' ) then\r
+ idle0_detected <= '0';\r
+ elsif ( (ctr_idle0(ctr_idle0'left) = '1') and (ce_idle0_ctr = '1') ) then\r
+ idle0_detected <= '1';\r
+ end if;\r
+ end if;\r
+ end process THE_IDLE0_DETECTED_PROC;\r
+ \r
+ THE_IDLE1_DETECTED_PROC: process( CLK_RXI )\r
+ begin\r
+ if( rising_edge(CLK_RXI) ) then\r
+ if ( rst_link_state = '1' ) then\r
+ idle1_detected <= '0';\r
+ elsif ( (ctr_idle1(ctr_idle1'left) = '1') and (ce_idle1_ctr = '1') ) then\r
+ idle1_detected <= '1';\r
+ end if;\r
+ end if;\r
+ end process THE_IDLE1_DETECTED_PROC;\r
+ \r
----------------------------------------------------------------------\r
-- Signals out\r
---------------------------------------------------------------------- \r
STAT_REG_OUT(17) <= '0';\r
STAT_REG_OUT(31 downto 18) <= (others => '0');\r
\r
- DEBUG_OUT(3 downto 0) <= rx_state_bits;\r
- DEBUG_OUT(4) <= '0';\r
- DEBUG_OUT(5) <= ct_fifo_afull;\r
- DEBUG_OUT(6) <= ct_fifo_empty;\r
- DEBUG_OUT(7) <= ct_fifo_write;\r
- DEBUG_OUT(15 downto 8) <= rx_data(7 downto 0);\r
- DEBUG_OUT(16) <= reg_rx_k_in;\r
- DEBUG_OUT(17) <= '0';\r
- DEBUG_OUT(18) <= '0';\r
- DEBUG_OUT(19) <= '1' when rx_state_bits = x"f" else '0';\r
- --DEBUG_OUT(16) <= rx_data(16);\r
- DEBUG_OUT(31 downto 20) <= (others => '0');\r
- -- DEBUG_OUT(23 downto 16) <= rx_data(7 downto 0);\r
- -- DEBUG_OUT(31 downto 24) <= ct_fifo_data_out(7 downto 0);\r
+ DEBUG_OUT(0) <= idle0_detected when rising_edge(CLK_RXI);\r
+ DEBUG_OUT(1) <= idle1_detected when rising_edge(CLK_RXI);\r
+ DEBUG_OUT(31 downto 2) <= (others => '0');\r
\r
end architecture;\r
signal save_eop : std_logic;\r
signal load_sop : std_logic;\r
signal load_eop : std_logic;\r
- signal toggle_idle : std_logic;\r
signal send_steady_idle_int : std_logic;\r
signal word_sync_i : std_logic;\r
\r
-- TX control state machine\r
----------------------------------------------------------------------\r
\r
- THE_DATA_CONTROL_FSM : process(CLK_TXI, link_tx_ready_qtx, RESET)\r
+ THE_DATA_CONTROL_FSM : process(CLK_TXI, RESET)\r
begin\r
if( RESET = '1' ) then\r
current_state <= IDLE;\r
TX_K_OUT <= '1';\r
TX_DATA_OUT <= K_NULL;\r
word_sync_i <= '0';\r
- toggle_idle <= '1';\r
else \r
if( rising_edge(CLK_TXI) ) then\r
TX_K_OUT <= '0';\r
word_sync_i <= '0';\r
debug_sending_dlm <= '0';\r
debug_sending_rst <= '0';\r
+ \r
case current_state is\r
when IDLE =>\r
TX_K_OUT <= '1';\r
TX_DATA_OUT <= K_NULL;\r
word_sync_i <= '0';\r
- toggle_idle <= '1';\r
if( link_tx_ready_qtx = '1' ) then\r
current_state <= SEND_IDLE_L;\r
else\r
\r
when SEND_IDLE_H =>\r
word_sync_i <= '1';\r
- if( (send_steady_idle_int = '1') or (toggle_idle = '1') ) then\r
+ if( send_steady_idle_int = '1' ) then\r
TX_DATA_OUT <= D_IDLE1;\r
- toggle_idle <= send_steady_idle_int;\r
else\r
TX_DATA_OUT <= D_IDLE0;\r
- toggle_idle <= '1';\r
end if;\r
\r
when SEND_DATA_L =>\r
DEBUG_OUT(29) <= debug_sending_rst when rising_edge(CLK_TXI);\r
DEBUG_OUT(28 downto 6) <= (others => '0');\r
DEBUG_OUT(5) <= send_steady_idle_int when rising_edge(CLK_TXI);\r
- DEBUG_OUT(4) <= toggle_idle when rising_edge(CLK_TXI);\r
+ DEBUG_OUT(4) <= '0'; --toggle_idle when rising_edge(CLK_TXI);\r
DEBUG_OUT(3 downto 0) <= state_bits when rising_edge(CLK_TXI);\r
\r
process(CLK_SYS)\r