14 Commits

Author SHA1 Message Date
7414bcacf6 Updated changelog 2023-09-11 13:05:53 +02:00
4826a093f4 Updated to the newest libraries 2023-09-11 11:28:47 +02:00
5bf9caae3a Merge branch 'added_robustness' into 'master'
Add robustness to comma-detection and reset generation.

See merge request GFA/Libraries/Firmware/VHDL/evr320!3
2021-03-16 07:44:43 +01:00
13d42baf14 Merge branch 'fix_issue_#5' into 'master'
Amendment: removed 'evr_params.cs_timeout_cnt' assignment

See merge request GFA/Libraries/Firmware/VHDL/evr320!2
2021-02-25 09:45:32 +01:00
till straumann
d135fbddca Add robustness to comma-detection and reset generation.
This patch addresses issues I occasionally observed:

a) I have seen occurrences when the GTX deasserts RXBYTEISALIGNED
   while the RXLOSSOFSYNC is *not* asserted.

   The comma-alignment state machine can be stuck in 'idle' believing
   all is well when in fact RXBYTEISALIGNED is deasserted.

   The proposed patch monitors RXBYTEISALIGNED in addition to
   RXLOSSOFSYNC in 'idle' state.

b) The synchronizer (inst_cdc_fast_stat) which takes the pulse
   width/delay to the EVR clock domain relies on a proper
   reset sequence for correct operation.

   It is possible, however, that the 'evr_clk' (which is generated
   from the recovered RX clock) is not ticking at all when 'xuser_RESET'
   resets said synchronizer. If e.g., there is no GTX reference clock
   present (because it requires i2c initialization which is performed
   later) then the EVR clock may not be ticking and prevent the
   destination side of the synchronizer from being reset. This
   has the consequence of 'width' and 'delay' *never* being
   updated.

   The proposed patch asserts the synchronizer reset while the RX PLL
   and/or MMCM are not locked.
2021-02-24 14:03:16 +01:00
till straumann
badd801839 Amendment: removed 'evr_params.cs_timeout_cnt' assignment
This parameter is a local enhancement and not present on the
master branch.

Also: two small changes which address GHDL issues.
2021-02-24 13:46:29 +01:00
df8522473d Merge branch 'fix_issue_#5' into 'master'
Fix for issue #5 (wrong endianness of data stream in test bed)

See merge request GFA/Libraries/Firmware/VHDL/evr320!1
2021-02-24 11:47:11 +01:00
till straumann
50860b9e20 Fix for issue #5 (wrong endianness of data stream in test bed)
The 'evr320_data_filter' entity presents data in little-endian format.
However, the test is written for big-endian; set the SWAP generic to
fix this.

Also; once this test passes events won't be detected because the checksum
timeout is not reached. Set to zero.

Last: ghdl complains about mem_data(x) indexing when x > C_MEM_DATA_WIDTH.
Replaced hard-coded statements by a simple loop that runs from
0 to C_MEM_DATA_WIDTH/8 - 1.
2021-02-24 11:08:05 +01:00
5bebe6dc41 Doc: Corrected latency counter register 0x38 description 2021-02-03 15:26:50 +01:00
83b6d6562d FIX: event_decoder ports in tb updated. Added Event Flag check for data width = 64. 2020-12-17 09:33:03 +01:00
34b221f62a FIX: typo introduced in rebase 2020-12-02 15:04:20 +01:00
26cc7548a3 FIX: default pulse width of user events set to 4 2020-12-02 10:29:58 +01:00
6d3fa8708a Merge branch 'latfix' 2020-11-18 15:21:13 +01:00
e6a3441a7a BUGFIX: added write register to stop latency counter 2020-03-05 07:46:30 +01:00
12 changed files with 3263 additions and 3229 deletions

View File

