]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
progress. reset handling can be considered a pain in the ass, again.
authorMichael Boehmer <mboehmer@ph.tum.de>
Thu, 2 Dec 2021 14:18:58 +0000 (15:18 +0100)
committerMichael Boehmer <mboehmer@ph.tum.de>
Thu, 2 Dec 2021 14:18:58 +0000 (15:18 +0100)
media_interfaces/med_ecp3_sfp_sync_all_RS.vhd
media_interfaces/sync/med_sync_control_RS.vhd
media_interfaces/sync/med_sync_define_RS.vhd
media_interfaces/sync/rx_rsl.vhd [new file with mode: 0644]

index 063dff92dc23fdf2f7f20bcdcef49255cae63163..00657765b78305a7d6ade8c71a71e90df3f734eb 100644 (file)
@@ -11,6 +11,7 @@ use work.med_sync_define_RS.all;
 
 entity med_ecp3_sfp_sync_all_RS is
   generic(
+    SERDES_NUM         : integer := 3;
     SIM_MODE           : integer := 0;
     IS_MODE            : int_array_t(0 to 3) := (c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED, c_IS_UNUSED);
     IS_WAP_ZERO        : integer := 1
@@ -132,6 +133,7 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is
   signal tx_reset_i         : std_logic_vector(3 downto 0);
 
   signal master_reset_sel   : std_logic;
+  signal pll_lol_i          : std_logic;
   
   signal quad_mode : integer range 0 to 100;
 
@@ -154,7 +156,7 @@ begin
   assert not ((quad_mode >= 1) and (quad_mode <= 4))   report "Note: QUAD with only master ports detected" severity note;
   assert not (quad_mode = 8)                           report "Note: QUAD with one slave port detected" severity note;
   assert not ((quad_mode >= 9) and (quad_mode <= 11))  report "Note: mixed master/slave QUAD detected" severity note;
-
+  
 -------------------------------------------------      
 -- only used SerDes are activated
 -------------------------------------------------      
@@ -227,6 +229,7 @@ begin
 -------------------------------------------------      
 -- Serdes
 -------------------------------------------------      
+  gen_pcs3: if SERDES_NUM = 3 generate 
   THE_SERDES : entity work.serdes_sync_all_RS
     port map(
       hdinp_ch0            => hdinp(0),
@@ -366,13 +369,15 @@ begin
       
       fpga_txrefclk        => MASTER_CLK_IN, -- reference TX clock
       tx_serdes_rst_c      => '0',
-      tx_pll_lol_qd_s      => TX_PLL_LOL_OUT,
+      tx_pll_lol_qd_s      => pll_lol_i,
       rst_qd_c             => master_reset_sel, --RST_QUAD_IN, -- deadlock caused by this...
       serdes_rst_qd_c      => '0', -- was wrong
       tx_sync_qd_c         => SYNC_TX_PLL_IN
     );
-
-
+  end generate;
+  
+  TX_PLL_LOL_OUT <= '1';
+  
 gen_control : for i in 0 to 3 generate   
   gen_used_control : if (IS_MODE(i) = c_IS_SLAVE) or (IS_MODE(i) = c_IS_MASTER) generate
     THE_MED_CONTROL : entity work.med_sync_control_RS
@@ -397,6 +402,9 @@ gen_control : for i in 0 to 3 generate
         SFP_LOS_IN         => SD_LOS_IN(i),
         RX_CDR_LOL_IN      => rx_cdr_lol(i),
         RX_LOS_IN          => rx_los_low(i),
+        CV_IN              => rx_error(i),
+        LSM_IN             => lsm_status(i),
+        PLL_LOL_IN         => pll_lol_i,
         WA_POSITION_IN     => wa_position(i*4+3 downto i*4),
         LINK_TX_READY_IN   => LINK_TX_READY_IN,
         -- control signals to SerDes
@@ -477,6 +485,9 @@ end generate;
   STAT_DEBUG(63 downto 0)  <= (others => '0');
   
   DEBUG_OUT <= debug_i(3*32+31 downto 3*32);
+--  DEBUG_OUT(11 downto 0)  <= debug_i(3*32+11 downto 3*32);
+--  DEBUG_OUT(15 downto 12) <= rx_los_low;
+--  DEBUG_OUT(31 downto 16) <= debug_i(3*32+31 downto 3*32+16);
   
 end architecture;
 
index e94cb388d76e02f3973df316e42461579b3c4a2c..92b1299503669bea0fc17eb7dc6018d116312192 100644 (file)
@@ -29,6 +29,9 @@ entity med_sync_control_RS is
     SFP_LOS_IN         : in  std_logic; -- SFP Loss Of Signal
     RX_CDR_LOL_IN      : in  std_logic; -- SerDes RX CDR status
     RX_LOS_IN          : in  std_logic; -- SerDes RX input signal status
+    CV_IN              : in  std_logic;
+    LSM_IN             : in  std_logic;
+    PLL_LOL_IN         : in  std_logic;
     WA_POSITION_IN     : in  std_logic_vector(3 downto 0); -- WordAlignment Position
     LINK_TX_READY_IN   : in  std_logic;
     -- control signals to SerDes
@@ -70,10 +73,10 @@ architecture med_sync_control_arch of med_sync_control_RS is
   signal led_rx, last_led_rx      : std_logic;
   signal led_tx, last_led_tx      : std_logic;
   signal timer                    : unsigned(20 downto 0);
-  signal sd_los_qsys              : std_logic;
+  signal sd_los_q                 : std_logic;
 
   signal reset_i                  : std_logic;
-  signal reset_rx_fsm_i           : std_logic;
+  signal clr_rx_fsm_i             : std_logic;
   signal link_rx_ready_i          : std_logic;
   signal link_rx_ready_qsys       : std_logic;
   signal link_half_done_i         : std_logic;
@@ -100,47 +103,49 @@ begin
     )
     port map(
       RESET    => '0',
-      CLK0     => CLK_SYS
-      CLK1     => CLK_SYS,
+      CLK0     => CLK_REF
+      CLK1     => CLK_REF,
       D_IN(0)  => SFP_LOS_IN, 
-      D_OUT(0) => sd_los_qsys
+      D_OUT(0) => sd_los_q
     );
 
