401 lines
18 KiB
VHDL
401 lines
18 KiB
VHDL
---------------------------------------------------------------------------
|
|
-- 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;
|
|
-- ----------------------------------------------------------------------------
|
|
-- ////////////////////////////////////////////////////////////////////////////
|
|
-- ----------------------------------------------------------------------------
|