--- /dev/null
+--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;
+