+-- obselete
 -- keep central TX reset FSM idle while no clock is present
-  TX_RESET_OUT <=      (CLEAR or RESET or not link_rx_ready_i) when (IS_MODE = c_IS_SLAVE)
-                  else (CLEAR or RESET);
-
+--  TX_RESET_OUT <=      (CLEAR or RESET or not link_rx_ready_i) when (IS_MODE = c_IS_SLAVE)
+--                  else (CLEAR or RESET);
+  TX_RESET_OUT <= '0';
+                  
 -- RX_RESET_FSM reset
-  reset_rx_fsm_i <= (CLEAR or RESET or sd_los_qsys);
+--  clrn_rx_fsm_i <= not (CLEAR or RESET or sd_los_q);
+  clr_rx_fsm_i     <= sd_los_q;
+
+  MASTER_RESET_OUT <= sd_los_q;
 
 -- TX_CONTROL and RX_CONTROL reset
-  reset_i   <=      (RESET or sd_los_qsys) when (IS_MODE = c_IS_SLAVE)
+  reset_i   <=      (RESET or sd_los_q) when (IS_MODE = c_IS_SLAVE)
                else (RESET);
 
 -------------------------------------------------
 -- Reset RX FSM
 -------------------------------------------------
-  THE_RX_RST_FSM: main_rx_reset_RS  -- OK
-    generic map(
-      SIM_MODE    => SIM_MODE,
-      IS_WAP_ZERO => IS_WAP_ZERO,
-      IS_MODE     => IS_MODE
-    )
+  THE_RX_RST_FSM: rx_rsl
     port map(
-      CLEAR                  => reset_rx_fsm_i,
-      LOCALCLK               => CLK_REF,
-      TX_PLL_LOL_IN          => '0', -- TX and RX channel are independent
-      RX_CDR_LOL_IN          => RX_CDR_LOL_IN, -- internally synced
-      RX_LOS_LOW_IN          => RX_LOS_IN, -- internally synced
-      WA_POSITION_IN         => WA_POSITION_IN, -- internally synced
-      SFP_LOS_IN             => SFP_LOS_IN, -- internally synced
-      RX_PCS_RST_CH_C_OUT    => rx_pcs_rst_i,
-      RX_SERDES_RST_CH_C_OUT => rx_serdes_rst_i,
-      LINK_RX_READY_OUT      => link_rx_ready_i,
-      MASTER_RESET_OUT       => MASTER_RESET_OUT, -- not necessary???
-      STATE_OUT              => rx_fsm_state
+      CLEAR         => clr_rx_fsm_i,
+      REFCLK        => CLK_REF,
+      pll_lol       => PLL_LOL_IN,
+      cdr_lol       => RX_CDR_LOL_IN,
+      cv            => CV_IN,
+      lsm           => LSM_IN,
+      los           => RX_LOS_IN,
+      -- outputs
+      rx_serdes_rst => rx_serdes_rst_i,
+      rx_pcs_rst    => rx_pcs_rst_i,
+      state_out     => rx_fsm_state
     );
 
+    
+  link_rx_ready_i <= '0'; -- BUG
+
 -- reset signals for RX SerDes need to be sync'ed to real RX clock
   SYNC_RST_SIGS: entity work.signal_sync 
     generic map( WIDTH => 2 )
@@ -253,7 +258,7 @@ begin
 -------------------------------------------------   
   led_ok  <= link_full_done_i when rising_edge(CLK_SYS); 
   led_rx  <= (media_med2int_i.dataready or led_rx)  and not timer(20) when rising_edge(CLK_SYS);
-  led_tx  <= (MEDIA_INT2MED.dataready or led_tx or sd_los_qsys)  and not timer(20) when rising_edge(CLK_SYS);
+  led_tx  <= (MEDIA_INT2MED.dataready or led_tx or sd_los_q)  and not timer(20) when rising_edge(CLK_SYS);
 
   ROC_TIMER_PROC: process( CLK_SYS, RESET )
   begin
@@ -292,12 +297,12 @@ begin
   DEBUG_OUT(2)            <= RX_CDR_LOL_IN;
   DEBUG_OUT(3)            <= rx_pcs_rst_i;
   DEBUG_OUT(4)            <= rx_serdes_rst_i;
-  DEBUG_OUT(5)            <= link_rx_ready_i;
-  DEBUG_OUT(6)            <= link_half_done_i;
-  DEBUG_OUT(7)            <= link_full_done_i;
-  DEBUG_OUT(8)            <= LINK_TX_READY_IN;
-  DEBUG_OUT(9)            <= is_wap_zero_i;
-  DEBUG_OUT(10)           <= reset_rx_fsm_i;
+  DEBUG_OUT(5)            <= CV_IN;--link_rx_ready_i;
+  DEBUG_OUT(6)            <= LSM_IN;--link_half_done_i;
+  DEBUG_OUT(7)            <= PLL_LOL_IN;--link_full_done_i;
+  DEBUG_OUT(8)            <= RESET;--LINK_TX_READY_IN;
+  DEBUG_OUT(9)            <= CLEAR;--is_wap_zero_i;
+  DEBUG_OUT(10)           <= clr_rx_fsm_i;
   DEBUG_OUT(11)           <= reset_i;
   DEBUG_OUT(15 downto 12) <= rx_fsm_state;
   DEBUG_OUT(21 downto 16) <= debug_tx_control_i(5 downto 0);
index a71751efa736e5abff002c0b577742a546e9a039..5b44a8526628b53a3f6fd87605702c65a28d71fe 100644 (file)
@@ -1,11 +1,11 @@
-library ieee;
-USE IEEE.std_logic_1164.ALL;
-USE IEEE.std_logic_ARITH.ALL;
-USE IEEE.std_logic_UNSIGNED.ALL;
-
-use work.trb_net_std.all;
-
-package med_sync_define_RS is
+library ieee;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.std_logic_ARITH.ALL;\r
+USE IEEE.std_logic_UNSIGNED.ALL;\r
+\r
+use work.trb_net_std.all;\r
+\r
+package med_sync_define_RS is\r
 \r
 -- These idles are available\r
 constant K_BGN    : std_logic_vector(7 downto 0) := x"1c"; -- K28.0 -- reserved for retransmission\r
@@ -22,157 +22,173 @@ constant K_EOP    : std_logic_vector(7 downto 0) := x"fd"; -- K29.7 -- reserved
 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
