--------------------------------------------------------------------------- -- Paul Scherrer Institute (PSI) -- --------------------------------------------------------------------------- -- Unit : evr320_ifc1210_wrapper.vhd -- Author : Patric Bucher, Benoit Stef -- --------------------------------------------------------------------------- -- Copyright© PSI, Section DSV -- --------------------------------------------------------------------------- -- Comment : Wraps evr320 decoder together with GTX component and TMEM registers. -- --------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; library tosca2; use tosca2.tosca2_glb_pkg.all; use work.evr320_pkg.all; use work.v6vlx_gtxe1_pkg.all; entity evr320_ifc1210_wrapper is generic( g_MGT_LOCATION : string := "GTXE1_X0Y16"; -- "GTXE1_X0Y0" to "GTXE1_X0Y11" | "GTXE1_X0Y16" to "GTXE1_X0Y19" g_FACILITY : string := "SFEL"; -- "HIPA" | "SFEL" g_EVENT_RECORDER : boolean := false; -- enable/disable Event Recorder functionality g_XUSER_CLK_FREQ : natural := 125000000 -- Xuser Clk Frequency in Hz ); port( -- ------------------------------------------------------------------------ -- Debug interface -- ------------------------------------------------------------------------ debug_clk : out std_logic; debug : out std_logic_vector(127 downto 0); -- ------------------------------------------------------------------------ -- TOSCA2 TMEM Interface (xuser clock domain, 100-250MHz) -- ------------------------------------------------------------------------ xuser_CLK : in std_logic; xuser_RESET : in std_logic; xuser_TMEM_ENA : in std_logic; xuser_TMEM_WE : in std_logic_vector(7 downto 0); xuser_TMEM_ADD : in std_logic_vector(13 downto 3); xuser_TMEM_DATW : in std_logic_vector(63 downto 0); xuser_TMEM_DATR : out std_logic_vector(63 downto 0); -- ------------------------------------------------------------------------ -- MGT Interface -- ------------------------------------------------------------------------ mgt_refclk_i : in std_logic; -- MGT Reference Clock mgt_sfp_los_i : in std_logic; -- SFP Loss of Signal (light on receiver) mgt_rx_n : in std_logic; -- MGT RX N mgt_rx_p : in std_logic; -- MGT RX P mgt_tx_n : out std_logic; -- MGT TX N mgt_tx_p : out std_logic; -- MGT TX P mgt_status_o : out std_logic_vector(31 downto 0); -- MGT Status mgt_control_i : in std_logic_vector(31 downto 0); -- MGT Control mgt_rx_data_o : out std_logic_Vector(15 downto 0); -- for debug purpose mgt_rx_charisk_o : out std_logic_vector(1 downto 0); -- for debug purpose --------------------------------------------------------------------------- -- User interface MGT clock --------------------------------------------------------------------------- clk_evr_o : out std_logic; -- Recovered parallel clock from MGT rst_evr_o : out std_logic; -- reset according to RX Loss of sync usr_events_o : out std_logic_vector(3 downto 0); -- User defined event pulses with one clock cycles length & no delay sos_event_o : out std_logic; -- Start-of-Sequence Event usr_events_adj_o : out std_logic_vector(3 downto 0); -- User defined event pulses adjusted in delay & length sos_events_adj_o : out std_logic; -- Start-of-Sequence adjusted in delay & length -------------------------------------------------------------------------- -- Decoder axi stream interface, User clock -------------------------------------------------------------------------- stream_clk_i : in std_logic := '0'; stream_data_o : out std_logic_vector(7 downto 0); stream_addr_o : out std_logic_vector(10 downto 0); stream_valid_o : out std_logic ); end evr320_ifc1210_wrapper; architecture rtl of evr320_ifc1210_wrapper is -- -------------------------------------------------------------------------- -- Parameters -- -------------------------------------------------------------------------- constant c_TOSCA2_DATA_WIDTH : integer := 64; constant c_EVR_REG64_COUNT : integer := 16; -- unused, only documentation constant c_EVR_MEM_SIZE : integer := 16384; -- unused, only documentation -- -------------------------------------------------------------------------- -- Signal definitions -- -------------------------------------------------------------------------- signal clk_evr : std_logic; --signal clk_evr_monitor : std_logic; -- for debugging signal rst_evr : std_logic; signal mgt_control : std_logic_vector(31 downto 0) := (others => '0'); signal mgt_status : std_logic_vector(31 downto 0); signal mgt_rx_data : std_logic_vector(15 downto 0); signal mgt_rx_charisk : std_logic_vector(1 downto 0); signal mgt_lossofsync : std_logic; signal mgt_reset_tmem_evr : std_logic; -- for legacy reasons, ifc1210 mgt control is in tmem_psi_generic part signal mem_clk : std_logic; signal mem_addr_evr : std_logic_vector(11 downto 0); signal mem_addr_tosca : std_logic_vector(10 downto 0); signal mem_data : std_logic_vector(c_TOSCA2_DATA_WIDTH - 1 downto 0); signal evr_params : typ_evr320_params; signal evr_params_sync : typ_evr320_params; signal evr_params_xuser : typ_evr320_params; signal event_recorder_status : typ_evt_rec_status; signal event_recorder_control : typ_evt_rec_ctrl; signal event_recorder_control_sync : typ_evt_rec_ctrl; signal event_recorder_control_xuser : typ_evt_rec_ctrl; signal evr_latency_measure_stat : typ_rec_latency_measure_stat; signal evr_latency_measure_ctrl : typ_rec_latency_measure_ctrl; signal evr_frequency : std_logic_vector(31 downto 0) := (others => '0'); signal debug_data : std_logic_vector(127 downto 0); signal decoder_event_valid : std_logic; signal decoder_event : std_logic_vector(7 downto 0); -- -------------------------------------------------------------------------- -- Attribute definitions -- -------------------------------------------------------------------------- attribute keep : string; attribute keep of clk_evr : signal is "TRUE"; attribute keep of debug_data : signal is "TRUE"; signal usr_events_s : std_logic_vector(3 downto 0); signal sos_event_s : std_logic; signal evr_rst_s : std_logic; signal usr_event_delay_s : typ_arr_delay; signal usr_event_width_s : typ_arr_width; -- ---------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- //////////////////// Main Body ///////////////////////// -- ---------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- begin -- -------------------------------------------------------------------------- -- static signal assignments -- -------------------------------------------------------------------------- mgt_lossofsync <= mgt_status(15); rst_evr_o <= mgt_status(15); mem_addr_evr <= '0' & mem_addr_tosca; mgt_control(c_GTXRESET) <= mgt_control_i(c_GTXRESET) or mgt_sfp_los_i or mgt_reset_tmem_evr; mgt_control(4 downto 1) <= mgt_control_i(4 downto 1); mgt_control(c_RXCDRRESET) <= mgt_control_i(c_RXCDRRESET); mgt_control(31 downto 6) <= mgt_control_i(31 downto 6); -- -------------------------------------------------------------------------- -- Synchronisation to EVR Clock -- -------------------------------------------------------------------------- prc_sync_evr : process(clk_evr) begin if rising_edge(clk_evr) then --- evr_params_sync <= evr_params_xuser; evr_params <= evr_params_sync; --- event_recorder_control_sync <= event_recorder_control_xuser; event_recorder_control <= event_recorder_control_sync; --- end if; end process; -- -------------------------------------------------------------------------- -- EVR320 Decoder -- -------------------------------------------------------------------------- evr320_decoder_inst : entity work.evr320_decoder generic map( FACILITY => g_FACILITY, EVENT_RECORDER => g_EVENT_RECORDER, MEM_DATA_WIDTH => c_TOSCA2_DATA_WIDTH, EXP_REC_CLK_FREQ => 50_632_820) port map( -- Debug interface debug_clk => debug_clk, debug => debug_data, -- GTX parallel interface i_mgt_rst => mgt_lossofsync, i_mgt_rx_clk => clk_evr, i_mgt_rx_data => mgt_rx_data, i_mgt_rx_charisk => mgt_rx_charisk, -- User interface CPU clock i_usr_clk => mem_clk, i_evr_params => evr_params, o_event_recorder_stat => event_recorder_status, i_event_recorder_ctrl => event_recorder_control, i_mem_addr => mem_addr_evr, o_mem_data => mem_data, -- user stream interface, user clock i_stream_clk => stream_clk_i, o_stream_data => stream_data_o, o_stream_addr => stream_addr_o, o_stream_valid => stream_valid_o, -- User interface MGT clock o_usr_events => usr_events_s, -- o_usr_events_ext => usr_events_ext_o, -- not in use anymore o_sos_event => sos_event_s, o_event => decoder_event, o_event_valid => decoder_event_valid ); usr_events_o <= usr_events_s; sos_event_o <= sos_event_s; -- -------------------------------------------------------------------------- -- MGT Wrapper for GTX Virtex-6 -- -------------------------------------------------------------------------- mgt_wrapper_inst : entity work.v6vlx_gtxe1_wrapper generic map( g_MGT_LOCATION => g_MGT_LOCATION, g_FACILITY => g_FACILITY) port map( -- MGT serial interface i_mgt_refclk => mgt_refclk_i, o_mgt_refclk => open, i_mgt_rx_p => mgt_rx_p, i_mgt_rx_n => mgt_rx_n, o_mgt_tx_p => mgt_tx_p, o_mgt_tx_n => mgt_tx_n, -- MGT parallel interface o_mgt_status => mgt_status, i_mgt_control => mgt_control, o_mgt_recclk => clk_evr, o_mgt_rx_data => mgt_rx_data, o_mgt_rx_charisk => mgt_rx_charisk ); mgt_rx_charisk_o <= mgt_rx_charisk; mgt_rx_data_o <= mgt_rx_data; -- -------------------------------------------------------------------------- -- TMEM -- -------------------------------------------------------------------------- --formatter:off evr320_tmem_inst : entity work.evr320_tmem port map( -- TOSCA2 TMEM Interface xuser_CLK => xuser_CLK, xuser_RESET => xuser_RESET, xuser_TMEM_ENA => xuser_TMEM_ENA, xuser_TMEM_WE => xuser_TMEM_WE, xuser_TMEM_ADD => xuser_TMEM_ADD, xuser_TMEM_DATW => xuser_TMEM_DATW, xuser_TMEM_DATR => xuser_TMEM_DATR, -- EVR320 Memory/Parameter Interface evr_params_o => evr_params_xuser, evr_frequency_i => evr_frequency, evr_evt_rec_status_i => event_recorder_status, evr_evt_rec_control_o => event_recorder_control_xuser, evr_latency_measure_stat_i => evr_latency_measure_stat, evr_latency_measure_ctrl_o => evr_latency_measure_ctrl, mgt_status_i => mgt_status, mgt_reset_o => mgt_reset_tmem_evr, mem_clk_o => mem_clk, mem_addr_o => mem_addr_tosca, mem_data_i => mem_data, -- evr_clk_i => clk_evr, evr_rst_i => evr_rst_s, evr_pulse_delay_o => usr_event_delay_s, evr_pulse_width_o => usr_event_width_s); -- -------------------------------------------------------------------------- -- Measure EVR Clock (based on xuser_CLK) -- -------------------------------------------------------------------------- clock_meas_inst : entity work.psi_common_clk_meas generic map( master_frequency_g => g_XUSER_CLK_FREQ, max_meas_frequency_g => 150000000 ) port map( clk_master_i => xuser_CLK, rst_i => xuser_RESET, clk_test_i => clk_evr, frequency_hz_o => evr_frequency ); -- -------------------------------------------------------------------------- -- Event Latency Measurement for SW tests -- -------------------------------------------------------------------------- lat_meas_block : block type state_type is (armed, count); signal state : state_type; signal counter : unsigned(31 downto 0); signal event_nr_sync, event_nr : std_logic_vector(7 downto 0); signal event_detected : std_logic_vector(3 downto 0); signal event_detected_sync : std_logic_vector(1 downto 0); constant MAX_COUNT : unsigned(31 downto 0) := to_unsigned(g_XUSER_CLK_FREQ / 10, 32); -- MAX 100ms ~ 10Hz begin -- Process: filter events for matching event_nr register: --------------------------------------------------------- ext_event_proc : process(clk_evr) begin if (rising_edge(clk_evr)) then -- sync to MGT clock domain: event_nr_sync <= evr_latency_measure_ctrl.event_nr; event_nr <= event_nr_sync; -- check if event has been detected and stretch pulse: event_detected <= event_detected(2 downto 0) & '0'; if (decoder_event_valid = '1' and decoder_event = event_nr) then event_detected <= (others => '1'); end if; end if; end process; -- Process: Counter when configured event has been detected: ------------------------------------------------------------ lat_meas_proc : process(xuser_CLK, counter) begin if rising_edge(xuser_CLK) then -- sync to user clock domain: event_detected_sync <= event_detected_sync(0) & event_detected(3); -- counter FSM: --------------- case state is -- counter is armed: when armed => counter <= (others => '0'); -- start counting when event detected (rising edge): if (event_detected_sync(1) = '0' and event_detected_sync(0) = '1') then state <= count; end if; -- counting: when count => -- count only up to 10ms, and stop: if (counter < MAX_COUNT) then counter <= counter + 1; end if; if (evr_latency_measure_ctrl.counter_arm = '1') then state <= armed; end if; end case; end if; evr_latency_measure_stat.counter_val <= std_logic_vector(counter); end process; end block; -- -------------------------------------------------------------------------- -- Add delay output -- -------------------------------------------------------------------------- output_delay_block : block --signal rst0_s, rst1_s : std_logic; -- double stage sync for reset signal usr_evt_shaped_s : std_logic_vector(4 downto 0); signal usr_events_adj_s : std_logic_vector(4 downto 0); signal usr_events_concat_s : std_logic_vector(4 downto 0); begin evr_rst_s <= mgt_status(15); -- RXLOSSOFSYNC usr_events_concat_s <= usr_events_s & sos_event_s; gene_adj_out : for i in 0 to 4 generate --*** Adjust pulse length in clk cycles EVENT 0,1,2,3 *** inst_pulslength_evt0 : entity work.psi_common_pulse_shaper_cfg generic map(HoldIn_g => false, hold_off_ena_g => false, max_hold_off_g => 10, max_duration_g => MaxDuration_c, Rst_Pol_g => '1') port map(clk_i => clk_evr, rst_i => evr_rst_s, width_i => usr_event_width_s(i), hold_i => (others => '0'), dat_i => usr_events_concat_s(i), dat_o => usr_evt_shaped_s(i)); --*** delay adjust EVENT 0,1,2,3*** inst_adjdelay_evt0 : entity work.psi_common_delay_cfg generic map(width_g => 1, max_delay_g => MaxDelay_c, rst_pol_g => '1', ram_behavior_g => "RBW", hold_g => True) port map(clk_i => clk_evr, rst_i => evr_rst_s, dat_i(0) => usr_evt_shaped_s(i), vld_i => '1', del_i => usr_event_delay_s(i), dat_o(0) => usr_events_adj_s(i)); end generate; usr_events_adj_o <= usr_events_adj_s(4 downto 1); sos_events_adj_o <= usr_events_adj_s(0); end block; -- -------------------------------------------------------------------------- -- port mapping -- -------------------------------------------------------------------------- clk_evr_o <= clk_evr; mgt_status_o <= mgt_status; debug <= debug_data; end rtl; -- ---------------------------------------------------------------------------- -- //////////////////////////////////////////////////////////////////////////// -- ----------------------------------------------------------------------------