]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Phy finally operational (again)
authorManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 3 Oct 2013 13:33:12 +0000 (15:33 +0200)
committerManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 3 Oct 2013 13:33:12 +0000 (15:33 +0200)
cbmnet/code/cbmnet_interface_pkg.vhd
cbmnet/code/cbmnet_phy_ecp3.vhd
cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd
cbmnet/code/cbmnet_phy_gear.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_phy_pkg.vhd
cbmnet/code/cbmnet_pkg.vhd [deleted file]
cbmnet/compile_periph_frankfurt.pl
cbmnet/trb3_periph_cbmnet.vhd

index da8f28686c0879d6f52e0c90f7c0cb2ef413af43..8460f902e7d9a4bf83cad9ad6c7c0d4b6e06dedb 100644 (file)
@@ -15,7 +15,11 @@ package cbmnet_interface_pkg is
    constant K277 : std_logic_vector(7 downto 0) := "11111011";
    constant K297 : std_logic_vector(7 downto 0) := "11111101";
    constant K307 : std_logic_vector(7 downto 0) := "11111110";
-
+   
+   constant CBMNET_READY_CHAR0 : std_logic_vector(7 downto 0) :=  K284;
+   constant CBMNET_READY_CHAR1 : std_logic_vector(7 downto 0) :=  K287;
+   constant CBMNET_ALIGN_CHAR  : std_logic_vector(7 downto 0) :=  K285;
+         
    component gtp_rx_ready_module is
       generic (
          READY_CHAR0  : std_logic_vector(7 downto 0) :=  K284;
index b3a3dae26f85340446092d1557586ec585912db5..8ea9cae6ed600302afd04750de009e47ef2b1691 100644 (file)
@@ -80,10 +80,10 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
 
    signal tx_data_i         : std_logic_vector(17 downto 0);
    
-   signal rx_data_i         : std_logic_vector(17 downto 0);
+   signal rx_data_i         : std_logic_vector(8 downto 0);
    signal rx_data_buf_i     : std_logic_vector(17 downto 0);
    
-   signal rx_error          : std_logic_vector(1 downto 0);
+   signal rx_error          : std_logic;
 
    signal rst_n             : std_logic;
    signal rst               : std_logic;
@@ -120,10 +120,13 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    
    signal rx_fsm_state       : std_logic_vector(3 downto 0);
    signal tx_fsm_state       : std_logic_vector(3 downto 0);
+   signal tx_rst_fsm_ready_i  : std_logic;
+   signal tx_rst_fsm_ready_buf_i  : std_logic;
+   
 
    type sci_ctrl is (IDLE, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH);
    signal sci_state         : sci_ctrl;
-   signal sci_timer         : unsigned(7 downto 0) := (others => '0');
+   signal sci_timer         : unsigned( 4 downto 0) := (others => '0');
    signal start_timer       : unsigned(18 downto 0) := (others => '0');
 
    signal led_ok                 : std_logic;
@@ -132,8 +135,19 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    signal led_timer              : unsigned(20 downto 0);
 
    signal proper_byte_align_i : std_logic;
-   signal proper_word_align_i : std_logic;
+   signal byte_alignment_to_fsm_i : std_logic;
+   
+   signal gear_to_serder_rst_i : std_logic;
+   signal word_alignment_to_fsm_i : std_logic;
+   
+   signal rx_rm_to_gear_reset_i : std_logic;
    
+   signal rx_rst_fsm_ready_i : std_logic;
+   signal rx_serdes_ready_for_gear_i : std_logic;
+   
+   signal lsm_status_i : std_logic;
+   
+   signal rx_error_delay : std_logic_vector(3 downto 0);
    
 -- RX READY MODULE
    signal rx_ready_i : std_logic;
@@ -146,6 +160,11 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    
    signal rx_rm_rst_n, tx_rm_rst_n :std_logic;
    
+   signal dummy_output_i : std_logic_vector(8 downto 0);
+   
+   signal gear_to_rm_rst_i : std_logic;
+   signal gear_to_rm_n_rst_i : std_logic;
+   
 -- TX READY MODULE   
    signal tx_ready_i : std_logic;
    signal tx_almost_ready_i : std_logic;
@@ -179,11 +198,11 @@ begin
       hdoutn_ch0           => SD_TXD_N_OUT,
       
    -- CLOCKS
-      rxiclk_ch0           => clk_125_i,
+      --rxiclk_ch0           => clk_125_i,
       txiclk_ch0           => clk_125_i,
       
       rx_full_clk_ch0      => clk_rx_full,
-      rx_half_clk_ch0      => clk_rx_half,
+   --   rx_half_clk_ch0      => clk_rx_half,
       
       tx_full_clk_ch0      => open,
       tx_half_clk_ch0      => open,
@@ -211,8 +230,8 @@ begin
       tx_div2_mode_ch0_c   => '0',
       
    -- RX DATA PORT
-      rxdata_ch0           => rx_data_i(15 downto 0),
-      rx_k_ch0             => rx_data_i(17 downto 16),
+      rxdata_ch0           => rx_data_i(7 downto 0),
+      rx_k_ch0             => rx_data_i(8),
 
       rx_disp_err_ch0      => open,
       rx_cv_err_ch0        => rx_error,
@@ -226,7 +245,7 @@ begin
       tx_pll_lol_qd_s      => tx_pll_lol,
       rx_los_low_ch0_s     => rx_los_low,
       rx_cdr_lol_ch0_s     => rx_cdr_lol,
-      lsm_status_ch0_s     => open,
+      lsm_status_ch0_s     => lsm_status_i,
     
       SCI_WRDATA           => sci_data_in_i,
       SCI_RDDATA           => sci_data_out_i,
@@ -242,26 +261,16 @@ begin
    
    DEBUG_OUT(19 downto  0) <= "00" & tx_data_i;
    DEBUG_OUT(23 downto 20) <= "0" & tx_pll_lol & rx_los_low & rx_cdr_lol;
-   DEBUG_OUT(27 downto 24) <= proper_word_align_i & proper_byte_align_i & SD_PRSNT_N_IN & SD_LOS_IN;
+   DEBUG_OUT(27 downto 24) <= gear_to_serder_rst_i & proper_byte_align_i & SD_PRSNT_N_IN & SD_LOS_IN;
    DEBUG_OUT(31 downto 28) <= rst_qd & rx_serdes_rst & tx_pcs_rst & rx_pcs_rst;
    
    DEBUG_OUT(51 downto 32) <= "00" & rx_data_buf_i;
    DEBUG_OUT(59 downto 52) <= rx_fsm_state & tx_fsm_state;
       
-   DEBUG_OUT(63 downto 60) <= "00" &  tx_ready_i & tx_almost_ready_i;
+   DEBUG_OUT(63 downto 60) <= SERDES_ready & rx_ready_i &  tx_ready_i & tx_almost_ready_i;
    DEBUG_OUT(99 downto 96) <= rx_almost_ready_i & rx_see_ready0_i & rx_saw_ready1_i & rx_valid_char_i;
-      
-   process is
-      variable cnt, cntr : unsigned(15 downto 0);
-   begin
-      wait until rising_edge(clk_125_i);
-      cnt := cnt + 1;
-      cntr := cntr + 1;
-      if rst_n = '0' then
-         cntr := x"0000";
-      end if;
-      DEBUG_OUT(31 + 64 downto 64) <= std_logic_vector(cnt) & std_logic_vector(cntr);
-   end process;
+   DEBUG_OUT(103 downto 100) <= wa_position(3 downto 0);
+   DEBUG_OUT(107 downto 104) <= "00" & rx_rm_to_gear_reset_i & gear_to_rm_rst_i;
       
    -------------------------------------------------      
    -- Reset FSM & Link states
@@ -274,14 +283,18 @@ begin
       RX_CDR_LOL_CH_S     => rx_cdr_lol,
       RX_LOS_LOW_CH_S     => rx_los_low,
       
-      RM_RESET_IN         => '0', --rx_reset_from_rm_i,
-      PROPER_BYTE_ALIGN_IN=> proper_byte_align_i,
-      PROPER_WORD_ALIGN_IN=> proper_word_align_i,
+      RM_RESET_IN         => CTRL_OP(4), --rx_reset_from_rm_i,
+      PROPER_BYTE_ALIGN_IN=> byte_alignment_to_fsm_i,
+      PROPER_WORD_ALIGN_IN=> word_alignment_to_fsm_i,
       
       RX_SERDES_RST_CH_C  => rx_serdes_rst,
       RX_PCS_RST_CH_C     => rx_pcs_rst,
       STATE_OUT           => rx_fsm_state
    );
+   byte_alignment_to_fsm_i <=  proper_byte_align_i or CTRL_OP(1);
+   word_alignment_to_fsm_i <= not (gear_to_serder_rst_i or AND_ALL(rx_error_delay)) or CTRL_OP(2);
+   rx_error_delay <= rx_error_delay(rx_error_delay'high - 1 downto 0) & rx_error when rising_edge(clk_125_local);
+   
       
    THE_TX_FSM : tx_reset_fsm
    port map(
@@ -292,73 +305,36 @@ begin
       TX_PCS_RST_CH_C => tx_pcs_rst,
       STATE_OUT       => tx_fsm_state
    );
+   --tx_data_i <= "01" & x"00" & CBMNET_READY_CHAR0;
    
-   sd_los_i <= SD_LOS_IN when rising_edge(CLK);
+   proc_rst_fsms_ready: process is begin
+      wait until rising_edge(clk_125_local);
+      rx_rst_fsm_ready_i <= '0';
+      if rx_fsm_state = x"6" then
+         rx_rst_fsm_ready_i <= '1';
+      end if;
 
-   gen_wa_fixation: if WA_FIXATION = c_YES generate
-      -- In slave mode, we need the barrel shifter to lock on the lowest position in 
-      -- order to avoid a non-deterministic skew in the clock/data phase
-      -- If we're the master, we don't care about the proper barrel shifter alignment
-      proper_byte_align_i <= 
-         '1' when IS_SYNC_SLAVE = c_NO else
-         proper_byte_align_i when not rising_edge(clk_125_i) else
-         '1' when wa_position(3 downto 0) = x"0" else '0';
-         
-      -- detect misaligned gearing fifo
-      proper_word_align_i <= 
-         '1' when rst_n = '0' or rx_serdes_rst = '1' else
-         proper_word_align_i when not rising_edge(clk_125_i) else
-        -- '0' when rx_serdes_rst ='1' or rst = '1' else
-         '0' when rx_data_i(17 downto 16) = "10" and
-            (rx_data_i(15 downto 8) = K284 or rx_data_i(15 downto 8) = K285 or rx_data_i(15 downto 8) = K287)
-            and rx_data_i(7 downto 0) = x"00" else '1';
-
-      serdes_rx_ready_i <= (not rx_cdr_lol) and proper_word_align_i and proper_byte_align_i when rx_fsm_state = x"6" else '0';
-      serdes_tx_ready_i <= (not tx_pll_lol) when tx_fsm_state = x"5" else '0';
-      serdes_ready_i <= serdes_rx_ready_i and serdes_tx_ready_i;
-      
-      rx_data_buf_i <= rx_data_i;
-   end generate;
+      tx_rst_fsm_ready_i <= '0';
+      if tx_fsm_state = x"5" then
+         tx_rst_fsm_ready_i <= '1';
+      end if;
+   end process;
    
-   gen_wa_no_fixation: if WA_FIXATION = c_NO generate
-      proper_byte_align_i <= '1';
-      serdes_ready_i <= not (rx_cdr_lol or tx_pll_lol) when tx_fsm_state = x"5" and rx_fsm_state = x"6" else '0';
-      
-      proc_wa: process is
-         variable locked : std_logic;
-         variable locked_with_delay : std_logic;
-         
-         variable delay  : std_logic_vector(8 downto 0);
-         variable rx_pcs_rst_del : std_logic := '0';
-      begin
-         wait until rising_edge(clk_125_i);
-
-         if locked_with_delay = '1' then
-            rx_data_buf_i <= delay(8) & rx_data_i(17) & delay(7 downto 0) &  rx_data_i(15 downto 8);
-         else
-            rx_data_buf_i <= rx_data_i;
-         end if;
-         
-         delay := rx_data_i(16) & rx_data_i(7 downto 0);
-         
-         if rx_pcs_rst = '1' and rx_pcs_rst_del = '0' then
-            locked := '0';
-            
-         elsif locked = '0' then
-            if rx_data_i(17 downto 16) = "10" and (rx_data_i(15 downto 8) = K284 or rx_data_i(15 downto 8) = K285 or rx_data_i(15 downto 8) = K287) and rx_data_i(7 downto 0) = x"00" then
-               locked_with_delay := '1';
-               locked := '1';
-            elsif rx_data_i(17 downto 16) = "01" and (rx_data_i(7 downto 0) = K284 or rx_data_i(7 downto 0) = K285 or rx_data_i(7 downto 0) = K287) and rx_data_i(15 downto 8) = x"00" then
-               locked_with_delay := '0';
-               locked := '1';
-            end if;
-            
-         end if;
-
-         rx_pcs_rst_del := rx_pcs_rst;
-         proper_word_align_i <= locked;
-      end process;
-   end generate;
+   THE_GEAR: CBMNET_PHY_GEAR port map (
+      -- SERDES PORT
+         CLK_250_IN      => clk_rx_full,             -- in std_logic;
+         PCS_READY_IN    => rx_serdes_ready_for_gear_i, -- in std_logic;
+         SERDES_RESET_OUT=> gear_to_serder_rst_i,    -- out std_logic;
+         DATA_IN         => rx_data_i,               -- in  std_logic_vector( 8 downto 0);
+
+      -- RM PORT
+         RM_RESET_IN => rx_rm_to_gear_reset_i,      -- in std_logic;
+         CLK_125_OUT => clk_rx_half,                -- out std_logic;
+         RESET_OUT   => gear_to_rm_rst_i,           -- out std_logic;
+         DATA_OUT    => rx_data_buf_i               -- out std_logic_vector(17 downto 0)
+   );
+   rx_serdes_ready_for_gear_i <= (rx_rst_fsm_ready_i and proper_byte_align_i) or CTRL_OP(5);
+   rx_rm_to_gear_reset_i <= rx_reset_from_rm_i and not CTRL_OP(6);
    
    -------------------------------------------------      
    -- CBMNet Ready Modules
@@ -367,8 +343,8 @@ begin
    generic map (INCL_8B10B_DEC => c_No)
    port map (
       clk => clk_125_i,
-      res_n => rx_rm_rst_n,
-      ready_MGT2RM => serdes_ready_i,
+      res_n => gear_to_rm_n_rst_i,
+      ready_MGT2RM => '1',
       
       rxdata_in(17 downto 0) => rx_data_buf_i,
       rxdata_in(19 downto 18) => "00",
@@ -387,15 +363,14 @@ begin
       
       reset_rx => rx_reset_from_rm_i
    );
+   gear_to_rm_n_rst_i <= not gear_to_rm_rst_i when rising_edge(clk_125_i);
    
-   rx_rm_rst_n <= not (rst or CTRL_OP(1) or not serdes_rx_ready_i); -- or not serdes_ready_i);
-
    THE_TX_READY: gtp_tx_ready_module
    port map (
       clk => clk_125_i,                   -- :  in std_logic;
-      res_n => rx_rm_rst_n,               -- :  in std_logic;
+      res_n => tx_rst_fsm_ready_buf_i,               -- :  in std_logic;
       restart_link => CTRL_OP(14),        -- :  in std_logic;
-      ready_MGT2RM => serdes_tx_ready_i,     -- :  in std_logic;
+      ready_MGT2RM => '1',     -- :  in std_logic;
       txdata_in => PHY_TXDATA_IN ,        -- :  in std_logic_vector((DATAWIDTH-1) downto 0);
       txcharisk_in => PHY_TXDATA_K_IN,    -- :  in std_logic_vector((WORDS-1) downto 0);
 
@@ -410,22 +385,37 @@ begin
       gt11_reinit => open                 -- :  out std_logic   
    );
    
-   tx_rm_rst_n <= not (rst or CTRL_OP(2) or not serdes_tx_ready_i);
-   
+   process is begin
+      wait until rising_edge(clk_125_i);
+      
+      if IS_SYNC_SLAVE = c_YES then
+         tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i and not gear_to_rm_rst_i;
+         
+      else
+         tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i;
+         
+      end if;
+   end process;
+      
+      
    rx_rm_ready_i <= rx_almost_ready_i or rx_ready_i;
    
    SERDES_ready <= tx_ready_i and rx_ready_i when rising_edge(clk_125_i);
    led_ok       <= SERDES_ready;
    
+   
    -------------------------------------------------      
    -- SCI
    -------------------------------------------------      
    --gives access to serdes config port from slow control and reads word alignment every ~ 40 us
    PROC_SCI_CTRL: process 
       variable cnt : integer range 0 to 4 := 0;
+      variable lsm_status_buf : std_logic;
    begin
       wait until rising_edge(CLK);
       SCI_ACK <= '0';
+      proper_byte_align_i <= '1';
+      
       case sci_state is
          when IDLE =>
             sci_ch_i        <= x"0";
@@ -441,15 +431,21 @@ begin
 
       when GET_WA =>
             if cnt = 4 then
-            cnt           := 0;
-            sci_state     <= IDLE;
+               cnt           := 0;
+               sci_state     <= IDLE;
+               
+               if lsm_status_buf = '1' and wa_position(3 downto 0) /= x"0" then
+                  proper_byte_align_i <= '0';
+               end if;
+               
             else
-            sci_state     <= GET_WA_WAIT;
-            sci_addr_i    <= '0' & x"22";
-            sci_ch_i      <= x"0";
-            sci_ch_i(cnt) <= '1';
-            sci_read_i    <= '1';
+               sci_state     <= GET_WA_WAIT;
+               sci_addr_i    <= '0' & x"22";
+               sci_ch_i      <= x"0";
+               sci_ch_i(cnt) <= '1';
+               sci_read_i    <= '1';
             end if;
+            
          when GET_WA_WAIT  =>
             sci_state       <= GET_WA_WAIT2;
             
@@ -460,7 +456,7 @@ begin
             wa_position(cnt*4+3 downto cnt*4) <= sci_data_out_i(3 downto 0);
             sci_state       <= GET_WA;    
             cnt             := cnt + 1;
-            
+         
       end case;
       
       if (SCI_READ = '1' or SCI_WRITE = '1') and sci_state /= IDLE then
@@ -468,6 +464,8 @@ begin
       else
          SCI_NACK <= '0';
       end if;
+      
+      lsm_status_buf := lsm_status_i;
    end process;
 
    -- RX/TX leds are on as soon as the correspondent pll is locked and data
@@ -479,7 +477,7 @@ begin
       led_rx <= not rx_cdr_lol;
       led_tx <= not tx_pll_lol;
       
-      if (led_timer(20) = '1') or (rx_data_i(17 downto 16) = "10" and rx_data_i(15 downto 0) = x"fcce") then
+      if (led_timer(20) = '1') or (rx_data_buf_i(17 downto 16) = "10" and rx_data_buf_i(15 downto 0) = x"fcce") then
          led_rx <= '0';
       end if;
       
@@ -514,25 +512,44 @@ begin
    end process;
    
 -- STAT_OP REGISTER
-STAT_OP(0) <= clk_125_local;
-STAT_OP(1) <= clk_125_i;
-STAT_OP(2) <= rst;
-STAT_OP(3) <= SD_LOS_IN;
-
-STAT_OP(4) <= rx_serdes_rst;
-STAT_OP(5) <= rx_pcs_rst;
-STAT_OP(6) <= tx_pcs_rst;
-STAT_OP(7) <= rst_qd;
-
-STAT_OP(8) <= rx_los_low;
-STAT_OP(9) <= rx_cdr_lol;
-STAT_OP(10) <= OR_ALL(rx_error);
-STAT_OP(11) <= rx_reset_from_rm_i;
-
-STAT_OP(12) <= tx_pll_lol;
-STAT_OP(13) <= proper_byte_align_i;
-STAT_OP(14) <= proper_word_align_i;
-STAT_OP(15) <= serdes_ready_i;
+STAT_OP(8 downto 0) <= rx_data_i when CTRL_OP(8) = '0' else dummy_output_i;
+
+STAT_OP(9)  <= clk_rx_full;
+STAT_OP(10) <= clk_125_i;
+STAT_OP(11) <= rx_cdr_lol;
+STAT_OP(12) <= rx_los_low;
+STAT_OP(13) <= lsm_status_i;
+STAT_OP(14) <= rx_serdes_rst;
+STAT_OP(15) <= rx_pcs_rst;
+
+dummy_output_i(3 downto 0) <= wa_position(3 downto 0);
+
+dummy_output_i(4) <= rx_rst_fsm_ready_i;
+dummy_output_i(5) <= tx_pll_lol;
+dummy_output_i(6) <= tx_pcs_rst;
+dummy_output_i(7) <= rx_serdes_ready_for_gear_i;
+dummy_output_i(8) <= serdes_rx_ready_i;
+
+
+-- STAT_OP(0) <= clk_125_i;
+-- STAT_OP(1) <= rst;
+-- STAT_OP(2) <= rx_serdes_rst;
+-- STAT_OP(3) <= rx_pcs_rst;
+-- 
+-- STAT_OP(4) <= tx_pcs_rst;
+-- STAT_OP(5) <= rst_qd;
+-- STAT_OP(6) <= tx_pll_lol;
+-- STAT_OP(7) <= rx_cdr_lol;
+-- 
+-- STAT_OP(8) <= rx_los_low;
+-- STAT_OP(9) <= rx_rst_fsm_ready_i;
+-- STAT_OP(10) <= proper_byte_align_i;
+-- STAT_OP(11) <= gear_to_serder_rst_i;
+-- 
+-- STAT_OP(12) <= serdes_rx_ready_i;
+-- STAT_OP(13) <= wa_position(0);
+-- STAT_OP(14) <= wa_position(1);
+-- STAT_OP(15) <= wa_position(2);
 
 
 --    STAT_OP(3) <= rx_valid_char_i;
index 7d192e779db0ba0cead60006a244a1f8bc2783fd..68c5b9b33bf2aea668a9381dd121f78d47b321cf 100644 (file)
@@ -74,7 +74,9 @@ begin
          cs <= ns;
          rx_lol_los_del <= rx_lol_los;
          rx_lol_los_int <= rx_lol_los_del;
+         
          tx_pll_lol_qd_s_int <= tx_pll_lol_qd_s;
+         
          RX_PCS_RST_CH_C <= rx_pcs_rst_ch_c_int;
          RX_SERDES_RST_CH_C <= rx_serdes_rst_ch_c_int;
          rx_los_low_int <= rx_los_low_ch_s;
@@ -154,8 +156,8 @@ begin
                else
                   ns <= NORMAL;
                end if;
-            elsif rx_lol_los_int = '0' then
-               ns <= NORMAL;
+          --  elsif rx_lol_los_int = '0' then
+          --     ns <= NORMAL;
             else
                ns <= WAIT_FOR_timer2;
             end if;
