From a26a6d72d7c968df4b2c958358ce40322f074476 Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Wed, 17 Nov 2021 07:54:01 +0100 Subject: [PATCH] first RS media interface --- .../med_ecp3_sfp_sync_full_RS.vhd | 394 ++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 media_interfaces/med_ecp3_sfp_sync_full_RS.vhd diff --git a/media_interfaces/med_ecp3_sfp_sync_full_RS.vhd b/media_interfaces/med_ecp3_sfp_sync_full_RS.vhd new file mode 100644 index 0000000..d8fe468 --- /dev/null +++ b/media_interfaces/med_ecp3_sfp_sync_full_RS.vhd @@ -0,0 +1,394 @@ +--four links, all with receive buffers, as masters only. + + + +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; + +entity med_ecp3_sfp_sync_full_RS is + generic( + IS_MODE : int_array_t(0 to 3) := (IS_UNUSED, IS_UNUSED, IS_UNUSED, IS_UNUSED); + ); + 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/RX + MEDIA_MED2INT : out med2int_array_t(0 to 3); + MEDIA_INT2MED : in int2med_array_t(0 to 3); + + --Sync operation + RX_DLM_OUT : out std_logic_vector(3 downto 0) := x"0"; + RX_DLM_WORD_OUT : out std_logic_vector(4*8-1 downto 0) := (others => '0'); + TX_DLM_IN : in std_logic_vector(3 downto 0) := x"0"; + TX_DLM_WORD_IN : in std_logic_vector(4*8-1 downto 0) := (others => '0'); + WORD_SYNC_IN : in std_logic := '1'; + WORD_SYNC_OUT : out std_logic; + SYNC_TX_PLL_IN : in std_logic; + SYNC_TX_PLL_OUT : out std_logic; + + --SFP Connection + SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in std_logic_vector(3 downto 0); -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out std_logic_vector(3 downto 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 med_ecp3_sfp_sync_full_RS_arch of med_ecp3_sfp_sync_full_RS is + + -- Placer Directives + attribute HGROUP : string; + -- for whole architecture + attribute HGROUP of med_ecp3_sfp_sync_4_arch : architecture is "media_interface_group"; + attribute syn_sharing : string; + attribute syn_sharing of med_ecp3_sfp_sync_4_arch : architecture is "off"; + attribute syn_hier : string; + attribute syn_hier of med_ecp3_sfp_sync_4_arch : architecture is "hard"; + + signal clk_200_i : std_logic; + signal clk_rx_full : std_logic_vector(3 downto 0); + signal clk_rx_half : std_logic_vector(3 downto 0); + signal clk_tx_full : std_logic_vector(3 downto 0); + signal clk_tx_half : std_logic_vector(3 downto 0); + + signal tx_data : std_logic_vector(4*8-1 downto 0); + signal tx_k : std_logic_vector(3 downto 0); + signal tx_cd : std_logic_vector(3 downto 0); + signal rx_data : std_logic_vector(4*8-1 downto 0); + signal rx_k : std_logic_vector(3 downto 0); + signal rx_error : std_logic_vector(3 downto 0); + + signal rst_n : std_logic; + signal rx_serdes_rst : std_logic_vector(3 downto 0); + signal tx_serdes_rst : std_logic_vector(3 downto 0); + signal tx_pcs_rst : std_logic_vector(3 downto 0); + signal rx_pcs_rst : std_logic_vector(3 downto 0); + signal rst_qd : std_logic_vector(3 downto 0); + signal serdes_rst_qd : std_logic_vector(3 downto 0); + + signal rx_los_low : std_logic_vector(3 downto 0); + signal lsm_status : std_logic_vector(3 downto 0); + signal rx_cdr_lol : std_logic_vector(3 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(15 downto 0) := x"FFFF"; + signal wa_position_sel : std_logic_vector(3 downto 0); + + signal stat_rx_control_i : std_logic_vector(4*32-1 downto 0); + signal stat_tx_control_i : std_logic_vector(4*32-1 downto 0); + signal debug_rx_control_i : std_logic_vector(4*32-1 downto 0); + signal debug_tx_control_i : std_logic_vector(4*32-1 downto 0); + signal stat_fsm_reset_i : std_logic_vector(4*32-1 downto 0); + + signal hdinp, hdinn, hdoutp, hdoutn : std_logic_vector(3 downto 0); + attribute nopad : string; + attribute nopad of hdinp, hdinn, hdoutp, hdoutn : signal is "true"; + + type u8_arr is array (0 to 3) of unsigned(7 downto 0); + signal cv_cnt, cv_cnt_sys : u8_arr; + + signal powerup_ch : std_logic_vector(3 downto 0); + +begin + +------------------------------------------------- +-- only used SerDes are activated +------------------------------------------------- +powerup_ch(3) <= '0' if IS_MODE(3) = IS_UNUSED else '1'; +powerup_ch(2) <= '0' if IS_MODE(2) = IS_UNUSED else '1'; +powerup_ch(1) <= '0' if IS_MODE(1) = IS_UNUSED else '1'; +powerup_ch(0) <= '0' if IS_MODE(0) = IS_UNUSED else '1'; + +------------------------------------------------- +------------------------------------------------- + +------------------------------------------------- +------------------------------------------------- + + +------------------------------------------------- +-- will be used for link reset later +------------------------------------------------- + SD_TXDIS_OUT <= (others => '0'); + +------------------------------------------------- +-- Serdes +------------------------------------------------- + THE_SERDES : entity work.serdes_sync_full_RS + port map( + hdinp_ch0 => hdinp(0), + hdinn_ch0 => hdinn(0), + hdoutp_ch0 => hdoutp(0), + hdoutn_ch0 => hdoutn(0), + txiclk_ch0 => CLK_REF_FULL, -- drives TX FIFO bridge + rxiclk_ch0 => clk_rx_full(0), -- drives RX FIFO bridge + rx_full_clk_ch0 => clk_rx_full(0), -- recovered RX clock + rx_half_clk_ch0 => clk_rx_half(0), + tx_full_clk_ch0 => clk_tx_full(0), -- TX clock from PLL + tx_half_clk_ch0 => clk_tx_half(0), + fpga_rxrefclk_ch0 => CLK_INTERNAL_FULL, -- reference RX clock + txdata_ch0 => tx_data(0*8+7 downto 0*8), + tx_k_ch0 => tx_k(0), + tx_force_disp_ch0 => tx_cd(0), + tx_disp_sel_ch0 => '0', + rxdata_ch0 => rx_data(0*8+7 downto 0*8), + rx_k_ch0 => rx_k(0), + rx_disp_err_ch0 => open, + rx_cv_err_ch0 => rx_error(0), + rx_serdes_rst_ch0_c => rx_serdes_rst(0), + sb_felb_ch0_c => '0', + sb_felb_rst_ch0_c => '0', + tx_pcs_rst_ch0_c => tx_pcs_rst(0), + tx_pwrup_ch0_c => powerup_ch(0), -- new + rx_pcs_rst_ch0_c => rx_pcs_rst(0), + rx_pwrup_ch0_c => powerup_ch(0), -- new + rx_los_low_ch0_s => rx_los_low(0), + lsm_status_ch0_s => lsm_status(0), + rx_cdr_lol_ch0_s => rx_cdr_lol(0), + tx_div2_mode_ch0_c => '0', + rx_div2_mode_ch0_c => '0', + + hdinp_ch1 => hdinp(1), + hdinn_ch1 => hdinn(1), + hdoutp_ch1 => hdoutp(1), + hdoutn_ch1 => hdoutn(1), + txiclk_ch1 => CLK_REF_FULL, + rxiclk_ch1 => clk_rx_full(1), + rx_full_clk_ch1 => clk_rx_full(1), + rx_half_clk_ch1 => clk_rx_half(1), + tx_full_clk_ch1 => clk_tx_full(1), + tx_half_clk_ch1 => clk_tx_half(1), + fpga_rxrefclk_ch1 => CLK_INTERNAL_FULL, + txdata_ch1 => tx_data(1*8+7 downto 1*8), + tx_k_ch1 => tx_k(1), + tx_force_disp_ch1 => tx_cd(1), + tx_disp_sel_ch1 => '0', + rxdata_ch1 => rx_data(1*8+7 downto 1*8), + rx_k_ch1 => rx_k(1), + rx_disp_err_ch1 => open, + rx_cv_err_ch1 => rx_error(1), + rx_serdes_rst_ch1_c => rx_serdes_rst(1), + sb_felb_ch1_c => '0', + sb_felb_rst_ch1_c => '0', + tx_pcs_rst_ch1_c => tx_pcs_rst(1), + tx_pwrup_ch1_c => powerup_ch(1), -- new + rx_pcs_rst_ch1_c => rx_pcs_rst(1), + rx_pwrup_ch1_c => powerup_ch(1), -- new + rx_los_low_ch1_s => rx_los_low(1), + lsm_status_ch1_s => lsm_status(1), + rx_cdr_lol_ch1_s => rx_cdr_lol(1), + tx_div2_mode_ch1_c => '0', + rx_div2_mode_ch1_c => '0', + + hdinp_ch2 => hdinp(2), + hdinn_ch2 => hdinn(2), + hdoutp_ch2 => hdoutp(2), + hdoutn_ch2 => hdoutn(2), + txiclk_ch2 => CLK_REF_FULL, + rxiclk_ch2 => clk_rx_full(2), + rx_full_clk_ch2 => clk_rx_full(2), + rx_half_clk_ch2 => clk_rx_half(2), + tx_full_clk_ch2 => clk_tx_full(2), + tx_half_clk_ch2 => clk_tx_half(2), + fpga_rxrefclk_ch2 => CLK_INTERNAL_FULL, + txdata_ch2 => tx_data(2*8+7 downto 2*8), + tx_k_ch2 => tx_k(2), + tx_force_disp_ch2 => tx_cd(2), + tx_disp_sel_ch2 => '0', + rxdata_ch2 => rx_data(2*8+7 downto 2*8), + rx_k_ch2 => rx_k(2), + rx_disp_err_ch2 => open, + rx_cv_err_ch2 => rx_error(2), + rx_serdes_rst_ch2_c => rx_serdes_rst(2), + sb_felb_ch2_c => '0', + sb_felb_rst_ch2_c => '0', + tx_pcs_rst_ch2_c => tx_pcs_rst(2), + tx_pwrup_ch2_c => powerup_ch(2), -- new + rx_pcs_rst_ch2_c => rx_pcs_rst(2), + rx_pwrup_ch2_c => powerup_ch(2), -- new + rx_los_low_ch2_s => rx_los_low(2), + lsm_status_ch2_s => lsm_status(2), + rx_cdr_lol_ch2_s => rx_cdr_lol(2), + tx_div2_mode_ch2_c => '0', + rx_div2_mode_ch2_c => '0', + + hdinp_ch3 => hdinp(3), + hdinn_ch3 => hdinn(3), + hdoutp_ch3 => hdoutp(3), + hdoutn_ch3 => hdoutn(3), + txiclk_ch3 => CLK_REF_FULL, + rxiclk_ch3 => clk_rx_full(3), + rx_full_clk_ch3 => clk_rx_full(3), + rx_half_clk_ch3 => clk_rx_half(3), + tx_full_clk_ch3 => clk_tx_full(3), + tx_half_clk_ch3 => clk_tx_half(3), + fpga_rxrefclk_ch3 => CLK_INTERNAL_FULL, + txdata_ch3 => tx_data(3*8+7 downto 3*8), + tx_k_ch3 => tx_k(3), + tx_force_disp_ch3 => tx_cd(3), + tx_disp_sel_ch3 => '0', + rxdata_ch3 => rx_data(3*8+7 downto 3*8), + rx_k_ch3 => rx_k(3), + rx_disp_err_ch3 => open, + rx_cv_err_ch3 => rx_error(3), + rx_serdes_rst_ch3_c => rx_serdes_rst(3), + sb_felb_ch3_c => '0', + sb_felb_rst_ch3_c => '0', + tx_pcs_rst_ch3_c => tx_pcs_rst(3), + tx_pwrup_ch3_c => powerup_ch(3), -- new + rx_pcs_rst_ch3_c => rx_pcs_rst(3), + rx_pwrup_ch3_c => powerup_ch(3), -- new + rx_los_low_ch3_s => rx_los_low(3), + lsm_status_ch3_s => lsm_status(3), + rx_cdr_lol_ch3_s => rx_cdr_lol(3), + tx_div2_mode_ch3_c => '0', + rx_div2_mode_ch3_c => '0', + + SCI_WRDATA => sci_data_in_i, + SCI_RDDATA => sci_data_out_i, + SCI_ADDR => sci_addr_i, + SCI_SEL_QUAD => sci_ch_i(4), + SCI_SEL_CH0 => sci_ch_i(0), + SCI_SEL_CH1 => sci_ch_i(1), + SCI_SEL_CH2 => sci_ch_i(2), + SCI_SEL_CH3 => sci_ch_i(3), + SCI_RD => sci_read_i, + SCI_WRN => sci_write_i, + + fpga_txrefclk => CLK_REF_FULL, -- reference TX clock + tx_serdes_rst_c => '0', + tx_pll_lol_qd_s => tx_pll_lol, + rst_qd_c => rst_qd(0), + serdes_rst_qd_c => '0', + tx_sync_qd_c => '0' + ); + + + + + +gen_control : for i in 0 to 3 generate + gen_used_control : if IS_USED(i) = c_YES 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_REF_FULL, + CLK_RXHALF => clk_rx_half(i), + CLK_TXI => CLK_REF_FULL, --clk_tx_full(i), + 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 => wa_position(i*4+3 downto i*4), + + 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*8+7 downto i*8), + TX_K => tx_k(i), + TX_CD => tx_cd(i), + RX_DATA => rx_data(i*8+7 downto i*8), + RX_K => rx_k(i), + + TX_DLM_WORD => TX_DLM_WORD(i*8+7 downto i*8), + TX_DLM => TX_DLM(i), + RX_DLM_WORD => RX_DLM_WORD(i*8+7 downto i*8), + RX_DLM => RX_DLM(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) + ); + + cv_cnt(i) <= cv_cnt(i) + 1 when rx_error(i) = '1' and rising_edge(clk_rx_full(i)); + end generate; + + gen_not_used : if IS_USED(i) = c_NO generate + MEDIA_MED2INT(i).dataready <= '0'; + MEDIA_MED2INT(i).tx_read <= '1'; + MEDIA_MED2INT(i).stat_op <= x"0007"; + end generate; + +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 => open, + + --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(191 downto 64) => stat_fsm_reset_i(127 downto 0), + MEDIA_STATUS_REG_IN(199 downto 192) => cv_cnt_sys(0), + MEDIA_STATUS_REG_IN(207 downto 200) => cv_cnt_sys(1), + MEDIA_STATUS_REG_IN(215 downto 208) => cv_cnt_sys(2), + MEDIA_STATUS_REG_IN(223 downto 216) => cv_cnt_sys(3), + + MEDIA_STATUS_REG_IN(255 downto 224) => (others => '0'), + DEBUG_OUT => open + ); + +cv_cnt_sys <= cv_cnt when rising_edge(SYSCLK); + +wa_position <= (others => '0'); + +STAT_DEBUG(13 downto 0) <= debug_tx_control_i(13 downto 0); +STAT_DEBUG(15 downto 14) <= debug_tx_control_i(17 downto 16); + + +end architecture; + -- 2.43.0