]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Backup
authorManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Tue, 1 Oct 2013 07:16:38 +0000 (09:16 +0200)
committerManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Tue, 1 Oct 2013 07:16:38 +0000 (09:16 +0200)
cbmnet/code/cbmnet_interface_pkg.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_phy_ecp3.vhd
cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_phy_pkg.vhd
cbmnet/compile_periph_frankfurt.pl

diff --git a/cbmnet/code/cbmnet_interface_pkg.vhd b/cbmnet/code/cbmnet_interface_pkg.vhd
new file mode 100644 (file)
index 0000000..da8f286
--- /dev/null
@@ -0,0 +1,129 @@
+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 7eaf52495ae8aa07f59d54da371cbf700bf2799a..b3a3dae26f85340446092d1557586ec585912db5 100644 (file)
@@ -71,14 +71,17 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    attribute syn_sharing : string;
    attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off";
 
+   constant WA_FIXATION : integer := c_YES;
+   
    signal clk_125_i         : std_logic;
-   signal clk_125_internal  : std_logic;
+   signal clk_125_local  : std_logic;
    signal clk_rx_full       : std_logic;
    signal clk_rx_half       : std_logic;
 
    signal tx_data_i         : std_logic_vector(17 downto 0);
-   signal tx_data_buf_i     : std_logic_vector(17 downto 0);
+   
    signal rx_data_i         : std_logic_vector(17 downto 0);
+   signal rx_data_buf_i     : std_logic_vector(17 downto 0);
    
    signal rx_error          : std_logic_vector(1 downto 0);
 
@@ -91,21 +94,16 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    signal sd_los_i          : std_logic;
 
    signal rx_pcs_rst        : std_logic;
-   signal rx_fsm_pcs_rst    : std_logic:= '0';
-   signal rx_init_pcs_rst   : std_logic:= '0';
-   
    signal rx_serdes_rst     : std_logic;
-   signal rx_fsm_serdes_rst     : std_logic := '0';
-   signal rx_init_serdes_rst     : std_logic := '0';
-
-
-      
+   signal rx_reset_from_rm_i: std_logic;
    
    signal rx_los_low        : std_logic;
    signal rx_cdr_lol        : std_logic;
    signal tx_pll_lol        : std_logic;
    
    signal serdes_ready_i    : std_logic;
+   signal serdes_rx_ready_i : std_logic;
+   signal serdes_tx_ready_i : std_logic;
 
    signal sci_ch_i          : std_logic_vector(3 downto 0);
    signal sci_qd_i          : std_logic;
@@ -119,37 +117,23 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    signal sci_read_shift_i  : std_logic_vector(2 downto 0);
 
    signal wa_position        : std_logic_vector(15 downto 0) := x"FFFF";
-   signal wa_position_rx     : std_logic_vector(15 downto 0) := x"FFFF";
    
-   signal wa_position_buf    : std_logic_vector(3 downto 0);
-   
-   signal request_retr_i     : std_logic;
-   signal start_retr_i       : std_logic;
-   signal request_retr_position_i  : std_logic_vector(7 downto 0);
-   signal start_retr_position_i    : std_logic_vector(7 downto 0);
-   signal send_link_reset_i  : std_logic := '0';
-   signal got_link_ready_i   : std_logic;
-
-   signal stat_rx_control_i  : std_logic_vector(31 downto 0);
-   signal stat_tx_control_i  : std_logic_vector(31 downto 0);
-   signal debug_rx_control_i : std_logic_vector(31 downto 0);
-   signal debug_tx_control_i : std_logic_vector(31 downto 0);
    signal rx_fsm_state       : std_logic_vector(3 downto 0);
    signal tx_fsm_state       : std_logic_vector(3 downto 0);
-   signal debug_reg          : std_logic_vector(63 downto 0);
 
-   type sci_ctrl is (IDLE, SCTRL, SCTRL_WAIT, SCTRL_WAIT2, SCTRL_FINISH, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH);
+   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(12 downto 0) := (others => '0');
+   signal sci_timer         : unsigned(7 downto 0) := (others => '0');
    signal start_timer       : unsigned(18 downto 0) := (others => '0');
 
    signal led_ok                 : std_logic;
    signal led_tx, last_led_tx    : std_logic;
    signal led_rx, last_led_rx    : std_logic;
