1150 lines
50 KiB
VHDL
1150 lines
50 KiB
VHDL
--------------------------------------------------------------------------------
|
|
-- Paul Scherrer Institute (PSI)
|
|
--------------------------------------------------------------------------------
|
|
-- Unit : evr320_decoder.vhd
|
|
-- Author : Waldemar Koprek, Section Diagnostic
|
|
-- Goran Marinkovic, Section Diagnostic
|
|
-- Patric Bucher, Section DSV
|
|
-- Benoît Stef, Section DSP
|
|
--------------------------------------------------------------------------------
|
|
-- Copyright© PSI, Section Diagnostic
|
|
--------------------------------------------------------------------------------
|
|
-- Comment : Rewrite code to be complient with numeric_std
|
|
--------------------------------------------------------------------------------
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library unisim;
|
|
use unisim.vcomponents.all;
|
|
|
|
use work.evr320_pkg.all;
|
|
|
|
entity evr320_decoder is
|
|
generic
|
|
(
|
|
EVENT_RECORDER : boolean := false;
|
|
MEM_DATA_WIDTH : integer := 32
|
|
);
|
|
port
|
|
(
|
|
--------------------------------------------------------------------------
|
|
-- Debug interface
|
|
--------------------------------------------------------------------------
|
|
debug_clk : out std_logic;
|
|
debug : out std_logic_vector(127 downto 0);
|
|
--------------------------------------------------------------------------
|
|
-- GTX parallel interface
|
|
--------------------------------------------------------------------------
|
|
i_mgt_rst : in std_logic; -- GTX loss of sync
|
|
i_mgt_rx_clk : in std_logic;
|
|
i_mgt_rx_data : in std_logic_vector(15 downto 0);
|
|
i_mgt_rx_charisk : in std_logic_vector( 1 downto 0);
|
|
--------------------------------------------------------------------------
|
|
-- User interface CPU clock
|
|
--------------------------------------------------------------------------
|
|
i_usr_clk : in std_logic;
|
|
i_evr_params : in typ_evr320_params;
|
|
o_event_recorder_stat : out typ_evt_rec_status;
|
|
i_event_recorder_ctrl : in typ_evt_rec_ctrl;
|
|
i_mem_addr : in std_logic_vector(11 downto 0);
|
|
o_mem_data : out std_logic_vector(MEM_DATA_WIDTH - 1 downto 0);
|
|
--------------------------------------------------------------------------
|
|
-- User stream interface User clock
|
|
--------------------------------------------------------------------------
|
|
i_stream_clk : in std_logic;
|
|
o_stream_data : out std_logic_vector(7 downto 0);
|
|
o_stream_addr : out std_logic_vector(10 downto 0);
|
|
o_stream_valid : out std_logic;
|
|
--------------------------------------------------------------------------
|
|
-- User interface MGT clock
|
|
--------------------------------------------------------------------------
|
|
o_usr_events : out std_logic_vector( 3 downto 0);
|
|
o_usr_events_ext : out std_logic_vector( 3 downto 0);
|
|
o_sos_event : out std_logic
|
|
);
|
|
end evr320_decoder;
|
|
|
|
architecture behavioral of evr320_decoder is
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Constant
|
|
-----------------------------------------------------------------------------
|
|
constant HIGH : std_logic := '1';
|
|
constant LOW : std_logic := '0';
|
|
constant LOW_slv : std_logic_vector(15 downto 0) := (others => '0');
|
|
-- Data Width
|
|
constant MEM_DATA_BYTES : integer := MEM_DATA_WIDTH / 8;
|
|
constant MEM_ADDR_LSB : integer := MEM_DATA_WIDTH / 64; -- 0 = 32 bit / 1 = 64 bit
|
|
-- Framing
|
|
constant C_KCHAR_START : std_logic_vector( 7 downto 0) := X"5C";
|
|
constant C_KCHAR_END : std_logic_vector( 7 downto 0) := X"3C";
|
|
-- Events received
|
|
type usr_events_type is array (0 to 3) of std_logic_vector( 3 downto 0);
|
|
signal usr_events : usr_events_type := (others => (others => '0'));
|
|
signal cs_timeout_cnt : unsigned(23 downto 0) := (others => '0');
|
|
signal cs_min_cnt : unsigned(31 downto 0) := (others => '0');
|
|
signal cs_min_time : unsigned(31 downto 0) := (others => '0');
|
|
signal evr_stable : std_logic := '0';
|
|
-- signal frame_fsm : frame_fsm_type;
|
|
constant frame_idle : std_logic_vector( 3 downto 0) := "0000";
|
|
constant frame_addr_gap : std_logic_vector( 3 downto 0) := "0001";
|
|
constant frame_addr : std_logic_vector( 3 downto 0) := "0010";
|
|
constant frame_data_gap : std_logic_vector( 3 downto 0) := "0011";
|
|
constant frame_data : std_logic_vector( 3 downto 0) := "0100";
|
|
constant frame_chk1_gap : std_logic_vector( 3 downto 0) := "0101";
|
|
constant frame_chk1 : std_logic_vector( 3 downto 0) := "0110";
|
|
constant frame_chk2_gap : std_logic_vector( 3 downto 0) := "0111";
|
|
constant frame_chk2 : std_logic_vector( 3 downto 0) := "1000";
|
|
signal frame_fsm : std_logic_vector( 3 downto 0) := "0000";
|
|
-- Frame checksum
|
|
signal frame_chk : std_logic_vector(15 downto 0) := X"FFFF";
|
|
signal frame_chk_ok : std_logic := '0';
|
|
signal frame_chk1_ok : std_logic := '0';
|
|
signal frame_chk2_ok : std_logic := '0';
|
|
-- Frame control FIFO
|
|
signal frame_ctrl_full : std_logic := '0';
|
|
signal frame_ctrl_empty : std_logic := '0';
|
|
signal frame_ctrl_wren : std_logic := '0';
|
|
signal frame_ctrl_di : std_logic_vector(63 downto 0) := (others => '0');
|
|
signal frame_ctrl_rden : std_logic := '0';
|
|
signal frame_ctrl_do : std_logic_vector(63 downto 0) := (others => '0');
|
|
-- Frame control FIFO write port
|
|
signal frame_ctrl_wr_id : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal frame_ctrl_wr_ok : std_logic := '0';
|
|
-- Frame control FIFO read port
|
|
signal frame_ctrl_rd_id : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal frame_ctrl_rd_ok : std_logic := '0';
|
|
-- Frame data FIFO
|
|
signal frame_data_full : std_logic := '0';
|
|
signal frame_data_empty : std_logic := '0';
|
|
signal frame_data_wren : std_logic := '0';
|
|
signal frame_data_di : std_logic_vector(63 downto 0) := (others => '0');
|
|
signal frame_data_rden : std_logic := '0';
|
|
signal frame_data_do : std_logic_vector(63 downto 0) := (others => '0');
|
|
-- Frame data FIFO write port
|
|
signal frame_data_wr_id : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal frame_data_wr_addr_cnt: std_logic_vector(15 downto 0) := (others => '0');
|
|
signal frame_data_wr_addr : std_logic_vector(10 downto 0) := (others => '0');
|
|
signal frame_data_wr_byte : std_logic_vector( 7 downto 0) := (others => '0');
|
|
-- Frame data FIFO read port
|
|
signal frame_data_rd_id : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal frame_data_rd_addr : std_logic_vector(10 downto 0) := (others => '0');
|
|
signal frame_data_rd_byte : std_logic_vector( 7 downto 0) := (others => '0');
|
|
-- Memory fsm
|
|
-- type mem_fsm_type is
|
|
-- (
|
|
-- mem_idle,
|
|
-- mem_data_rd,
|
|
-- mem_data_del,
|
|
-- mem_ctrl_rd
|
|
-- );
|
|
-- signal mem_fsm : mem_fsm_type;
|
|
constant mem_idle : std_logic_vector( 1 downto 0) := "00";
|
|
constant mem_data_rd : std_logic_vector( 1 downto 0) := "01";
|
|
constant mem_data_del : std_logic_vector( 1 downto 0) := "10";
|
|
constant mem_ctrl_rd : std_logic_vector( 1 downto 0) := "11";
|
|
signal mem_fsm : std_logic_vector( 1 downto 0) := "00";
|
|
-- Data memory address
|
|
signal mem_addr : std_logic_vector(11 downto 0);
|
|
-- Data memory write
|
|
signal mem_data_wren : std_logic := '0';
|
|
signal mem_data_wr_addr : std_logic_vector(10 downto 0) := (others => '0');
|
|
signal mem_data_wr_byte : std_logic_vector( 7 downto 0) := (others => '0');
|
|
-- Data memory read
|
|
signal mem_data_dpram : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event0 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event1 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event2 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event3 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
-- Event Recorder
|
|
signal sos_event : std_logic_vector( 3 downto 0) := (others => '0');
|
|
signal usr_events_save : std_logic := '0';
|
|
signal usr_events_save_dly : std_logic := '0';
|
|
signal usr_events_nr : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal usr_events_nr_dly : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal usr_events_addr : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal usr_events_addr_dly : std_logic_vector( 7 downto 0) := (others => '0');
|
|
signal usr_events_cnt : std_logic_vector( 31 downto 0) := (others => '0');
|
|
signal usr_events_cnt_d : std_logic_vector( 31 downto 0) := (others => '0');
|
|
signal all_events_flags : std_logic_vector(255 downto 0) := (others => '0');
|
|
signal all_events_flags_d : std_logic_vector(255 downto 0) := (others => '0');
|
|
signal all_events_flags_sync1 : std_logic_vector(255 downto 0) := (others => '0');
|
|
signal all_events_flags_sync2 : std_logic_vector(255 downto 0) := (others => '0');
|
|
signal timestamp_cnt : std_logic_vector( 31 downto 0) := (others => '0');
|
|
signal timestamp_cnt_dly : std_logic_vector( 31 downto 0) := (others => '0');
|
|
signal segment_addr_wren : std_logic;
|
|
signal mem_data_valid : std_logic;
|
|
signal mem_data_error : std_logic;
|
|
signal mem_data_read_ack : std_logic_vector( 1 downto 0);
|
|
signal mem_data_error_ack : std_logic_vector( 1 downto 0);
|
|
signal mem_data_event_recorder : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event_flag : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event_nr : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_event_nr_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_dpram_sos : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal mem_data_segment_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
|
signal stream_raw : std_logic_vector(18 downto 0);
|
|
-- attribute safe_implementation: string;
|
|
-- attribute safe_implementation of frame_fsm : signal is "yes";
|
|
-- attribute safe_implementation of mem_fsm : signal is "yes";
|
|
|
|
-- attribute fsm_safe_state : string;
|
|
-- attribute fsm_safe_state of frame_fsm : signal is "default_state";
|
|
-- attribute fsm_safe_state of mem_fsm : signal is "default_state";
|
|
|
|
begin
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Debug
|
|
-----------------------------------------------------------------------------
|
|
debug_clk <= i_mgt_rx_clk;
|
|
debug( 15 downto 0) <= i_mgt_rx_data;
|
|
debug( 17 downto 16) <= i_mgt_rx_charisk;
|
|
debug( 23 downto 18) <= (others=>'0');
|
|
debug( 31 downto 24) <= (others => '0');
|
|
debug( 35 downto 32) <= "0001" when (frame_fsm = frame_idle ) else
|
|
"0010" when (frame_fsm = frame_addr_gap) else
|
|
"0011" when (frame_fsm = frame_addr ) else
|
|
"0100" when (frame_fsm = frame_data_gap) else
|
|
"0101" when (frame_fsm = frame_data ) else
|
|
"0110" when (frame_fsm = frame_chk1_gap) else
|
|
"0111" when (frame_fsm = frame_chk1 ) else
|
|
"1000" when (frame_fsm = frame_chk2_gap) else
|
|
"1001" when (frame_fsm = frame_chk2 ) else
|
|
"0000";
|
|
debug( 39 downto 36) <= (others => '0');
|
|
debug( 40) <= usr_events( 0)( 3);
|
|
debug( 41) <= usr_events( 1)( 3);
|
|
debug( 42) <= usr_events( 2)( 3);
|
|
debug( 43) <= usr_events( 3)( 3);
|
|
debug( 44) <= frame_data_wren;
|
|
debug( 55 downto 45) <= frame_data_wr_addr;
|
|
debug( 63 downto 56) <= frame_data_wr_byte;
|
|
|
|
dbg_evt_rec: if EVENT_RECORDER generate
|
|
debug( 64) <= sos_event(3);
|
|
debug( 65) <= usr_events_save_dly;
|
|
debug( 73 downto 66) <= usr_events_nr_dly;
|
|
debug( 81 downto 74) <= usr_events_addr_dly;
|
|
debug(113 downto 82) <= timestamp_cnt_dly;
|
|
debug(114) <= segment_addr_wren;
|
|
debug(115) <= mem_data_valid;
|
|
debug(116) <= mem_data_error;
|
|
debug(117) <= mem_data_read_ack(0);
|
|
debug(118) <= mem_data_error_ack(0);
|
|
debug(119) <= all_events_flags(27); -- event code 27 (photonics)
|
|
debug(127 downto 120) <= usr_events_cnt(7 downto 0);
|
|
end generate dbg_evt_rec;
|
|
|
|
dbg_no_evt_rec: if not(EVENT_RECORDER) generate
|
|
debug(127 downto 64) <= (others => '0');
|
|
end generate dbg_no_evt_rec;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Address Alignment for 32/64-bit Data Width
|
|
-----------------------------------------------------------------------------
|
|
gen_addr_align64: if MEM_DATA_WIDTH = 64 generate
|
|
mem_addr <= i_mem_addr(10 downto 0) & '0';
|
|
end generate gen_addr_align64;
|
|
|
|
gen_addr_align32: if MEM_DATA_WIDTH = 32 generate
|
|
mem_addr <= i_mem_addr;
|
|
end generate gen_addr_align32;
|
|
|
|
-- Design Rule Check
|
|
assert (MEM_DATA_WIDTH = 32 or MEM_DATA_WIDTH = 64)
|
|
report "Invalid Memory Data Width, 32|64 is allowed"
|
|
severity error;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- evr stable state
|
|
-----------------------------------------------------------------------------
|
|
prc_evr_stable : process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
evr_stable <= '0';
|
|
else
|
|
if ((cs_min_cnt > unsigned(i_evr_params.cs_min_cnt)) and (cs_min_time > unsigned(i_evr_params.cs_min_time)) and (cs_timeout_cnt < X"15CA20")) then
|
|
evr_stable <= '1';
|
|
else
|
|
evr_stable <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- user event decoder
|
|
-- the process generates 4 clock cycle pulses
|
|
-----------------------------------------------------------------------------
|
|
prc_user_event_decoder : process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
usr_events <= (others => (others => '0'));
|
|
else
|
|
for i in 0 to 3 loop
|
|
if ((i_evr_params.event_enable(i) = '1') and (i_mgt_rx_charisk( 0) = '0') and (i_mgt_rx_data( 7 downto 0) = i_evr_params.event_numbers(i)) and (evr_stable = '1')) then
|
|
usr_events(i) <= "1111";
|
|
else
|
|
usr_events(i) <= usr_events(i)( 2 downto 0) & '0';
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
usr_event_port_map: for i in 0 to 3 generate
|
|
o_usr_events(i) <= usr_events(i)(0); -- single pulses for evr clock domain
|
|
o_usr_events_ext(i) <= usr_events(i)(3); -- 4 cycle pulses for clock domain crossing
|
|
end generate;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Counting valid window for events after the last check sums was received
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
cs_timeout_cnt <= X"000000";
|
|
else
|
|
if ((frame_ctrl_wren = '1') and (frame_chk_ok = '1')) then
|
|
cs_timeout_cnt <= X"000000";
|
|
else
|
|
if (cs_timeout_cnt /= X"FFFFFF") then
|
|
cs_timeout_cnt <= cs_timeout_cnt + 1;--X"000001";
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Counting valid frame check sums received
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
cs_min_cnt <= X"00000000";
|
|
else
|
|
if (frame_ctrl_wren = '1') then
|
|
if (frame_chk_ok = '1') then
|
|
if (cs_min_cnt /= X"FFFFFFFF") then
|
|
cs_min_cnt <= cs_min_cnt + 1;--X"00000001";
|
|
end if;
|
|
else
|
|
cs_min_cnt <= X"00000000";
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Counting time in which no invalid frame check sums was received
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
cs_min_time <= X"00000000";
|
|
else
|
|
if ((frame_ctrl_wren = '1') and (frame_chk_ok = '0')) then
|
|
cs_min_time <= X"00000000";
|
|
else
|
|
if (cs_min_time /= X"FFFFFFFF") then
|
|
cs_min_time <= cs_min_time + X"00000001";
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Data buffer
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
frame_fsm <= frame_idle;
|
|
else
|
|
case frame_fsm is
|
|
when frame_idle =>
|
|
if ((i_mgt_rx_charisk( 1) = '1') and (i_mgt_rx_data(15 downto 8) = C_KCHAR_START)) then
|
|
frame_fsm <= frame_addr_gap;
|
|
end if;
|
|
when frame_addr_gap =>
|
|
frame_fsm <= frame_addr;
|
|
when frame_addr =>
|
|
frame_fsm <= frame_data_gap;
|
|
when frame_data_gap =>
|
|
if (((i_mgt_rx_charisk( 1) = '1') and (i_mgt_rx_data(15 downto 8) = C_KCHAR_END)) or
|
|
((i_mgt_rx_charisk( 0) = '1') and (i_mgt_rx_data( 7 downto 0) = C_KCHAR_END))) then
|
|
frame_fsm <= frame_idle;
|
|
else
|
|
frame_fsm <= frame_data;
|
|
end if;
|
|
when frame_data =>
|
|
if (((i_mgt_rx_charisk( 1) = '1') and (i_mgt_rx_data(15 downto 8) = C_KCHAR_END)) or
|
|
((i_mgt_rx_charisk( 0) = '1') and (i_mgt_rx_data( 7 downto 0) = C_KCHAR_END))) then
|
|
frame_fsm <= frame_chk1_gap;
|
|
else
|
|
frame_fsm <= frame_data_gap;
|
|
end if;
|
|
when frame_chk1_gap =>
|
|
frame_fsm <= frame_chk1;
|
|
when frame_chk1 =>
|
|
frame_fsm <= frame_chk2_gap;
|
|
when frame_chk2_gap =>
|
|
frame_fsm <= frame_chk2;
|
|
when frame_chk2 =>
|
|
frame_fsm <= frame_idle;
|
|
when others =>
|
|
frame_fsm <= frame_idle;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
segment_addr_wren <= '0';
|
|
frame_data_wren <= '0';
|
|
frame_data_wr_id <= (others => '0');
|
|
frame_data_wr_addr_cnt<= (others => '0');
|
|
frame_data_wr_addr <= (others => '0');
|
|
frame_data_wr_byte <= (others => '0');
|
|
else
|
|
segment_addr_wren <= '0';
|
|
frame_data_wren <= '0';
|
|
case frame_fsm is
|
|
when frame_idle =>
|
|
frame_data_wr_addr_cnt <= (others => '0');
|
|
when frame_addr =>
|
|
frame_data_wr_id <= std_logic_vector(unsigned(frame_data_wr_id) + 1);
|
|
frame_data_wr_addr_cnt <= "0000" & i_mgt_rx_data(15 downto 8) & "0000";
|
|
segment_addr_wren <= '1';
|
|
when frame_data =>
|
|
if (((i_mgt_rx_charisk( 1) = '1') and (i_mgt_rx_data(15 downto 8) = C_KCHAR_END)) or
|
|
((i_mgt_rx_charisk( 0) = '1') and (i_mgt_rx_data( 7 downto 0) = C_KCHAR_END))) then
|
|
frame_data_wren <= '0';
|
|
else
|
|
frame_data_wren <= not frame_data_full;
|
|
frame_data_wr_addr_cnt <= std_logic_vector(unsigned(frame_data_wr_addr_cnt) + 1);
|
|
frame_data_wr_addr <= frame_data_wr_addr_cnt(10 downto 0);
|
|
frame_data_wr_byte <= i_mgt_rx_data(15 downto 8);
|
|
end if;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Frame check sum calculator
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
case frame_fsm is
|
|
when frame_idle =>
|
|
frame_chk <= X"FFFF";
|
|
when frame_addr | frame_data =>
|
|
if (i_mgt_rx_charisk = "00") then
|
|
frame_chk <= std_logic_vector(unsigned(frame_chk) - unsigned(i_mgt_rx_data(15 downto 8)));
|
|
end if;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
case frame_fsm is
|
|
when frame_idle =>
|
|
frame_chk1_ok <= '0';
|
|
frame_chk2_ok <= '0';
|
|
when frame_chk1 =>
|
|
if (frame_chk(15 downto 8) = i_mgt_rx_data(15 downto 8)) then
|
|
frame_chk1_ok <= '1';
|
|
end if;
|
|
when frame_chk2 =>
|
|
if (frame_chk( 7 downto 0) = i_mgt_rx_data(15 downto 8)) then
|
|
frame_chk2_ok <= '1';
|
|
end if;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
frame_chk_ok <= frame_chk1_ok and frame_chk2_ok;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Frame FIFO
|
|
-----------------------------------------------------------------------------
|
|
-- Frame control received
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (frame_fsm = frame_chk2) then
|
|
frame_ctrl_wren <= not frame_ctrl_full;
|
|
else
|
|
frame_ctrl_wren <= '0';
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
frame_ctrl_wr_id <= frame_data_wr_id;
|
|
frame_ctrl_wr_ok <= frame_chk_ok;
|
|
|
|
frame_ctrl_di( 7 downto 0) <= frame_ctrl_wr_id;
|
|
frame_ctrl_di( 8) <= frame_ctrl_wr_ok;
|
|
frame_ctrl_di(11 downto 9) <= "000";
|
|
frame_ctrl_di(63 downto 12) <= X"0000000000000";
|
|
|
|
frame_ctrl_inst: FIFO36E1
|
|
generic map
|
|
(
|
|
ALMOST_EMPTY_OFFSET => X"0080",
|
|
ALMOST_FULL_OFFSET => X"0080",
|
|
DATA_WIDTH => 36,
|
|
DO_REG => 1,
|
|
EN_ECC_READ => FALSE,
|
|
EN_ECC_WRITE => FALSE,
|
|
EN_SYN => FALSE,
|
|
FIFO_MODE => "FIFO36",
|
|
FIRST_WORD_FALL_THROUGH => TRUE,
|
|
INIT => X"000000000000000000",
|
|
SIM_DEVICE => "7SERIES",
|
|
SRVAL => X"000000000000000000"
|
|
)
|
|
port map
|
|
(
|
|
-- Status
|
|
ALMOSTEMPTY => open,
|
|
ALMOSTFULL => open,
|
|
EMPTY => frame_ctrl_empty,
|
|
FULL => frame_ctrl_full,
|
|
RDCOUNT => open,
|
|
RDERR => open,
|
|
WRCOUNT => open,
|
|
WRERR => open,
|
|
-- Write port
|
|
WRCLK => i_mgt_rx_clk,
|
|
WREN => frame_ctrl_wren,
|
|
DI => frame_ctrl_di,
|
|
DIP => X"00",
|
|
-- Read port
|
|
RDCLK => i_mgt_rx_clk,
|
|
RDEN => frame_ctrl_rden,
|
|
REGCE => '1',
|
|
RST => i_mgt_rst,
|
|
RSTREG => '1',
|
|
DO => frame_ctrl_do,
|
|
DOP => open,
|
|
-- ECC port
|
|
INJECTDBITERR => '0',
|
|
INJECTSBITERR => '0',
|
|
DBITERR => open,
|
|
ECCPARITY => open,
|
|
SBITERR => open
|
|
);
|
|
|
|
frame_ctrl_rden <= '1' when ((frame_ctrl_empty = '0') and (mem_fsm = mem_ctrl_rd)) else '0';
|
|
|
|
frame_ctrl_rd_id <= frame_ctrl_do( 7 downto 0);
|
|
frame_ctrl_rd_ok <= frame_ctrl_do( 8);
|
|
|
|
-- Frame data received
|
|
frame_data_di( 7 downto 0) <= frame_data_wr_id;
|
|
frame_data_di(18 downto 8) <= frame_data_wr_addr;
|
|
frame_data_di(23 downto 19) <= "00000";
|
|
frame_data_di(31 downto 24) <= frame_data_wr_byte;
|
|
frame_data_di(63 downto 32) <= X"00000000";
|
|
|
|
frame_data_inst: FIFO36E1
|
|
generic map
|
|
(
|
|
ALMOST_EMPTY_OFFSET => X"0080",
|
|
ALMOST_FULL_OFFSET => X"0080",
|
|
DATA_WIDTH => 36,
|
|
DO_REG => 1,
|
|
EN_ECC_READ => FALSE,
|
|
EN_ECC_WRITE => FALSE,
|
|
EN_SYN => FALSE,
|
|
FIFO_MODE => "FIFO36",
|
|
FIRST_WORD_FALL_THROUGH => TRUE,
|
|
INIT => X"000000000000000000",
|
|
SIM_DEVICE => "7SERIES",
|
|
SRVAL => X"000000000000000000"
|
|
)
|
|
port map
|
|
(
|
|
-- Status
|
|
ALMOSTEMPTY => open,
|
|
ALMOSTFULL => open,
|
|
EMPTY => frame_data_empty,
|
|
FULL => frame_data_full,
|
|
RDCOUNT => open,
|
|
RDERR => open,
|
|
WRCOUNT => open,
|
|
WRERR => open,
|
|
-- Write port
|
|
WRCLK => i_mgt_rx_clk,
|
|
WREN => frame_data_wren,
|
|
DI => frame_data_di,
|
|
DIP => X"00",
|
|
-- Read port
|
|
RDCLK => i_mgt_rx_clk,
|
|
RDEN => frame_data_rden,
|
|
REGCE => '1',
|
|
RST => i_mgt_rst,
|
|
RSTREG => '1',
|
|
DO => frame_data_do,
|
|
DOP => open,
|
|
-- ECC port
|
|
INJECTDBITERR => '0',
|
|
INJECTSBITERR => '0',
|
|
DBITERR => open,
|
|
ECCPARITY => open,
|
|
SBITERR => open
|
|
);
|
|
|
|
frame_data_rden <= '1' when ((frame_data_empty = '0') and (mem_fsm = mem_data_rd) and (frame_data_rd_id = frame_ctrl_rd_id)) else
|
|
'1' when ((frame_data_empty = '0') and (mem_fsm = mem_data_del) and (frame_data_rd_id /= frame_ctrl_rd_id)) else '0';
|
|
|
|
frame_data_rd_id <= frame_data_do( 7 downto 0);
|
|
frame_data_rd_addr <= frame_data_do(18 downto 8);
|
|
frame_data_rd_byte <= frame_data_do(31 downto 24);
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Memory fsm
|
|
-----------------------------------------------------------------------------
|
|
process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
mem_fsm <= mem_idle;
|
|
else
|
|
case mem_fsm is
|
|
when mem_idle =>
|
|
if (frame_ctrl_empty = '0') then
|
|
if (frame_data_empty = '0') then
|
|
if (frame_data_rd_id = frame_ctrl_rd_id) then
|
|
mem_fsm <= mem_data_rd;
|
|
else
|
|
mem_fsm <= mem_data_del;
|
|
end if;
|
|
else
|
|
mem_fsm <= mem_ctrl_rd;
|
|
end if;
|
|
end if;
|
|
when mem_data_rd =>
|
|
if ((frame_data_empty = '0') and (frame_data_rd_id = frame_ctrl_rd_id)) then
|
|
mem_fsm <= mem_data_rd;
|
|
else
|
|
mem_fsm <= mem_ctrl_rd;
|
|
end if;
|
|
when mem_data_del =>
|
|
if ((frame_data_empty = '0') and (frame_data_rd_id /= frame_ctrl_rd_id)) then
|
|
mem_fsm <= mem_data_del;
|
|
else
|
|
mem_fsm <= mem_idle;
|
|
end if;
|
|
when mem_ctrl_rd =>
|
|
mem_fsm <= mem_idle;
|
|
when others =>
|
|
mem_fsm <= mem_idle;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Data memory write
|
|
-----------------------------------------------------------------------------
|
|
mem_data_wren <= '1' when ((mem_fsm = mem_data_rd) and (frame_data_rd_id = frame_ctrl_rd_id) and (frame_ctrl_empty = '0') and (frame_data_empty = '0') and (frame_ctrl_rd_ok = '1')) else '0';
|
|
mem_data_wr_addr <= frame_data_rd_addr;
|
|
mem_data_wr_byte <= frame_data_rd_byte;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Data memory selector
|
|
-----------------------------------------------------------------------------
|
|
o_mem_data <= mem_data_dpram when (mem_addr(11 downto 9) = "000") else
|
|
mem_data_event0 when (mem_addr(11 downto 9) = "001") else
|
|
mem_data_event1 when (mem_addr(11 downto 9) = "010") else
|
|
mem_data_event2 when (mem_addr(11 downto 9) = "011") else
|
|
mem_data_event3 when (mem_addr(11 downto 9) = "100") else
|
|
mem_data_event_recorder;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Data Memory
|
|
-- write port - timing decoder
|
|
-- read port - usr domain
|
|
-----------------------------------------------------------------------------
|
|
evr320_dpram_inst: entity work.evr320_dpram
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_dpram
|
|
);
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Data Memory
|
|
-- write port - timing decoder
|
|
-- read port - usr domain
|
|
-----------------------------------------------------------------------------
|
|
evr320_event0_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
page => usr_events( 0)( 3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event0
|
|
);
|
|
|
|
evr320_event1_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
page => usr_events( 1)( 3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event1
|
|
);
|
|
|
|
evr320_event2_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
page => usr_events( 2)( 3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event2
|
|
);
|
|
|
|
evr320_event3_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
page => usr_events( 3)( 3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event3
|
|
);
|
|
|
|
-------------------------------------------------------------------------
|
|
-- async fifo for streaming interface
|
|
-------------------------------------------------------------------------
|
|
strm_fifo_inst : entity work.psi_common_async_fifo
|
|
generic map (
|
|
Width_g => 11+8,
|
|
Depth_g => 2048,
|
|
AlmFullOn_g => false,
|
|
AlmFullLevel_g => 2,
|
|
AlmEmptyOn_g => false,
|
|
AlmEmptyLevel_g => 2,
|
|
RamStyle_g => "WBR",
|
|
RamBehavior_g => "block" -- auto, distributed
|
|
)
|
|
port map (
|
|
-- Control Ports
|
|
InClk => i_mgt_rx_clk,
|
|
InRst => i_mgt_rst,
|
|
OutClk => i_stream_clk,
|
|
OutRst => '0',
|
|
|
|
-- Input Data
|
|
InData => mem_data_wr_addr & mem_data_wr_byte,
|
|
InVld => mem_data_wren,
|
|
InRdy => open,
|
|
|
|
-- Output Data
|
|
OutData => stream_raw,
|
|
OutVld => o_stream_valid,
|
|
OutRdy => '1',
|
|
|
|
-- Input Status
|
|
InFull => open,
|
|
InEmpty => open,
|
|
InAlmFull => open,
|
|
InAlmEmpty => open,
|
|
InLevel => open,
|
|
|
|
-- Output Status
|
|
OutFull => open,
|
|
OutEmpty => open,
|
|
OutAlmFull => open,
|
|
OutAlmEmpty => open,
|
|
OutLevel => open
|
|
);
|
|
|
|
o_stream_data <= stream_raw(7 downto 0);
|
|
o_stream_addr <= stream_raw(18 downto 8);
|
|
-----------------------------------------------------------------------------
|
|
-----------------------------------------------------------------------------
|
|
-- EVENT RECORDER
|
|
-----------------------------------------------------------------------------
|
|
-----------------------------------------------------------------------------
|
|
gen_evt_rec: if EVENT_RECORDER generate
|
|
|
|
--------------------------------------------------------------------------
|
|
-- standard event filter
|
|
-- user event counter
|
|
-- start-of-sequence event decoder
|
|
--------------------------------------------------------------------------
|
|
prc_event_recorder : process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
sos_event <= (others => '0');
|
|
timestamp_cnt <= (others => '0');
|
|
usr_events_save <= '0';
|
|
usr_events_nr <= (others => '0');
|
|
usr_events_addr <= (others => '0');
|
|
usr_events_cnt <= (others => '0');
|
|
usr_events_cnt_d <= (others => '0');
|
|
all_events_flags <= (others => '0');
|
|
all_events_flags_d <= (others => '0');
|
|
else
|
|
|
|
-- default assignments
|
|
sos_event <= sos_event( 2 downto 0) & '0';
|
|
usr_events_save <= '0';
|
|
|
|
-- timestamp for event and segement tagging
|
|
if (timestamp_cnt /= X"FFFF_FFFF") then
|
|
timestamp_cnt <= std_logic_vector(unsigned(timestamp_cnt) + 1);
|
|
end if;
|
|
|
|
-- only run event recorder when stable operation
|
|
if ( (i_event_recorder_ctrl.event_enable = '1') and (i_mgt_rx_charisk( 0) = '0') and (evr_stable = '1')) then
|
|
|
|
-- filter standard events (user events = 0x01-0x6F, 0x72-0x78, 0x80-0xFF)
|
|
if unsigned(i_mgt_rx_data(7 downto 0)) /= 0 and i_mgt_rx_data(7 downto 4) /= X"7" then
|
|
usr_events_nr <= i_mgt_rx_data(7 downto 0);
|
|
|
|
-- write event nr memory
|
|
if (usr_events_addr /= X"FF") then
|
|
usr_events_save <= '1';
|
|
usr_events_addr <= std_logic_vector(unsigned(usr_events_addr) + 1);
|
|
end if;
|
|
|
|
-- count all user events
|
|
if (usr_events_cnt /= X"FFFF_FFFF") then
|
|
usr_events_cnt <= std_logic_vector(unsigned(usr_events_cnt) + 1);
|
|
end if;
|
|
|
|
-- start-of-sequence, trigger event for event recorder
|
|
if (i_mgt_rx_data( 7 downto 0) = i_event_recorder_ctrl.event_number) then
|
|
sos_event <= "1111";
|
|
timestamp_cnt <= (others => '0');
|
|
usr_events_cnt <= X"0000_0001";
|
|
usr_events_cnt_d <= usr_events_cnt;
|
|
usr_events_save <= '1';
|
|
usr_events_addr <= X"00";
|
|
all_events_flags <= (others => '0');
|
|
all_events_flags_d <= all_events_flags;
|
|
end if;
|
|
end if;
|
|
|
|
-- set flag for appeared event
|
|
all_events_flags(to_integer(unsigned(i_mgt_rx_data(7 downto 0)))) <= '1';
|
|
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
-- delayed event data (write after page switch in buffer)
|
|
--------------------------------------------------------------------------
|
|
prc_dly_event_data : process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
timestamp_cnt_dly <= timestamp_cnt;
|
|
usr_events_save_dly <= usr_events_save;
|
|
usr_events_nr_dly <= usr_events_nr;
|
|
usr_events_addr_dly <= usr_events_addr;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
-- memory read handshake
|
|
--------------------------------------------------------------------------
|
|
prc_mem_read_handshake : process(i_mgt_rx_clk)
|
|
begin
|
|
if (i_mgt_rx_clk'event and (i_mgt_rx_clk = '1')) then
|
|
if (i_mgt_rst = '1') then
|
|
mem_data_error <= '0';
|
|
mem_data_valid <= '0';
|
|
mem_data_read_ack <= "00";
|
|
mem_data_error_ack <= "00";
|
|
else
|
|
-- default assignments
|
|
mem_data_read_ack <= mem_data_read_ack(0) & i_event_recorder_ctrl.data_ack;
|
|
mem_data_error_ack <= mem_data_error_ack(0) & i_event_recorder_ctrl.error_ack;
|
|
|
|
if (sos_event(0) = '1') then
|
|
if (mem_data_valid = '0') then
|
|
mem_data_valid <= '1';
|
|
else --> mem read too slow or not acknowledged, valid is still present
|
|
mem_data_error <= '1';
|
|
end if;
|
|
end if;
|
|
|
|
-- data read acknowledge
|
|
if (mem_data_read_ack = "01") then
|
|
mem_data_valid <= '0';
|
|
end if;
|
|
|
|
-- data error acknowledge
|
|
if (mem_data_error_ack = "01") then
|
|
mem_data_error <= '0';
|
|
end if;
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Memory Selector Event Recorder
|
|
--------------------------------------------------------------------------
|
|
mem_data_event_recorder <= mem_data_dpram_sos when (mem_addr(11 downto 9) = B"101") else -- 2K
|
|
mem_data_event_nr_timestamp when (mem_addr(11 downto 8) = B"1100") else -- 1K
|
|
mem_data_segment_timestamp when (mem_addr(11 downto 7) = B"1101_0") else -- 512B
|
|
mem_data_event_nr when (mem_addr(11 downto 6) = B"1101_10") else -- 256B
|
|
mem_data_event_flag when (mem_addr(11 downto 6) = B"1101_11") else -- 256B
|
|
(others => '0');
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Event Recorder Data Memories
|
|
-- write port - timing decoder
|
|
-- read port - usr domain
|
|
--------------------------------------------------------------------------
|
|
-- Segemented Data Buffer at Start-of-Sequence Event
|
|
evr320_dpram_sos_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 2048,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => mem_data_wren,
|
|
addra => mem_data_wr_addr,
|
|
dia => mem_data_wr_byte,
|
|
page => sos_event(3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr(8 downto MEM_ADDR_LSB),
|
|
dob => mem_data_dpram_sos
|
|
);
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Data Buffer Segment Timestamps
|
|
--------------------------------------------------------------------------
|
|
evr320_segment_timestamp_inst: entity work.evr320_timestamp
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 512,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => segment_addr_wren,
|
|
addra => frame_data_wr_addr_cnt(10 downto 4),
|
|
dia => timestamp_cnt,
|
|
page => sos_event(3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr(6 downto MEM_ADDR_LSB),
|
|
dob => mem_data_segment_timestamp
|
|
);
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Event Number Timestamps
|
|
--------------------------------------------------------------------------
|
|
evr320_event_nr_timestamp_inst: entity work.evr320_timestamp
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 1024,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => usr_events_save_dly,
|
|
addra => usr_events_addr_dly,
|
|
dia => timestamp_cnt_dly,
|
|
page => sos_event(3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr(7 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event_nr_timestamp
|
|
);
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Event Numbers (in timeline)
|
|
--------------------------------------------------------------------------
|
|
evr320_event_nr_inst: entity work.evr320_buffer
|
|
generic map
|
|
(
|
|
MEM_SIZE_BYTE => 256,
|
|
MEM_DOB_WIDTH => MEM_DATA_WIDTH
|
|
)
|
|
port map
|
|
(
|
|
-- port a
|
|
clka => i_mgt_rx_clk,
|
|
ena => HIGH,
|
|
wea => usr_events_save_dly,
|
|
addra => usr_events_addr_dly,
|
|
dia => usr_events_nr_dly,
|
|
page => sos_event(3),
|
|
-- port b
|
|
clkb => i_usr_clk,
|
|
enb => HIGH,
|
|
addrb => mem_addr(5 downto MEM_ADDR_LSB),
|
|
dob => mem_data_event_nr
|
|
);
|
|
|
|
--------------------------------------------------------------------------
|
|
-- Event Flags of all Events
|
|
--------------------------------------------------------------------------
|
|
prc_event_flags: process(i_usr_clk)
|
|
variable v_addr : integer range 0 to 255;
|
|
variable v_addr_slv : std_logic_vector(7 downto 0);
|
|
begin
|
|
if (i_usr_clk'event and (i_usr_clk = '1')) then
|
|
-- sync to usr clk
|
|
all_events_flags_sync1 <= all_events_flags_d;
|
|
all_events_flags_sync2 <= all_events_flags_sync1;
|
|
|
|
-- address fragment of vector / expand bit to bytes for data read
|
|
v_addr_slv := mem_addr(5 downto MEM_ADDR_LSB) & LOW_slv(1 + MEM_ADDR_LSB downto 0);
|
|
v_addr := to_integer(unsigned(v_addr_slv));
|
|
mem_data_event_flag <= bit2byte(all_events_flags_sync2(v_addr + MEM_DATA_BYTES - 1 downto v_addr));
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
-- port mapping
|
|
--------------------------------------------------------------------------
|
|
o_sos_event <= sos_event(3);
|
|
o_event_recorder_stat.usr_events_counter <= usr_events_cnt_d;
|
|
o_event_recorder_stat.data_valid <= mem_data_valid;
|
|
o_event_recorder_stat.data_error <= mem_data_error;
|
|
|
|
|
|
end generate gen_evt_rec;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- NO Event Recorder implemented
|
|
-----------------------------------------------------------------------------
|
|
gen_no_evt_rec: if not(EVENT_RECORDER) generate
|
|
|
|
mem_data_event_recorder <= (others => '0');
|
|
o_sos_event <= '0';
|
|
o_event_recorder_stat <= c_INIT_EVT_REC_STATUS;
|
|
|
|
end generate gen_no_evt_rec;
|
|
|
|
|
|
end behavioral;
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- End of file
|
|
--------------------------------------------------------------------------------
|