-constant D_IDLE1  : std_logic_vector(7 downto 0) := x"50"; -- D16.2
-
-component signal_sync is
-  generic(
-    WIDTH : integer := 1;     --
-    DEPTH : integer := 3
-    );
-  port(
-    RESET    : in  std_logic; --Reset is neceessary to avoid optimization to shift register
-    CLK0     : in  std_logic;                          --clock for first FF
-    CLK1     : in  std_logic;                          --Clock for other FF
-    D_IN     : in  std_logic_vector(WIDTH-1 downto 0); --Data input
-    D_OUT    : out std_logic_vector(WIDTH-1 downto 0)  --Data output
-    );
-end component;
-
-component lattice_ecp3_fifo_18x16_dualport_oreg
-  port(
-    Data        : in  std_logic_vector(17 downto 0);
-    WrClock     : in  std_logic;
-    RdClock     : in  std_logic;
-    WrEn        : in  std_logic;
-    RdEn        : in  std_logic;
-    Reset       : in  std_logic;
-    RPReset     : in  std_logic;
-    Q           : out std_logic_vector(17 downto 0);
-    Empty       : out std_logic;
-    Full        : out std_logic;
-    AlmostFull  : out std_logic
-  );
-end component;
+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
+\r
+component rx_rsl is\r
+  port (\r
+    CLEAR         : in  std_logic;\r
+    refclk        : in  std_logic;\r
+    pll_lol       : in  std_logic;\r
+    cdr_lol       : in  std_logic;\r
+    cv            : in  std_logic;\r
+    lsm           : in  std_logic;\r
+    los           : in  std_logic;\r
+    -- outputs\r
+    rx_serdes_rst : out  std_logic;\r
+    rx_pcs_rst    : out  std_logic;\r
+    state_out     : out  std_logic_vector(3 downto 0)\r
+  );\r
+end component;  \r
+\r
+component signal_sync is\r
+  generic(\r
+    WIDTH : integer := 1;     --\r
+    DEPTH : integer := 3\r
+    );\r
+  port(\r
+    RESET    : in  std_logic; --Reset is neceessary to avoid optimization to shift register\r
+    CLK0     : in  std_logic;                          --clock for first FF\r
+    CLK1     : in  std_logic;                          --Clock for other FF\r
+    D_IN     : in  std_logic_vector(WIDTH-1 downto 0); --Data input\r
+    D_OUT    : out std_logic_vector(WIDTH-1 downto 0)  --Data output\r
+    );\r
+end component;\r
 \r
-component main_rx_reset_RS is
-  generic(
-    SIM_MODE    : integer := 0;
-    IS_WAP_ZERO : integer := 0;
-    IS_MODE     : integer := c_IS_SLAVE\r
-  );
-  port(
-    CLEAR                  : in  std_logic; -- async reset, active high
-    LOCALCLK               : in  std_logic; -- CDR reference clock
-    TX_PLL_LOL_IN          : in  std_logic; -- TX_PLOL form AUX channel
-    RX_CDR_LOL_IN          : in  std_logic; -- CDR LOL 
-    RX_LOS_LOW_IN          : in  std_logic; -- RX LOS
-    WA_POSITION_IN         : in  std_logic_vector(3 downto 0);
-    SFP_LOS_IN             : in  std_logic; -- SFP LOS signal
-    RX_PCS_RST_CH_C_OUT    : out std_logic;
-    RX_SERDES_RST_CH_C_OUT : out std_logic;
-    LINK_RX_READY_OUT      : out std_logic; -- RX SerDes is fully operational
-    MASTER_RESET_OUT       : out std_logic; -- can be used as master reset if sourced from Slave port
-    STATE_OUT              : out std_logic_vector(3 downto 0)
-  );
+component lattice_ecp3_fifo_18x16_dualport_oreg\r
+  port(\r
+    Data        : in  std_logic_vector(17 downto 0);\r
+    WrClock     : in  std_logic;\r
+    RdClock     : in  std_logic;\r
+    WrEn        : in  std_logic;\r
+    RdEn        : in  std_logic;\r
+    Reset       : in  std_logic;\r
+    RPReset     : in  std_logic;\r
+    Q           : out std_logic_vector(17 downto 0);\r
+    Empty       : out std_logic;\r
+    Full        : out std_logic;\r
+    AlmostFull  : out std_logic\r
+  );\r
 end component;\r
 \r