-   signal timer    : unsigned(20 downto 0);
-   
-   signal lsm_status_i : std_logic;
+   signal led_timer              : unsigned(20 downto 0);
 
+   signal proper_byte_align_i : std_logic;
+   signal proper_word_align_i : std_logic;
+   
    
 -- RX READY MODULE
    signal rx_ready_i : std_logic;
@@ -160,29 +144,27 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
    signal rx_valid_char_i : std_logic;
    signal link_init_rx_reset_i : std_logic;
    
-   signal rx_rm_rst_n :std_logic;
-
+   signal rx_rm_rst_n, tx_rm_rst_n :std_logic;
    
 -- TX READY MODULE   
    signal tx_ready_i : std_logic;
    signal tx_almost_ready_i : std_logic;
 begin
-   clk_125_internal <= CLK;
+   clk_125_local <= CLK;
    CLK_RX_HALF_OUT <= clk_rx_half;
    CLK_RX_FULL_OUT <= clk_rx_full;
 
    SD_TXDIS_OUT <= '0';
 
-   rst_n <= not (CLEAR or sd_los_i or CTRL_OP(0));
-   rst   <=     (CLEAR or sd_los_i or CTRL_OP(0));
-
+   rst   <=     (CLEAR or CTRL_OP(0));
+   rst_n <= not rst;
 
    gen_slave_clock : if IS_SYNC_SLAVE = c_YES generate
       clk_125_i        <= clk_rx_half;
    end generate;
 
    gen_master_clock : if IS_SYNC_SLAVE = c_NO generate
-      clk_125_i        <= clk_125_internal;
+      clk_125_i        <= clk_125_local;
    end generate;
 
    -------------------------------------------------      
@@ -206,7 +188,7 @@ begin
       tx_full_clk_ch0      => open,
       tx_half_clk_ch0      => open,
       
-      fpga_rxrefclk_ch0    => clk_125_internal,
+      fpga_rxrefclk_ch0    => clk_125_local,
 
    -- RESETS
       fpga_txrefclk        => clk_125_i,
@@ -221,8 +203,8 @@ begin
       rx_pwrup_ch0_c       => '1',
    
    -- TX DATA PORT    
-      txdata_ch0           => tx_data_buf_i(15 downto 0),
-      tx_k_ch0             => tx_data_buf_i(17 downto 16),
+      txdata_ch0           => tx_data_i(15 downto 0),
+      tx_k_ch0             => tx_data_i(17 downto 16),
 
       tx_force_disp_ch0    => "00",
       tx_disp_sel_ch0      => "00",
@@ -244,7 +226,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     => lsm_status_i,
+      lsm_status_ch0_s     => open,
     
       SCI_WRDATA           => sci_data_in_i,
       SCI_RDDATA           => sci_data_out_i,
@@ -255,24 +237,19 @@ begin
       SCI_WRN              => sci_write_i
    );
    
-   wa_position_buf <= x"1" when (rx_init_pcs_rst  = '1' and CTRL_OP(2) = '0') or (CTRL_OP(4) = '1') else
-      wa_position_rx(3 downto 0);
-   
-   tx_data_buf_i <=
-    ("01" & x"009c") when CTRL_OP(9 downto 8) = "01" else
-    ("01" & x"00bc") when CTRL_OP(9 downto 8) = "11" else
-    tx_data_i;
-   
-   rx_pcs_rst    <= rx_fsm_pcs_rst;
-   rx_serdes_rst <= rx_fsm_serdes_rst;
-   
    tx_serdes_rst <= '0'; --no function
    serdes_rst_qd <= '0'; --included in rst_qd
    
-   DEBUG_OUT(17    downto  0) <= tx_data_i;
-   DEBUG_OUT(22    downto 20) <= tx_pll_lol & rx_los_low & rx_cdr_lol;
+   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(31 downto 28) <= rst_qd & rx_serdes_rst & tx_pcs_rst & rx_pcs_rst;
    