diff --git a/cbmnet/code/cbmnet_phy_gear.vhd b/cbmnet/code/cbmnet_phy_gear.vhd
new file mode 100644 (file)
index 0000000..6a43775
--- /dev/null
@@ -0,0 +1,160 @@
+--Media interface for Lattice ECP3 using PCS at 2.5GHz
+
+LIBRARY IEEE;
+   USE IEEE.std_logic_1164.ALL;
+   USE IEEE.numeric_std.all;
+
+library work;
+   use work.trb_net_std.all;
+   use work.trb_net_components.all;
+   use work.med_sync_define.all;
+   use work.cbmnet_interface_pkg.all;
+   use work.cbmnet_phy_pkg.all;
+
+entity CBMNET_PHY_GEAR is
+   port (
+   -- SERDES PORT
+      CLK_250_IN  : in std_logic;
+      PCS_READY_IN: in std_logic;
+      SERDES_RESET_OUT : out std_logic;
+      DATA_IN     : in  std_logic_vector( 8 downto 0);
+
+   -- RM PORT
+      RM_RESET_IN : in std_logic;
+      CLK_125_OUT : out std_logic;
+      RESET_OUT   : out std_logic;
+      DATA_OUT    : out std_logic_vector(17 downto 0)
+   );
+end entity;
+
+architecture RTL of CBMNET_PHY_GEAR is
+   type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_RESET, FSM_DELAY, FSM_LOCKED);
+   signal fsm_i, fsm_next_i : FSM_STATES_T;
+   
+   signal delay_clock_i : std_logic;
+   
+   signal indi_alignment_i    : std_logic;
+   signal indi_misalignment_i : std_logic;
+   
+   signal data_delay_i   : std_logic_vector(8 downto 0);
+   signal data_out_buf_i : std_logic_vector(17 downto 0);
+   signal clk_125_i : std_logic;
+   
+   signal reset_timer_i : std_logic;
+   signal timeout_i : std_logic;
+begin
+-- FSM sych part
+   proc_sych: process is begin
+      wait until rising_edge(clk_125_i);
+      
+      if PCS_READY_IN = '0' then
+         fsm_i <= FSM_START;
+      else
+         fsm_i <= fsm_next_i;
+      end if;
+   end process;
+   
+   
+   process(fsm_i, indi_alignment_i, indi_misalignment_i) is begin
+      fsm_next_i <= fsm_i;
+      
+      SERDES_RESET_OUT <= '0';
+      RESET_OUT <= '1';
+      reset_timer_i <= '0';
+      delay_clock_i <= '0';
+      
+      case (fsm_i) is
+         when FSM_START =>
+            reset_timer_i <= '1';
+            fsm_next_i <= FSM_WAIT_FOR_LOCK;
+            
+         when FSM_WAIT_FOR_LOCK =>
+            if indi_alignment_i = '1' then
+               -- already correctly aligned, so just fix current state
+               fsm_next_i <= FSM_LOCKED;
+               
+            elsif indi_misalignment_i = '1' then
+               -- we're off by one word. just wait a single frame
+               delay_clock_i <= '1';
+               fsm_next_i <= FSM_LOCKED;
+            
+            elsif timeout_i = '1' then
+               fsm_next_i <= FSM_RESET;
+               
+            end if;
+
+         when FSM_LOCKED =>
+            RESET_OUT <= '0';
+            
+            if RM_RESET_IN = '1' then
+               fsm_next_i <= FSM_RESET;
+            
+            elsif indi_misalignment_i = '1' then
+               -- in this state we should already have a stable and correct lock. 
+               -- if we, however detect a missalignment, something is terribly wrong.
+               -- in this case, will perform a resychronisation
+               
+               fsm_next_i <= FSM_RESET;
+            end if;
+         
+         
+         when FSM_RESET =>
+            SERDES_RESET_OUT <= '1';
+         
+      end case;
+   end process;
+   
+-- Timeout (approx. 1ms)
+   proc_timeout: process is 
+      variable timer_v : unsigned(17 downto 0);
+   begin
+      wait until rising_edge(clk_125_i);
+      
+      if reset_timer_i = '1' then
+         timer_v := TO_UNSIGNED(0, timer_v'length);
+         
+      elsif timer_v(timer_v'high) = '0' then
+         timer_v := timer_v + TO_UNSIGNED(1,1);
+         
+      end if;
+
+      timeout_i <= timer_v(timer_v'high);
+   end process;
+
+-- Implement the 2:1 gearing and clock down-sampling
+   proc_gear: process is
+      variable last_delay_clock_v : std_logic := '0';
+      variable word_idx_v : std_logic;
+   begin
+      wait until rising_edge(CLK_250_IN);
+
+      if (delay_clock_i = '1' and last_delay_clock_v = '0') then
+         -- just wait
+      else
+         if word_idx_v = '0' then
+            data_delay_i <= DATA_IN;
+            clk_125_i <= '0';
+            
+         else
+            data_out_buf_i <= data_delay_i(8) & DATA_IN(8) & data_delay_i(7 downto 0) & DATA_IN(7 downto 0);
+            clk_125_i <= '1';
+            
+         end if;      
+      
+         word_idx_v := not word_idx_v;
+      end if;
+      
+      last_delay_clock_v := delay_clock_i;
+   end process;
+   
+   DATA_OUT <= data_out_buf_i;
+   CLK_125_OUT <= clk_125_i;
+   
+-- Detect Indications for correct or wrong alignment   
+   indi_alignment_i <= '1' when data_out_buf_i(17 downto 16) = "01" and data_out_buf_i(15 downto 8) = x"00" and
+      (data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR0 or data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR1 or data_out_buf_i(7 downto 0) = CBMNET_ALIGN_CHAR) else '0';
+   
+   indi_misalignment_i <= '1' when data_out_buf_i(17 downto 16) = "10" and data_out_buf_i(7 downto 0) = x"00" and
+      (data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR0 or data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR1 or data_out_buf_i(15 downto 8) = CBMNET_ALIGN_CHAR) else '0';
+   
+end architecture RTL;  
\ No newline at end of file
index 3adddc2fab847dc9af2ba0fa6d93d18023879fbb..87eaa8d8cbf9e5613617f1343d04c26ded87229e 100644 (file)
@@ -55,66 +55,71 @@ package cbmnet_phy_pkg is
          DEBUG_OUT          : out std_logic_vector (127 downto 0) := (others => '0')
       );
    end component;
+   
+   component CBMNET_PHY_GEAR is
+      port (
+      -- SERDES PORT
+         CLK_250_IN  : in std_logic;
+         PCS_READY_IN: in std_logic;
+         SERDES_RESET_OUT : out std_logic;
+         DATA_IN     : in  std_logic_vector( 8 downto 0);
+
+      -- RM PORT
+         RM_RESET_IN : in std_logic;
+         CLK_125_OUT : out std_logic;
+         RESET_OUT   : out std_logic;
+         DATA_OUT    : out std_logic_vector(17 downto 0)
+      );
+   end component;   
+   
   
 --------------------------------------------------- INTERNAL
-   component cbmnet_sfp1 is
-      generic (
-         USER_CONFIG_FILE    :  String := "cbmnet_sfp1.txt"
-      );
-      port (
-         ------------------
-         -- CH0 --
-         hdinp_ch0, hdinn_ch0    :   in std_logic;
-         hdoutp_ch0, hdoutn_ch0   :   out std_logic;
-         sci_sel_ch0    :   in std_logic;
-         rxiclk_ch0    :   in std_logic;
-         txiclk_ch0    :   in std_logic;
-         rx_full_clk_ch0   :   out std_logic;
-         rx_half_clk_ch0   :   out std_logic;
-         tx_full_clk_ch0   :   out std_logic;
-         tx_half_clk_ch0   :   out std_logic;
-         fpga_rxrefclk_ch0    :   in std_logic;
-         txdata_ch0    :   in std_logic_vector (15 downto 0);
-         tx_k_ch0    :   in std_logic_vector (1 downto 0);
-         tx_force_disp_ch0    :   in std_logic_vector (1 downto 0);
-         tx_disp_sel_ch0    :   in std_logic_vector (1 downto 0);
-         rxdata_ch0   :   out std_logic_vector (15 downto 0);
-         rx_k_ch0   :   out std_logic_vector (1 downto 0);
-         rx_disp_err_ch0   :   out std_logic_vector (1 downto 0);
-         rx_cv_err_ch0   :   out std_logic_vector (1 downto 0);
-         rx_serdes_rst_ch0_c    :   in std_logic;
-         sb_felb_ch0_c    :   in std_logic;
-         sb_felb_rst_ch0_c    :   in std_logic;
-         --word_align_en_ch0_c    :   in std_logic;
-         tx_pcs_rst_ch0_c    :   in std_logic;
-         tx_pwrup_ch0_c    :   in std_logic;
-         rx_pcs_rst_ch0_c    :   in std_logic;
-         rx_pwrup_ch0_c    :   in std_logic;
-         rx_los_low_ch0_s   :   out std_logic;
-         rx_cdr_lol_ch0_s   :   out std_logic;
-         tx_div2_mode_ch0_c   : in std_logic;
-         rx_div2_mode_ch0_c   : in std_logic;
-         lsm_status_ch0_s : OUT std_logic;
-         
-         -- CH1 --
-         -- CH2 --
-         -- CH3 --
-         ---- Miscillaneous ports
-         sci_wrdata    :   in std_logic_vector (7 downto 0);
-         sci_addr    :   in std_logic_vector (5 downto 0);
-         sci_rddata   :   out std_logic_vector (7 downto 0);
-         sci_sel_quad    :   in std_logic;
-         sci_rd    :   in std_logic;
-         sci_wrn    :   in std_logic;
-         sci_int    :   out std_logic;
-         fpga_txrefclk  :   in std_logic;
-         tx_serdes_rst_c    :   in std_logic;
-         tx_pll_lol_qd_s   :   out std_logic;
-         rst_qd_c    :   in std_logic;
-   --      refclk2fpga   :   out std_logic;
-         serdes_rst_qd_c    :   in std_logic
+   COMPONENT cbmnet_sfp1
+   PORT(
+      hdinp_ch0 : IN std_logic;
+      hdinn_ch0 : IN std_logic;
+      sci_sel_ch0 : IN std_logic;
+      txiclk_ch0 : IN std_logic;
+      fpga_rxrefclk_ch0 : IN std_logic;
+      txdata_ch0 : IN std_logic_vector(15 downto 0);
+      tx_k_ch0 : IN std_logic_vector(1 downto 0);
+      tx_force_disp_ch0 : IN std_logic_vector(1 downto 0);
+      tx_disp_sel_ch0 : IN std_logic_vector(1 downto 0);
+      rx_serdes_rst_ch0_c : IN std_logic;
+      sb_felb_ch0_c : IN std_logic;
+      sb_felb_rst_ch0_c : IN std_logic;
+      tx_pcs_rst_ch0_c : IN std_logic;
+      tx_pwrup_ch0_c : IN std_logic;
+      rx_pcs_rst_ch0_c : IN std_logic;
+      rx_pwrup_ch0_c : IN std_logic;
+      tx_div2_mode_ch0_c : IN std_logic;
+      rx_div2_mode_ch0_c : IN std_logic;
+      sci_wrdata : IN std_logic_vector(7 downto 0);
+      sci_addr : IN std_logic_vector(5 downto 0);
+      sci_sel_quad : IN std_logic;
+      sci_rd : IN std_logic;
+      sci_wrn : IN std_logic;
+      fpga_txrefclk : IN std_logic;
+      tx_serdes_rst_c : IN std_logic;
+      rst_qd_c : IN std_logic;
+      serdes_rst_qd_c : IN std_logic;          
+      hdoutp_ch0 : OUT std_logic;
+      hdoutn_ch0 : OUT std_logic;
+      rx_full_clk_ch0 : OUT std_logic;
+      rx_half_clk_ch0 : OUT std_logic;
+      tx_full_clk_ch0 : OUT std_logic;
+      tx_half_clk_ch0 : OUT std_logic;
+      rxdata_ch0 : OUT std_logic_vector(7 downto 0);
+      rx_k_ch0 : OUT std_logic;
+      rx_disp_err_ch0 : OUT std_logic;
+      rx_cv_err_ch0 : OUT std_logic;
+      rx_los_low_ch0_s : OUT std_logic;
+      lsm_status_ch0_s : OUT std_logic;
+      rx_cdr_lol_ch0_s : OUT std_logic;
+      sci_rddata : OUT std_logic_vector(7 downto 0);
+      tx_pll_lol_qd_s : OUT std_logic
       );
-   end component;
+   END COMPONENT;
    
    component cbmnet_phy_ecp3_rx_reset_fsm is
       port (
diff --git a/cbmnet/code/cbmnet_pkg.vhd b/cbmnet/code/cbmnet_pkg.vhd
deleted file mode 100644 (file)
index da8f286..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-library ieee;
-   use ieee.std_logic_1164.all;
-   use ieee.numeric_std.all;
-
-package cbmnet_interface_pkg is
-   constant K280 : std_logic_vector(7 downto 0) := "00011100";
-   constant K281 : std_logic_vector(7 downto 0) := "00111100";
-   constant K282 : std_logic_vector(7 downto 0) := "01011100";
-   constant K283 : std_logic_vector(7 downto 0) := "01111100";
-   constant K284 : std_logic_vector(7 downto 0) := "10011100";
-   constant K285 : std_logic_vector(7 downto 0) := "10111100";
-   constant K286 : std_logic_vector(7 downto 0) := "11011100";
-   constant K287 : std_logic_vector(7 downto 0) := "11111100";
-   constant K237 : std_logic_vector(7 downto 0) := "11111110";
-   constant K277 : std_logic_vector(7 downto 0) := "11111011";
-   constant K297 : std_logic_vector(7 downto 0) := "11111101";
-   constant K307 : std_logic_vector(7 downto 0) := "11111110";
-
-   component gtp_rx_ready_module is
-      generic (
-         READY_CHAR0  : std_logic_vector(7 downto 0) :=  K284;
-         READY_CHAR1  : std_logic_vector(7 downto 0) :=  K287;
-         ALIGN_CHAR  : std_logic_vector(7 downto 0) :=  K285;
-         DATAWIDTH  : integer :=  16;
-         WORDS : integer := 2; --DATAWIDTH/8;
-         
-         INCL_8B10B_DEC : integer range 0 to 1 := 1
-      );
-      port (
-         clk : in std_logic;
-         res_n : in std_logic;
-         ready_MGT2RM : in std_logic;
-         rxdata_in : in std_logic_vector((WORDS*10)-1 downto 0);
-
-         tx_ready : in std_logic;
-         tx_almost_ready : in std_logic;
-
-         ready_RM2LP : out std_logic;
-         almost_ready_OUT : out std_logic;
-         rxdata_out : out std_logic_vector((DATAWIDTH-1) downto 0);
-         charisk_out : out std_logic_vector((WORDS-1) downto 0);
-         see_ready0 : out std_logic;
-         saw_ready1 : out std_logic;
-         valid_char : out std_logic;
-         reset_rx : out std_logic
-      );
-   end component;
-
-   component gtp_tx_ready_module is
-      generic (
-         READY_CHAR0  : std_logic_vector(7 downto 0) :=  K284;
-         READY_CHAR1  : std_logic_vector(7 downto 0) :=  K287;
-         ALIGN_CHAR  : std_logic_vector(7 downto 0) :=  K285;
-         DATAWIDTH  : integer :=  16;
-         WORDS :integer := 2 --DATAWIDTH/8;
-      );
-      port (
-         clk : in std_logic;
-         res_n : in std_logic;
-         restart_link : in std_logic;
-         ready_MGT2RM : in std_logic;
-         txdata_in : in std_logic_vector((DATAWIDTH-1) downto 0);
-         txcharisk_in : in std_logic_vector((WORDS-1) downto 0);
-
-         see_ready0 : in std_logic;
-         saw_ready1 : in std_logic;
-         valid_char : in std_logic;
-         rx_rm_ready : in std_logic;
-
-         ready_RM2LP : out std_logic;
-         txdata_out : out std_logic_vector((WORDS*9)-1 downto 0);
-         almost_ready : out std_logic;
-         gt11_reinit : out std_logic
-      );
-   end component;
-
-   component lp_top is 
-      generic (
-         NUM_LANES : integer := 1;  -- Number of data lanes
-         TX_SLAVE  : integer := 0   -- If set; module will act as TX slave; otherwise as RX slave
-                                   -- If only one lane is used; parameter does not matter
-      );
-      port (
-         clk               : in  std_logic; -- Main clock
-         res_n             : in  std_logic; -- Active low reset; can be changed by define
-         link_active       : out std_logic; -- link is active and can send and receive data
-
-         ctrl2send_stop    : out std_logic; -- send control interface
-         ctrl2send_start   : in  std_logic;
-         ctrl2send_end     : in  std_logic;
-         ctrl2send         : in  std_logic_vector(15 downto 0);
-
-         data2send_stop    : out std_logic_vector(NUM_LANES-1 downto 0); -- send data interface
-         data2send_start   : in  std_logic_vector(NUM_LANES-1 downto 0);
-         data2send_end     : in  std_logic_vector(NUM_LANES-1 downto 0);
-         data2send         : in  std_logic_vector((16*NUM_LANES)-1 downto 0);
-
-         dlm2send_va       : in  std_logic;                      -- send dlm interface
-         dlm2send          : in  std_logic_vector(3 downto 0);
-
-         dlm_rec_type      : out std_logic_vector(3 downto 0);   -- receive dlm interface
-         dlm_rec_va        : out std_logic;
-
-         data_rec          : out std_logic_vector((16*NUM_LANES)-1 downto 0);   -- receive data interface
-         data_rec_start    : out std_logic_vector(NUM_LANES-1 downto 0);
-         data_rec_end      : out std_logic_vector(NUM_LANES-1 downto 0);         
-         data_rec_stop     : in  std_logic_vector(NUM_LANES-1 downto 0);  
-                     
-         ctrl_rec          : out std_logic_vector(15 downto 0);       -- receive control interface
-         ctrl_rec_start    : out std_logic;
-         ctrl_rec_end      : out std_logic;                 
-         ctrl_rec_stop     : in  std_logic;
-                     
-         data_from_link    : in  std_logic_vector((18*NUM_LANES)-1 downto 0);   -- interface from the PHY
-         data2link         : out std_logic_vector((18*NUM_LANES)-1 downto 0);   -- interface to the PHY
-
-         link_activeovr    : in  std_logic; -- Overrides; set 0 by default
-         link_readyovr     : in  std_logic;
-
-         SERDES_ready      : in  std_logic    -- signalize when PHY ready
-      );
-   end component;
-   
-   
-   
-end package cbmnet_interface_pkg;
-
-package body cbmnet_interface_pkg is
-end package body;
\ No newline at end of file
index fd58eed5bcfcefcb6a3d5820c26b1918b8d9d4e4..939fd0d2db8f8a1aa373328cd928f3db6f3fb5b8 100755 (executable)
@@ -31,13 +31,6 @@ if ($build_master and $build_slave) {
    system "xterm -e './compile_periph_frankfurt.pl s; read' &";
    sleep 5;
    system "xterm -e './compile_periph_frankfurt.pl w; read' &";      
-   sleep 5;
-   local $| = 1;
-   while ( (-e '.lock_slave') or (-e '.lock_master')) {
-      sleep 3;
-      print '.';
-   }
-   
    exit;
 }
 
@@ -55,7 +48,6 @@ my $lm_license_file_for_par      = "1702\@hadeb05.gsi.de";
 
 my $workdir = "workdir_" . ($build_slave ? 'slave' : 'master');
 
-system "touch .lock_" . ($build_slave ? 'slave' : 'master');
 symlink($CbmNetPath, 'cbmnet') unless (-e 'cbmnet');
 
 unless(-e $workdir) {
@@ -182,14 +174,6 @@ execute($c);
 
 chdir "..";
 
-unlink ".lock_" . ($build_slave ? 'slave' : 'master');
-
-print "DONE\n";
-
-unless (-e "$workdir/trb3_periph_cbmnet.bit") {
-   print "no bit file found. press enter to continue\n\a"; <>;
-}
-  
 
 sub execute {
     my ($c, $op) = @_;
index c00e9abc7bd49cf4323080e853aa43a720e73128..97db0e199802de5ea993920128330fb8cad10ea2 100644 (file)
@@ -14,7 +14,7 @@ use work.cbmnet_phy_pkg.all;
 
 entity trb3_periph_cbmnet is
    generic (
-      CBM_FEE_MODE : integer := c_YES -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received
+      CBM_FEE_MODE : integer := CBM_FEE_MODE_C -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received
                                      -- in Master mode, logic will run on internal clock and regularly send dlms
    );
    port(
@@ -281,6 +281,8 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is
 
    signal phy_stat_op,    phy_ctrl_op    : std_logic_vector(15 downto 0) := (others => '0');
    signal phy_stat_debug, phy_ctrl_debug : std_logic_vector(63 downto 0) := (others => '0');
+   
+   signal phy_debug_i : std_logic_vector (127 downto 0) := (others => '0');
 
 begin
    clk_125_i <= CLK_GPLL_LEFT; 
@@ -330,7 +332,8 @@ begin
       STAT_OP            => phy_stat_op,
       CTRL_OP            => phy_ctrl_op,
       STAT_DEBUG         => phy_stat_debug,
-      CTRL_DEBUG         => phy_ctrl_debug
+      CTRL_DEBUG         => phy_ctrl_debug,
+      DEBUG_OUT          => phy_debug_i
    );
 
    SFP_RATESEL   <= (others => '1');
@@ -421,12 +424,17 @@ begin
       
       debug_ack <= debug_read_en or debug_write_en;
       case (address) is
-         when 0 => debug_data_out <= x"0000" & phy_stat_op;
-         when 1 => debug_data_out <= x"0000" & phy_ctrl_op;
-         when 2 => debug_data_out <= phy_stat_debug(31 downto  0);
-         when 3 => debug_data_out <= phy_stat_debug(63 downto 32);
-         when 4 => debug_data_out <= phy_ctrl_debug(31 downto  0);
-         when 5 => debug_data_out <= phy_ctrl_debug(63 downto 32);
+         when 0  => debug_data_out <= x"0000" & phy_stat_op;
+         when 1  => debug_data_out <= x"0000" & phy_ctrl_op;
+         when 2  => debug_data_out <= phy_stat_debug(31 downto  0);
+         when 3  => debug_data_out <= phy_stat_debug(63 downto 32);
+         when 4  => debug_data_out <= phy_ctrl_debug(31 downto  0);
+         when 5  => debug_data_out <= phy_ctrl_debug(63 downto 32);
+         when 6  => debug_data_out <= STD_LOGIC_VECTOR(TO_UNSIGNED(CBM_FEE_MODE, 32));
+         when 8  => debug_data_out <= phy_debug_i(31+32*0 downto 32*0);
+         when 9  => debug_data_out <= phy_debug_i(31+32*1 downto 32*1);
+         when 10 => debug_data_out <= phy_debug_i(31+32*2 downto 32*2);
+         when 11 => debug_data_out <= phy_debug_i(31+32*3 downto 32*3);         
          when others => debug_ack <= '0';
       end case;
    
@@ -439,7 +447,8 @@ begin
          end case;
       end if;
    end process;
-      
+    
+   --TEST_LINE <= phy_stat_op;
       
 ---------------------------------------------------------------------------
 -- Reset Generation