-component main_tx_reset_RS is
-  generic(
-    SIM_MODE    : integer := 0
-  );
-  port(
-    CLEAR                : in  std_logic; -- async reset
-    LOCALCLK             : in  std_logic; -- usually RX_REFCLK, not TX_REFCLK!   
-    TX_PLL_LOL_QD_A_IN   : in  std_logic; -- QUAD A
-    TX_PLL_LOL_QD_B_IN   : in  std_logic; -- QUAD B
-    TX_PLL_LOL_QD_C_IN   : in  std_logic; -- QUAD C
-    TX_PLL_LOL_QD_D_IN   : in  std_logic; -- QUAD D
-    TX_CLOCK_AVAIL_IN    : in  std_logic; -- recovered RX clock available (if needed)
-    RST_QD_C_OUT         : out std_logic; -- full QUAD reset
-    TX_PCS_RST_CH_C_OUT  : out std_logic; -- PCS reset
-    SYNC_TX_QUAD_OUT     : out std_logic; -- sync all QUADs to TX bit 0
-    LINK_TX_READY_OUT    : out std_logic; -- TX lane can use used now
-    STATE_OUT            : out std_logic_vector(3 downto 0)
-  );
+--component 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
+--  );\r
+--end component;\r
+\r
+component main_tx_reset_RS is\r
+  generic(\r
+    SIM_MODE    : integer := 0\r
+  );\r
+  port(\r
+    CLEAR                : in  std_logic; -- async reset\r
+    LOCALCLK             : 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
+    TX_PLL_LOL_QD_D_IN   : in  std_logic; -- QUAD D\r
+    TX_CLOCK_AVAIL_IN    : in  std_logic; -- recovered RX clock available (if needed)\r
+    RST_QD_C_OUT         : out std_logic; -- full QUAD reset\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_TX_READY_OUT    : out std_logic; -- TX lane can use used now\r
+    STATE_OUT            : out std_logic_vector(3 downto 0)\r
+  );\r
 end component;\r
 \r
-component rx_control_RS is
-  generic(
-    SIM_MODE    : integer := 0
-  );
-  port(
-    CLK_RXI                        : in  std_logic;
-    CLK_SYS                        : in  std_logic;
-    RESET                          : in  std_logic; -- synchronous to RXI
-    -- Media Interface
-    RX_DATA_OUT                    : out std_logic_vector(15 downto 0);
-    RX_PACKET_NUMBER_OUT           : out std_logic_vector(2 downto 0);
-    RX_WRITE_OUT                   : out std_logic;
-    -- SerDex data stream
-    RX_DATA_IN                     : in  std_logic_vector(7 downto 0);
-    RX_K_IN                        : in  std_logic;
-    -- synchronous link signals
-    WORD_SYNC_OUT                  : out std_logic;
-    RX_DLM_OUT                     : out std_logic;
-    RX_DLM_WORD_OUT                : out std_logic_vector(7 downto 0);
-    RX_RST_OUT                     : out std_logic;
-    RX_RST_WORD_OUT                : out std_logic_vector(7 downto 0);
-    -- link status signals
-    LINK_RX_READY_IN               : in  std_logic;
-    LINK_TX_READY_IN               : in  std_logic;
-    LINK_HALF_DONE_IN              : in  std_logic;
-    LINK_FULL_DONE_IN              : in  std_logic;
-    -- debug
-    DEBUG_OUT                      : out std_logic_vector(31 downto 0);
-    STAT_REG_OUT                   : out std_logic_vector(31 downto 0)
-  );
-end component;
+component rx_control_RS is\r
+  generic(\r
+    SIM_MODE    : integer := 0\r
+  );\r
+  port(\r
+    CLK_RXI                        : in  std_logic;\r
+    CLK_SYS                        : in  std_logic;\r
+    RESET                          : in  std_logic; -- synchronous to RXI\r
+    -- Media Interface\r
+    RX_DATA_OUT                    : out std_logic_vector(15 downto 0);\r
+    RX_PACKET_NUMBER_OUT           : out std_logic_vector(2 downto 0);\r
+    RX_WRITE_OUT                   : out std_logic;\r
+    -- SerDex data stream\r
+    RX_DATA_IN                     : in  std_logic_vector(7 downto 0);\r
+    RX_K_IN                        : in  std_logic;\r
+    -- synchronous link signals\r
+    WORD_SYNC_OUT                  : out std_logic;\r
+    RX_DLM_OUT                     : out std_logic;\r
+    RX_DLM_WORD_OUT                : out std_logic_vector(7 downto 0);\r
+    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;\r
+    LINK_HALF_DONE_IN              : in  std_logic;\r
+    LINK_FULL_DONE_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
+  );\r
+end component;\r
 \r