-   DEBUG_OUT(17+32 downto 32) <= rx_data_i;
+   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(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);
@@ -289,64 +266,102 @@ begin
    -------------------------------------------------      
    -- Reset FSM & Link states
    -------------------------------------------------      
-   THE_RX_FSM : rx_reset_fsm
+   THE_RX_FSM : cbmnet_phy_ecp3_rx_reset_fsm
    port map(
       RST_N               => rst_n,
-      RX_REFCLK           => clk_125_i,
+      RX_REFCLK           => clk_125_local,
       TX_PLL_LOL_QD_S     => tx_pll_lol,
-      RX_SERDES_RST_CH_C  => rx_fsm_serdes_rst,
       RX_CDR_LOL_CH_S     => rx_cdr_lol,
       RX_LOS_LOW_CH_S     => rx_los_low,
-      RX_PCS_RST_CH_C     => rx_fsm_pcs_rst,
-      WA_POSITION         => wa_position_buf,
+      
+      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,
+      
+      RX_SERDES_RST_CH_C  => rx_serdes_rst,
+      RX_PCS_RST_CH_C     => rx_pcs_rst,
       STATE_OUT           => rx_fsm_state
    );
       
    THE_TX_FSM : tx_reset_fsm
    port map(
       RST_N           => rst_n,
-      TX_REFCLK       => clk_125_internal,
+      TX_REFCLK       => clk_125_local,
       TX_PLL_LOL_QD_S => tx_pll_lol,
       RST_QD_C        => rst_qd,
       TX_PCS_RST_CH_C => tx_pcs_rst,
       STATE_OUT       => tx_fsm_state
    );
+   
+   sd_los_i <= SD_LOS_IN when rising_edge(CLK);
 
-   PROC_CLK_RESET: process is
-      variable counter : unsigned(8 downto 0) := (others => '0');
-   begin
-      wait until rising_edge(clk_rx_half);
-      CLK_RX_RESET_OUT <= '1';
+   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;
       
-      if rx_cdr_lol = '1' then
-         counter := (others => '0');
+      rx_data_buf_i <= rx_data_i;
+   end generate;
+   
+   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;
          
-      elsif counter(counter'high) = '0' then
-         counter := counter + 1;
+         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;
          
-      else
-         CLK_RX_RESET_OUT <= '0';
+         delay := rx_data_i(16) & rx_data_i(7 downto 0);
          
-      end if;
-   end process;
-      
-   -- Master does not do bit-locking  
-   SYNC_WA_POSITION : process begin
-      wait until rising_edge(clk_125_i);
-      if IS_SYNC_SLAVE = 1 then
-         wa_position_rx <= wa_position;
-      else
-         wa_position_rx <= x"0000";
-      end if;
-   end process;
+         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;
 
-   serdes_ready_i <= not (rx_cdr_lol or tx_pll_lol) when 
-      wa_position_rx = x"0000" and
-      tx_fsm_state = x"5" and 
-      rx_fsm_state = x"6" else '0';
+         rx_pcs_rst_del := rx_pcs_rst;
+         proper_word_align_i <= locked;
+      end process;
+   end generate;
    
    -------------------------------------------------      
-   -- CBMNet Link Init
+   -- CBMNet Ready Modules
    -------------------------------------------------      
    THE_RX_READY: gtp_rx_ready_module 
    generic map (INCL_8B10B_DEC => c_No)
@@ -355,14 +370,14 @@ begin
       res_n => rx_rm_rst_n,
       ready_MGT2RM => serdes_ready_i,
       
-      rxdata_in(17 downto 0) => rx_data_i,
+      rxdata_in(17 downto 0) => rx_data_buf_i,
       rxdata_in(19 downto 18) => "00",
       tx_ready => tx_ready_i,
       tx_almost_ready => tx_almost_ready_i,
 
       ready_RM2LP => rx_ready_i,
 
-      rxdata_out => PHY_RXDATA_OUT,
+      rxdata_out  => PHY_RXDATA_OUT,
       charisk_out => PHY_RXDATA_K_OUT,
       
       almost_ready_OUT => rx_almost_ready_i,
@@ -370,17 +385,17 @@ begin
       saw_ready1 => rx_saw_ready1_i,
       valid_char => rx_valid_char_i,
       
-      reset_rx => rx_init_pcs_rst
+      reset_rx => rx_reset_from_rm_i
    );
    
