]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
new ECP5 media interface for 2 links
authorJan Michel <j.michel@gsi.de>
Thu, 19 Nov 2020 16:13:39 +0000 (17:13 +0100)
committerJan Michel <j.michel@gsi.de>
Thu, 19 Nov 2020 16:33:46 +0000 (17:33 +0100)
media_interfaces/med_ecp5_sfp_sync_2.vhd [new file with mode: 0644]

diff --git a/media_interfaces/med_ecp5_sfp_sync_2.vhd b/media_interfaces/med_ecp5_sfp_sync_2.vhd
new file mode 100644 (file)
index 0000000..4e22911
--- /dev/null
@@ -0,0 +1,330 @@
+--Media interface for Lattice ECP5 using PCS at 2GHz
+
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.config.all;
+use work.trb_net_components.all;
+use work.med_sync_define.all;
+
+entity med_ecp5_sfp_sync_2 is
+  generic(
+    IS_SYNC_SLAVE   : int_array_t(0 to 1) := (c_YES, c_NO) --select slave mode
+    );
+  port(
+    CLK_REF_FULL       : in  std_logic; -- 200 MHz reference clock
+    CLK_INTERNAL_FULL  : in  std_logic; -- internal 200 MHz, always on
+    SYSCLK             : in  std_logic; -- 100 MHz main clock net, synchronous to RX clock
+    RESET              : in  std_logic; -- synchronous reset
+    CLEAR              : in  std_logic; -- asynchronous reset
+    --Internal Connection TX
+    MEDIA_MED2INT      : out med2int_array_t(0 to 1);
+    MEDIA_INT2MED      : in  int2med_array_t(0 to 1);
+    
+    --Sync operation
+--     RX_DLM             : out std_logic_vector(1 downto 0)  := x"0";
+--     RX_DLM_WORD        : out std_logic_vector(31 downto 0) := (others => '0');
+--     TX_DLM             : in  std_logic_vector(1 downto 0)  := x"0";
+--     TX_DLM_WORD        : in  std_logic_vector(31 downto 0) := (others => '0');
+    
+    --SFP Connection
+    SD_PRSNT_N_IN      : in  std_logic_vector(1 downto 0);  -- SFP Present ('0' = SFP in place, '1' = no SFP mounted)
+    SD_LOS_IN          : in  std_logic_vector(1 downto 0);  -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
+    SD_TXDIS_OUT       : out  std_logic_vector(1 downto 0) := x"0"; -- SFP disable
+    --Control Interface
+    BUS_RX             : in  CTRLBUS_RX;
+    BUS_TX             : out CTRLBUS_TX
+
+    -- Status and control port
+--     STAT_DEBUG         : out std_logic_vector (63 downto 0);
+--     CTRL_DEBUG         : in  std_logic_vector (63 downto 0) := (others => '0')
+   );
+end entity;
+
+
+architecture arch of med_ecp5_sfp_sync_4 is
+
+
+  -- Placer Directives
+  attribute HGROUP : string;
+  -- for whole architecture
+  attribute HGROUP of arch : architecture  is "media_interface_group";
+  attribute syn_sharing : string;
+  attribute syn_sharing of arch : architecture is "off";
+  attribute syn_hier : string;
+  attribute syn_hier of arch : architecture is "hard";
+
+-- signal clk_200_i         : std_logic;
+signal clk_200_ref       : std_logic;
+signal clk_rx_full : std_logic_vector(1 downto 0);
+signal clk_tx_full : std_logic_vector(1 downto 0);
+signal reset_n     : std_logic;
+
+signal tx_data           : std_logic_vector_array_8(0 to 1);
+signal tx_k              : std_logic_vector(1 downto 0);
+signal rx_data           : std_logic_vector_array_8(0 to 1);
+signal rx_k              : std_logic_vector(1 downto 0);
+signal rx_error          : std_logic_vector(1 downto 0);
+
+signal rst_n             : std_logic;
+signal rx_serdes_rst     : std_logic_vector(1 downto 0);
+signal tx_serdes_rst     : std_logic_vector(1 downto 0);
+signal tx_pcs_rst        : std_logic_vector(1 downto 0);
+signal rx_pcs_rst        : std_logic_vector(1 downto 0);
+signal rst_qd            : std_logic_vector(1 downto 0);
+signal serdes_rst_qd     : std_logic_vector(1 downto 0);
+
+signal rx_los_low        : std_logic_vector(1 downto 0);
+signal lsm_status        : std_logic_vector(1 downto 0);
+signal rx_cdr_lol        : std_logic_vector(1 downto 0);
+signal tx_pll_lol        : std_logic;
+
+signal sci_ch_i          : std_logic_vector(4 downto 0);
+signal sci_addr_i        : std_logic_vector(5 downto 0);
+signal sci_data_in_i     : std_logic_vector(7 downto 0);
+signal sci_data_out_i    : std_logic_vector(7 downto 0);
+signal sci_read_i        : std_logic;
+signal sci_write_i       : std_logic;
+
+signal wa_position        : std_logic_vector(7 downto 0) := x"FF";
+signal wa_position_sel    : std_logic_vector(1 downto 0);
+
+signal stat_rx_control_i  : std_logic_vector(63 downto 0);
+signal stat_tx_control_i  : std_logic_vector(63 downto 0);
+signal debug_rx_control_i : std_logic_vector(63 downto 0);
+signal debug_tx_control_i : std_logic_vector(63 downto 0);
+signal stat_fsm_reset_i   : std_logic_vector(63 downto 0);
+signal debug_med_sync_control_i : std_logic_vector(63 downto 0);
+
+signal rx_ready, tx_ready : std_logic_vector(1 downto 0);
+signal  hdinp, hdinn, hdoutp, hdoutn : std_logic_vector(1 downto 0);
+attribute nopad : string;
+attribute nopad of  hdinp, hdinn, hdoutp, hdoutn : signal is "true";
+
+signal stat_med : std_logic_vector(63 downto 0);
+
+begin
+
+reset_n <= not RESET;
+clk_200_ref <= CLK_REF_FULL;
+
+
+gen_txdis : for i in 0 to 1 generate
+  SD_TXDIS_OUT(i) <= not rx_ready(i)  when IS_SYNC_SLAVE(i) = 1 else '0';   --slave only switches on when RX is ready
+end generate;  
+-- SD_TXDIS_OUT <= RESET;
+
+-- gen_slave_clock : if IS_SYNC_SLAVE = c_YES generate
+--   clk_200_i        <= clk_rx_full;
+-- end generate;
+-- 
+-- gen_master_clock : if IS_SYNC_SLAVE = c_NO generate
+--   clk_200_i        <= clk_200_internal;
+-- end generate;
+
+
+-------------------------------------------------      
+-- Serdes
+-------------------------------------------------      
+THE_SERDES : entity work.dual_serdes
+    port map (
+    
+    
+        serdes0_hdinn            => hdinn(0),
+        serdes0_hdinp            => hdinp(0),
+        serdes0_hdoutn           => hdoutn(0),
+        serdes0_hdoutp           => hdoutp(0),        
+        serdes0_lsm_status_s      => lsm_status(0),
+        serdes0_rsl_disable       => '1',
+        serdes0_rsl_rst           => '0',
+        serdes0_rsl_rx_rdy        => rx_ready(0),
+        serdes0_rsl_tx_rdy        => tx_ready(0),
+        serdes0_rst_dual_c        => rst_qd(0), --ON EVERY CHANNEL?
+        serdes0_rx_cdr_lol_s      => rx_cdr_lol(0),
+        serdes0_rx_cv_err(0)      => rx_error(0),
+        serdes0_rxdata            => rx_data(0),
+        serdes0_rx_disp_err       => open,
+        serdes0_rx_k(0)           => rx_k(0),
+        serdes0_rx_los_low_s      => rx_los_low(0),
+        serdes0_rx_pclk           => clk_rx_full(0),
+        serdes0_rx_pcs_rst_c      => rx_pcs_rst(0),
+        serdes0_rx_pwrup_c        => '1',
+        serdes0_rxrefclk          => CLK_INTERNAL_FULL,
+        serdes0_rx_serdes_rst_c   => rx_serdes_rst(0),
+        serdes0_serdes_rst_dual_c => '0',
+        serdes0_signal_detect_c   => '0',
+        serdes0_txdata            => tx_data(0),
+        serdes0_tx_disp_sel(0)    => '0',
+        serdes0_tx_force_disp(0)  => '0',
+        serdes0_tx_idle_c         => '0',
+        serdes0_tx_k(0)           => tx_k(0),
+        serdes0_tx_pclk           => clk_tx_full(0),
+        serdes0_tx_pcs_rst_c      => tx_pcs_rst(0),
+        serdes0_tx_pwrup_c        => '1',
+        serdes0_tx_serdes_rst_c   => '0',  
+
+        serdes1_hdinn            => hdinn(1),
+        serdes1_hdinp            => hdinp(1),
+        serdes1_hdoutn           => hdoutn(1),
+        serdes1_hdoutp           => hdoutp(1),
+        serdes1_lsm_status_s      => lsm_status(1),
+        serdes1_rsl_disable       => '1',
+        serdes1_rsl_rst           => '0',
+        serdes1_rsl_rx_rdy        => rx_ready(1),
+        serdes1_rsl_tx_rdy        => tx_ready(1),
+        serdes1_rst_dual_c        => rst_qd(1),
+        serdes1_rx_cdr_lol_s      => rx_cdr_lol(1),
+        serdes1_rx_cv_err(0)      => rx_error(1),
+        serdes1_rxdata            => rx_data(1),
+        serdes1_rx_disp_err       => open,
+        serdes1_rx_k(0)           => rx_k(1),
+        serdes1_rx_los_low_s      => rx_los_low(1),
+        serdes1_rx_pclk           => clk_rx_full(1),
+        serdes1_rx_pcs_rst_c      => rx_pcs_rst(1),
+        serdes1_rx_pwrup_c        => '1',
+        serdes1_rxrefclk          => CLK_INTERNAL_FULL,
+        serdes1_rx_serdes_rst_c   => rx_serdes_rst(1),
+        serdes1_serdes_rst_dual_c => '0',
+        serdes1_signal_detect_c   => '0',
+        serdes1_txdata            => tx_data(1),
+        serdes1_tx_disp_sel(0)    => '0',
+        serdes1_tx_force_disp(0)  => '0',
+        serdes1_tx_idle_c         => '0',
+        serdes1_tx_k(0)           => tx_k(1),
+        serdes1_tx_pclk           => clk_tx_full(1),
+        serdes1_tx_pcs_rst_c      => tx_pcs_rst(1),
+        serdes1_tx_pwrup_c        => '1',
+        serdes1_tx_serdes_rst_c   => '0', 
+         
+        serdes0_sci_en           => reset_n,
+        serdes0_sci_sel          => sci_ch_i(0),
+        serdes1_sci_addr         => sci_addr_i,
+        serdes1_sci_en_dual      => reset_n,
+        serdes1_sci_en           => reset_n,
+        serdes1_sci_rddata       => sci_data_out_i(7 downto 0),
+        serdes1_sci_rd           => sci_read_i,
+        serdes1_sci_sel_dual     => sci_ch_i(4),
+        serdes1_sci_sel          => sci_ch_i(1),
+        serdes1_sci_wrdata       => sci_data_in_i,
+        serdes1_sci_wrn          => sci_write_i,
+        
+        serdes0_pll_lol          => tx_pll_lol,
+        
+        serdes1_cyawstn          => '0',
+        serdes1_pll_refclki      => CLK_REF_FULL,
+        serdes1_serdes_pdb       => '1'
+    );
+
+
+gen_channels : for i in 0 to 1 generate
+THE_MED_CONTROL : entity work.med_sync_control
+  generic map(
+    IS_SYNC_SLAVE => IS_SYNC_SLAVE(i),
+    IS_TX_RESET   => 1
+    )
+  port map(
+    CLK_SYS     => SYSCLK,
+    CLK_RXI     => clk_rx_full(i), --clk_rx_full,
+    CLK_RXHALF  => '0',
+    CLK_TXI     => clk_tx_full(i), --clk_200_ref, --clk_200_internal, --clk_tx_full, JM150706
+    CLK_REF     => CLK_INTERNAL_FULL,
+    RESET       => RESET,
+    CLEAR       => CLEAR,
+    
+    SFP_LOS     => SD_LOS_IN(i),
+    TX_LOL      => tx_pll_lol,
+    RX_CDR_LOL  => rx_cdr_lol(i),
+    RX_LOS      => rx_los_low(i),
+    WA_POSITION => x"0",
+    
+    RX_SERDES_RST => rx_serdes_rst(i),
+    RX_PCS_RST    => rx_pcs_rst(i),
+    QUAD_RST      => rst_qd(i),
+    TX_PCS_RST    => tx_pcs_rst(i),
+
+    MEDIA_MED2INT => MEDIA_MED2INT(i),
+    MEDIA_INT2MED => MEDIA_INT2MED(i),
+    
+    TX_DATA       => tx_data(i),
+    TX_K          => tx_k(i),
+    RX_DATA       => rx_data(i),
+    RX_K          => rx_k(i),
+    
+    TX_DLM_WORD   => open, --TX_DLM_WORD(i*8+7 downto i*8),
+    TX_DLM        => open, --TX_DLM(i),
+    RX_DLM_WORD   => open, --RX_DLM_WORD(i*8+7 downto i*8),
+    RX_DLM        => open, --RX_DLM(i),
+    
+    SERDES_RX_READY_IN => rx_ready(i),
+    SERDES_TX_READY_IN => tx_ready(i),
+    
+    STAT_TX_CONTROL  => stat_tx_control_i(i*32+31 downto i*32),
+    STAT_RX_CONTROL  => stat_rx_control_i(i*32+31 downto i*32),
+    DEBUG_TX_CONTROL => debug_tx_control_i(i*32+31 downto i*32),
+    DEBUG_RX_CONTROL => debug_rx_control_i(i*32+31 downto i*32),
+    STAT_RESET       => stat_fsm_reset_i(i*32+31 downto i*32),
+    DEBUG_OUT        => debug_med_sync_control_i(i*32+31 downto i*32)
+    );
+
+-- STAT_DEBUG(4 downto 0)   <= debug_rx_control_i(4 downto 0);
+-- STAT_DEBUG(6 downto 5)   <= stat_fsm_reset_i(9 downto 8);
+-- STAT_DEBUG(7)            <= '0';
+-- STAT_DEBUG(15 downto 8)  <= stat_fsm_reset_i(7 downto 0);
+-- STAT_DEBUG(15 downto 0) <= debug_tx_control_i(31 downto 16);
+-- STAT_DEBUG(31 downto 0) <= debug_rx_control_i(31 downto 0);
+-- -- --  STAT_DEBUG(1 downto 0) <= debug_med_sync_control_i(1 downto 0);
+-- -- --  STAT_DEBUG(7 downto 4) <= rx_los_low(0) & lsm_status(0) & rx_cdr_lol(0) & tx_pll_lol;
+--  STAT_DEBUG(9)  <= CLK_REF_FULL;
+--  STAT_DEBUG(10) <= clk_rx_full;
+--  STAT_DEBUG(11) <= clk_tx_full;
+
+
+  stat_med(i*32+0) <= rst_qd(i); 
+  stat_med(i*32+1) <= rx_pcs_rst(i);
+  stat_med(i*32+2) <= tx_pcs_rst(i);
+  stat_med(i*32+3) <= rx_serdes_rst(i);
+  stat_med(i*32+4) <= tx_pll_lol;
+  stat_med(i*32+5) <= rx_cdr_lol(i);
+  stat_med(i*32+6) <= rx_los_low(i);
+  stat_med(i*32+7) <= rx_ready(i);
+  stat_med(i*32+8) <= tx_ready(i);
+  stat_med(i*32+9) <= lsm_status(i);
+  stat_med(i*32+31 downto i*32+10) <= (others => '0');
+end generate; 
+
+THE_SCI_READER : entity work.sci_reader
+  port map(
+    CLK        => SYSCLK,
+    RESET      => RESET,
+    
+    --SCI
+    SCI_WRDATA  => sci_data_in_i,
+    SCI_RDDATA  => sci_data_out_i,
+    SCI_ADDR    => sci_addr_i,
+    SCI_SEL     => sci_ch_i,
+    SCI_RD      => sci_read_i,
+    SCI_WR      => sci_write_i,
+    
+    WA_POS_OUT  => wa_position,
+    
+    --Slowcontrol
+    BUS_RX      => BUS_RX,
+    BUS_TX      => BUS_TX,
+    
+    MEDIA_STATUS_REG_IN(31 downto 0)   => stat_rx_control_i(31 downto 0),
+    MEDIA_STATUS_REG_IN(63 downto 32)  => stat_tx_control_i(31 downto 0),
+    MEDIA_STATUS_REG_IN(95 downto 64)  => stat_fsm_reset_i(31 downto 0),
+    MEDIA_STATUS_REG_IN(159 downto 96) => stat_med,
+    MEDIA_STATUS_REG_IN(255 downto 160) => (others => '0'),
+    DEBUG_OUT   => open
+    );
+end architecture;
+