-component rx_lsm_RS is
-  port(
-    LINK_RX_READY_IN       : in  std_logic; -- serves as async reset, active low
-    RXCLK                  : in  std_logic; -- recovered RX clock
-    RX_K_IN                : in  std_logic;
-    RX_DATA_IN             : in  std_logic_vector(7 downto 0); 
-    LINK_HALF_DONE_OUT     : out std_logic;
-    LINK_FULL_DONE_OUT     : out std_logic;
-    STATE_OUT              : out std_logic_vector(3 downto 0)
-  );
+component rx_lsm_RS is\r
+  port(\r
+    LINK_RX_READY_IN       : in  std_logic; -- serves as async reset, active low\r
+    RXCLK                  : 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
-  generic(
-    SIM_MODE    : integer := 0;
-    IS_MODE     : integer := c_IS_UNUSED
-  );
-  port(
-    CLK_TX                         : in  std_logic;
-    CLK_SYS                        : in  std_logic;
-    RESET                          : in  std_logic; -- async/sync reset
-    -- Media Interface
-    TX_DATA_IN                     : in  std_logic_vector(15 downto 0); -- media interface
-    TX_PACKET_NUMBER_IN            : in  std_logic_vector(2 downto 0); -- media interface
-    TX_WRITE_IN                    : in  std_logic; -- media interface
-    TX_READ_OUT                    : out std_logic; -- media interface
-    -- SerDes data stream
-    TX_DATA_OUT                    : out std_logic_vector(7 downto 0); -- to TX SerDes
-    TX_K_OUT                       : out std_logic; -- to TX SerDes
-    -- synchronous signals
-    WORD_SYNC_IN                   : in  std_logic; -- byte/word sync
-    SEND_DLM_IN                    : in  std_logic;
-    SEND_DLM_WORD_IN               : in  std_logic_vector(7 downto 0);
-    SEND_RST_IN                    : in  std_logic;
-    SEND_RST_WORD_IN               : in  std_logic_vector(7 downto 0);
-    -- link status signals, internally synced
-    LINK_TX_READY_IN               : in  std_logic; -- local ref clock
-    LINK_RX_READY_IN               : in  std_logic; -- local ref clock
-    LINK_HALF_DONE_IN              : in  std_logic; -- recovered RX clock
-    LINK_FULL_DONE_IN              : in  std_logic; -- recovered RX clock
-    -- debug
-    DEBUG_OUT                      : out std_logic_vector(31 downto 0);
-    STAT_REG_OUT                   : out std_logic_vector(31 downto 0)
-  );
+component tx_control_RS is\r
+  generic(\r
+    SIM_MODE    : integer := 0;\r
+    IS_MODE     : integer := c_IS_UNUSED\r
+  );\r
+  port(\r
+    CLK_TX                         : in  std_logic;\r
+    CLK_SYS                        : in  std_logic;\r
+    RESET                          : in  std_logic; -- async/sync reset\r
+    -- Media Interface\r
+    TX_DATA_IN                     : in  std_logic_vector(15 downto 0); -- media interface\r
+    TX_PACKET_NUMBER_IN            : in  std_logic_vector(2 downto 0); -- media interface\r
+    TX_WRITE_IN                    : in  std_logic; -- media interface\r
+    TX_READ_OUT                    : out std_logic; -- media interface\r
+    -- SerDes data stream\r
+    TX_DATA_OUT                    : out std_logic_vector(7 downto 0); -- to TX SerDes\r
+    TX_K_OUT                       : out std_logic; -- to TX SerDes\r
+    -- synchronous signals\r
+    WORD_SYNC_IN                   : in  std_logic; -- byte/word sync\r
+    SEND_DLM_IN                    : in  std_logic;\r
+    SEND_DLM_WORD_IN               : in  std_logic_vector(7 downto 0);\r
+    SEND_RST_IN                    : in  std_logic;\r
+    SEND_RST_WORD_IN               : in  std_logic_vector(7 downto 0);\r
+    -- link status signals, internally synced\r
+    LINK_TX_READY_IN               : in  std_logic; -- local ref clock\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
+    -- 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
-
-end package;
+\r
+end package;\r
diff --git a/media_interfaces/sync/rx_rsl.vhd b/media_interfaces/sync/rx_rsl.vhd
new file mode 100644 (file)
index 0000000..90af3c8
--- /dev/null
@@ -0,0 +1,195 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use IEEE.std_logic_unsigned.all;\r
+use IEEE.std_logic_arith.all;\r
+\r
+entity rx_rsl is\r
+  port (\r
+    CLEAR         : in  std_logic;\r
+    refclk        : in  std_logic;\r
+    pll_lol       : in  std_logic;\r
+    cdr_lol       : in  std_logic;\r
+    cv            : in  std_logic;\r
+    lsm           : in  std_logic;\r
+    los           : in  std_logic;\r
+    -- outputs\r
+    rx_serdes_rst : out  std_logic;\r
+    rx_pcs_rst    : 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
+------------------------------------------------------------------\r
+--                  Constants Declaration           --\r
+------------------------------------------------------------------\r
+\r
+--@125MHz 100ms\r
+\r
+constant Tplol      : std_logic_vector (31 downto 0):=x"00BEBC20";\r
+constant Tcdr       : std_logic_vector (31 downto 0):=x"00BEBC20";\r
+constant Tviol      : std_logic_vector (31 downto 0):=x"00BEBC20";\r
+\r
+------------------------------------------------------------------\r
+--                  Internal Variables             --\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        : std_logic_vector (31 downto 0);\r
+\r
+type rx_sm_state is (powerup, apply_cdr_rst, wait_cdr_lock, test_cdr, apply_rxpcs_rst, wait_rxpcs_lock, test_rxpcs, idle);\r
+signal rx_sm        : rx_sm_state;\r
+attribute syn_keep of rx_sm : signal is true;\r
+\r
+begin\r
+------------------------------------------------------------------\r
+--                  Components Instantiation        --\r
+------------------------------------------------------------------\r
+\r
+------------------------------------------------------------------\r
+--                  Begin Of The Design             --\r
+------------------------------------------------------------------\r
+\r
+-- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL.\r
+\r
+------------------------------------------------------------------\r
+rx_reset_proc    :  process (CLEAR, refclk)\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 <= '1';\r
+    rx_pcs_rst    <= '1';\r
+  \r
+    rx_sm         <= powerup;\r
+    cnt           <= (others => '0');  \r
+  elsif( rising_edge(refclk) ) then\r
+    pll_lol_s     <= pll_lol;\r
+    cdr_lol_s     <= cdr_lol;\r
+    cv_s          <= cv;    \r
+    lsm_s         <= lsm;    \r
+    los_s         <= los;  \r
+  \r
+    case rx_sm is\r
+      when powerup =>\r
+        state_out <= x"0";\r
+--        rx_serdes_rst  <= '1'; -- bad idea\r
+        rx_serdes_rst  <= '0';\r
+        rx_pcs_rst     <= '1';\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  <= '1';\r
+        rx_pcs_rst     <= '1';\r
+        if( cnt = x"00000007" ) 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  <= '0';\r
+        rx_pcs_rst     <= '1';\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  <= '0';\r
+        rx_pcs_rst     <= '1';\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
+      when apply_rxpcs_rst =>\r
+        state_out <= x"4";\r
+        rx_serdes_rst  <= '0';\r
+        rx_pcs_rst     <= '1';\r
+        if (cnt = x"00000007") 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  <= '0';\r
+        rx_pcs_rst     <= '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
+      when test_rxpcs =>\r
+        state_out <= x"6";\r
+        rx_serdes_rst  <= '0';\r
+        rx_pcs_rst     <= '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  <= idle;\r
+          else\r
+            cnt     <= cnt + '1';\r
+          end if;\r
+        end if;\r
+     \r
+      when idle =>\r
+        state_out <= x"7";\r
+        rx_serdes_rst  <= '0';\r
+        rx_pcs_rst     <= '0';\r
+        if (lsm_s = '0') or (cv_s = '1') then\r
+          rx_sm    <= apply_rxpcs_rst;      \r
+          cnt      <= (others => '0');\r
+        end if;\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