@@ -1,3 +1,6 @@
## 2.3.1
* Updated git submodule to the newest libraries
## 2.3
* Added Features
* IFC1210 wrapper includes block to adjust pulse length of individual event and also its delay, both in recovery clock cycles. Set by constant parameter under array format.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,400 +1,400 @@
---------------------------------------------------------------------------
-- 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(
MasterFrequency_g => g_XUSER_CLK_FREQ,
MaxMeasFrequency_g => 150000000
)
port map(
ClkMaster => xuser_CLK,
Rst => xuser_RESET,
ClkTest => clk_evr,
FrequencyHz => 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,
HoldOffEna_g => false,
MaxHoldOff_g => 10,
MaxDuration_g => MaxDuration_c,
RstPol_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,
MaxDelay_g => MaxDelay_c,
RStPol_g => '1',
RamBehavior_g => "RBW",
Hold_g => True)
port map( clk_i => clk_evr,
rst_i => evr_rst_s,
dat_i(0) => usr_evt_shaped_s(i),
str_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;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------
---------------------------------------------------------------------------
-- 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;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------

View File

@@ -12,6 +12,7 @@
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.psi_common_math_pkg.all;
package evr320_pkg is
@@ -19,9 +20,9 @@ package evr320_pkg is
-- --------------------------------------------------------------------------
-- Constants
-- --------------------------------------------------------------------------
constant c_CHECKSUM_MIN_EVT : std_logic_vector(31 downto 0) := X"00000064"; -- Check sum min count for events 100
constant c_CHECKSUM_MIN_TIME : std_logic_vector(31 downto 0) := X"0015CA20"; -- Check sum min time for events 10 ms
constant c_SOS_EVENT_DEFAULT : std_logic_vector( 7 downto 0) := X"20"; -- decimal 32
constant c_CHECKSUM_MIN_EVT : std_logic_vector(31 downto 0) := X"00000064"; -- Check sum min count for events 100
constant c_CHECKSUM_MIN_TIME : std_logic_vector(31 downto 0) := X"0015CA20"; -- Check sum min time for events 10 ms
constant c_SOS_EVENT_DEFAULT : std_logic_vector( 7 downto 0) := X"26"; -- default start-of-sequence (SOS) event
-- --------------------------------------------------------------------------
@@ -60,14 +61,17 @@ package evr320_pkg is
type typ_rec_latency_measure_stat is record
counter_val : std_logic_vector(31 downto 0);
event_detected : std_logic;
end record;
--*** Type record and constant for new feature pulse width & delay ***
constant MaxDuration_c : positive := 2**16-1; -- defines maximum pulse width to add on user events pulse output, in recovery clock cycles
constant MaxDelay_c : positive := 2**16-1; -- defines maximum delay to add on user events pulse output, in recovery clock cycles
constant MaxDuration_c : positive := 2**16-1; -- defines maximum pulse width to add on user events pulse output, in recovery clock cycles
constant MaxDelay_c : positive := 2**16-1; -- defines maximum delay to add on user events pulse output, in recovery clock cycles
constant UsrEventWidthDefault_c : std_logic_vector(log2ceil(MaxDuration_c)-1 downto 0) := std_logic_vector(to_unsigned(4, log2ceil(MaxDuration_c))); -- default pulse width of usr_events_adj_o
type typ_arr_width is array (4 downto 0) of std_logic_vector(log2ceil(MaxDuration_c)-1 downto 0);
type typ_arr_delay is array (4 downto 0) of std_logic_vector(log2ceil(MaxDelay_c)-1 downto 0);
-- --------------------------------------------------------------------------
-- Type Initialisation
-- --------------------------------------------------------------------------
@@ -82,7 +86,8 @@ package evr320_pkg is
constant c_INIT_REC_LATENCY_MEASURE_CTRL : typ_rec_latency_measure_ctrl := (event_nr => (others =>'0'),
counter_arm => '1');
constant c_INIT_REC_LATENCY_MEASURE_STAT : typ_rec_latency_measure_stat := (counter_val => (others =>'0'));
constant c_INIT_REC_LATENCY_MEASURE_STAT : typ_rec_latency_measure_stat := (counter_val => (others =>'0'),
event_detected => '0');
-- --------------------------------------------------------------------------
-- Function Prototypes
-- --------------------------------------------------------------------------

View File

@@ -1,403 +1,403 @@
-- ---------------------------------------------------------------------------
-- Paul Scherrer Institute (PSI)
-- ---------------------------------------------------------------------------
-- Unit : evr320_tmem.vhd
-- Author : Patric Bucher, Benoit Stef
-- ---------------------------------------------------------------------------
-- Copyright (c) PSI, Section DSV
-- ---------------------------------------------------------------------------
-- Comment : TMEM address decoding for register and memory access to evr320.
-- ---------------------------------------------------------------------------
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;
entity evr320_tmem is
port(
-- ------------------------------------------------------------------------
-- 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);
---------------------------------------------------------------------------
-- EVR320 Memory/Parameter Interface
---------------------------------------------------------------------------
evr_params_o : out typ_evr320_params;
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;
mgt_status_i : in std_logic_vector(31 downto 0);
mgt_reset_o : out std_logic;
mem_clk_o : out std_logic;
mem_addr_o : out std_logic_vector(10 downto 0);
mem_data_i : in std_logic_vector(63 downto 0);
---------------------------------------------------------------------------
-- EVR320 pulse output paremters
---------------------------------------------------------------------------
evr_clk_i : in std_logic;
evr_rst_i : in std_logic;
evr_pulse_delay_o : out typ_arr_delay;
evr_pulse_width_o : out typ_arr_width
);
end evr320_tmem;
architecture rtl of evr320_tmem is
-- ---------------------------------------------------------------------------
-- Constants
-- ---------------------------------------------------------------------------
constant reserved : std_logic_vector(63 downto 0) := X"0000_0000_0000_0000";
constant c_LOW : std_logic_vector(63 downto 0) := X"0000_0000_0000_0000";
constant NUM_REG64 : integer := 16;
constant TMEM_ADDR_LSB : integer := 3; -- 64 bit
constant REG_ADDR_WIDTH : integer := integer(ceil(log2(real(NUM_REG64)))) + TMEM_ADDR_LSB;
constant REG_ADDR_MSB : integer := REG_ADDR_WIDTH - 1;
constant MEM_ADDR_START : std_logic_vector(7 downto 0) := X"10";
-- --------------------------------------------------------------------------
-- Signal definitions
-- --------------------------------------------------------------------------
-- xuser tmem signals
signal xuser_TMEM_WE_reg : std_logic_vector( 7 downto 0) := (others => '0');
signal xuser_TMEM_ENA_reg : std_logic := '0';
signal xuser_TMEM_ADD_reg : std_logic_vector(13 downto 3) := (others => '0');
signal xuser_TMEM_DATW_reg : std_logic_vector(63 downto 0) := (others => '0');
-- evr params
signal mgt_status_evr : std_logic_vector(15 downto 0) := (others => '0');
signal mgt_status_evr_sync : std_logic_vector(15 downto 0) := (others => '0');
signal mgt_reset : std_logic := '0';
signal event_enable : std_logic_vector( 3 downto 0) := (others => '0');
signal event_numbers : typ_arr8(3 downto 0) := (others => (others => '0'));
signal event_numbers_concat : std_logic_vector(31 downto 0);
signal cs_min_cnt : std_logic_vector(31 downto 0) := c_CHECKSUM_MIN_EVT;
signal cs_min_time : std_logic_vector(31 downto 0) := c_CHECKSUM_MIN_TIME;
signal evr_frequency_sync : std_logic_vector(31 downto 0) := (others => '0');
signal evr_frequency : std_logic_vector(31 downto 0) := (others => '0');
-- event recorder
signal er_status : typ_evt_rec_status := c_INIT_EVT_REC_STATUS;
signal er_status_sync : typ_evt_rec_status := c_INIT_EVT_REC_STATUS;
signal er_event_enable : std_logic := '0';
signal er_event_number : std_logic_vector( 7 downto 0) := c_SOS_EVENT_DEFAULT;
signal er_data_ack : std_logic_vector( 3 downto 0) := (others => '0');
signal er_error_ack : std_logic_vector( 3 downto 0) := (others => '0');
signal er_handshake_status : std_logic_vector(31 downto 0) := (others => '0');
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) := x"26"; -- default SOS event
signal lat_counter_val : std_logic_vector(31 downto 0) := (others=>'0');
-- signal evr_force : std_logic_vector(3 downto 0) := (others => '0');
-- signal evr_force_rd : std_logic_vector(3 downto 0) := (others => '0'); -- readback
-- signal evr_force_pulse : typ_arr4(3 downto 0) := (others => (others => '0'));
-- event pulse config
signal evr_puls_width_cfg_s : typ_arr_width :=((others=>(others=>'0')));
signal evr_puls_delay_cfg_s : typ_arr_delay :=((others=>(others=>'0')));
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- //////////////////// Main Body /////////////////////////
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
begin
-- --------------------------------------------------------------------------
-- static signal assignments
-- --------------------------------------------------------------------------
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;
-- --------------------------------------------------------------------------
-- TODO: proper CDC
-- Synchronisation to xuser_CLK
-- --------------------------------------------------------------------------
prc_sync_xuser: process (xuser_CLK)
begin
if rising_edge(xuser_CLK) then
---
xuser_TMEM_WE_reg <= xuser_TMEM_WE;
xuser_TMEM_ENA_reg <= xuser_TMEM_ENA;
xuser_TMEM_DATW_reg <= xuser_TMEM_DATW;
xuser_TMEM_ADD_reg <= xuser_TMEM_ADD;
---
mgt_status_evr_sync <= "000000" & mgt_status_i(c_RXRESETDONE) & mgt_status_i(c_RXLOSSOFSYNC) & "000000" & mgt_status_i(c_RXRESETDONE) & mgt_status_i(c_RXPLLLKDET);
mgt_status_evr <= mgt_status_evr_sync;
---
er_status_sync <= evr_evt_rec_status_i;
er_status <= er_status_sync;
---
evr_frequency_sync <= evr_frequency_i;
evr_frequency <= evr_frequency_sync;
---
end if;
end process;
-- --------------------------------------------------------------------------
-- Read operation
-- --------------------------------------------------------------------------
read_tmem_evr: process(xuser_CLK)
begin
if (rising_edge(xuser_CLK)) then
lat_counter_arm <= '0';
if (xuser_TMEM_ENA_reg = '1') then
if (xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH) = c_LOW(13 downto REG_ADDR_WIDTH)) then
case xuser_TMEM_ADD_reg(REG_ADDR_MSB downto TMEM_ADDR_LSB) is
when X"0" => xuser_TMEM_DATR <= event_numbers_concat & X"0000" & mgt_status_evr; -- 64bit / ByteAddr 000
when X"1" => xuser_TMEM_DATR <= reserved(63 downto 32) & X"0000_00" & bit2byte(mgt_reset); -- 64bit / ByteAddr 008 --> 0x00C = not implemented in ifc1210
when X"2" => xuser_TMEM_DATR <= reserved(63 downto 32) & bit2byte(event_enable); -- 64bit / ByteAddr 010 --> 0x014 = Bit0 SW Trigger Event 0, Bit8 SW Trigger Event 1, ... evr_force
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"000000" & lat_event_nr; -- 64bit / ByteAddr 030
when X"7" => xuser_TMEM_DATR <= reserved(63 downto 32) & lat_counter_val; lat_counter_arm <= '1'; -- 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
when X"B" => xuser_TMEM_DATR <= evr_puls_width_cfg_s(4) & evr_puls_width_cfg_s(3) & evr_puls_width_cfg_s(2) & evr_puls_width_cfg_s(1) ; --64 bit / ByteAddr 054
when X"C" => xuser_TMEM_DATR <= reserved(63 downto 32) & evr_puls_width_cfg_s(0) & evr_puls_delay_cfg_s(0); -- 64bit / ByteAddr 058
when others => xuser_TMEM_DATR <= (others => '0');
end case;
else --> 0x0080-0x4000
xuser_TMEM_DATR <= mem_data_i;
end if;
end if;
end if;
end process;
-- --------------------------------------------------------------------------
-- Write operation - Byte control
-- --------------------------------------------------------------------------
write_tmem_evr: process(xuser_CLK)
begin
if rising_edge(xuser_CLK) then
-- default assignments
er_data_ack <= er_data_ack(2 downto 0) & '0';
er_error_ack <= er_error_ack(2 downto 0) & '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
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"0" then --ByteAddr 000
-- if xuser_TMEM_WE_reg(0) = '1' then -read only- <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -read only- <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -read only- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -read only- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
if xuser_TMEM_WE_reg(4) = '1' then event_numbers(0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
if xuser_TMEM_WE_reg(5) = '1' then event_numbers(1) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' then event_numbers(2) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
if xuser_TMEM_WE_reg(7) = '1' then event_numbers(3) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"1" then --ByteAddr 008
if xuser_TMEM_WE_reg(0) = '1' then mgt_reset <= xuser_TMEM_DATW_reg(0); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -reserved- <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"2" then --ByteAddr 010
if xuser_TMEM_WE_reg(0) = '1' then event_enable(0) <= xuser_TMEM_DATW_reg( 0); end if;
if xuser_TMEM_WE_reg(1) = '1' then event_enable(1) <= xuser_TMEM_DATW_reg( 8); end if;
if xuser_TMEM_WE_reg(2) = '1' then event_enable(2) <= xuser_TMEM_DATW_reg(16); end if;
if xuser_TMEM_WE_reg(3) = '1' then event_enable(3) <= xuser_TMEM_DATW_reg(24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"4" then --ByteAddr 020
if xuser_TMEM_WE_reg(0) = '1' then cs_min_cnt ( 7 downto 0) <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
if xuser_TMEM_WE_reg(1) = '1' then cs_min_cnt (15 downto 8) <= xuser_TMEM_DATW_reg(15 downto 8); end if;
if xuser_TMEM_WE_reg(2) = '1' then cs_min_cnt (23 downto 16) <= xuser_TMEM_DATW_reg(23 downto 16); end if;
if xuser_TMEM_WE_reg(3) = '1' then cs_min_cnt (31 downto 24) <= xuser_TMEM_DATW_reg(31 downto 24); end if;
if xuser_TMEM_WE_reg(4) = '1' then cs_min_time( 7 downto 0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
if xuser_TMEM_WE_reg(5) = '1' then cs_min_time(15 downto 8) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' then cs_min_time(23 downto 16) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
if xuser_TMEM_WE_reg(7) = '1' then cs_min_time(31 downto 24) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
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(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;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- ( 7 downto 0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- (15 downto 8) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- (23 downto 16) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- (31 downto 24) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"8" then --ByteAddr 040
if xuser_TMEM_WE_reg(0) = '1' then er_event_enable <= xuser_TMEM_DATW_reg(0); end if;
if xuser_TMEM_WE_reg(1) = '1' then er_event_number <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -read only- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -read only- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' and xuser_TMEM_DATW_reg(48) = '1' then er_data_ack <= (others => '1'); end if;
if xuser_TMEM_WE_reg(7) = '1' and xuser_TMEM_DATW_reg(56) = '1' then er_error_ack <= (others => '1'); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"A" then --ByteAddr 050
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_delay_cfg_s(1) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- usr evt 0 del
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_delay_cfg_s(2) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- usr evt 1 del
if xuser_TMEM_WE_reg(5 downto 4) = "11" then evr_puls_delay_cfg_s(3) <= xuser_TMEM_DATW_reg(47 downto 32); end if; -- usr evt 2 del
if xuser_TMEM_WE_reg(7 downto 6) = "11" then evr_puls_delay_cfg_s(4) <= xuser_TMEM_DATW_reg(63 downto 48); end if; -- usr evt 3 del
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"B" then --ByteAddr 058
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_width_cfg_s(1) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- usr evt 0 width
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_width_cfg_s(2) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- usr evt 1 width
if xuser_TMEM_WE_reg(5 downto 4) = "11" then evr_puls_width_cfg_s(3) <= xuser_TMEM_DATW_reg(47 downto 32); end if; -- usr evt 2 width
if xuser_TMEM_WE_reg(7 downto 6) = "11" then evr_puls_width_cfg_s(4) <= xuser_TMEM_DATW_reg(63 downto 48); end if; -- usr evt 3 width
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"C" then --ByteAddr 060
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_delay_cfg_s(0) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- sos evt del
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_width_cfg_s(0) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- sos evt width
end if;
end if;
end if;
end process;
-- --------------------------------------------------------------------------
-- Port mapping
-- --------------------------------------------------------------------------
mem_clk_o <= xuser_CLK;
mem_addr_o <= std_logic_vector(unsigned(xuser_TMEM_ADD) - unsigned(MEM_ADDR_START));
--event recorder had to be also added to cdc
evr_evt_rec_control_o <= (er_event_number, er_event_enable, er_data_ack(3), er_error_ack(3));
mgt_reset_o <= mgt_reset;
-- --------------------------------------------------------------------------
-- add CDC output
-- --------------------------------------------------------------------------
block_cdc_evr_puls_param : block
signal input_s, output_s : std_logic_vector(10 * 16 - 1 downto 0);
begin
-- ------------------------------------------------------------------------
-- Assemble Input
-- ------------------------------------------------------------------------
--** pulse delay parameters **
input_s(15 downto 0) <= evr_puls_delay_cfg_s(0);
input_s(31 downto 16) <= evr_puls_delay_cfg_s(1);
input_s(47 downto 32) <= evr_puls_delay_cfg_s(2);
input_s(63 downto 48) <= evr_puls_delay_cfg_s(3);
input_s(79 downto 64) <= evr_puls_delay_cfg_s(4);
--** pulse width parameters **
input_s(95 downto 80) <= evr_puls_width_cfg_s(0);
input_s(111 downto 96) <= evr_puls_width_cfg_s(1);
input_s(127 downto 112) <= evr_puls_width_cfg_s(2);
input_s(143 downto 128) <= evr_puls_width_cfg_s(3);
input_s(159 downto 144) <= evr_puls_width_cfg_s(4);
-- Instance
inst_cdc_fast_stat : entity work.psi_common_status_cc
generic map(DataWidth_g => input_s'length)
port map(ClkA => xuser_CLK,
RstInA => xuser_RESET,
DataA => input_s,
ClkB => evr_clk_i,
RstInB => evr_rst_i,
DataB => output_s);
-- ------------------------------------------------------------------------
-- Disassemble Output
-- ------------------------------------------------------------------------
--** pulse delay parameters **
evr_pulse_delay_o(0) <= output_s(15 downto 0);
evr_pulse_delay_o(1) <= output_s(31 downto 16);
evr_pulse_delay_o(2) <= output_s(47 downto 32);
evr_pulse_delay_o(3) <= output_s(63 downto 48);
evr_pulse_delay_o(4) <= output_s(79 downto 64);
--** pulse width parameters **
evr_pulse_width_o(0) <= output_s(95 downto 80);
evr_pulse_width_o(1) <= output_s(111 downto 96);
evr_pulse_width_o(2) <= output_s(127 downto 112);
evr_pulse_width_o(3) <= output_s(143 downto 128);
evr_pulse_width_o(4) <= output_s(159 downto 144);
end block;
block_cdc_evr_code_param : block
signal input_s, output_s : std_logic_vector(108 downto 0);
begin
-- ------------------------------------------------------------------------
-- Assemble Input
-- ------------------------------------------------------------------------
--** event numbers **
input_s( 7 downto 0) <= event_numbers(0);
input_s(15 downto 8) <= event_numbers(1);
input_s(23 downto 16) <= event_numbers(2);
input_s(31 downto 24) <= event_numbers(3);
--** event pulse enable **
input_s(35 downto 32) <= event_enable;
--** time counter **
input_s(67 downto 36) <= cs_min_time;
input_s(99 downto 68) <= cs_min_cnt;
--** latency counter **
input_s(100) <= lat_counter_arm;
input_s(108 downto 101) <= lat_event_nr;
-- Instance
inst_cdc_fast_stat : entity work.psi_common_status_cc
generic map(DataWidth_g => input_s'length)
port map(ClkA => xuser_CLK,
RstInA => xuser_RESET,
RstOutA => open,
DataA => input_s,
ClkB => evr_clk_i,
RstInB => evr_rst_i,
RstOutB => open,
DataB => output_s);
-- ------------------------------------------------------------------------
-- Disassemble Output
-- ------------------------------------------------------------------------
--** event numbers **
evr_params_o.event_numbers(0) <= output_s( 7 downto 0) ;
evr_params_o.event_numbers(1) <= output_s(15 downto 8) ;
evr_params_o.event_numbers(2) <= output_s(23 downto 16);
evr_params_o.event_numbers(3) <= output_s(31 downto 24);
--** event pulse enable **
evr_params_o.event_enable <= output_s(35 downto 32);
--** time counter **
evr_params_o.cs_min_time <= output_s(67 downto 36);
evr_params_o.cs_min_cnt <= output_s(99 downto 68);
--** latency counter **
evr_latency_measure_ctrl_o.counter_arm <= output_s(100) ;
evr_latency_measure_ctrl_o.event_nr <= output_s(108 downto 101) ;
end block;
end rtl;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- Paul Scherrer Institute (PSI)
-- ---------------------------------------------------------------------------
-- Unit : evr320_tmem.vhd
-- Author : Patric Bucher, Benoit Stef
-- ---------------------------------------------------------------------------
-- Copyright (c) PSI, Section DSV
-- ---------------------------------------------------------------------------
-- Comment : TMEM address decoding for register and memory access to evr320.
-- ---------------------------------------------------------------------------
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;
entity evr320_tmem is
port(
-- ------------------------------------------------------------------------
-- 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);
---------------------------------------------------------------------------
-- EVR320 Memory/Parameter Interface
---------------------------------------------------------------------------
evr_params_o : out typ_evr320_params;
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;
mgt_status_i : in std_logic_vector(31 downto 0);
mgt_reset_o : out std_logic;
mem_clk_o : out std_logic;
mem_addr_o : out std_logic_vector(10 downto 0);
mem_data_i : in std_logic_vector(63 downto 0);
---------------------------------------------------------------------------
-- EVR320 pulse output paremters
---------------------------------------------------------------------------
evr_clk_i : in std_logic;
evr_rst_i : in std_logic;
evr_pulse_delay_o : out typ_arr_delay;
evr_pulse_width_o : out typ_arr_width
);
end evr320_tmem;
architecture rtl of evr320_tmem is
-- ---------------------------------------------------------------------------
-- Constants
-- ---------------------------------------------------------------------------
constant reserved : std_logic_vector(63 downto 0) := X"0000_0000_0000_0000";
constant c_LOW : std_logic_vector(63 downto 0) := X"0000_0000_0000_0000";
constant NUM_REG64 : integer := 16;
constant TMEM_ADDR_LSB : integer := 3; -- 64 bit
constant REG_ADDR_WIDTH : integer := integer(ceil(log2(real(NUM_REG64)))) + TMEM_ADDR_LSB;
constant REG_ADDR_MSB : integer := REG_ADDR_WIDTH - 1;
constant MEM_ADDR_START : std_logic_vector(7 downto 0) := X"10";
-- --------------------------------------------------------------------------
-- Signal definitions
-- --------------------------------------------------------------------------
-- xuser tmem signals
signal xuser_TMEM_WE_reg : std_logic_vector( 7 downto 0) := (others => '0');
signal xuser_TMEM_ENA_reg : std_logic := '0';
signal xuser_TMEM_ADD_reg : std_logic_vector(13 downto 3) := (others => '0');
signal xuser_TMEM_DATW_reg : std_logic_vector(63 downto 0) := (others => '0');
-- evr params
signal mgt_status_evr : std_logic_vector(15 downto 0) := (others => '0');
signal mgt_status_evr_sync : std_logic_vector(15 downto 0) := (others => '0');
signal mgt_reset : std_logic := '0';
signal event_enable : std_logic_vector( 3 downto 0) := (others => '0');
signal event_numbers : typ_arr8(3 downto 0) := (others => (others => '0'));
signal event_numbers_concat : std_logic_vector(31 downto 0);
signal cs_min_cnt : std_logic_vector(31 downto 0) := c_CHECKSUM_MIN_EVT;
signal cs_min_time : std_logic_vector(31 downto 0) := c_CHECKSUM_MIN_TIME;
signal evr_frequency_sync : std_logic_vector(31 downto 0) := (others => '0');
signal evr_frequency : std_logic_vector(31 downto 0) := (others => '0');
-- event recorder
signal er_status : typ_evt_rec_status := c_INIT_EVT_REC_STATUS;
signal er_status_sync : typ_evt_rec_status := c_INIT_EVT_REC_STATUS;
signal er_event_enable : std_logic := '0';
signal er_event_number : std_logic_vector( 7 downto 0) := c_SOS_EVENT_DEFAULT;
signal er_data_ack : std_logic_vector( 3 downto 0) := (others => '0');
signal er_error_ack : std_logic_vector( 3 downto 0) := (others => '0');
signal er_handshake_status : std_logic_vector(31 downto 0) := (others => '0');
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) := x"26"; -- default SOS event
signal lat_counter_val : std_logic_vector(31 downto 0) := (others=>'0');
-- signal evr_force : std_logic_vector(3 downto 0) := (others => '0');
-- signal evr_force_rd : std_logic_vector(3 downto 0) := (others => '0'); -- readback
-- signal evr_force_pulse : typ_arr4(3 downto 0) := (others => (others => '0'));
-- event pulse config
signal evr_puls_width_cfg_s : typ_arr_width :=((others=>(others=>'0')));
signal evr_puls_delay_cfg_s : typ_arr_delay :=((others=>(others=>'0')));
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- //////////////////// Main Body /////////////////////////
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
begin
-- --------------------------------------------------------------------------
-- static signal assignments
-- --------------------------------------------------------------------------
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;
-- --------------------------------------------------------------------------
-- TODO: proper CDC
-- Synchronisation to xuser_CLK
-- --------------------------------------------------------------------------
prc_sync_xuser: process (xuser_CLK)
begin
if rising_edge(xuser_CLK) then
---
xuser_TMEM_WE_reg <= xuser_TMEM_WE;
xuser_TMEM_ENA_reg <= xuser_TMEM_ENA;
xuser_TMEM_DATW_reg <= xuser_TMEM_DATW;
xuser_TMEM_ADD_reg <= xuser_TMEM_ADD;
---
mgt_status_evr_sync <= "000000" & mgt_status_i(c_RXRESETDONE) & mgt_status_i(c_RXLOSSOFSYNC) & "000000" & mgt_status_i(c_RXRESETDONE) & mgt_status_i(c_RXPLLLKDET);
mgt_status_evr <= mgt_status_evr_sync;
---
er_status_sync <= evr_evt_rec_status_i;
er_status <= er_status_sync;
---
evr_frequency_sync <= evr_frequency_i;
evr_frequency <= evr_frequency_sync;
---
end if;
end process;
-- --------------------------------------------------------------------------
-- Read operation
-- --------------------------------------------------------------------------
read_tmem_evr: process(xuser_CLK)
begin
if (rising_edge(xuser_CLK)) then
lat_counter_arm <= '0';
if (xuser_TMEM_ENA_reg = '1') then
if (xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH) = c_LOW(13 downto REG_ADDR_WIDTH)) then
case xuser_TMEM_ADD_reg(REG_ADDR_MSB downto TMEM_ADDR_LSB) is
when X"0" => xuser_TMEM_DATR <= event_numbers_concat & X"0000" & mgt_status_evr; -- 64bit / ByteAddr 000
when X"1" => xuser_TMEM_DATR <= reserved(63 downto 32) & X"0000_00" & bit2byte(mgt_reset); -- 64bit / ByteAddr 008 --> 0x00C = not implemented in ifc1210
when X"2" => xuser_TMEM_DATR <= reserved(63 downto 32) & bit2byte(event_enable); -- 64bit / ByteAddr 010 --> 0x014 = Bit0 SW Trigger Event 0, Bit8 SW Trigger Event 1, ... evr_force
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"000000" & lat_event_nr; -- 64bit / ByteAddr 030
when X"7" => xuser_TMEM_DATR <= reserved(63 downto 32) & lat_counter_val; lat_counter_arm <= '1'; -- 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
when X"B" => xuser_TMEM_DATR <= evr_puls_width_cfg_s(4) & evr_puls_width_cfg_s(3) & evr_puls_width_cfg_s(2) & evr_puls_width_cfg_s(1) ; --64 bit / ByteAddr 054
when X"C" => xuser_TMEM_DATR <= reserved(63 downto 32) & evr_puls_width_cfg_s(0) & evr_puls_delay_cfg_s(0); -- 64bit / ByteAddr 058
when others => xuser_TMEM_DATR <= (others => '0');
end case;
else --> 0x0080-0x4000
xuser_TMEM_DATR <= mem_data_i;
end if;
end if;
end if;
end process;
-- --------------------------------------------------------------------------
-- Write operation - Byte control
-- --------------------------------------------------------------------------
write_tmem_evr: process(xuser_CLK)
begin
if rising_edge(xuser_CLK) then
-- default assignments
er_data_ack <= er_data_ack(2 downto 0) & '0';
er_error_ack <= er_error_ack(2 downto 0) & '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
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"0" then --ByteAddr 000
-- if xuser_TMEM_WE_reg(0) = '1' then -read only- <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -read only- <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -read only- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -read only- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
if xuser_TMEM_WE_reg(4) = '1' then event_numbers(0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
if xuser_TMEM_WE_reg(5) = '1' then event_numbers(1) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' then event_numbers(2) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
if xuser_TMEM_WE_reg(7) = '1' then event_numbers(3) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"1" then --ByteAddr 008
if xuser_TMEM_WE_reg(0) = '1' then mgt_reset <= xuser_TMEM_DATW_reg(0); end if;
-- if xuser_TMEM_WE_reg(1) = '1' then -reserved- <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"2" then --ByteAddr 010
if xuser_TMEM_WE_reg(0) = '1' then event_enable(0) <= xuser_TMEM_DATW_reg( 0); end if;
if xuser_TMEM_WE_reg(1) = '1' then event_enable(1) <= xuser_TMEM_DATW_reg( 8); end if;
if xuser_TMEM_WE_reg(2) = '1' then event_enable(2) <= xuser_TMEM_DATW_reg(16); end if;
if xuser_TMEM_WE_reg(3) = '1' then event_enable(3) <= xuser_TMEM_DATW_reg(24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"4" then --ByteAddr 020
if xuser_TMEM_WE_reg(0) = '1' then cs_min_cnt ( 7 downto 0) <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
if xuser_TMEM_WE_reg(1) = '1' then cs_min_cnt (15 downto 8) <= xuser_TMEM_DATW_reg(15 downto 8); end if;
if xuser_TMEM_WE_reg(2) = '1' then cs_min_cnt (23 downto 16) <= xuser_TMEM_DATW_reg(23 downto 16); end if;
if xuser_TMEM_WE_reg(3) = '1' then cs_min_cnt (31 downto 24) <= xuser_TMEM_DATW_reg(31 downto 24); end if;
if xuser_TMEM_WE_reg(4) = '1' then cs_min_time( 7 downto 0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
if xuser_TMEM_WE_reg(5) = '1' then cs_min_time(15 downto 8) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' then cs_min_time(23 downto 16) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
if xuser_TMEM_WE_reg(7) = '1' then cs_min_time(31 downto 24) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
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(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;
-- if xuser_TMEM_WE_reg(4) = '1' then -reserved- ( 7 downto 0) <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -reserved- (15 downto 8) <= xuser_TMEM_DATW_reg(47 downto 40); end if;
-- if xuser_TMEM_WE_reg(6) = '1' then -reserved- (23 downto 16) <= xuser_TMEM_DATW_reg(55 downto 48); end if;
-- if xuser_TMEM_WE_reg(7) = '1' then -reserved- (31 downto 24) <= xuser_TMEM_DATW_reg(63 downto 56); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"8" then --ByteAddr 040
if xuser_TMEM_WE_reg(0) = '1' then er_event_enable <= xuser_TMEM_DATW_reg(0); end if;
if xuser_TMEM_WE_reg(1) = '1' then er_event_number <= xuser_TMEM_DATW_reg(15 downto 8); end if;
-- if xuser_TMEM_WE_reg(2) = '1' then -reserved- <= xuser_TMEM_DATW_reg(23 downto 16); end if;
-- if xuser_TMEM_WE_reg(3) = '1' then -reserved- <= xuser_TMEM_DATW_reg(31 downto 24); end if;
-- if xuser_TMEM_WE_reg(4) = '1' then -read only- <= xuser_TMEM_DATW_reg(39 downto 32); end if;
-- if xuser_TMEM_WE_reg(5) = '1' then -read only- <= xuser_TMEM_DATW_reg(47 downto 40); end if;
if xuser_TMEM_WE_reg(6) = '1' and xuser_TMEM_DATW_reg(48) = '1' then er_data_ack <= (others => '1'); end if;
if xuser_TMEM_WE_reg(7) = '1' and xuser_TMEM_DATW_reg(56) = '1' then er_error_ack <= (others => '1'); end if;
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"A" then --ByteAddr 050
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_delay_cfg_s(1) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- usr evt 0 del
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_delay_cfg_s(2) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- usr evt 1 del
if xuser_TMEM_WE_reg(5 downto 4) = "11" then evr_puls_delay_cfg_s(3) <= xuser_TMEM_DATW_reg(47 downto 32); end if; -- usr evt 2 del
if xuser_TMEM_WE_reg(7 downto 6) = "11" then evr_puls_delay_cfg_s(4) <= xuser_TMEM_DATW_reg(63 downto 48); end if; -- usr evt 3 del
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"B" then --ByteAddr 058
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_width_cfg_s(1) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- usr evt 0 width
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_width_cfg_s(2) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- usr evt 1 width
if xuser_TMEM_WE_reg(5 downto 4) = "11" then evr_puls_width_cfg_s(3) <= xuser_TMEM_DATW_reg(47 downto 32); end if; -- usr evt 2 width
if xuser_TMEM_WE_reg(7 downto 6) = "11" then evr_puls_width_cfg_s(4) <= xuser_TMEM_DATW_reg(63 downto 48); end if; -- usr evt 3 width
end if;
-----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"C" then --ByteAddr 060
if xuser_TMEM_WE_reg(1 downto 0) = "11" then evr_puls_delay_cfg_s(0) <= xuser_TMEM_DATW_reg(15 downto 0); end if; -- sos evt del
if xuser_TMEM_WE_reg(3 downto 2) = "11" then evr_puls_width_cfg_s(0) <= xuser_TMEM_DATW_reg(31 downto 16); end if; -- sos evt width
end if;
end if;
end if;
end process;
-- --------------------------------------------------------------------------
-- Port mapping
-- --------------------------------------------------------------------------
mem_clk_o <= xuser_CLK;
mem_addr_o <= std_logic_vector(unsigned(xuser_TMEM_ADD) - unsigned(MEM_ADDR_START));
--event recorder had to be also added to cdc
evr_evt_rec_control_o <= (er_event_number, er_event_enable, er_data_ack(3), er_error_ack(3));
mgt_reset_o <= mgt_reset;
-- --------------------------------------------------------------------------
-- add CDC output
-- --------------------------------------------------------------------------
block_cdc_evr_puls_param : block
signal input_s, output_s : std_logic_vector(10 * 16 - 1 downto 0);
begin
-- ------------------------------------------------------------------------
-- Assemble Input
-- ------------------------------------------------------------------------
--** pulse delay parameters **
input_s(15 downto 0) <= evr_puls_delay_cfg_s(0);
input_s(31 downto 16) <= evr_puls_delay_cfg_s(1);
input_s(47 downto 32) <= evr_puls_delay_cfg_s(2);
input_s(63 downto 48) <= evr_puls_delay_cfg_s(3);
input_s(79 downto 64) <= evr_puls_delay_cfg_s(4);
--** pulse width parameters **
input_s(95 downto 80) <= evr_puls_width_cfg_s(0);
input_s(111 downto 96) <= evr_puls_width_cfg_s(1);
input_s(127 downto 112) <= evr_puls_width_cfg_s(2);
input_s(143 downto 128) <= evr_puls_width_cfg_s(3);
input_s(159 downto 144) <= evr_puls_width_cfg_s(4);
-- Instance
inst_cdc_fast_stat : entity work.psi_common_status_cc
generic map(width_g => input_s'length)
port map(a_clk_i => xuser_CLK,
a_rst_i => xuser_RESET,
a_dat_i => input_s,
b_clk_i => evr_clk_i,
b_rst_i => evr_rst_i,
b_dat_o => output_s);
-- ------------------------------------------------------------------------
-- Disassemble Output
-- ------------------------------------------------------------------------
--** pulse delay parameters **
evr_pulse_delay_o(0) <= output_s(15 downto 0);
evr_pulse_delay_o(1) <= output_s(31 downto 16);
evr_pulse_delay_o(2) <= output_s(47 downto 32);
evr_pulse_delay_o(3) <= output_s(63 downto 48);
evr_pulse_delay_o(4) <= output_s(79 downto 64);
--** pulse width parameters **
evr_pulse_width_o(0) <= output_s(95 downto 80);
evr_pulse_width_o(1) <= output_s(111 downto 96);
evr_pulse_width_o(2) <= output_s(127 downto 112);
evr_pulse_width_o(3) <= output_s(143 downto 128);
evr_pulse_width_o(4) <= output_s(159 downto 144);
end block;
block_cdc_evr_code_param : block
signal input_s, output_s : std_logic_vector(108 downto 0);
begin
-- ------------------------------------------------------------------------
-- Assemble Input
-- ------------------------------------------------------------------------
--** event numbers **
input_s( 7 downto 0) <= event_numbers(0);
input_s(15 downto 8) <= event_numbers(1);
input_s(23 downto 16) <= event_numbers(2);
input_s(31 downto 24) <= event_numbers(3);
--** event pulse enable **
input_s(35 downto 32) <= event_enable;
--** time counter **
input_s(67 downto 36) <= cs_min_time;
input_s(99 downto 68) <= cs_min_cnt;
--** latency counter **
input_s(100) <= lat_counter_arm;
input_s(108 downto 101) <= lat_event_nr;
-- Instance
inst_cdc_fast_stat : entity work.psi_common_status_cc
generic map(width_g => input_s'length)
port map(a_clk_i => xuser_CLK,
a_rst_i => xuser_RESET,
a_rst_o => open,
a_dat_i => input_s,
b_clk_i => evr_clk_i,
b_rst_i => evr_rst_i,
b_rst_o => open,
b_dat_o => output_s);
-- ------------------------------------------------------------------------
-- Disassemble Output
-- ------------------------------------------------------------------------
--** event numbers **
evr_params_o.event_numbers(0) <= output_s( 7 downto 0) ;
evr_params_o.event_numbers(1) <= output_s(15 downto 8) ;
evr_params_o.event_numbers(2) <= output_s(23 downto 16);
evr_params_o.event_numbers(3) <= output_s(31 downto 24);
--** event pulse enable **
evr_params_o.event_enable <= output_s(35 downto 32);
--** time counter **
evr_params_o.cs_min_time <= output_s(67 downto 36);
evr_params_o.cs_min_cnt <= output_s(99 downto 68);
--** latency counter **
evr_latency_measure_ctrl_o.counter_arm <= output_s(100) ;
evr_latency_measure_ctrl_o.event_nr <= output_s(108 downto 101) ;
end block;
end rtl;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------

View File

@@ -7,7 +7,7 @@
-- : Patric Bucher, Section DSV
-- Version : $Revision: 1.1 $
------------------------------------------------------------------------------
-- Copyright<EFBFBD> PSI, Section Diagnostic
-- Copyright© PSI, Section Diagnostic
------------------------------------------------------------------------------
-- Comment : Virtex-6 GTXE1 primitive configured for HIPA 50.63282 MHz
------------------------------------------------------------------------------
@@ -384,7 +384,7 @@ begin
RXPLLLKDET => o_mgt.ctrl.RXPLLLKDET , --RXPLLLKDET_OUT,
RXPLLLKDETEN => '1', --
RXPLLPOWERDOWN => '0', --
RXPLLREFSELDY => "000", --GREFCLKRX
RXPLLREFSELDY => "000", -- GREFCLKRX
RXRATE => "00", --
RXRATEDONE => open, --
RXRESETDONE => o_mgt.ctrl.RXRESETDONE , --RXRESETDONE_OUT,

View File

@@ -7,7 +7,7 @@
-- : Patric Bucher, Section DSV
-- Version : $Revision: 1.1 $
------------------------------------------------------------------------------
-- Copyright<EFBFBD> PSI, Section Diagnostic
-- Copyright© PSI, Section Diagnostic
------------------------------------------------------------------------------
-- Comment : Wrapper vor Virtex-6 GTX ready to use in HIPA and SwissFEL (SFEL)
------------------------------------------------------------------------------
@@ -137,8 +137,8 @@ begin
o_mgt_status(16) <= sl_rx0_slide;
o_mgt_status(17) <= sl_gtxe_rx_sync_done;
o_mgt_status(19 downto 18) <= o_mgt.rx.RXNOTINTABLE(1 downto 0); -- Byte 1 + Byte 0
o_mgt_status(23 downto 20) <= o_mgt.rx.RXDISPERR(3 downto 0); -- Byte 1 + Byte 0
o_mgt_status(31 downto 24) <= B"0000_0000"; -- undefined
o_mgt_status(21 downto 20) <= o_mgt.rx.RXDISPERR(1 downto 0); -- Byte 1 + Byte 0
o_mgt_status(31 downto 22) <= B"00_0000_0000"; -- undefined
-- GTXE RX IF ---------------------------------------------------------------------
@@ -260,7 +260,7 @@ begin
else
case s_align_fsm is
when align_idle =>
if o_mgt.rx.RXLOSSOFSYNC( 1) = '1' then
if o_mgt.rx.RXLOSSOFSYNC( 1) = '1' or o_mgt.rx.RXBYTEISALIGNED = '0' then
s_align_fsm <= align_slide;
end if;
when align_slide =>

View File

@@ -64,7 +64,6 @@ add_sources $LibPath/Firmware/VHDL/evr320/hdl {
# EVR320 Decoder Testbench
add_sources $LibPath/Firmware/VHDL/evr320/tb {
evr320_decoder_tb.vhd \
evr320_ifc1210_wrapper_tb.vhd \
} -tag evr320_tb
# EVR320 IFC1210 Wrapper Testbench

View File

@@ -80,7 +80,7 @@ architecture testbench of evr320_decoder_tb is
signal usr_clk : std_logic := '0';
signal evr_params : typ_evr320_params;
signal mem_addr : std_logic_vector(11 downto 0) := (others => '0');
signal mem_data : std_logic_vector(31 downto 0) := (others => '0');
signal mem_data : std_logic_vector(C_MEM_DATA_WIDTH-1 downto 0) := (others => '0');
-- Decoder stream
type dec_stream_type is record
@@ -169,12 +169,14 @@ begin
--------------------------------------------------------------------------
o_usr_events => usr_events,
o_usr_events_ext => open,
o_sos_event => sos_event
o_sos_event => sos_event,
o_event => open,
o_event_valid => open
);
evr320_data_filter_inst: entity work.evr320_data_filter
generic map (
SWAP => false
SWAP => true, -- non-swapped uses LE layout; our check below converts to BE
NUM_BYTES => 8
)
port map (
@@ -399,7 +401,7 @@ begin
variable i : integer := 0;
type state is (idle, payload, frame_end, segment_nr);
variable mem_base : integer range 0 to 127;
variable segment_data_word : std_logic_vector(31 downto 0);
variable segment_data_word : std_logic_vector(C_MEM_DATA_WIDTH-1 downto 0);
variable var_filter_offset : integer range 0 to 2047;
variable var_filter_word : std_logic_vector(FILTER_NUM_BYTES*8-1 downto 0);
variable expected_evt_rec_events : integer range 0 to 255 := 0;
@@ -486,37 +488,51 @@ begin
log(ID_DATA, "Check expected Event Flags after SOS Event detected");
----------------------------------------------------------------------
wait until rising_edge(usr_clk);
for addr in 0 to 63 loop
mem_addr <= C_EVENT_REC_FLAGS & std_logic_vector(to_unsigned(addr, 6));
wait until rising_edge(usr_clk);
await_value(mem_data(0), all_expected_events(4*addr), 0 ns, 1 ns, ERROR, "Event " & to_string(4*addr) & " Flag");
await_value(mem_data(8), all_expected_events(4*addr + 1), 0 ns, 1 ns, ERROR, "Event " & to_string(4*addr + 1) & " Flag");
await_value(mem_data(16), all_expected_events(4*addr + 2), 0 ns, 1 ns, ERROR, "Event " & to_string(4*addr + 2) & " Flag");
await_value(mem_data(24), all_expected_events(4*addr + 3), 0 ns, 1 ns, ERROR, "Event " & to_string(4*addr + 3) & " Flag");
end loop;
----------------------------------------------------------------------
log(ID_DATA, "Check Memory block border");
----------------------------------------------------------------------
-- read data mux switching made visible with delayed address.
mem_addr <= C_EVENT_REC_FLAGS & "000000";
wait until rising_edge(usr_clk);
wait for C_USRCLK_CYCLE/4;
for addr in 62 to 65 loop
mem_addr <= (C_EVENT_REC_FLAGS & "000000") + std_logic_vector(to_unsigned(addr, 7));
wait until rising_edge(usr_clk);
check_stable(mem_data, C_USRCLK_CYCLE, ERROR, "Read Data stable on Output");
wait for C_USRCLK_CYCLE/4;
if (addr < 64) then
if (C_MEM_DATA_WIDTH = 32) then
for addr in 0 to 63 loop
mem_addr <= C_EVENT_REC_FLAGS & std_logic_vector(to_unsigned(addr, 6));
wait_num_rising_edge_plus_margin(usr_clk, 1, 1 ns);
check_value(mem_data(0), all_expected_events(4*addr), ERROR, "Event " & to_string(4*addr) & " Flag");
check_value(mem_data(8), all_expected_events(4*addr + 1), ERROR, "Event " & to_string(4*addr + 1) & " Flag");
check_value(mem_data(16), all_expected_events(4*addr + 2), ERROR, "Event " & to_string(4*addr + 2) & " Flag");
check_value(mem_data(24), all_expected_events(4*addr + 3), ERROR, "Event " & to_string(4*addr + 3) & " Flag");
else
check_value(mem_data, X"0000_0000", ERROR, "After Event Recorder Mem Map");
end if;
end loop;
wait until rising_edge(usr_clk);
end loop;
elsif (C_MEM_DATA_WIDTH = 64) then
for addr in 0 to 31 loop
mem_addr <= '0' & C_EVENT_REC_FLAGS & std_logic_vector(to_unsigned(addr, 5));
wait_num_rising_edge_plus_margin(usr_clk, 1, 1 ns);
for j in 0 to C_MEM_DATA_WIDTH/8 loop
check_value(mem_data(8*j), all_expected_events(8*addr + j), ERROR, "Event " & to_string(8*addr + j) & " Flag");
end loop;
end loop;
else
error("Unsupported width of C_MEM_DATA_WIDTH");
end if;
-- ----------------------------------------------------------------------
-- log(ID_DATA, "Check Memory block border");
-- ----------------------------------------------------------------------
if (C_MEM_DATA_WIDTH = 32) then
-- read data mux switching made visible with delayed address.
mem_addr <= C_EVENT_REC_FLAGS & "000000";
wait until rising_edge(usr_clk);
wait for C_USRCLK_CYCLE/4;
for addr in 62 to 65 loop
mem_addr <= (C_EVENT_REC_FLAGS & "000000") + std_logic_vector(to_unsigned(addr, 7));
wait until rising_edge(usr_clk);
check_stable(mem_data, C_USRCLK_CYCLE, ERROR, "Read Data stable on Output");
wait for C_USRCLK_CYCLE/4;
if (addr < 64) then
check_value(mem_data(0), all_expected_events(4*addr), ERROR, "Event " & to_string(4*addr) & " Flag");
check_value(mem_data(8), all_expected_events(4*addr + 1), ERROR, "Event " & to_string(4*addr + 1) & " Flag");
check_value(mem_data(16), all_expected_events(4*addr + 2), ERROR, "Event " & to_string(4*addr + 2) & " Flag");
check_value(mem_data(24), all_expected_events(4*addr + 3), ERROR, "Event " & to_string(4*addr + 3) & " Flag");
else
check_value(mem_data, X"0000_0000", ERROR, "After Event Recorder Mem Map");
end if;
end loop;
end if;
----------------------------------------------------------------------
log(ID_DATA, "Check expected Event Recorder User Events");
----------------------------------------------------------------------
@@ -528,22 +544,24 @@ begin
--------------------------------------------------------------------------
log(ID_LOG_HDR, "Read DPRAM buffer", C_SCOPE);
--------------------------------------------------------------------------
wait for 50 * C_USRCLK_CYCLE;
log(ID_DATA, "Read Segment from DPRAM");
-- print 16 words from dpram data buffer:
for offset in 0 to segment_length/4-1 loop
mem_base := to_integer(unsigned(segment_addr));
mem_addr <= std_logic_vector(to_unsigned(4*mem_base + offset , 12));
wait until rising_edge(usr_clk);
wait until rising_edge(usr_clk);
wait until rising_edge(usr_clk);
segment_data_word := segment_data(offset*4+3)
& segment_data(offset*4+2)
& segment_data(offset*4+1)
& segment_data(offset*4);
check_value(mem_data, segment_data_word, ERROR, "Compare DPRAM with Sent Segment");
--log(ID_PACKET_DATA, "Data buffer DPRAM: addr=0x" & to_string(mem_addr, HEX) & " data=0x" & to_string(mem_data, HEX));
end loop;
if (C_MEM_DATA_WIDTH = 32) then
wait for 50 * C_USRCLK_CYCLE;
log(ID_DATA, "Read Segment from DPRAM");
-- print 16 words from dpram data buffer:
for offset in 0 to segment_length/4-1 loop
mem_base := to_integer(unsigned(segment_addr));
mem_addr <= std_logic_vector(to_unsigned(4*mem_base + offset , 12));
wait until rising_edge(usr_clk);
wait until rising_edge(usr_clk);
wait until rising_edge(usr_clk);
segment_data_word := segment_data(offset*4+3)
& segment_data(offset*4+2)
& segment_data(offset*4+1)
& segment_data(offset*4);
check_value(mem_data, segment_data_word, ERROR, "Compare DPRAM with Sent Segment");
--log(ID_PACKET_DATA, "Data buffer DPRAM: addr=0x" & to_string(mem_addr, HEX) & " data=0x" & to_string(mem_data, HEX));
end loop;
end if;
--------------------------------------------------------------------------
-- Test Done

View File

@@ -167,7 +167,7 @@ FE 0 00 0 event 254
FF 0 00 0 event 255
BC 1 00 0 align
00 0 00 0 gap
0F 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap