]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
TRBnet reset works again with link re-establishment
authorMichael Boehmer <mboehmer@ph.tum.de>
Wed, 22 Dec 2021 08:41:53 +0000 (09:41 +0100)
committerMichael Boehmer <mboehmer@ph.tum.de>
Wed, 22 Dec 2021 08:41:53 +0000 (09:41 +0100)
media_interfaces/med_ecp3_sfp_sync_all_RS.vhd
special/trb_net_reset_handler.vhd

index b4d30b4874f8efb0075b30a11d65194f304a1770..0a8387a726729824a6bc99639eb4c94a87f36d29 100644 (file)
@@ -46,7 +46,7 @@ entity med_ecp3_sfp_sync_all_RS is
     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)
@@ -164,21 +164,25 @@ begin
 -------------------------------------------------
 -- 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';
 
 -------------------------------------------------      
index ed1e3da0ffb7743c1b2b722ad92642b89f8224db..c4213e51fe3d02038a3cc52e6f9343bf50097c55 100644 (file)
@@ -30,109 +30,110 @@ end entity;
 -- 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