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)
QUAD_RST_IN : in std_logic; -- HANDLE WITH CARE
- GLOBAL_RESET_OUT : out std_logic; -- only available on MI with slave port
+ LINK_TX_NULL_IN : in std_logic; --
+ LINK_RX_NULL_OUT : out std_logic; --
SLAVE_ACTIVE_OUT : out std_logic; -- for delaying MPs in hub
- SLAVE_ACTIVE_IN : in std_logic; -- set to '1' on normal endpoints
- TX_PLL_LOL_IN : in std_logic; -- and'ed TX PLL LOL to sync startup
TX_PLL_LOL_OUT : out std_logic; -- status signal of TX PLL
TX_CLK_AVAIL_OUT : out std_logic; -- stable RX recovered clock available
TX_PCS_RST_IN : in std_logic; -- TX PCS reset signal
signal rx_rst_i : std_logic_vector(3 downto 0);
signal rx_dlm_i : std_logic_vector(3 downto 0);
- signal global_reset_i : std_logic_vector(3 downto 0);
-
signal pll_lol_i : std_logic;
signal link_rx_ready_i : std_logic_vector(3 downto 0);
- signal tx_clk_avail_sel : std_logic;
-
+
+ signal link_rx_null_i : std_logic_vector(3 downto 0);
+ signal link_tx_null_i : std_logic_vector(3 downto 0);
+
signal word_sync_i : std_logic_vector(3 downto 0);
signal word_sync_sel : std_logic;
-------------------------------------------------
-- SFPs are disabled on unused SerDes channels
-------------------------------------------------
--- BUG: slave ports need also disable with link_tx_ready(i)
- SD_TXDIS_OUT(3) <= DESTROY_LINK_IN(3) or (not SLAVE_ACTIVE_IN) --or RESET
- when IS_MODE(3) = c_IS_MASTER else
- not link_rx_ready_i(3) when IS_MODE(3) = c_IS_SLAVE else
- '1' when IS_MODE(3) = c_IS_UNUSED else
- '0';
- SD_TXDIS_OUT(2) <= DESTROY_LINK_IN(2) or (not SLAVE_ACTIVE_IN) --or RESET
- when IS_MODE(2) = c_IS_MASTER else
- not link_rx_ready_i(2) when IS_MODE(2) = c_IS_SLAVE else
- '1' when IS_MODE(2) = c_IS_UNUSED else
- '0';
- SD_TXDIS_OUT(1) <= DESTROY_LINK_IN(1) or (not SLAVE_ACTIVE_IN) --or RESET
- when IS_MODE(1) = c_IS_MASTER else
- not link_rx_ready_i(1) when IS_MODE(1) = c_IS_SLAVE else
- '1' when IS_MODE(1) = c_IS_UNUSED else
- '0';
- SD_TXDIS_OUT(0) <= DESTROY_LINK_IN(0) or (not SLAVE_ACTIVE_IN) --or RESET
- when IS_MODE(0) = c_IS_MASTER else
- not link_rx_ready_i(0) when IS_MODE(0) = c_IS_SLAVE else
- '1' when IS_MODE(0) = c_IS_UNUSED else
- '0';
-
--------------------------------------------------
+ SD_TXDIS_OUT(3) <= '1' when (IS_MODE(3) = c_IS_UNUSED) else '0';
+ SD_TXDIS_OUT(2) <= '1' when (IS_MODE(2) = c_IS_UNUSED) else '0';
+ SD_TXDIS_OUT(1) <= '1' when (IS_MODE(1) = c_IS_UNUSED) else '0';
+ SD_TXDIS_OUT(0) <= '1' when (IS_MODE(0) = c_IS_UNUSED) else '0';
+
+-------------------------------------------------
-- TX ref clock
-- output only if a slave port is available in QUAD
--------------------------------------------------
+-------------------------------------------------
MASTER_CLK_OUT <= clk_rx_full(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
clk_rx_full(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
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';
--------------------------------------------------
+-------------------------------------------------
-- global reset
-- output only if a slave port is available in QUAD
--------------------------------------------------
- GLOBAL_RESET_OUT <= global_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
- global_reset_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
- global_reset_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
- global_reset_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
+-------------------------------------------------
+ LINK_RX_NULL_OUT <= link_rx_null_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
+ link_rx_null_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
+ link_rx_null_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
+ link_rx_null_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
'0';
+ link_tx_null_i(3) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(3)) when (IS_MODE(3) = c_IS_MASTER) else '0';
+ link_tx_null_i(2) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(2)) when (IS_MODE(2) = c_IS_MASTER) else '0';
+ link_tx_null_i(1) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(1)) when (IS_MODE(1) = c_IS_MASTER) else '0';
+ link_tx_null_i(0) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(0)) when (IS_MODE(0) = c_IS_MASTER) else '0';
+
-------------------------------------------------
-- stable RX recovered clock available
-------------------------------------------------
- tx_clk_avail_sel <= link_rx_ready_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
+ TX_CLK_AVAIL_OUT <= link_rx_ready_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
link_rx_ready_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
link_rx_ready_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
link_rx_ready_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
'1';
- TX_CLK_AVAIL_OUT <= tx_clk_avail_sel;
-
-------------------------------------------------
--
-------------------------------------------------
RX_LOS_IN => rx_los_low(i),
RX_CV_IN => rx_error(i),
RX_LSM_IN => lsm_status(i),
- TX_PLL_LOL_IN => TX_PLL_LOL_IN,
WA_POSITION_IN => wa_position_i(i*4+3 downto i*4),
WAP_REQUESTED_IN => wap_requested_i(i*4+3 downto i*4),
WAP_REQ_OUT => wap_req_i(i),
-- ports for synchronous operation
WORD_SYNC_IN => WORD_SYNC_IN,
WORD_SYNC_OUT => word_sync_i(i),
- GLOBAL_RESET_OUT => global_reset_i(i),
LINK_TX_READY_IN => LINK_TX_READY_IN,
LINK_RX_READY_OUT => link_rx_ready_i(i),
LINK_ACTIVE_OUT => link_active_i(i),
+ LINK_RX_NULL_OUT => link_rx_null_i(i),
+ LINK_TX_NULL_IN => link_tx_null_i(i),
-- komma operation
TX_DLM_IN => TX_DLM_IN,
TX_DLM_WORD_IN => TX_DLM_WORD_IN,
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
WAP_REQ_OUT : out std_logic;\r
constant Tcdr_bit : integer := 22;\r
constant Tviol_bit : integer := 22;\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
signal wap_zero_s : std_logic;\r
\r
signal cnt : unsigned(31 downto 0);\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
wap_zero_s <= '0';\r
\r
RX_SERDES_RST_OUT <= '1';\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
wap_zero_s <= WAP_ZERO_IN;\r
\r
case rx_sm is\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
+ if( (los_s = '1') ) then -- seems to work\r
cnt <= (others => '0');\r
else\r
if( cnt(Tplol_bit) = '1' ) then\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
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( cdr_lol_s = '1' ) then\r
cnt <= (others => '0');\r
rx_sm <= APPLY_CDR_RST;\r
else\r
RX_SERDES_RST_OUT <= '0';\r
RX_PCS_RST_OUT <= '1';\r
LINK_RX_READY_OUT <= '0';\r
- if( cnt(Tshort_bit) = '1' ) then\r
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( cnt(Tshort_bit) = '1' ) then\r
cnt <= (others => '0');\r
rx_sm <= WAIT_RXPCS_LOCK;\r
else\r
RX_SERDES_RST_OUT <= '0';\r
RX_PCS_RST_OUT <= '0';\r
LINK_RX_READY_OUT <= '0';\r
- if( cnt(Tviol_bit) = '1' ) then\r
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( cnt(Tviol_bit) = '1' ) then\r
cnt <= (others => '0');\r
rx_sm <= TEST_RXPCS;\r
else\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
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( (lsm_s = '0') or (cv_s = '1') ) then\r
cnt <= (others => '0');\r
rx_sm <= APPLY_RXPCS_RST;\r
else\r
RX_PCS_RST_OUT <= '0';\r
LINK_RX_READY_OUT <= '0';\r
cnt <= (others => '0');\r
- if( cnt(Tshort_bit) = '1' ) then\r
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( cnt(Tshort_bit) = '1' ) then\r
cnt <= (others => '0');\r
if( wap_zero_s = '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
else\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 -- DANGEROUS\r
+ if ( los_s = '1' ) then\r
+ rx_sm <= POWERUP; \r
+ cnt <= (others => '0');\r
+ elsif( (lsm_s = '0') or (cv_s = '1') ) then -- DANGEROUS\r
rx_sm <= APPLY_RXPCS_RST; \r
end if;\r
\r
cnt <= (others => '0');\r
\r
end case;\r
- \r
-------------------------------------------------\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
--- WAP_REQ_OUT <= '1' when ((rx_sm = WAIT_RXPCS_LOCK) or (rx_sm = TEST_RXPCS)) else '0';\r
WAP_REQ_OUT <= '1' when ((rx_sm = TEST_RXPCS)) else '0';\r
\r
end architecture;\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
TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D\r
- TX_PLL_LOL_OUT : out std_logic; -- wired'or for RX state machines\r
TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)\r
TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
tx_pll_lol_all <= TX_PLL_LOL_QD_A_IN or TX_PLL_LOL_QD_B_IN or\r
TX_PLL_LOL_QD_C_IN or TX_PLL_LOL_QD_D_IN;\r
\r
- \r
- TX_PLL_LOL_OUT <= tx_pll_lol_all;\r
- \r
-- synchronize, just to be on the safe side\r
SYNC_SFP_SIGS : entity work.signal_sync\r
generic map(\r
D_OUT(1) => tx_clock_avail_q\r
);\r
\r
-\r
-- Timer\r
THE_TIMER_PROC: process( CLK_REF )\r
begin\r
\r
timer <= counter(count_index);\r
\r
-\r
-- State machine clocked process\r
THE_FSM_PROC: process( CLK_REF, CLEAR )\r
begin\r
when WAIT_FOR_TIMER =>\r
STATE_OUT <= x"2";\r
tx_pcs_rst_ch_c_int <= '1';\r
- if( timer = '1' ) then\r
+ if( (timer = '1') and (tx_pll_lol_all_q = '0') ) then\r
NEXT_STATE <= SYNC_ALL;\r
else\r
NEXT_STATE <= WAIT_FOR_TIMER;\r
RX_LOS_IN : in std_logic; -- SerDes RX input signal status
RX_CV_IN : in std_logic; -- SerDes RX CodeViolation status
RX_LSM_IN : in std_logic; -- SerDes TX LinkStateMachine status
- TX_PLL_LOL_IN : in std_logic; -- wired'or from all QUADs
WA_POSITION_IN : in std_logic_vector(3 downto 0); -- WordAlignment Position
WAP_REQUESTED_IN : in std_logic_vector(3 downto 0); -- TESTTESTTEST
WAP_REQ_OUT : out std_logic;
-- ports for synchronous operation
WORD_SYNC_IN : in std_logic; -- sync signal for Byte/Word Alignment
WORD_SYNC_OUT : out std_logic;
- GLOBAL_RESET_OUT : out std_logic; -- global reset from slave port
LINK_TX_READY_IN : in std_logic; --
LINK_RX_READY_OUT : out std_logic; --
LINK_ACTIVE_OUT : out std_logic; --
+ LINK_RX_NULL_OUT : out std_logic;
+ LINK_TX_NULL_IN : in std_logic;
-- komma handling
TX_DLM_IN : in std_logic; -- transmit one DLM komma
TX_DLM_WORD_IN : in std_logic_vector(7 downto 0);
signal link_active_i : std_logic;
signal link_active_qref : std_logic;
signal link_active_qsys : std_logic;
+ signal link_rx_null_i : std_logic;
+ signal link_rx_null_qref : std_logic;
-- attribute syn_keep : boolean;
-- attribute syn_preserve : boolean;
-- Reset signals
-------------------------------------------------
--- we use uplink signal detection as global reset (slave port)
--- doesn't make sense to start while no link partner is available
- GLOBAL_RESET_OUT <= SFP_LOS_IN;
-
-- TX_CONTROL and RX_CONTROL reset
reset_i <= RESET;
port map(
CLEAR => '0',
CLK_REF => CLK_REF,
- PLL_LOL_IN => TX_PLL_LOL_IN,
CDR_LOL_IN => RX_CDR_LOL_IN,
CV_IN => RX_CV_IN,
LSM_IN => RX_LSM_IN,
LOS_IN => RX_LOS_IN,
- SD_LOS_IN => SFP_LOS_IN,
WAP_ZERO_IN => is_wap_zero_i,
-- outputs
WAP_REQ_OUT => WAP_REQ_OUT,
port map(
CLK_RXI => CLK_RXI,
CLK_SYS => CLK_SYS,
- RESET => reset_i,
+ RESET => '0', --reset_i,
--
RX_DATA_OUT => media_med2int_i.data,
RX_PACKET_NUMBER_OUT => media_med2int_i.packet_num,
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
+ LINK_RX_NULL_OUT => link_rx_null_i, -- CLK_RXI based
--
DEBUG_OUT => debug_rx_control_i,
STAT_REG_OUT => STAT_RX_CONTROL
port map(
CLK_TXI => CLK_TXI,
CLK_SYS => CLK_SYS,
- RESET => reset_i,
+ RESET => '0', --reset_i,
-- Media Interface
TX_DATA_IN => MEDIA_INT2MED.data,
TX_PACKET_NUMBER_IN => MEDIA_INT2MED.packet_num,
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
+ LINK_TX_NULL_IN => LINK_TX_NULL_IN,
-- debug
DEBUG_OUT => debug_tx_control_i,
STAT_REG_OUT => STAT_TX_CONTROL
SYNC_LA_SIGS : entity work.signal_sync
generic map(
- WIDTH => 1,
+ WIDTH => 2,
DEPTH => 3
)
port map(
CLK0 => CLK_REF,
CLK1 => CLK_REF,
D_IN(0) => link_active_i,
- D_OUT(0) => link_active_qref
+ D_IN(1) => link_rx_null_i,
+ D_OUT(0) => link_active_qref,
+ D_OUT(1) => link_rx_null_qref
);
- LINK_ACTIVE_OUT <= link_active_qref;
-
+ LINK_ACTIVE_OUT <= link_active_qref;
+ LINK_RX_NULL_OUT <= link_rx_null_qref;
+
-- TEST_LINE signals
-- DEBUG_OUT(31 downto 12) <= (others => '0');
-- DEBUG_OUT(11) <= link_full_done_qsys;
TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B\r
TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C\r
TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D\r
- TX_PLL_LOL_OUT : out std_logic; -- wired'or for RX state machines\r
TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)\r
TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
LINK_RX_READY_IN : in std_logic;\r
LINK_HALF_DONE_OUT : out std_logic;\r
LINK_FULL_DONE_OUT : out std_logic;\r
+ LINK_RX_NULL_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
LINK_RX_READY_IN : in std_logic; -- local ref clock\r
LINK_HALF_DONE_IN : in std_logic; -- recovered RX clock\r
LINK_FULL_DONE_IN : in std_logic; -- recovered RX clock\r
+ LINK_TX_NULL_IN : in 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
LINK_RX_READY_IN : in std_logic; -- used for synchronous reset\r
LINK_HALF_DONE_OUT : out std_logic;\r
LINK_FULL_DONE_OUT : out std_logic;\r
+ LINK_RX_NULL_OUT : out std_logic; -- link received K_NULL\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
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, GET_NULL,\r
GET_UNKNOWN);\r
\r
signal rx_state : rx_state_t;\r
attribute syn_noprune : boolean;\r
attribute syn_noprune of rx_dlm_i : signal is true;\r
\r
- -- attribute syn_keep : boolean;\r
--- attribute syn_preserve : boolean; \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
-- Syncing things\r
rx_state <= GET_DLM;\r
when K_RST =>\r
rx_state <= GET_RST;\r
+ when K_NULL =>\r
+ rx_state <= GET_NULL;\r
when others =>\r
rx_state <= GET_UNKNOWN;\r
end case;\r
rx_rst_i <= '1';\r
rx_rst_word_i <= reg_rx_data_in;\r
rx_state <= FIRST;\r
- \r
+\r
+ -- QUICK HACK\r
+ when GET_NULL =>\r
+ rx_state_bits <= x"8";\r
+ if( (reg_rx_k_in = '1') and (reg_rx_data_in = K_NULL) ) then\r
+ rx_state <= SLEEP;\r
+ else\r
+ rx_state <= FIRST;\r
+ end if;\r
+ \r
end case;\r
\r
-- BUG: master ports don't reset correctly\r
if( (RESET = '1') or (link_rx_ready_qrx = '0') ) then\r
--- if( (RESET = '1') ) then\r
rx_state <= SLEEP;\r
rx_dlm_word_i <= x"00";\r
rx_rst_word_i <= x"00";\r
\r
LINK_HALF_DONE_OUT <= idle0_detected;\r
LINK_FULL_DONE_OUT <= idle1_detected;\r
-\r
+ LINK_RX_NULL_OUT <= rst_link_state;\r
+ \r
----------------------------------------------------------------------\r
-- Debug and Status\r
---------------------------------------------------------------------- \r
LINK_RX_READY_IN : in std_logic; -- local ref clock\r
LINK_HALF_DONE_IN : in std_logic; -- recovered RX clock\r
LINK_FULL_DONE_IN : in std_logic; -- recovered RX clock\r
+ LINK_TX_NULL_IN : in 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 link_active_int : std_logic;\r
signal link_active_qtx : std_logic;\r
signal link_active_qsys : std_logic;\r
+ signal link_tx_null_qtx : std_logic;\r
\r
signal tx_k_i : std_logic;\r
signal tx_data_i : std_logic_vector(7 downto 0);\r
\r
--- attribute syn_keep : boolean;\r
--- attribute syn_preserve : boolean; \r
--- attribute syn_keep of word_sync_i : signal is true;\r
--- attribute syn_preserve of word_sync_i : signal is true;\r
-\r
begin\r
\r
-- Sync\r
SYNC_STATUS_SIGS : entity work.signal_sync \r
generic map( \r
- WIDTH => 4,\r
+ WIDTH => 5,\r
DEPTH => 3\r
)\r
port map(\r
D_IN(1) => LINK_RX_READY_IN,\r
D_IN(2) => LINK_HALF_DONE_IN,\r
D_IN(3) => LINK_FULL_DONE_IN,\r
+ D_IN(4) => LINK_TX_NULL_IN,\r
D_OUT(0) => link_tx_ready_qtx,\r
D_OUT(1) => link_rx_ready_qtx,\r
D_OUT(2) => link_half_done_qtx,\r
- D_OUT(3) => link_full_done_qtx\r
+ D_OUT(3) => link_full_done_qtx,\r
+ D_OUT(4) => link_tx_null_qtx \r
);\r
\r
-- Payload is only allowed on fully active links\r
when IDLE =>\r
tx_k_i <= '1';\r
tx_data_i <= K_NULL;\r
--- word_sync_i <= '0';\r
- if( link_tx_ready_qtx = '1' ) then\r
+ if( (link_tx_ready_qtx = '1') and (link_tx_null_qtx = '0') ) then\r
current_state <= SEND_IDLE_L;\r
else\r
current_state <= IDLE;\r
\r
if( (current_state = SEND_IDLE_H) or (current_state = SEND_DATA_H) or\r
(current_state = SEND_DLM_H) or (current_state = SEND_RST_H) ) then\r
--- if ( link_active_qtx = '0' ) then\r
--- current_state <= SEND_IDLE_L;\r
- if ( link_tx_ready_qtx = '0' ) then\r
- current_state <= IDLE; -- stay in reset until TX is possible\r
+ if ( (link_tx_ready_qtx = '0') or (link_tx_null_qtx = '1') ) then\r
+ current_state <= IDLE;\r
elsif( send_dlm_i = '1' ) then\r
current_state <= SEND_DLM_L;\r
elsif( send_rst_i = '1' ) then\r
send_dlm_i <= SEND_DLM_IN when rising_edge(CLK_TXI);\r
send_dlm_word_i <= SEND_DLM_WORD_IN when rising_edge(CLK_TXI);\r
\r
---Send DLM message\r
--- THE_STORE_DLM_PROC: process( CLK_TXI, RESET )\r
--- begin\r
--- if( RESET = '1' ) then\r
--- send_dlm_i <= '0';\r
--- send_dlm_word_i <= (others => '0');\r
--- elsif( rising_edge(CLK_TXI) ) then\r
--- if ( link_active_qtx = '0' ) then\r
--- send_dlm_i <= '0';\r
--- send_dlm_word_i <= (others => '0');\r
--- elsif( SEND_DLM_IN = '1' ) then\r
--- send_dlm_i <= '1';\r
--- send_dlm_word_i <= SEND_DLM_WORD_IN;\r
--- elsif( current_state = SEND_DLM_L ) then\r
--- send_dlm_i <= '0';\r
--- elsif( current_state = SEND_DLM_H ) then\r
--- send_dlm_word_i <= (others => '0');\r
--- end if;\r
--- end if;\r
--- end process THE_STORE_DLM_PROC;\r
-\r
-- Send RST message\r
-- UNTESTED\r
THE_STORE_RST_PROC: process( CLK_TXI, RESET )\r