-   rx_rm_rst_n <= not (rst or CTRL_OP(1)); -- or not serdes_ready_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;
-      restart_link => CTRL_OP(14),                -- :  in std_logic;
-      ready_MGT2RM => serdes_ready_i,     -- :  in std_logic;
+      res_n => rx_rm_rst_n,               -- :  in std_logic;
+      restart_link => CTRL_OP(14),        -- :  in std_logic;
+      ready_MGT2RM => serdes_tx_ready_i,     -- :  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);
 
@@ -395,6 +410,8 @@ begin
       gt11_reinit => open                 -- :  out std_logic   
    );
    
+   tx_rm_rst_n <= not (rst or CTRL_OP(2) or not serdes_tx_ready_i);
+   
    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);
@@ -407,177 +424,126 @@ begin
    PROC_SCI_CTRL: process 
       variable cnt : integer range 0 to 4 := 0;
    begin
-   wait until rising_edge(CLK);
-   SCI_ACK <= '0';
-   case sci_state is
-      when IDLE =>
-         sci_ch_i        <= x"0";
-         sci_qd_i        <= '0';
-         sci_reg_i       <= '0';
-         sci_read_i      <= '0';
-         sci_write_i     <= '0';
-         sci_timer       <= sci_timer + 1;
-         if SCI_READ = '1' or SCI_WRITE = '1' then
-         sci_ch_i(0)   <= not SCI_ADDR(6) and not SCI_ADDR(7) and not SCI_ADDR(8);
-         sci_ch_i(1)   <=     SCI_ADDR(6) and not SCI_ADDR(7) and not SCI_ADDR(8);
-         sci_ch_i(2)   <= not SCI_ADDR(6) and     SCI_ADDR(7) and not SCI_ADDR(8);
-         sci_ch_i(3)   <=     SCI_ADDR(6) and     SCI_ADDR(7) and not SCI_ADDR(8);
-         sci_qd_i      <= not SCI_ADDR(6) and not SCI_ADDR(7) and     SCI_ADDR(8);
-         sci_reg_i     <=     SCI_ADDR(6) and not SCI_ADDR(7) and     SCI_ADDR(8);
-         sci_addr_i    <= SCI_ADDR;
-         sci_data_in_i <= SCI_DATA_IN;
-         sci_read_i    <= SCI_READ  and not (SCI_ADDR(6) and not SCI_ADDR(7) and     SCI_ADDR(8));
-         sci_write_i   <= SCI_WRITE and not (SCI_ADDR(6) and not SCI_ADDR(7) and     SCI_ADDR(8));
-         sci_state     <= SCTRL;
-         elsif sci_timer(sci_timer'left) = '1' then
-         sci_timer     <= (others => '0');
-         sci_state     <= GET_WA;
-         end if;      
-      when SCTRL =>
-         if sci_reg_i = '1' then
-         SCI_DATA_OUT  <= debug_reg(8*(to_integer(unsigned(SCI_ADDR(3 downto 0))))+7 downto 8*(to_integer(unsigned(SCI_ADDR(3 downto 0)))));
-         SCI_ACK       <= '1';
-         sci_write_i   <= '0';
-         sci_read_i    <= '0';
-         sci_state     <= IDLE;
-         else
-         sci_state     <= SCTRL_WAIT;
-         end if;
-      when SCTRL_WAIT   =>
-         sci_state       <= SCTRL_WAIT2;
-      when SCTRL_WAIT2  =>
-         sci_state       <= SCTRL_FINISH;
-      when SCTRL_FINISH =>
-         SCI_DATA_OUT    <= sci_data_out_i;
-         SCI_ACK         <= '1';
-         sci_write_i     <= '0';
-         sci_read_i      <= '0';
-         sci_state       <= IDLE;
-      
+      wait until rising_edge(CLK);
+      SCI_ACK <= '0';
+      case sci_state is
+         when IDLE =>
+            sci_ch_i        <= x"0";
+            sci_qd_i        <= '0';
+            sci_reg_i       <= '0';
+            sci_read_i      <= '0';
+            sci_write_i     <= '0';
+            sci_timer       <= sci_timer + 1;
+            if sci_timer(sci_timer'left) = '1' then
+               sci_timer     <= (others => '0');
+               sci_state     <= GET_WA;
+            end if;      
+
       when GET_WA =>
-         if cnt = 4 then
-         cnt           := 0;
-         sci_state     <= IDLE;
-         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';
-         end if;
-      when GET_WA_WAIT  =>
-         sci_state       <= GET_WA_WAIT2;
-      when GET_WA_WAIT2 =>
-         sci_state       <= GET_WA_FINISH;
-      when GET_WA_FINISH =>
-         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
-      SCI_NACK <= '1';
-   else
-      SCI_NACK <= '0';
-   end if;
-   
+            if cnt = 4 then
+            cnt           := 0;
+            sci_state     <= IDLE;
+            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';
+            end if;
+         when GET_WA_WAIT  =>
+            sci_state       <= GET_WA_WAIT2;
+            
+         when GET_WA_WAIT2 =>
+            sci_state       <= GET_WA_FINISH;
+            
+         when GET_WA_FINISH =>
+            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
+         SCI_NACK <= '1';
+      else
+         SCI_NACK <= '0';
+      end if;
    end process;
 
    -- RX/TX leds are on as soon as the correspondent pll is locked and data
    -- other than the idle word is transmitted
-   PROC_RX_TX_LEDS: process is
+   PROC_LEDS: process is
    begin
       wait until rising_edge(CLK);
 
       led_rx <= not rx_cdr_lol;
       led_tx <= not tx_pll_lol;
       
-      if (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_i(17 downto 16) = "10" and rx_data_i(15 downto 0) = x"fcce") then
          led_rx <= '0';
       end if;
       
-      if (timer(20) = '1') or (tx_data_i(17 downto 16) = "10" and tx_data_i(15 downto 0) = x"fcce") then
+      if (led_timer(20) = '1') or (tx_data_i(17 downto 16) = "10" and tx_data_i(15 downto 0) = x"fcce") then
          led_tx <= '0';
       end if;
-   end process;
-   
-   ROC_TIMER : process begin
-   wait until rising_edge(CLK);
-   timer <= timer + 1 ;
-   if timer(20) = '1' then
-      timer <= (others => '0');
-      last_led_rx <= led_rx ;
-      last_led_tx <= led_tx;
-   end if;
-   end process;
 
-   -------------------------------------------------      
-   -- Debug Registers
-   -------------------------------------------------            
-   debug_reg(2 downto 0)   <= rx_fsm_state(2 downto 0);
-   debug_reg(3)            <= rx_serdes_rst;
-   
-   debug_reg(4)            <= CLEAR;
-   debug_reg(5)            <= '1';
-   debug_reg(6)            <= rx_los_low;
-   debug_reg(7)            <= rx_cdr_lol;
-
-   debug_reg(8)            <= RESET;
-   debug_reg(9)            <= tx_pll_lol;
-   debug_reg(10)           <= '1';
-   debug_reg(11)           <= CTRL_OP(15);
+      led_timer <= led_timer + 1 ;
+      if led_timer(20) = '1' then
+         led_timer <= (others => '0');
+         last_led_rx <= led_rx ;
+         last_led_tx <= led_tx;
+      end if;      
+   end process;
    
-   debug_reg(12)           <= '0';
-   debug_reg(13)           <= send_link_reset_i;
-   debug_reg(14)           <= sd_los_i;
-   debug_reg(15)           <= rx_pcs_rst;
-   -- debug_reg(31 downto 24) <= tx_data;
-
-   debug_reg(16)           <= '0';
-   debug_reg(17)           <= '1';
-   debug_reg(18)           <= RESET;
-   debug_reg(19)           <= CLEAR;
-   debug_reg(31 downto 20) <= debug_rx_control_i(4) & debug_rx_control_i(2 downto 0) & debug_rx_control_i(15 downto 8);
-
-   debug_reg(35 downto 32) <= wa_position(3 downto 0);
-   debug_reg(36)           <= debug_tx_control_i(6);
-   debug_reg(39 downto 37) <= "000";
-   debug_reg(63 downto 40) <= debug_rx_control_i(23 downto 0);
-
+   PROC_CLK_RESET: process is
+      variable counter : unsigned(8 downto 0) := (others => '0');
+   begin
+      wait until rising_edge(clk_rx_half);
+      CLK_RX_RESET_OUT <= '1';
+      
+      if rx_cdr_lol = '1' then
+         counter := (others => '0');
          
-   STAT_DEBUG <= debug_reg;
-
-   sd_los_i <= SD_LOS_IN when rising_edge(CLK);
-
-   
-   
-   
--- STAT_OP REGISTER   
-   STAT_OP(0) <= led_tx;
-   STAT_OP(1) <= led_rx;
-   STAT_OP(2) <= led_ok;
-   
-   STAT_OP(3) <= rx_valid_char_i;
-   STAT_OP(4) <= rx_see_ready0_i;
-   STAT_OP(5) <= rx_saw_ready1_i;
-   STAT_OP(6) <= rx_almost_ready_i;
-   STAT_OP(7) <= rx_ready_i;
-   STAT_OP(8) <= rx_init_pcs_rst;
-   STAT_OP(9) <= tx_almost_ready_i;
-   STAT_OP(10) <= tx_ready_i;
-   STAT_OP(11) <= rst_n;
-   STAT_OP(12) <= serdes_ready_i;
-   STAT_OP(13) <= lsm_status_i;
-   
-
-   
-   
-  -- STAT_OP(11 downto 8) <= rx_fsm_state;
-   
- --  STAT_OP(15 downto 12) <= wa_position_rx( 3 downto 0);
+      elsif counter(counter'high) = '0' then
+         counter := counter + 1;
+         
+      else
+         CLK_RX_RESET_OUT <= '0';
+         
+      end if;
+   end process;
    
-   --STAT_OP(12) <= rx_los_low;
-   --STAT_OP(13) <= ;
-   --STAT_OP(14) <= ;
-   --STAT_OP(15) <= ;
+-- 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(3) <= rx_valid_char_i;
+--    STAT_OP(4) <= rx_see_ready0_i;
+--    STAT_OP(5) <= rx_saw_ready1_i;
+--    STAT_OP(6) <= rx_almost_ready_i;
+--    STAT_OP(7) <= rx_ready_i;
+--    STAT_OP(8) <= rx_reset_from_rm_i;
+--    STAT_OP(9) <= tx_almost_ready_i;
+--    STAT_OP(10) <= tx_ready_i;
+--    STAT_OP(11) <= serdes_tx_ready_i;
+--    STAT_OP(12) <= proper_byte_align_i;
+--    STAT_OP(13) <= proper_word_align_i;
 end architecture;
diff --git a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd
new file mode 100644 (file)
index 0000000..7d192e7
--- /dev/null
@@ -0,0 +1,184 @@
+--Media interface RX state machine
+-- initial version by lattice tempte
+-- adopted by Jan Michel for sync. TrbNet
+-- adopted by Manuel Penschuck for CbmNet phy
+
+
+LIBRARY IEEE;
+   USE IEEE.std_logic_1164.ALL;
+   USE IEEE.numeric_std.all;
+
+
+entity cbmnet_phy_ecp3_rx_reset_fsm is
+  port (
+    RST_N             : in std_logic;
+    RX_REFCLK         : in std_logic;
+    TX_PLL_LOL_QD_S   : in std_logic;
+    RX_CDR_LOL_CH_S   : in std_logic;
+    RX_LOS_LOW_CH_S   : in std_logic;
+    
+    RM_RESET_IN          : in std_logic := '0';
+    PROPER_BYTE_ALIGN_IN : in std_logic := '1';
+    PROPER_WORD_ALIGN_IN : in std_logic := '1';
+    
+    RX_SERDES_RST_CH_C: out std_logic;
+    RX_PCS_RST_CH_C   : out std_logic;
+    STATE_OUT         : out std_logic_vector(3 downto 0)
+    );
+end entity ;
+                                                                                              
+architecture rx_reset_fsm_arch of cbmnet_phy_ecp3_rx_reset_fsm is
+   constant count_index : integer := 19;
+   type statetype is (WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_timer1, CHECK_LOL_LOS, WAIT_FOR_timer2, NORMAL);
+                                                                                                
+   signal   cs:      statetype;  -- current state of lsm
+   signal   ns:      statetype;  -- next state of lsm
+                                                                                                
+   signal   tx_pll_lol_qd_s_int: std_logic;
+   signal   rx_los_low_int:         std_logic;
+   signal   plol_los_int:        std_logic;
+   signal   rx_lol_los  :  std_logic;
+   signal   rx_lol_los_int:      std_logic;
+   signal   rx_lol_los_del:      std_logic;
+   signal   rx_pcs_rst_ch_c_int: std_logic;
+   signal   rx_serdes_rst_ch_c_int: std_logic;
+                                                                                                
+   signal   reset_timer1:  std_logic;
+   signal   reset_timer2:  std_logic;
+                                                                                                
+   signal   counter1:   unsigned(1 downto 0);
+   signal   timer1:  std_logic;
+                                                                                                
+   signal   counter2: unsigned(19 downto 0);
+   signal   timer2   : std_logic;
+                                        
+   signal rm_reset_i          : std_logic;
+   signal proper_byte_align_i : std_logic;
+   signal proper_word_align_i : std_logic;                                        
+begin
+                                                                                              
+   rx_lol_los <= rx_cdr_lol_ch_s or rx_los_low_ch_s ;
+                                                                                                
+   proc_fsm_sync: process(RX_REFCLK)
+   begin
+   if rising_edge(RX_REFCLK) then
+      if RST_N = '0' then
+         cs <= WAIT_FOR_PLOL;
+         rx_lol_los_int <= '1';
+         rx_lol_los_del <= '1';
+         tx_pll_lol_qd_s_int <= '1';
+         RX_PCS_RST_CH_C <= '1';
+         RX_SERDES_RST_CH_C <= '0';
+         rx_los_low_int <= '1';
+      else
+         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;
+         
+         rm_reset_i <= RM_RESET_IN;
+         proper_byte_align_i <= PROPER_BYTE_ALIGN_IN;
+         proper_word_align_i <= PROPER_WORD_ALIGN_IN;
+      end if;
+   end if;
+   end process;
+                                                                                             
+                                                                                              
+--timer2 = 400,000 Refclk cycles or 200,000 REFCLKDIV2 cycles
+--An 18 bit counter ([17:0]) counts 262144 cycles, so a 19 bit ([18:0]) counter will do if we set timer2 = bit[18]
+  proc_timer2: process begin
+    wait until rising_edge(RX_REFCLK);
+    if reset_timer2 = '1' then
+      counter2 <= "00000000000000000000";
+      timer2 <= '0';
+    else
+      if counter2(count_index) = '1' then
+        timer2 <='1';
+      else
+        timer2 <='0';
+        counter2 <= counter2 + 1 ;
+      end if;
+    end if;
+   end process;
+                                                                                              
+                                                                                              
+   proc_fsm_trans: process(cs, tx_pll_lol_qd_s_int, rx_los_low_int, timer1, rx_lol_los_int, timer2)
+   begin
+   --       reset_timer1 <= '0';
+         reset_timer2 <= '0';
+   STATE_OUT <= x"F";                                                                                              
+   case cs is
+      when WAIT_FOR_PLOL =>
+         rx_pcs_rst_ch_c_int <= '1';
+         rx_serdes_rst_ch_c_int <= '0';
+         if (tx_pll_lol_qd_s_int = '1' or rx_los_low_int = '1') then  --Also make sure A Signal
+            ns <= WAIT_FOR_PLOL;             --is Present prior to moving to the next
+         else
+            ns <= RX_SERDES_RESET;
+         end if;
+         STATE_OUT <= x"1";
+                                                                                             
+      when RX_SERDES_RESET =>
+         rx_pcs_rst_ch_c_int <= '1';
+         rx_serdes_rst_ch_c_int <= '1';
+   --       reset_timer1 <= '1';
+         ns <= WAIT_FOR_timer1;
+         STATE_OUT <= x"2";
+                                                                                             
+                                                                                             
+      when WAIT_FOR_timer1 =>
+         rx_pcs_rst_ch_c_int <= '1';
+         rx_serdes_rst_ch_c_int <= '1';
+         ns <= CHECK_LOL_LOS;
+         STATE_OUT <= x"3";
+
+      when CHECK_LOL_LOS =>
+         rx_pcs_rst_ch_c_int <= '1';
+         rx_serdes_rst_ch_c_int <= '0';
+         reset_timer2 <= '1';
+         ns <= WAIT_FOR_timer2;
+         STATE_OUT <= x"4";
+
+      when WAIT_FOR_timer2 =>
+         rx_pcs_rst_ch_c_int <= '1';
+         rx_serdes_rst_ch_c_int <= '0';
+         if rx_lol_los_int = rx_lol_los_del then   --NO RISING OR FALLING EDGES
+            if timer2 = '1' then
+               if rx_lol_los_int = '1' then
+                  ns <= WAIT_FOR_PLOL;
+   --            elsif proper_byte_align_i = '0' or proper_word_align_i = '0' then
+   --               ns <= CHECK_LOL_LOS;
+               else
+                  ns <= NORMAL;
+               end if;
+            elsif rx_lol_los_int = '0' then
+               ns <= NORMAL;
+            else
+               ns <= WAIT_FOR_timer2;
+            end if;
+         else
+            ns <= CHECK_LOL_LOS;    --RESET timer2
+         end if;
+         STATE_OUT <= x"5";
+
+                                                                                             
+      when NORMAL =>
+         rx_pcs_rst_ch_c_int <= '0';
+         rx_serdes_rst_ch_c_int <= '0';
+         if rx_lol_los_int = '1' or proper_byte_align_i = '0' or proper_word_align_i = '0' or rm_reset_i = '1' then
+            ns <= WAIT_FOR_PLOL;
+         else
+            ns <= NORMAL;
+         end if;
+         STATE_OUT <= x"6";
+                                                                                             
+      when others =>
+         ns <= WAIT_FOR_PLOL;
+                                                                                             
+   end case;
+   end process;
+                                                                                              
+end architecture;
\ No newline at end of file
index c8cb47a0961710de303335a8fe05045506994562..3adddc2fab847dc9af2ba0fa6d93d18023879fbb 100644 (file)
@@ -114,7 +114,25 @@ package cbmnet_phy_pkg is
    --      refclk2fpga   :   out std_logic;
          serdes_rst_qd_c    :   in std_logic
       );
-   end component;  
+   end component;
+   
+   component cbmnet_phy_ecp3_rx_reset_fsm is
+      port (
+         RST_N             : in std_logic;
+         RX_REFCLK         : in std_logic;
+         TX_PLL_LOL_QD_S   : in std_logic;
+         RX_CDR_LOL_CH_S   : in std_logic;
+         RX_LOS_LOW_CH_S   : in std_logic;
+
+         RM_RESET_IN          : in std_logic := '0';
+         PROPER_BYTE_ALIGN_IN : in std_logic := '1';
+         PROPER_WORD_ALIGN_IN : in std_logic := '1';
+
+         RX_SERDES_RST_CH_C: out std_logic;
+         RX_PCS_RST_CH_C   : out std_logic;
+         STATE_OUT         : out std_logic_vector(3 downto 0)
+      );
+   end component ;
 end package cbmnet_phy_pkg;
 
 package body cbmnet_phy_pkg is
index 939fd0d2db8f8a1aa373328cd928f3db6f3fb5b8..fd58eed5bcfcefcb6a3d5820c26b1918b8d9d4e4 100755 (executable)
@@ -31,6 +31,13 @@ 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;
 }
 
@@ -48,6 +55,7 @@ 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) {
@@ -174,6 +182,14 @@ 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) = @_;