Compare commits
4 Commits
master
...
latency_me
| Author | SHA1 | Date | |
|---|---|---|---|
| 36a99d0bf4 | |||
| 4322debe14 | |||
| 83c3a4d910 | |||
| 98ba65bc62 |
BIN
doc/evr320.odt
Normal file
BIN
doc/evr320.odt
Normal file
Binary file not shown.
BIN
doc/evr320.pdf
BIN
doc/evr320.pdf
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
98
hdl/latency_measurement.vhd
Normal file
98
hdl/latency_measurement.vhd
Normal 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;
|
||||
Reference in New Issue
Block a user