From: Jan Michel Date: Thu, 19 Nov 2020 16:13:39 +0000 (+0100) Subject: new ECP5 media interface for 2 links X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=a7d08093e497fcffcc29763bbcb23b4482c8d168;p=trbnet.git new ECP5 media interface for 2 links --- diff --git a/media_interfaces/med_ecp5_sfp_sync_2.vhd b/media_interfaces/med_ecp5_sfp_sync_2.vhd new file mode 100644 index 0000000..4e22911 --- /dev/null +++ b/media_interfaces/med_ecp5_sfp_sync_2.vhd @@ -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; +