4 Commits

Author SHA1 Message Date
36a99d0bf4 Doc: Typo 2021-08-05 11:05:55 +02:00
4322debe14 Add 2nd interrupt latency measurement instance 2021-07-20 13:17:20 +02:00
83c3a4d910 Merge branch 'master' into latency_measure 2021-07-02 08:24:30 +02:00
98ba65bc62 Add open document format, register description of 2nd latency
measurement core
2021-07-02 08:18:36 +02:00
5 changed files with 171 additions and 90 deletions

BIN
doc/evr320.odt Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -104,8 +104,10 @@ architecture rtl of evr320_ifc1210_wrapper is
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_latency_measure_A_stat : typ_rec_latency_measure_stat;
signal evr_latency_measure_A_ctrl : typ_rec_latency_measure_ctrl;
signal evr_latency_measure_B_stat : typ_rec_latency_measure_stat;
signal evr_latency_measure_B_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;
@@ -239,8 +241,10 @@ begin
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,
evr_latency_measure_A_stat_i => evr_latency_measure_A_stat,
evr_latency_measure_A_ctrl_o => evr_latency_measure_A_ctrl,
evr_latency_measure_B_stat_i => evr_latency_measure_B_stat,
evr_latency_measure_B_ctrl_o => evr_latency_measure_B_ctrl,
mgt_status_i => mgt_status,
mgt_reset_o => mgt_reset_tmem_evr,
mem_clk_o => mem_clk,
@@ -268,70 +272,33 @@ begin
);
-- --------------------------------------------------------------------------
-- Event Latency Measurement for SW tests
-- Latency Measurement for IFC1210 Interrupts
-- --------------------------------------------------------------------------
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 / 100, 32); -- MAX 10ms
begin
latency_meas_A_inst : entity work.latency_measurement
generic map(
CLK_FREQ_HZ => g_XUSER_CLK_FREQ
)
port map(
evr_clk_i => clk_evr,
xuser_clk_i => xuser_CLK,
decoder_event_valid_i => decoder_event_valid,
decoder_event_i => decoder_event,
status_o => evr_latency_measure_A_stat,
ctrl_i => evr_latency_measure_A_ctrl
);
-- 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);
evr_latency_measure_stat.event_detected <= event_detected_sync(event_detected_sync'left);
end process;
end block;
latency_meas_B_inst : entity work.latency_measurement
generic map(
CLK_FREQ_HZ => g_XUSER_CLK_FREQ
)
port map(
evr_clk_i => clk_evr,
xuser_clk_i => xuser_CLK,
decoder_event_valid_i => decoder_event_valid,
decoder_event_i => decoder_event,
status_o => evr_latency_measure_B_stat,
ctrl_i => evr_latency_measure_B_ctrl
);
-- --------------------------------------------------------------------------
-- Add delay output

View File

@@ -37,8 +37,10 @@ entity evr320_tmem is
evr_frequency_i : in std_logic_vector(31 downto 0);
evr_evt_rec_status_i : in typ_evt_rec_status;
evr_evt_rec_control_o : out typ_evt_rec_ctrl;
evr_latency_measure_stat_i : in typ_rec_latency_measure_stat;
evr_latency_measure_ctrl_o : out typ_rec_latency_measure_ctrl;
evr_latency_measure_A_stat_i : in typ_rec_latency_measure_stat;
evr_latency_measure_A_ctrl_o : out typ_rec_latency_measure_ctrl;
evr_latency_measure_B_stat_i : in typ_rec_latency_measure_stat;
evr_latency_measure_B_ctrl_o : out typ_rec_latency_measure_ctrl;
mgt_status_i : in std_logic_vector(31 downto 0) := (others=>'0');
mgt_reset_o : out std_logic;
mem_clk_o : out std_logic;
@@ -102,16 +104,15 @@ architecture rtl of evr320_tmem is
signal er_control_concat : std_logic_vector(31 downto 0) := (others => '0');
-- latency measurement
signal lat_counter_arm : std_logic := '0';
signal lat_event_nr : std_logic_vector(7 downto 0) := c_SOS_EVENT_DEFAULT;
signal lat_counter_val : std_logic_vector(31 downto 0) := (others=>'0');
signal lat_event_detected : std_logic_vector(7 downto 0);
signal lat_arm : std_logic := '0';
signal lat_arm_edge : std_logic_vector(1 downto 0) := (others=>'0');
signal lat_A_counter_arm, lat_B_counter_arm : std_logic := '0';
signal lat_A_event_nr, lat_B_event_nr : std_logic_vector(7 downto 0) := c_SOS_EVENT_DEFAULT;
signal lat_A_event_detected, lat_B_event_detected : std_logic_vector(7 downto 0);
signal lat_A_arm, lat_B_arm : std_logic := '0';
signal lat_A_arm_edge, lat_B_arm_edge : std_logic_vector(1 downto 0) := (others=>'0');
-- event pulse config
signal evr_puls_width_cfg_s : typ_arr_width :=(others => UsrEventWidthDefault_c);
signal evr_puls_delay_cfg_s : typ_arr_delay :=(others => (others => '0'));
signal evr_puls_width_cfg_s : typ_arr_width := (others => UsrEventWidthDefault_c);
signal evr_puls_delay_cfg_s : typ_arr_delay := (others => (others => '0'));
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
@@ -126,21 +127,31 @@ begin
event_numbers_concat <= event_numbers(3) & event_numbers(2) & event_numbers(1) & event_numbers(0);
er_handshake_status <= X"0000" & bit2byte(er_status.data_error) & bit2byte(er_status.data_valid);
er_control_concat <= X"0000" & er_event_number & bit2byte(er_event_enable);
lat_counter_val <= evr_latency_measure_stat_i.counter_val;
-- -----------------------------
-- latency measurement, arm
-- -----------------------------
process (xuser_CLK)
begin
if rising_edge(xuser_CLK) then
-- edge detection of latency arm:
lat_arm_edge <= lat_arm_edge(0) & lat_arm;
lat_counter_arm <= lat_arm_edge(0) and not lat_arm_edge(1);
lat_A_arm_edge <= lat_A_arm_edge(0) & lat_A_arm;
lat_A_counter_arm <= lat_A_arm_edge(0) and not lat_A_arm_edge(1);
lat_B_arm_edge <= lat_B_arm_edge(0) & lat_B_arm;
lat_B_counter_arm <= lat_B_arm_edge(0) and not lat_B_arm_edge(1);
if (evr_latency_measure_stat_i.event_detected = '1') then
lat_event_detected <= (others=>'1');
if (evr_latency_measure_A_stat_i.event_detected = '1') then
lat_A_event_detected <= (others=>'1');
end if;
if (lat_counter_arm = '1') then
lat_event_detected <= (others=>'0');
if (lat_A_counter_arm = '1') then
lat_A_event_detected <= (others=>'0');
end if;
if (evr_latency_measure_B_stat_i.event_detected = '1') then
lat_B_event_detected <= (others=>'1');
end if;
if (lat_B_counter_arm = '1') then
lat_B_event_detected <= (others=>'0');
end if;
end if;
end process;
@@ -187,8 +198,9 @@ begin
when X"3" => xuser_TMEM_DATR <= evr_frequency & reserved(31 downto 0); -- 64bit / ByteAddr 018 --> 0x018 = Implementation Options + c_EVR_Location_vec
when X"4" => xuser_TMEM_DATR <= cs_min_time & cs_min_cnt; -- 64bit / ByteAddr 020
when X"5" => xuser_TMEM_DATR <= reserved(63 downto 0); -- 64bit / ByteAddr 028
when X"6" => xuser_TMEM_DATR <= lat_counter_val & x"00" & lat_event_detected & X"00" & lat_event_nr; -- 64bit / ByteAddr 030
when X"7" => xuser_TMEM_DATR <= reserved(63 downto 32) & reserved(31 downto 0); -- 64bit / ByteAddr 038
when X"6" => xuser_TMEM_DATR <= evr_latency_measure_A_stat_i.counter_val &
lat_B_event_detected & lat_A_event_detected & lat_B_event_nr & lat_A_event_nr; -- 64bit / ByteAddr 030
when X"7" => xuser_TMEM_DATR <= evr_latency_measure_B_stat_i.counter_val & reserved(31 downto 0); -- 64bit / ByteAddr 038
when X"8" => xuser_TMEM_DATR <= er_handshake_status & er_control_concat; -- 64bit / ByteAddr 040
when X"9" => xuser_TMEM_DATR <= reserved(63 downto 32) & er_status.usr_events_counter; -- 64bit / ByteAddr 048
when X"A" => xuser_TMEM_DATR <= evr_puls_delay_cfg_s(4) & evr_puls_delay_cfg_s(3) & evr_puls_delay_cfg_s(2) & evr_puls_delay_cfg_s(1) ; -- 64bit / ByteAddr 050
@@ -215,7 +227,8 @@ begin
-- default assignments
er_data_ack <= er_data_ack(2 downto 0) & '0';
er_error_ack <= er_error_ack(2 downto 0) & '0';
lat_arm <= '0';
lat_A_arm <= '0';
lat_B_arm <= '0';
if (xuser_TMEM_ENA_reg = '1' and xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH) = c_LOW(13 downto REG_ADDR_WIDTH)) then
@@ -265,7 +278,8 @@ begin
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"6" then --ByteAddr 030 Latency Measurement
if xuser_TMEM_WE_reg(0) = '1' then lat_event_nr ( 7 downto 0) <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
if xuser_TMEM_WE_reg(0) = '1' then lat_A_event_nr ( 7 downto 0) <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
if xuser_TMEM_WE_reg(1) = '1' then lat_B_event_nr ( 7 downto 0) <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -reserved- (15 downto 8) <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- (23 downto 16) <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- (31 downto 24) <= xuser_TMEM_DATW_reg(31 downto 24); end if;
@@ -276,7 +290,8 @@ begin
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"7" then --ByteAddr 038 Latency Measurement
if xuser_TMEM_WE_reg(0) = '1' then lat_arm <= xuser_TMEM_DATW_reg(0); end if;
if xuser_TMEM_WE_reg(0) = '1' then lat_A_arm <= xuser_TMEM_DATW_reg(0); end if;
if xuser_TMEM_WE_reg(1) = '1' then lat_B_arm <= xuser_TMEM_DATW_reg(8); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -reserved- (15 downto 8) <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- (23 downto 16) <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- (31 downto 24) <= xuser_TMEM_DATW_reg(31 downto 24); end if;
@@ -328,7 +343,8 @@ begin
evr_params_o <= (event_numbers, event_enable, cs_min_cnt, cs_min_time);
evr_evt_rec_control_o <= (er_event_number, er_event_enable, er_data_ack(3), er_error_ack(3));
mgt_reset_o <= mgt_reset;
evr_latency_measure_ctrl_o <= (lat_event_nr, lat_counter_arm);
evr_latency_measure_A_ctrl_o <= (lat_A_event_nr, lat_A_counter_arm);
evr_latency_measure_B_ctrl_o <= (lat_B_event_nr, lat_B_counter_arm);
-- --------------------------------------------------------------------------
-- add CDC output

