TX_CLK_AVAIL_OUT : out std_logic; -- stable RX recovered clock available
TX_PCS_RST_IN : in std_logic; -- TX PCS reset signal
SYNC_TX_PLL_IN : in std_logic; -- bit0 alignment for TX serializer
- LINK_TX_READY_IN : in std_logic; --
+ LINK_TX_READY_IN : in std_logic; -- from TX reset generator
DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- hard reset for links
--SFP Connection
SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted)
-------------------------------------------------
-- BUG: link_tx_ready(i) for master ports to be included
-- BUG: slave ports need also disable with link_tx_ready(i)
- SD_TXDIS_OUT(3) <= DESTROY_LINK_IN(3) or (not SLAVE_ACTIVE_IN) 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
+ 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) 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
+ 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) 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
+ 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) 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
+ 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';
-------------------------------------------------
-- It is not recommended to reset the system clock PLL/DLL with\r
-- any of the reset signals generated here. It may deadlock.\r
\r
+-- Usually 200M clock is used, so we have 5ns. To get a suitable time for link reset,\r
+-- more than 16bit counter is needed. \r
+-- With 200MHz and 20bit counter (19 bit effective), we get 2.6ms reset time, which\r
+-- should be sufficient to shut down the TX laser in SFP.\r
+\r
architecture behavioral of trb_net_reset_handler is\r
\r
--- normal signals\r
-signal async_sampler : std_logic_vector(7 downto 0); -- input shift register\r
-signal comb_async_pulse : std_logic;\r
-signal async_pulse : std_logic;\r
-signal reset_cnt : std_logic_vector(15 downto 0) := x"0000";\r
-signal debug : std_logic_vector(15 downto 0);\r
-signal reset : std_logic; -- DO NOT USE THIS SIGNAL!\r
-\r
-signal reset_buffer : std_logic; -- DO NOT USE THIS SIGNAL!\r
-signal trb_reset_buffer : std_logic; -- DO NOT USE THIS SIGNAL!\r
-signal reset_pulse : std_logic_vector(1 downto 0) := b"00";\r
-signal trb_reset_pulse : std_logic_vector(1 downto 0) := b"00";\r
-signal comb_async_rst_n : std_logic;\r
-signal final_reset : std_logic_vector(1 downto 0) := b"11"; -- DO NOT USE THIS SIGNAL!\r
-\r
-attribute syn_preserve : boolean;\r
-attribute syn_preserve of async_sampler : signal is true;\r
-attribute syn_preserve of async_pulse : signal is true;\r
-attribute syn_preserve of reset : signal is true;\r
-attribute syn_preserve of reset_cnt : signal is true;\r
-attribute syn_preserve of comb_async_rst_n : signal is true;\r
-\r
-attribute syn_hier : string;\r
-attribute syn_hier of behavioral : architecture is "firm";\r
+ -- normal signals\r
+ signal async_sampler : std_logic_vector(7 downto 0); -- input shift register\r
+ signal comb_async_pulse : std_logic;\r
+ signal async_pulse : std_logic;\r
+ signal reset_cnt : std_logic_vector(20 downto 0) := (others => '0');\r
+ signal debug : std_logic_vector(15 downto 0);\r
+ signal reset : std_logic; -- DO NOT USE THIS SIGNAL!\r
+\r
+ signal reset_buffer : std_logic; -- DO NOT USE THIS SIGNAL!\r
+ signal trb_reset_buffer : std_logic; -- DO NOT USE THIS SIGNAL!\r
+ signal reset_pulse : std_logic_vector(1 downto 0) := b"00";\r
+ signal trb_reset_pulse : std_logic_vector(1 downto 0) := b"00";\r
+ signal comb_async_rst_n : std_logic;\r
+ signal final_reset : std_logic_vector(1 downto 0) := b"11"; -- DO NOT USE THIS SIGNAL!\r
+\r
+ attribute syn_preserve : boolean;\r
+ attribute syn_preserve of async_sampler : signal is true;\r
+ attribute syn_preserve of async_pulse : signal is true;\r
+ attribute syn_preserve of reset : signal is true;\r
+ attribute syn_preserve of reset_cnt : signal is true;\r
+ attribute syn_preserve of comb_async_rst_n : signal is true;\r
+\r
+ attribute syn_hier : string;\r
+ attribute syn_hier of behavioral : architecture is "firm";\r
\r
begin\r
\r
----------------------------------------------------------------\r
-- Combine all async reset sources: CLR, /CLR, PLL_LOCK\r
----------------------------------------------------------------\r
-comb_async_rst_n <= not clear_in and clear_n_in and pll_locked_in;\r
+ comb_async_rst_n <= not clear_in and clear_n_in and pll_locked_in;\r
\r
----------------------------------------------------------------\r
-- sample the async reset line and react only on a long pulse\r
----------------------------------------------------------------\r
-THE_ASYNC_SAMPLER_PROC: process( clk_in )\r
-begin\r
- if( rising_edge(clk_in) ) then\r
- async_sampler(7 downto 0) <= async_sampler(6 downto 0) & comb_async_rst_n;\r
- async_pulse <= comb_async_pulse;\r
- end if;\r
-end process THE_ASYNC_SAMPLER_PROC;\r
+ THE_ASYNC_SAMPLER_PROC: process( clk_in )\r
+ begin\r
+ if( rising_edge(clk_in) ) then\r
+ async_sampler(7 downto 0) <= async_sampler(6 downto 0) & comb_async_rst_n;\r
+ async_pulse <= comb_async_pulse;\r
+ end if;\r
+ end process THE_ASYNC_SAMPLER_PROC;\r
\r
-- first two registers are clock domain transfer registers!\r
-comb_async_pulse <= '1' when ( async_sampler(7 downto 2) = b"0000_00" ) else '0';\r
+ comb_async_pulse <= '1' when ( async_sampler(7 downto 2) = b"0000_00" ) else '0';\r
\r
----------------------------------------------------------------\r
-- Sync the signals from SYSCLK to raw clock domain and back\r
----------------------------------------------------------------\r
-THE_SYNC_PROC: process( sysclk_in )\r
-begin\r
- if( rising_edge(sysclk_in) ) then\r
- reset_buffer <= RESET_IN; -- not really needed, but relaxes timing\r
- trb_reset_buffer <= TRB_RESET_IN; -- not really needed, but relaxes timing\r
- final_reset <= final_reset(0) & reset;\r
- end if;\r
-end process THE_SYNC_PROC;\r
-\r
-THE_CROSSING_PROC: process( clk_in )\r
-begin\r
- if( rising_edge(clk_in) ) then\r
- reset_pulse <= reset_pulse(0) & reset_buffer;\r
- trb_reset_pulse <= trb_reset_pulse(0) & trb_reset_buffer;\r
- end if;\r
-end process THE_CROSSING_PROC;\r
+ THE_SYNC_PROC: process( sysclk_in )\r
+ begin\r
+ if( rising_edge(sysclk_in) ) then\r
+ reset_buffer <= RESET_IN; -- not really needed, but relaxes timing\r
+ trb_reset_buffer <= TRB_RESET_IN; -- not really needed, but relaxes timing\r
+ final_reset <= final_reset(0) & reset;\r
+ end if;\r
+ end process THE_SYNC_PROC;\r
+\r
+ THE_CROSSING_PROC: process( clk_in )\r
+ begin\r
+ if( rising_edge(clk_in) ) then\r
+ reset_pulse <= reset_pulse(0) & reset_buffer;\r
+ trb_reset_pulse <= trb_reset_pulse(0) & trb_reset_buffer;\r
+ end if;\r
+ end process THE_CROSSING_PROC;\r
\r
----------------------------------------------------------------\r
-- one global reset counter\r
----------------------------------------------------------------\r
-THE_GLOBAL_RESET_PROC: process( clk_in )\r
-begin\r
- if( rising_edge(clk_in) ) then\r
- if( (async_pulse = '1') or (reset_pulse(1) = '1') or (trb_reset_pulse(1) = '1') ) then\r
- reset_cnt <= (others => '0');\r
- reset <= '1';\r
- else\r
- reset_cnt <= reset_cnt + 1;\r
- reset <= '1';\r
- if( reset_cnt = RESET_DELAY ) then\r
- reset <= '0';\r
- reset_cnt <= RESET_DELAY;\r
+ THE_GLOBAL_RESET_PROC: process( clk_in )\r
+ begin\r
+ if( rising_edge(clk_in) ) then\r
+ if( (async_pulse = '1') or (reset_pulse(1) = '1') or (trb_reset_pulse(1) = '1') ) then\r
+ reset_cnt <= (others => '0');\r
+ elsif( reset_cnt(reset_cnt'left) = '0' ) then\r
+ reset_cnt <= reset_cnt + 1;\r
end if;\r
end if;\r
- end if;\r
-end process THE_GLOBAL_RESET_PROC;\r
+ end process THE_GLOBAL_RESET_PROC;\r
\r
+ reset <= not reset_cnt(reset_cnt'left);\r
+ \r
----------------------------------------------------------------\r
-- Debug signals\r
----------------------------------------------------------------\r
-debug(15 downto 11) <= (others => '0');\r
-debug(10) <= reset;\r
-debug(9) <= '0';\r
-debug(8 downto 7) <= final_reset;\r
-debug(6) <= async_pulse;\r
-debug(5 downto 0) <= reset_cnt(5 downto 0);\r
+ debug(15 downto 11) <= (others => '0');\r
+ debug(10) <= reset;\r
+ debug(9) <= '0';\r
+ debug(8 downto 7) <= final_reset;\r
+ debug(6) <= async_pulse;\r
+ debug(5 downto 0) <= reset_cnt(5 downto 0);\r
\r
----------------------------------------------------------------\r
-- Output signals\r
----------------------------------------------------------------\r
-DEBUG_OUT <= debug;\r
-CLEAR_OUT <= not comb_async_rst_n;\r
-RESET_OUT <= final_reset(1);\r
+ DEBUG_OUT <= debug;\r
+ CLEAR_OUT <= not comb_async_rst_n;\r
+ RESET_OUT <= final_reset(1);\r
\r
end behavioral;\r