View File

@@ -0,0 +1,98 @@
---------------------------------------------------------------------------
-- Paul Scherrer Institute (PSI)
-- ---------------------------------------------------------------------------
-- Unit : latency_measurement.vhd
-- Author : Jonas Purtschert
-- ---------------------------------------------------------------------------
-- Copyright© PSI, Section DSV
-- ---------------------------------------------------------------------------
-- Comment : Latency Measurement for IFC1210 Interrupt latency debugging
-- ---------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.evr320_pkg.all;
entity latency_measurement is
generic (
CLK_FREQ_HZ : natural := 125000000 -- Xuser Clk Frequency in Hz
);
port (
evr_clk_i : in std_logic;
xuser_clk_i : in std_logic;
decoder_event_valid_i : in std_logic;
decoder_event_i : in std_logic_vector(7 downto 0);
status_o : out typ_rec_latency_measure_stat;
ctrl_i : in typ_rec_latency_measure_ctrl
);
end latency_measurement;
architecture rtl of latency_measurement is
-- --------------------------------------------------------------------------
-- Signal, Types, Constants
-- --------------------------------------------------------------------------
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(CLK_FREQ_HZ / 100, 32); -- MAX 10ms
begin
-- Process: filter events for matching event_nr register:
---------------------------------------------------------
ext_event_proc : process(evr_clk_i)
begin
if (rising_edge(evr_clk_i)) then
-- sync to MGT clock domain:
event_nr_sync <= ctrl_i.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_i = '1' and decoder_event_i = 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_i, counter)
begin
if rising_edge(xuser_clk_i) 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 (ctrl_i.counter_arm = '1') then
state <= armed;
end if;
end case;
end if;
status_o.counter_val <= std_logic_vector(counter);
status_o.event_detected <= event_detected_sync(event_detected_sync'left);
end process;
end rtl;