15 Commits
2.2 ... develop

Author SHA1 Message Date
a482d8dc31 BUGFIX: for ISE 2019-10-02 16:49:53 +02:00
b0c2476978 CLEANUP: getting rid of std_logic_unsigned library when unnecessary + sigasi project added 2019-10-02 16:24:19 +02:00
7a1d49eb2f LIB: use only necessary libraries 2019-10-02 09:20:12 +02:00
36a4dcb761 BUGFIX: UVVM adaptations pkg removed & unused library from wrapper, MTI_SE 10.6... 2019-10-01 16:45:10 +02:00
4f9e87b16d readme: add dependencies 2018-12-06 10:46:24 +01:00
82c023c610 change: split streaming port to data and address 2018-12-06 10:00:53 +01:00
84f23d13ab event event reception check in simulation, fix stimuli 2018-12-05 17:14:04 +01:00
c52673a8ca simulate stream filter, integrated to if1210 wrapper, syntax fixes 2018-12-05 10:08:52 +01:00
d7e669cb75 extended ifc1210_wrapper with data streaming port and replaced frequency
measurement by common lib
2018-12-04 21:13:51 +01:00
84440ce6a0 added data filter from decoder stream 2018-12-04 17:02:10 +01:00
5e79f3f426 self checking segment sent/recv comparison 2018-12-04 17:01:38 +01:00
35077a9d84 self checking testbench: read MGT frame from file and compare data
stream
2018-12-03 17:15:39 +01:00
2634412bd0 added decoder streaming output and UVVM simulation 2018-11-30 16:25:00 +01:00
da6ab3236a added constrain template 2018-11-29 14:07:45 +01:00
6b512782f3 migrate decoder sim from cvs: prints transfered data buffer to terminal 2018-11-29 13:05:15 +01:00
20 changed files with 1117 additions and 200 deletions

View File

@@ -3,12 +3,14 @@ The EVR320 Embedded Event Receiver (EEVR) is able to connect with a MRF Timing S
Mainly the EEVR is used to decode configurable events and use them in firmware as triggers. Mainly the EEVR is used to decode configurable events and use them in firmware as triggers.
## Maintainer ## Maintainer
Patric Bucher [patric.bucher@psi.ch] Patric Bucher [patric.bucher@psi.ch]
Jonas Purtschert [jonas.purtschert@psi.ch]
## Authors ## Authors
Waldemar Koprek [waldemar.koprek@psi.ch] Waldemar Koprek [waldemar.koprek@psi.ch]
Goran Marinkovic [goran.marinkovic@psi.ch] Goran Marinkovic [goran.marinkovic@psi.ch]
Patric Bucher [patric.bucher@psi.ch] Patric Bucher [patric.bucher@psi.ch]
Jonas Purtschert [jonas.purtschert@psi.ch]
## Documentation ## Documentation
See [EVR320 Documentation](doc/evr320.pdf "doc/evr320.pdf") See [EVR320 Documentation](doc/evr320.pdf "doc/evr320.pdf")
@@ -29,10 +31,13 @@ Examples for things that do not belong into this library:
## Dependencies ## Dependencies
### Synthesis ### Synthesis
- none - Libraries/Firmware/VHDL/psi\_common (https://github.com/paulscherrerinstitute/psi_common)
### Simulation ### Simulation
- Libraries/Firmware/TCL/PsiSim - Libraries/Firmware/TCL/PsiSim
- Libraries/Firmware/VHDL/psi\_common (https://github.com/paulscherrerinstitute/psi_common)
- Libraries/Firmware/VHDL/UVVM (https://github.com/UVVM/UVVM)
### with IFC1210 Bindings ### with IFC1210 Bindings
- Libraries/BoardSupport/IFC1210/tosca2 - Libraries/BoardSupport/IFC1210/tosca2

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<com.sigasi.hdt.shared.librarymapping.model:LibraryMappings xmlns:com.sigasi.hdt.shared.librarymapping.model="com.sigasi.hdt.vhdl.scoping.librarymapping" Version="2">
<Mappings Location="Common Libraries/IEEE" Library="ieee"/>
<Mappings Location="Common Libraries" Library="not mapped"/>
<Mappings Location="Common Libraries/psi_common/generators" Library="not mapped"/>
<Mappings Location="Common Libraries/unisim/primitive" Library="not mapped"/>
<Mappings Location="Common Libraries/unisim/secureip" Library="not mapped"/>
<Mappings Location="Common Libraries/STD" Library="std"/>
<Mappings Location="Common Libraries/tosca2" Library="tosca2"/>
<Mappings Location="Common Libraries/unisim" Library="unisim"/>
<Mappings Location="Common Libraries/UVVM" Library="uvvm_util"/>
<Mappings Location="" Library="work"/>
<Mappings Location="Common Libraries/psi_common" Library="work"/>
</com.sigasi.hdt.shared.librarymapping.model:LibraryMappings>

75
Sigasi/.project Normal file
View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>evr320</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.sigasi.hdt.vhdl.ui.vhdlNature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
<linkedResources>
<link>
<name>Common Libraries</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>hdl</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/hdl</locationURI>
</link>
<link>
<name>tb</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/tb</locationURI>
</link>
<link>
<name>Common Libraries/DRAG_REUSABLE_LIBRARIES_HERE.txt</name>
<type>1</type>
<locationURI>sigasiresource:/vhdl/readme2.txt</locationURI>
</link>
<link>
<name>Common Libraries/IEEE</name>
<type>2</type>
<locationURI>sigasiresource:/vhdl/2008/IEEE</locationURI>
</link>
<link>
<name>Common Libraries/STD</name>
<type>2</type>
<locationURI>sigasiresource:/vhdl/2008/STD</locationURI>
</link>
<link>
<name>Common Libraries/UVVM</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/UVVM</locationURI>
</link>
<link>
<name>Common Libraries/psi_common</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/psi_common</locationURI>
</link>
<link>
<name>Common Libraries/tosca2</name>
<type>2</type>
<locationURI>PARENT-4-PROJECT_LOC/BoardSupport/IFC1210/tosca2</locationURI>
</link>
<link>
<name>Common Libraries/unisim</name>
<type>2</type>
<locationURI>SIGASI_TOOLCHAIN_XILINX_ISE/vhdl/src/unisims</locationURI>
</link>
<link>
<name>Common Libraries/IEEE/Synopsys</name>
<type>2</type>
<locationURI>sigasiresource:/vhdl/2008/IEEE%20Synopsys</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@@ -0,0 +1 @@
<project>=2008

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//Common\ Libraries/IEEE=utf-8
encoding//Common\ Libraries/IEEE/Synopsys=utf-8
encoding//Common\ Libraries/STD=utf-8
encoding/Common\ Libraries=utf-8

6
constraints/eevr.ucf Normal file
View File

@@ -0,0 +1,6 @@
# FIFO clock crossing for streaming interface:
# constrain to have less delay than one clock cycle of the faster clock:
set_max_delay -datapath_only -from <ClkA> -to <ClkB> <faster_clock_period>
set_max_delay -datapath_only -from <ClkB> -to <ClkA> <faster_clock_period>

View File

@@ -4,14 +4,15 @@
-- Unit : evr320_buffer.vhd -- Unit : evr320_buffer.vhd
-- Author : Waldemar Koprek, Section Diagnostic -- Author : Waldemar Koprek, Section Diagnostic
-- Goran Marinkovic, Section Diagnostic -- Goran Marinkovic, Section Diagnostic
-- Benoît Stef, Section DSP
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic -- Copyright© PSI, Section Diagnostic
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Comment : -- Comment : modif 02.10.2019 - numeric_std instead of std_logic_unsigned
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
use ieee.math_real.all; use ieee.math_real.all;
@@ -89,20 +90,28 @@ begin
if rising_edge(clka) then if rising_edge(clka) then
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
RAM(conv_integer(page_addr_clka & addra)) := dia; RAM(to_integer(unsigned(page_addr_clka & addra))) := dia;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+3 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+3 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+3 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+3 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "00")); concat7to0_v := page_addr_clkb( 3) & addrb & "00";
dob(15 downto 8) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "01")); concat15to8_v := page_addr_clkb( 3) & addrb & "01";
dob(23 downto 16) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "10")); concat23to16_v := page_addr_clkb( 3) & addrb & "10";
dob(31 downto 24) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "11")); concat31to24_v := page_addr_clkb( 3) & addrb & "11";
dob( 7 downto 0) <= RAM(to_integer(unsigned( concat7to0_v)));
dob(15 downto 8) <= RAM(to_integer(unsigned( concat15to8_v)));
dob(23 downto 16) <= RAM(to_integer(unsigned(concat23to16_v)));
dob(31 downto 24) <= RAM(to_integer(unsigned(concat31to24_v)));
end if; end if;
end if; end if;
end process; end process;
@@ -117,9 +126,9 @@ begin
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
if (addra(0) = '1') then if (addra(0) = '1') then
RAM_ODD (conv_integer(page_addr_clka & addra(addra'high downto 1))) := dia; RAM_ODD (to_integer(unsigned(page_addr_clka & addra(addra'high downto 1)))) := dia;
else else
RAM_EVEN(conv_integer(page_addr_clka & addra(addra'high downto 1))) := dia; RAM_EVEN(to_integer(unsigned((page_addr_clka & addra(addra'high downto 1))))) := dia;
end if; end if;
end if; end if;
end if; end if;
@@ -127,17 +136,33 @@ begin
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+3 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+3 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+3 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+3 downto 0);
variable concat39to32_v : std_logic_vector(addrb'high+3 downto 0);
variable concat47to40_v : std_logic_vector(addrb'high+3 downto 0);
variable concat55to48_v : std_logic_vector(addrb'high+3 downto 0);
variable concat63to56_v : std_logic_vector(addrb'high+3 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "00")); concat7to0_v := page_addr_clkb( 3) & addrb & "00";
dob(15 downto 8) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "00")); concat15to8_v := page_addr_clkb( 3) & addrb & "00";
dob(23 downto 16) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "01")); concat23to16_v := page_addr_clkb( 3) & addrb & "01";
dob(31 downto 24) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "01")); concat31to24_v := page_addr_clkb( 3) & addrb & "01";
dob(39 downto 32) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "10")); concat39to32_v := page_addr_clkb( 3) & addrb & "10";
dob(47 downto 40) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "10")); concat47to40_v := page_addr_clkb( 3) & addrb & "10";
dob(55 downto 48) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "11")); concat55to48_v := page_addr_clkb( 3) & addrb & "11";
dob(63 downto 56) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "11")); concat63to56_v := page_addr_clkb( 3) & addrb & "11";
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(concat7to0_v )));
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(concat15to8_v )));
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(concat23to16_v )));
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(concat31to24_v )));
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(concat39to32_v )));
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(concat47to40_v )));
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(concat55to48_v )));
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(concat63to56_v )));
end if; end if;
end if; end if;
end process; end process;

View File

@@ -0,0 +1,65 @@
------------------------------------------------------------------------------
-- Copyright (c) 2018 by Paul Scherrer Institute, Switzerland
-- All rights reserved.
-- Project: evr320
-- Authors: Jonas Purtschert
-- Description: Filter a specific data field from data buffer stream of the decoder:
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity evr320_data_filter is
generic (
ADDRESS : std_logic_vector(11 downto 0);
NUM_BYTES : integer := 8
);
port (
-- User stream interface
i_stream_clk : in std_logic; -- user clock
i_stream_data : in std_logic_vector(7 downto 0);
i_stream_addr : in std_logic_vector(10 downto 0);
i_stream_valid : in std_logic;
-- filter output:
o_data : out std_logic_vector(NUM_BYTES*8-1 downto 0) := (others=>'0');
o_valid : out std_logic := '0'
);
end evr320_data_filter;
architecture behavioral of evr320_data_filter is
signal data_shift : std_logic_vector(NUM_BYTES*8-1 downto 0) := (others=>'0');
signal match : std_logic := '0';
signal shift_cnt : integer range 0 to NUM_BYTES;
begin
process(i_stream_clk)
variable addr : std_logic_vector(10 downto 0) := (others=>'0');
variable data : std_logic_vector(7 downto 0) := (others=>'0');
begin
if (rising_edge(i_stream_clk)) then
o_valid <= '0';
if (i_stream_valid = '1') then
addr := i_stream_addr;
data := i_stream_data;
if (addr = ADDRESS(10 downto 0) or match = '1') then
match <= '1';
if (shift_cnt < NUM_BYTES) then
data_shift <= data_shift((data_shift'high - data'length) downto 0) & data;
shift_cnt <= shift_cnt + 1;
else -- all data fetched, send to out
match <= '0';
shift_cnt <= 0;
o_valid <= '1';
o_data <= data_shift;
end if;
end if; -- if addr match
end if; -- if valid
end if;
end process;
end behavioral;

View File

@@ -5,22 +5,21 @@
-- Author : Waldemar Koprek, Section Diagnostic -- Author : Waldemar Koprek, Section Diagnostic
-- Goran Marinkovic, Section Diagnostic -- Goran Marinkovic, Section Diagnostic
-- Patric Bucher, Section DSV -- Patric Bucher, Section DSV
-- Benoît Stef, Section DSP
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic -- Copyright© PSI, Section Diagnostic
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Comment : -- Comment : Rewrite code to be complient with numeric_std
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
library unisim; library unisim;
use unisim.vcomponents.all; use unisim.vcomponents.all;
use work.evr320_pkg.all; use work.evr320_pkg.all;
entity evr320_decoder is entity evr320_decoder is
generic generic
( (
@@ -51,6 +50,13 @@ entity evr320_decoder is
i_mem_addr : in std_logic_vector(11 downto 0); i_mem_addr : in std_logic_vector(11 downto 0);
o_mem_data : out std_logic_vector(MEM_DATA_WIDTH - 1 downto 0); o_mem_data : out std_logic_vector(MEM_DATA_WIDTH - 1 downto 0);
-------------------------------------------------------------------------- --------------------------------------------------------------------------
-- User stream interface User clock
--------------------------------------------------------------------------
i_stream_clk : in std_logic;
o_stream_data : out std_logic_vector(7 downto 0);
o_stream_addr : out std_logic_vector(10 downto 0);
o_stream_valid : out std_logic;
--------------------------------------------------------------------------
-- User interface MGT clock -- User interface MGT clock
-------------------------------------------------------------------------- --------------------------------------------------------------------------
o_usr_events : out std_logic_vector( 3 downto 0); o_usr_events : out std_logic_vector( 3 downto 0);
@@ -73,39 +79,14 @@ architecture behavioral of evr320_decoder is
-- Framing -- Framing
constant C_KCHAR_START : std_logic_vector( 7 downto 0) := X"5C"; constant C_KCHAR_START : std_logic_vector( 7 downto 0) := X"5C";
constant C_KCHAR_END : std_logic_vector( 7 downto 0) := X"3C"; constant C_KCHAR_END : std_logic_vector( 7 downto 0) := X"3C";
-- system events
constant C_EVENT_NULL : std_logic_vector( 7 downto 0) := X"00";
constant C_EVENT_SEC_0 : std_logic_vector( 7 downto 0) := X"70";
constant C_EVENT_SEC_1 : std_logic_vector( 7 downto 0) := X"71";
constant C_EVENT_STOP_LOG : std_logic_vector( 7 downto 0) := X"79";
constant C_EVENT_HEARTBEAT : std_logic_vector( 7 downto 0) := X"7A";
constant C_EVENT_SYNC_PRESCA : std_logic_vector( 7 downto 0) := X"7B";
constant C_EVENT_TIM_CNT_INC : std_logic_vector( 7 downto 0) := X"7C";
constant C_EVENT_TIM_CNT_RST : std_logic_vector( 7 downto 0) := X"7D";
constant C_EVENT_BEACON : std_logic_vector( 7 downto 0) := X"7E";
constant C_EVENT_END_OF_SEQ : std_logic_vector( 7 downto 0) := X"7F";
-- Events received -- Events received
type usr_events_type is array (0 to 3) of std_logic_vector( 3 downto 0); type usr_events_type is array (0 to 3) of std_logic_vector( 3 downto 0);
signal usr_events : usr_events_type := (others => (others => '0')); signal usr_events : usr_events_type := (others => (others => '0'));
signal cs_timeout_cnt : std_logic_vector(23 downto 0) := (others => '0'); signal cs_timeout_cnt : unsigned(23 downto 0) := (others => '0');
signal cs_min_cnt : std_logic_vector(31 downto 0) := (others => '0'); signal cs_min_cnt : unsigned(31 downto 0) := (others => '0');
signal cs_min_time : std_logic_vector(31 downto 0) := (others => '0'); signal cs_min_time : unsigned(31 downto 0) := (others => '0');
signal evr_stable : std_logic := '0'; signal evr_stable : std_logic := '0';
-- signal frame_fsm : frame_fsm_type;
-- Frame fsm
-- type frame_fsm_type is
-- (
-- frame_idle,
-- frame_addr_gap,
-- frame_addr,
-- frame_data_gap,
-- frame_data,
-- frame_chk1_gap,
-- frame_chk1,
-- frame_chk2_gap,
-- frame_chk2
-- );
-- signal frame_fsm : frame_fsm_type;
constant frame_idle : std_logic_vector( 3 downto 0) := "0000"; constant frame_idle : std_logic_vector( 3 downto 0) := "0000";
constant frame_addr_gap : std_logic_vector( 3 downto 0) := "0001"; constant frame_addr_gap : std_logic_vector( 3 downto 0) := "0001";
constant frame_addr : std_logic_vector( 3 downto 0) := "0010"; constant frame_addr : std_logic_vector( 3 downto 0) := "0010";
@@ -203,7 +184,7 @@ architecture behavioral of evr320_decoder is
signal mem_data_event_nr_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0'); signal mem_data_event_nr_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_dpram_sos : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0'); signal mem_data_dpram_sos : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_segment_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0'); signal mem_data_segment_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal stream_raw : std_logic_vector(18 downto 0);
-- attribute safe_implementation: string; -- attribute safe_implementation: string;
-- attribute safe_implementation of frame_fsm : signal is "yes"; -- attribute safe_implementation of frame_fsm : signal is "yes";
-- attribute safe_implementation of mem_fsm : signal is "yes"; -- attribute safe_implementation of mem_fsm : signal is "yes";
@@ -220,7 +201,7 @@ begin
debug_clk <= i_mgt_rx_clk; debug_clk <= i_mgt_rx_clk;
debug( 15 downto 0) <= i_mgt_rx_data; debug( 15 downto 0) <= i_mgt_rx_data;
debug( 17 downto 16) <= i_mgt_rx_charisk; debug( 17 downto 16) <= i_mgt_rx_charisk;
debug( 18) <= '0'; debug( 23 downto 18) <= (others=>'0');
debug( 31 downto 24) <= (others => '0'); debug( 31 downto 24) <= (others => '0');
debug( 35 downto 32) <= "0001" when (frame_fsm = frame_idle ) else debug( 35 downto 32) <= "0001" when (frame_fsm = frame_idle ) else
"0010" when (frame_fsm = frame_addr_gap) else "0010" when (frame_fsm = frame_addr_gap) else
@@ -286,7 +267,7 @@ begin
if (i_mgt_rst = '1') then if (i_mgt_rst = '1') then
evr_stable <= '0'; evr_stable <= '0';
else else
if ((cs_min_cnt > i_evr_params.cs_min_cnt) and (cs_min_time > i_evr_params.cs_min_time) and (cs_timeout_cnt < X"15CA20")) then if ((cs_min_cnt > unsigned(i_evr_params.cs_min_cnt)) and (cs_min_time > unsigned(i_evr_params.cs_min_time)) and (cs_timeout_cnt < X"15CA20")) then
evr_stable <= '1'; evr_stable <= '1';
else else
evr_stable <= '0'; evr_stable <= '0';
@@ -334,7 +315,7 @@ begin
cs_timeout_cnt <= X"000000"; cs_timeout_cnt <= X"000000";
else else
if (cs_timeout_cnt /= X"FFFFFF") then if (cs_timeout_cnt /= X"FFFFFF") then
cs_timeout_cnt <= cs_timeout_cnt + X"000001"; cs_timeout_cnt <= cs_timeout_cnt + 1;--X"000001";
end if; end if;
end if; end if;
end if; end if;
@@ -353,7 +334,7 @@ begin
if (frame_ctrl_wren = '1') then if (frame_ctrl_wren = '1') then
if (frame_chk_ok = '1') then if (frame_chk_ok = '1') then
if (cs_min_cnt /= X"FFFFFFFF") then if (cs_min_cnt /= X"FFFFFFFF") then
cs_min_cnt <= cs_min_cnt + X"00000001"; cs_min_cnt <= cs_min_cnt + 1;--X"00000001";
end if; end if;
else else
cs_min_cnt <= X"00000000"; cs_min_cnt <= X"00000000";
@@ -447,7 +428,7 @@ begin
when frame_idle => when frame_idle =>
frame_data_wr_addr_cnt <= (others => '0'); frame_data_wr_addr_cnt <= (others => '0');
when frame_addr => when frame_addr =>
frame_data_wr_id <= frame_data_wr_id + X"01"; frame_data_wr_id <= std_logic_vector(unsigned(frame_data_wr_id) + 1);
frame_data_wr_addr_cnt <= "0000" & i_mgt_rx_data(15 downto 8) & "0000"; frame_data_wr_addr_cnt <= "0000" & i_mgt_rx_data(15 downto 8) & "0000";
segment_addr_wren <= '1'; segment_addr_wren <= '1';
when frame_data => when frame_data =>
@@ -456,7 +437,7 @@ begin
frame_data_wren <= '0'; frame_data_wren <= '0';
else else
frame_data_wren <= not frame_data_full; frame_data_wren <= not frame_data_full;
frame_data_wr_addr_cnt <= frame_data_wr_addr_cnt + X"0001"; frame_data_wr_addr_cnt <= std_logic_vector(unsigned(frame_data_wr_addr_cnt) + 1);
frame_data_wr_addr <= frame_data_wr_addr_cnt(10 downto 0); frame_data_wr_addr <= frame_data_wr_addr_cnt(10 downto 0);
frame_data_wr_byte <= i_mgt_rx_data(15 downto 8); frame_data_wr_byte <= i_mgt_rx_data(15 downto 8);
end if; end if;
@@ -478,7 +459,7 @@ begin
frame_chk <= X"FFFF"; frame_chk <= X"FFFF";
when frame_addr | frame_data => when frame_addr | frame_data =>
if (i_mgt_rx_charisk = "00") then if (i_mgt_rx_charisk = "00") then
frame_chk <= frame_chk - (X"00" & i_mgt_rx_data(15 downto 8)); frame_chk <= std_logic_vector(unsigned(frame_chk) - unsigned(i_mgt_rx_data(15 downto 8)));
end if; end if;
when others => when others =>
null; null;
@@ -826,7 +807,54 @@ begin
dob => mem_data_event3 dob => mem_data_event3
); );
-------------------------------------------------------------------------
-- async fifo for streaming interface
-------------------------------------------------------------------------
strm_fifo_inst : entity work.psi_common_async_fifo
generic map (
Width_g => 11+8,
Depth_g => 2048,
AlmFullOn_g => false,
AlmFullLevel_g => 2,
AlmEmptyOn_g => false,
AlmEmptyLevel_g => 2,
RamStyle_g => "WBR",
RamBehavior_g => "block" -- auto, distributed
)
port map (
-- Control Ports
InClk => i_mgt_rx_clk,
InRst => i_mgt_rst,
OutClk => i_stream_clk,
OutRst => '0',
-- Input Data
InData => mem_data_wr_addr & mem_data_wr_byte,
InVld => mem_data_wren,
InRdy => open,
-- Output Data
OutData => stream_raw,
OutVld => o_stream_valid,
OutRdy => '1',
-- Input Status
InFull => open,
InEmpty => open,
InAlmFull => open,
InAlmEmpty => open,
InLevel => open,
-- Output Status
OutFull => open,
OutEmpty => open,
OutAlmFull => open,
OutAlmEmpty => open,
OutLevel => open
);
o_stream_data <= stream_raw(7 downto 0);
o_stream_addr <= stream_raw(18 downto 8);
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- EVENT RECORDER -- EVENT RECORDER
@@ -860,36 +888,25 @@ begin
-- timestamp for event and segement tagging -- timestamp for event and segement tagging
if (timestamp_cnt /= X"FFFF_FFFF") then if (timestamp_cnt /= X"FFFF_FFFF") then
timestamp_cnt <= timestamp_cnt + X"0000_0001"; timestamp_cnt <= std_logic_vector(unsigned(timestamp_cnt) + 1);
end if; end if;
-- only run event recorder when stable operation -- only run event recorder when stable operation
if ( (i_event_recorder_ctrl.event_enable = '1') and (i_mgt_rx_charisk( 0) = '0') and (evr_stable = '1')) then if ( (i_event_recorder_ctrl.event_enable = '1') and (i_mgt_rx_charisk( 0) = '0') and (evr_stable = '1')) then
-- filter standard events (user events = 0x01-0x6F, 0x72-0x78, 0x80-0xFF) -- filter standard events (user events = 0x01-0x6F, 0x72-0x78, 0x80-0xFF)
if ( or_reduce(i_mgt_rx_data(7 downto 0)) = '1' and (i_mgt_rx_data(7 downto 4) /= X"7")) then if unsigned(i_mgt_rx_data(7 downto 0)) /= 0 and i_mgt_rx_data(7 downto 4) /= X"7" then
-- if ( i_mgt_rx_data(7 downto 0) /= C_EVENT_NULL and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_SEC_0 and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_SEC_1 and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_STOP_LOG and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_HEARTBEAT and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_SYNC_PRESCA and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_TIM_CNT_INC and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_TIM_CNT_RST and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_BEACON and
-- i_mgt_rx_data(7 downto 0) /= C_EVENT_END_OF_SEQ ) then
usr_events_nr <= i_mgt_rx_data(7 downto 0); usr_events_nr <= i_mgt_rx_data(7 downto 0);
-- write event nr memory -- write event nr memory
if (usr_events_addr /= X"FF") then if (usr_events_addr /= X"FF") then
usr_events_save <= '1'; usr_events_save <= '1';
usr_events_addr <= usr_events_addr + X"01"; usr_events_addr <= std_logic_vector(unsigned(usr_events_addr) + 1);
end if; end if;
-- count all user events -- count all user events
if (usr_events_cnt /= X"FFFF_FFFF") then if (usr_events_cnt /= X"FFFF_FFFF") then
usr_events_cnt <= usr_events_cnt + X"0000_0001"; usr_events_cnt <= std_logic_vector(unsigned(usr_events_cnt) + 1);
end if; end if;
-- start-of-sequence, trigger event for event recorder -- start-of-sequence, trigger event for event recorder
@@ -906,7 +923,7 @@ begin
end if; end if;
-- set flag for appeared event -- set flag for appeared event
all_events_flags(conv_integer(i_mgt_rx_data(7 downto 0))) <= '1'; all_events_flags(to_integer(unsigned(i_mgt_rx_data(7 downto 0)))) <= '1';
end if; end if;
end if; end if;
@@ -1081,12 +1098,12 @@ begin
dob => mem_data_event_nr dob => mem_data_event_nr
); );
-------------------------------------------------------------------------- --------------------------------------------------------------------------
-- Event Flags of all Events -- Event Flags of all Events
-------------------------------------------------------------------------- --------------------------------------------------------------------------
prc_event_flags: process(i_usr_clk) prc_event_flags: process(i_usr_clk)
variable v_addr : integer range 0 to 255; variable v_addr : integer range 0 to 255;
variable v_addr_slv : std_logic_vector(7 downto 0);
begin begin
if (i_usr_clk'event and (i_usr_clk = '1')) then if (i_usr_clk'event and (i_usr_clk = '1')) then
-- sync to usr clk -- sync to usr clk
@@ -1094,9 +1111,11 @@ begin
all_events_flags_sync2 <= all_events_flags_sync1; all_events_flags_sync2 <= all_events_flags_sync1;
-- address fragment of vector / expand bit to bytes for data read -- address fragment of vector / expand bit to bytes for data read
v_addr := conv_integer(mem_addr(5 downto MEM_ADDR_LSB) & LOW_slv(1 + MEM_ADDR_LSB downto 0)); v_addr_slv := mem_addr(5 downto MEM_ADDR_LSB) & LOW_slv(1 + MEM_ADDR_LSB downto 0);
v_addr := to_integer(unsigned(v_addr_slv));
mem_data_event_flag <= bit2byte(all_events_flags_sync2(v_addr + MEM_DATA_BYTES - 1 downto v_addr)); mem_data_event_flag <= bit2byte(all_events_flags_sync2(v_addr + MEM_DATA_BYTES - 1 downto v_addr));
end if; end if;
end process; end process;
@@ -1127,4 +1146,4 @@ end behavioral;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- End of file -- End of file
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -4,14 +4,15 @@
-- Unit : evr320_dpram.vhd -- Unit : evr320_dpram.vhd
-- Author : Waldemar Koprek, Section Diagnostic -- Author : Waldemar Koprek, Section Diagnostic
-- Goran Marinkovic, Section Diagnostic -- Goran Marinkovic, Section Diagnostic
-- Benoit Stef, Section DSP
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic -- Copyright© PSI, Section Diagnostic
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Comment : -- Comment : modif 02.10.2019 - numeric_std instead std_logic_unsigned
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
use ieee.math_real.all; use ieee.math_real.all;
entity evr320_dpram is entity evr320_dpram is
@@ -59,20 +60,29 @@ begin
if rising_edge(clka) then if rising_edge(clka) then
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
RAM(conv_integer(addra)) := dia; RAM(to_integer(unsigned(addra))) := dia;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+2 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+2 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+2 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+2 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM(conv_integer(addrb & "00")); concat7to0_v := addrb & "00";
dob(15 downto 8) <= RAM(conv_integer(addrb & "01")); concat15to8_v := addrb & "01";
dob(23 downto 16) <= RAM(conv_integer(addrb & "10")); concat23to16_v := addrb & "10";
dob(31 downto 24) <= RAM(conv_integer(addrb & "11")); concat31to24_v := addrb & "11";
--
dob( 7 downto 0) <= RAM(to_integer(unsigned( concat7to0_v)));
dob(15 downto 8) <= RAM(to_integer(unsigned( concat15to8_v)));
dob(23 downto 16) <= RAM(to_integer(unsigned(concat23to16_v)));
dob(31 downto 24) <= RAM(to_integer(unsigned(concat31to24_v)));
end if; end if;
end if; end if;
end process; end process;
@@ -87,9 +97,9 @@ begin
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
if (addra(0) = '1') then if (addra(0) = '1') then
RAM_ODD (conv_integer(addra(addra'high downto 1))) := dia; RAM_ODD (to_integer(unsigned(addra(addra'high downto 1)))) := dia;
else else
RAM_EVEN(conv_integer(addra(addra'high downto 1))) := dia; RAM_EVEN(to_integer(unsigned(addra(addra'high downto 1)))) := dia;
end if; end if;
end if; end if;
end if; end if;
@@ -97,17 +107,34 @@ begin
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+2 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+2 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+2 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+2 downto 0);
variable concat39to32_v : std_logic_vector(addrb'high+2 downto 0);
variable concat47to40_v : std_logic_vector(addrb'high+2 downto 0);
variable concat55to48_v : std_logic_vector(addrb'high+2 downto 0);
variable concat63to56_v : std_logic_vector(addrb'high+2 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM_EVEN(conv_integer(addrb & "00")); concat7to0_v :=addrb & "00";
dob(15 downto 8) <= RAM_ODD (conv_integer(addrb & "00")); concat15to8_v :=addrb & "00";
dob(23 downto 16) <= RAM_EVEN(conv_integer(addrb & "01")); concat23to16_v :=addrb & "01";
dob(31 downto 24) <= RAM_ODD (conv_integer(addrb & "01")); concat31to24_v :=addrb & "01";
dob(39 downto 32) <= RAM_EVEN(conv_integer(addrb & "10")); concat39to32_v :=addrb & "10";
dob(47 downto 40) <= RAM_ODD (conv_integer(addrb & "10")); concat47to40_v :=addrb & "10";
dob(55 downto 48) <= RAM_EVEN(conv_integer(addrb & "11")); concat55to48_v :=addrb & "11";
dob(63 downto 56) <= RAM_ODD (conv_integer(addrb & "11")); concat63to56_v :=addrb & "11";
--
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(concat7to0_v )));
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(concat15to8_v )));
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(concat23to16_v)));
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(concat31to24_v)));
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(concat39to32_v)));
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(concat47to40_v)));
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(concat55to48_v)));
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(concat63to56_v)));
end if; end if;
end if; end if;
end process; end process;

View File

@@ -10,8 +10,7 @@
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
use ieee.math_real.all;
library tosca2; library tosca2;
use tosca2.tosca2_glb_pkg.all; use tosca2.tosca2_glb_pkg.all;
@@ -22,57 +21,66 @@ use work.v6vlx_gtxe1_pkg.all;
entity evr320_ifc1210_wrapper is entity evr320_ifc1210_wrapper is
generic( generic(
g_MGT_LOCATION : string := "GTXE1_X0Y16"; -- "GTXE1_X0Y0" to "GTXE1_X0Y11" | "GTXE1_X0Y16" to "GTXE1_X0Y19" g_MGT_LOCATION : string := "GTXE1_X0Y16"; -- "GTXE1_X0Y0" to "GTXE1_X0Y11" | "GTXE1_X0Y16" to "GTXE1_X0Y19"
g_FACILITY : string := "SFEL"; -- "HIPA" | "SFEL" g_FACILITY : string := "SFEL"; -- "HIPA" | "SFEL"
g_EVENT_RECORDER : boolean := false -- enable/disable Event Recorder functionality g_EVENT_RECORDER : boolean := false; -- enable/disable Event Recorder functionality
g_XUSER_CLK_FREQ : natural := 125000000 -- Xuser Clk Frequency in Hz
); );
port( port(
tick1sec_i : in std_logic;
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
-- Debug interface -- Debug interface
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
debug_clk : out std_logic; debug_clk : out std_logic;
debug : out std_logic_vector(127 downto 0); debug : out std_logic_vector(127 downto 0);
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
-- TOSCA2 TMEM Interface (xuser clock domain, 100-250MHz) -- TOSCA2 TMEM Interface (xuser clock domain, 100-250MHz)
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
xuser_CLK : in std_logic; xuser_CLK : in std_logic;
xuser_RESET : in std_logic; xuser_RESET : in std_logic;
xuser_TMEM_ENA : in std_logic; xuser_TMEM_ENA : in std_logic;
xuser_TMEM_WE : in std_logic_vector( 7 downto 0); xuser_TMEM_WE : in std_logic_vector( 7 downto 0);
xuser_TMEM_ADD : in std_logic_vector(13 downto 3); xuser_TMEM_ADD : in std_logic_vector(13 downto 3);
xuser_TMEM_DATW : in std_logic_vector(63 downto 0); xuser_TMEM_DATW : in std_logic_vector(63 downto 0);
xuser_TMEM_DATR : out std_logic_vector(63 downto 0); xuser_TMEM_DATR : out std_logic_vector(63 downto 0);
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
-- MGT Interface -- MGT Interface
-- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------
mgt_refclk_i : in std_logic; -- MGT Reference Clock mgt_refclk_i : in std_logic; -- MGT Reference Clock
mgt_sfp_los_i : in std_logic; -- SFP Loss of Signal (light on receiver) 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_n : in std_logic; -- MGT RX N
mgt_rx_p : in std_logic; -- MGT RX P mgt_rx_p : in std_logic; -- MGT RX P
mgt_tx_n : out std_logic; -- MGT TX N mgt_tx_n : out std_logic; -- MGT TX N
mgt_tx_p : out std_logic; -- MGT TX P mgt_tx_p : out std_logic; -- MGT TX P
mgt_status_o : out std_logic_vector(31 downto 0); -- MGT Status 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_control_i : in std_logic_vector(31 downto 0); -- MGT Control
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- User interface MGT clock -- User interface MGT clock
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
clk_evr_o : out std_logic; -- Recovered parallel clock from MGT clk_evr_o : out std_logic; -- Recovered parallel clock from MGT
usr_events_o : out std_logic_vector( 3 downto 0); -- User defined event pulses with one clock cycle length usr_events_o : out std_logic_vector( 3 downto 0); -- User defined event pulses with one clock cycle length
usr_events_ext_o : out std_logic_vector( 3 downto 0); -- User defined event pulses with four clock cycle length usr_events_ext_o : out std_logic_vector( 3 downto 0); -- User defined event pulses with four clock cycle length
sos_event_o : out std_logic -- Start-of-Sequence Event sos_event_o : out std_logic; -- Start-of-Sequence Event
--------------------------------------------------------------------------
-- 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; end evr320_ifc1210_wrapper;
architecture rtl of evr320_ifc1210_wrapper is architecture rtl of evr320_ifc1210_wrapper is
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
-- Parameters -- Parameters
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
constant c_TOSCA2_DATA_WIDTH : integer := 64; constant c_TOSCA2_DATA_WIDTH : integer := 64;
constant c_EVR_REG64_COUNT : integer := 16; -- unused, only documentation -- constant c_EVR_REG64_COUNT : integer := 16; -- unused, only documentation
constant c_EVR_MEM_SIZE : integer := 16384; -- unused, only documentation -- constant c_EVR_MEM_SIZE : integer := 16384; -- unused, only documentation
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
@@ -103,8 +111,6 @@ architecture rtl of evr320_ifc1210_wrapper is
signal event_recorder_control_sync : typ_evt_rec_ctrl; signal event_recorder_control_sync : typ_evt_rec_ctrl;
signal event_recorder_control_xuser : typ_evt_rec_ctrl; signal event_recorder_control_xuser : typ_evt_rec_ctrl;
signal evr_counter_rst : std_logic_vector( 2 downto 0) := (others => '0');
signal evr_clk_counter : std_logic_vector(31 downto 0) := (others => '0');
signal evr_frequency : std_logic_vector(31 downto 0) := (others => '0'); signal evr_frequency : std_logic_vector(31 downto 0) := (others => '0');
signal debug_data : std_logic_vector(127 downto 0); signal debug_data : std_logic_vector(127 downto 0);
@@ -179,6 +185,11 @@ begin
i_event_recorder_ctrl => event_recorder_control, i_event_recorder_ctrl => event_recorder_control,
i_mem_addr => mem_addr_evr, i_mem_addr => mem_addr_evr,
o_mem_data => mem_data, 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 -- User interface MGT clock
o_usr_events => usr_events_o, o_usr_events => usr_events_o,
o_usr_events_ext => usr_events_ext_o, o_usr_events_ext => usr_events_ext_o,
@@ -235,24 +246,20 @@ begin
mem_data_i => mem_data mem_data_i => mem_data
); );
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
-- Measure EVR Clock (based on xuser_CLK) -- Measure EVR Clock (based on xuser_CLK)
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
prc_count_cycles: process(clk_evr) clock_meas_inst : entity work.psi_common_clk_meas
begin generic map (
if rising_edge(clk_evr) then MasterFrequency_g => g_XUSER_CLK_FREQ,
if (evr_counter_rst(2 downto 1) = "01") then MaxMeasFrequency_g => 150000000
evr_frequency <= evr_clk_counter; )
evr_clk_counter <= (others => '0'); port map (
else ClkMaster => xuser_CLK,
evr_clk_counter <= evr_clk_counter + X"0000_0001"; Rst => xuser_RESET,
end if; ClkTest => clk_evr,
-- sync reset and detect edge FrequencyHz => evr_frequency
evr_counter_rst <= evr_counter_rst(1 downto 0) & tick1sec_i; );
end if;
end process;
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
-- port mapping -- port mapping
@@ -260,10 +267,8 @@ begin
clk_evr_o <= clk_evr; clk_evr_o <= clk_evr;
mgt_status_o <= mgt_status; mgt_status_o <= mgt_status;
debug <= debug_data; debug <= debug_data;
end rtl; end rtl;
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
-- //////////////////////////////////////////////////////////////////////////// -- ////////////////////////////////////////////////////////////////////////////
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------

View File

@@ -60,7 +60,10 @@ package evr320_pkg is
data_error => '0', data_error => '0',
usr_events_counter => (others =>'0')); usr_events_counter => (others =>'0'));
constant c_INIT_EVT_REC_CTRL : typ_evt_rec_ctrl := ( event_number => (others=>'0'),
event_enable => '0',
data_ack => '0',
error_ack => '0');
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
-- Function Prototypes -- Function Prototypes
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
@@ -95,4 +98,4 @@ package body evr320_pkg is
end package body evr320_pkg; end package body evr320_pkg;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- End of file -- End of file
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -4,17 +4,17 @@
-- Unit : evr320_timestamp.vhd -- Unit : evr320_timestamp.vhd
-- Author : Patric Bucher, Section DSV -- Author : Patric Bucher, Section DSV
-- Goran Marinkovic, Section Diagnostic -- Goran Marinkovic, Section Diagnostic
-- Benoît Stef, Section DSP
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic -- Copyright© PSI, Section Diagnostic
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Comment : -- Comment : modif 02.10.2019 - numeric_std instead of std_logic_unsigned
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
use ieee.math_real.all; use ieee.math_real.all;
entity evr320_timestamp is entity evr320_timestamp is
generic generic
( (
@@ -90,28 +90,46 @@ begin
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
dob_32bit: if MEM_DOB_WIDTH = 32 generate dob_32bit: if MEM_DOB_WIDTH = 32 generate
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
process (clka) process (clka)
variable concat7to0_v : std_logic_vector(addra'high+3 downto 0);
variable concat15to8_v : std_logic_vector(addra'high+3 downto 0);
variable concat23to16_v : std_logic_vector(addra'high+3 downto 0);
variable concat31to24_v : std_logic_vector(addra'high+3 downto 0);
begin begin
if rising_edge(clka) then if rising_edge(clka) then
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
RAM(conv_integer(page_addr_clka & addra & "00")) := dia( 7 downto 0); concat7to0_v := page_addr_clka & addra & "00";
RAM(conv_integer(page_addr_clka & addra & "01")) := dia(15 downto 8); concat15to8_v := page_addr_clka & addra & "01";
RAM(conv_integer(page_addr_clka & addra & "10")) := dia(23 downto 16); concat23to16_v := page_addr_clka & addra & "10";
RAM(conv_integer(page_addr_clka & addra & "11")) := dia(31 downto 24); concat31to24_v := page_addr_clka & addra & "11";
--
RAM(to_integer(unsigned( concat7to0_v))) := dia( 7 downto 0);
RAM(to_integer(unsigned( concat15to8_v))) := dia(15 downto 8);
RAM(to_integer(unsigned(concat23to16_v))) := dia(23 downto 16);
RAM(to_integer(unsigned(concat31to24_v))) := dia(31 downto 24);
end if; end if;
end if; end if;
end if; end if;
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+3 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+3 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+3 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+3 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "00")); concat7to0_v := page_addr_clkb( 3) & addrb & "00";
dob(15 downto 8) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "01")); concat15to8_v := page_addr_clkb( 3) & addrb & "01";
dob(23 downto 16) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "10")); concat23to16_v := page_addr_clkb( 3) & addrb & "10";
dob(31 downto 24) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "11")); concat31to24_v := page_addr_clkb( 3) & addrb & "11";
--
dob( 7 downto 0) <= RAM(to_integer(unsigned(concat7to0_v)));
dob(15 downto 8) <= RAM(to_integer(unsigned(concat15to8_v )));
dob(23 downto 16) <= RAM(to_integer(unsigned(concat23to16_v)));
dob(31 downto 24) <= RAM(to_integer(unsigned(concat31to24_v)));
end if; end if;
end if; end if;
end process; end process;
@@ -120,32 +138,58 @@ begin
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
dob_64bit: if MEM_DOB_WIDTH = 64 generate dob_64bit: if MEM_DOB_WIDTH = 64 generate
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
process (clka) process (clka)
variable concat7to0_v : std_logic_vector(addra'high+2 downto 0);
variable concat15to8_v : std_logic_vector(addra'high+2 downto 0);
variable concat23to16_v : std_logic_vector(addra'high+2 downto 0);
variable concat31to24_v : std_logic_vector(addra'high+2 downto 0);
begin begin
if rising_edge(clka) then if rising_edge(clka) then
if (ena = '1') then if (ena = '1') then
if (wea = '1') then if (wea = '1') then
RAM_EVEN(conv_integer(page_addr_clka & addra & '0')) := dia( 7 downto 0); concat7to0_v := page_addr_clka & addra & '0';
RAM_ODD (conv_integer(page_addr_clka & addra & '0')) := dia(15 downto 8); concat15to8_v := page_addr_clka & addra & '0';
RAM_EVEN(conv_integer(page_addr_clka & addra & '1')) := dia(23 downto 16); concat23to16_v := page_addr_clka & addra & '1';
RAM_ODD (conv_integer(page_addr_clka & addra & '1')) := dia(31 downto 24); concat31to24_v := page_addr_clka & addra & '1';
--
RAM_EVEN(to_integer(unsigned(concat7to0_v ))) := dia( 7 downto 0);
RAM_ODD (to_integer(unsigned(concat15to8_v ))) := dia(15 downto 8);
RAM_EVEN(to_integer(unsigned(concat23to16_v ))) := dia(23 downto 16);
RAM_ODD (to_integer(unsigned(concat31to24_v ))) := dia(31 downto 24);
end if; end if;
end if; end if;
end if; end if;
end process; end process;
process (clkb) process (clkb)
variable concat7to0_v : std_logic_vector(addrb'high+3 downto 0);
variable concat15to8_v : std_logic_vector(addrb'high+3 downto 0);
variable concat23to16_v : std_logic_vector(addrb'high+3 downto 0);
variable concat31to24_v : std_logic_vector(addrb'high+3 downto 0);
variable concat39to32_v : std_logic_vector(addrb'high+3 downto 0);
variable concat47to40_v : std_logic_vector(addrb'high+3 downto 0);
variable concat55to48_v : std_logic_vector(addrb'high+3 downto 0);
variable concat63to56_v : std_logic_vector(addrb'high+3 downto 0);
begin begin
if rising_edge(clkb) then if rising_edge(clkb) then
if (enb = '1') then if (enb = '1') then
dob( 7 downto 0) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "00")); concat7to0_v := page_addr_clkb( 3) & addrb & "00";
dob(15 downto 8) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "00")); concat15to8_v := page_addr_clkb( 3) & addrb & "00";
dob(23 downto 16) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "01")); concat23to16_v := page_addr_clkb( 3) & addrb & "01";
dob(31 downto 24) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "01")); concat31to24_v := page_addr_clkb( 3) & addrb & "01";
dob(39 downto 32) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "10")); concat39to32_v := page_addr_clkb( 3) & addrb & "10";
dob(47 downto 40) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "10")); concat47to40_v := page_addr_clkb( 3) & addrb & "10";
dob(55 downto 48) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "11")); concat55to48_v := page_addr_clkb( 3) & addrb & "11";
dob(63 downto 56) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "11")); concat63to56_v := page_addr_clkb( 3) & addrb & "11";
--
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned( concat7to0_v)));
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned( concat15to8_v)));
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned( concat23to16_v)));
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned( concat31to24_v)));
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned( concat39to32_v)));
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned( concat47to40_v)));
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned( concat55to48_v)));
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned( concat63to56_v)));
end if; end if;
end if; end if;
end process; end process;

View File

@@ -3,14 +3,15 @@
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
-- Unit : evr320_tmem.vhd -- Unit : evr320_tmem.vhd
-- Author : Patric Bucher -- Author : Patric Bucher
-- Benoît Stef
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
-- Copyright© PSI, Section DSV -- Copyright© PSI, Section DSV
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
-- Comment : TMEM address decoding for register and memory access to evr320. -- Comment : TMEM address decoding for register and memory access to evr320.
-- modif 02.10.2019 - numeric_std only
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use ieee.math_real.all; use ieee.math_real.all;
@@ -146,7 +147,7 @@ begin
begin begin
if (rising_edge(xuser_CLK)) then if (rising_edge(xuser_CLK)) then
if (xuser_TMEM_ENA_reg = '1') then if (xuser_TMEM_ENA_reg = '1') then
if (xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH) = 0) then if (unsigned(xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH)) = 0) then
case xuser_TMEM_ADD_reg(REG_ADDR_MSB downto TMEM_ADDR_LSB) is 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"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"1" => xuser_TMEM_DATR <= reserved(63 downto 32) & X"0000_00" & bit2byte(mgt_reset); -- 64bit / ByteAddr 008 --> 0x00C = not implemented in ifc1210
@@ -180,7 +181,7 @@ begin
er_error_ack <= er_error_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) = 0) then if (xuser_TMEM_ENA_reg = '1' and unsigned(xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH)) = 0) then
----------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------
if xuser_TMEM_ADD_reg(6 downto 3) = X"0" then --ByteAddr 000 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(0) = '1' then -read only- <= xuser_TMEM_DATW_reg( 7 downto 0); end if;
@@ -246,7 +247,7 @@ begin
-- Port mapping -- Port mapping
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
mem_clk_o <= xuser_CLK; mem_clk_o <= xuser_CLK;
mem_addr_o <= xuser_TMEM_ADD - MEM_ADDR_START; mem_addr_o <= std_logic_vector(unsigned(xuser_TMEM_ADD) - unsigned(MEM_ADDR_START));
evr_params_o <= (event_numbers, event_enable, cs_min_cnt, cs_min_time); 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)); evr_evt_rec_control_o <= (er_event_number, er_event_enable, er_data_ack(3), er_error_ack(3));
mgt_reset_o <= mgt_reset; mgt_reset_o <= mgt_reset;

View File

@@ -284,7 +284,7 @@ begin
) )
port map ( port map (
------------------------ Loopback and Powerdown Ports ---------------------- ------------------------ Loopback and Powerdown Ports ----------------------
LOOPBACK => i_mgt.ctrl.LOOPBACK, --tied_to_ground_vec_i(2 downto 0), LOOPBACK => i_mgt.CTRL.LOOPBACK, --tied_to_ground_vec_i(2 downto 0),
RXPOWERDOWN => "00", -- RXPOWERDOWN => "00", --
TXPOWERDOWN => "00", -- TXPOWERDOWN => "00", --
-------------- Receive Ports - 64b66b and 64b67b Gearbox Ports ------------- -------------- Receive Ports - 64b66b and 64b67b Gearbox Ports -------------

View File

@@ -1,2 +1,2 @@
source run.tcl source run.tcl
quit #quit

View File

@@ -10,16 +10,26 @@ run_suppress 8684,3479,3813,8009,3812
# EVR320 Decoder # EVR320 Decoder
add_sources $LibPath/Libraries/VHDL/evr320/hdl { add_sources $LibPath/Firmware/VHDL/evr320/hdl {
evr320_pkg.vhd \ evr320_pkg.vhd \
evr320_buffer.vhd \ evr320_buffer.vhd \
evr320_dpram.vhd \ evr320_dpram.vhd \
evr320_timestamp.vhd \ evr320_timestamp.vhd \
evr320_decoder.vhd \ evr320_decoder.vhd \
evr320_data_filter.vhd \
} -tag evr320_decoder } -tag evr320_decoder
# EVR320 Decoder Testbench
add_sources $LibPath/Firmware/VHDL/evr320/tb {
evr320_decoder_tb.vhd \
} -tag evr320_decoder_tb
# setup tb runs
create_tb_run "evr320_decoder_tb"
add_tb_run
# IFC1210 Bindings # IFC1210 Bindings
add_sources $LibPath/Libraries/VHDL/evr320/hdl { add_sources $LibPath/Firmware/VHDL/evr320/hdl {
v6vlx_gtxe1_pkg.vhd \ v6vlx_gtxe1_pkg.vhd \
v6vlx_gtxe1_101MHz27_1Gbps0127.vhd \ v6vlx_gtxe1_101MHz27_1Gbps0127.vhd \
v6vlx_gtxe1_142MHz8_2Gbps856.vhd \ v6vlx_gtxe1_142MHz8_2Gbps856.vhd \
@@ -29,8 +39,21 @@ add_sources $LibPath/Libraries/VHDL/evr320/hdl {
evr320_ifc1210_wrapper.vhd \ evr320_ifc1210_wrapper.vhd \
} -tag evr320_ifc1210 } -tag evr320_ifc1210
# psi_common dependency:
add_sources $LibPath/Firmware/VHDL/psi_common/hdl {
psi_common_array_pkg.vhd \
psi_common_math_pkg.vhd \
psi_common_logic_pkg.vhd \
psi_common_sdp_ram.vhd \
psi_common_pulse_cc.vhd \
psi_common_async_fifo.vhd \
psi_common_clk_meas.vhd \
} -tag psi_common
# tosca2_glb_pkg dependency # tosca2_glb_pkg dependency
add_library tosca2 add_library tosca2
add_sources $LibPath/Libraries/BoardSupport/IFC1210/tosca2/hdl/top_ip/src {
add_sources $LibPath/BoardSupport/IFC1210/tosca2/hdl/top_ip/src {
tosca2_glb_pkg.vhd \ tosca2_glb_pkg.vhd \
} }

View File

@@ -1,8 +1,46 @@
# Library Path # Library Path
set LibPath "../../../../" set LibPath "../../../.."
#Load dependencies # Compile UVVM library (if necessary):
source $LibPath/Libraries/TCL/PsiSim/PsiSim.tcl # -------------------------------------------------------
set uvvm_lib $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
# compile lib if folder not exist:
#if {![file isdirectory $uvvm_lib]} {
# copy adapted pkg:
# comment the line after because adaptation pkg is in uvvm_util lib already... stef.b
#file copy -force ../tb/adaptations_pkg.vhd $LibPath/Firmware/VHDL/UVVM/uvvm_util/src/
set last_dir [pwd]
cd $LibPath/Firmware/VHDL/UVVM/uvvm_util/script/
do compile_src.do
cd $last_dir
#}
vmap uvvm_util $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
# -------------------------------------------------------
# Check if running in jenkins environment
if [info exists env(JENKINS_HOME)] {
set jenkins 1
} else {
set jenkins 0
}
# map different libraries when running on jenkins machine:
if {$jenkins == 1} {
vmap unisim /home/modelsim/xilinx_libs/13.4/unisim
vmap xilinxcorelib /home/modelsim/xilinx_libs/13.4/xilinxcorelib
vmap secureip /home/modelsim/xilinx_libs/13.4/secureip
} else {
#vmap unisim C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
vmap unisim C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.6/nt/unisim
#vmap xilinxcorelib C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/xilinxcorelib
vmap xilinxcorelib C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.6/nt/xilinxcorelib
#vmap secureip C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
vmap secureip C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.6/nt/unisim
}
#Load dependencies TODO
source $LibPath/Firmware/TCL/PsiSim/PsiSim.tcl
#Import psi::sim library #Import psi::sim library
namespace import psi::sim::* namespace import psi::sim::*
@@ -18,8 +56,12 @@ puts "------------------------------"
puts "-- Compile" puts "-- Compile"
puts "------------------------------" puts "------------------------------"
clean_libraries -all clean_libraries -all
compile_files -tag psi_common
compile_files -tag evr320_decoder compile_files -tag evr320_decoder
#compile_files -lib tosca2 compile_files -tag evr320_decoder_tb
compile_files -lib tosca2
compile_files -tag evr320_ifc1210
#compile_files -lib evr320 #compile_files -lib evr320
run_check_errors "###ERROR###" run_tb -all
run_check_errors "###ERROR###"

426
tb/evr320_decoder_tb.vhd Normal file
View File

@@ -0,0 +1,426 @@
--------------------------------------------------------------------------------
-- Paul Scherrer Institute (PSI)
--------------------------------------------------------------------------------
-- Unit : evr320_decoder_tb.vhd
-- Author : Goran Marinkovic, Section Diagnostic, Jonas Purtschert
-- Version : $Revision: 1.1 $
--------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic
--------------------------------------------------------------------------------
-- Comment : This is the test bench for the evr component.
--------------------------------------------------------------------------------
-- Std. library (platform) -----------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_1164.all;
library std;
use std.env.all;
use std.textio.all;
library uvvm_util;
context uvvm_util.uvvm_util_context;
-- Work library (application) --------------------------------------------------
library work;
use work.evr320_pkg.all;
entity evr320_decoder_tb is
end entity;
architecture testbench of evr320_decoder_tb is
---------------------------------------------------------------------------
-- System
---------------------------------------------------------------------------
-- System
constant C_RXUSRCLK_CYCLE : time:= 7 ns;
constant C_USRCLK_CYCLE : time:= 8 ns;
---------------------------------------------------------------------------
-- MGT stream
---------------------------------------------------------------------------
type mgt_stream_sample_type is record
data : std_logic_vector(7 downto 0);
data_k : std_logic_vector(0 downto 0);
event : std_logic_vector(7 downto 0);
event_k : std_logic_vector(0 downto 0);
end record mgt_stream_sample_type;
type mgt_stream_type is array (natural range <>) of mgt_stream_sample_type;
signal mgt_stream_index : integer range 0 to 511 := 0;
signal mgt_stream : mgt_stream_type(511 downto 0) := (others=>(others=>(others=>'0')));
-----------------------------------------------------------------------------
-- Timing decoder interface
-----------------------------------------------------------------------------
-- Link status
signal rxlos : std_logic := '0';
-- Clock
signal rxusrclk : std_logic := '0';
-- Data
signal rxdata : std_logic_vector(15 downto 0) := (others => '0');
-- Status 8B/10B decoder
signal rxcharisk : std_logic_vector( 1 downto 0) := (others => '0');
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');
-- Decoder stream:
type dec_stream_type is record
data : std_logic_vector(7 downto 0);
addr : std_logic_vector(10 downto 0);
end record dec_stream_type;
type dec_stream_check_arr is array (natural range <>) of dec_stream_type;
signal dec_stream_data : std_logic_vector(7 downto 0) := (others => '0');
signal dec_stream_addr : std_logic_vector(10 downto 0) := (others => '0');
signal dec_stream_valid : std_logic;
signal dec_stream_check : dec_stream_check_arr(0 to 2047);
signal dec_stream_recv_bytes : integer range 0 to 2047;
type segment_data_arr is array (natural range <>) of std_logic_vector(7 downto 0);
signal segment_addr : std_logic_vector(7 downto 0);
signal segment_data : segment_data_arr(0 to 2047);
signal segment_length : natural range 0 to 2047;
signal usr_events : std_logic_vector( 3 downto 0) := (others => '0');
constant FILTER_ADDRESS : std_logic_vector(11 downto 0) := x"028";
constant FILTER_NUM_BYTES : integer := 8;
constant STIMULI_RUNS : integer := 2;
signal received_events : integer := 0;
signal expect_num_events : integer := 0;
signal filter_data, filter_data_check : std_logic_vector(63 downto 0) := (others => '0');
signal filter_valid : std_logic := '0';
begin
-----------------------------------------------------------------------------
-- Timing decoder
-----------------------------------------------------------------------------
evr320_decoder_inst: entity work.evr320_decoder
port map
(
--------------------------------------------------------------------------
-- Debug interface
--------------------------------------------------------------------------
debug_clk => open,
debug => open,
--------------------------------------------------------------------------
-- GTX parallel interface
--------------------------------------------------------------------------
i_mgt_rst => rxlos,
i_mgt_rx_clk => rxusrclk,
i_mgt_rx_data => rxdata,
i_mgt_rx_charisk => rxcharisk,
--------------------------------------------------------------------------
-- User interface CPU clock
--------------------------------------------------------------------------
i_usr_clk => usr_clk,
i_evr_params => evr_params,
o_event_recorder_stat => open,
i_event_recorder_ctrl => c_INIT_EVT_REC_CTRL,
i_mem_addr => mem_addr,
o_mem_data => mem_data,
--------------------------------------------------------------------------
-- User stream interface User clock
--------------------------------------------------------------------------
i_stream_clk => usr_clk,
o_stream_data => dec_stream_data,
o_stream_addr => dec_stream_addr,
o_stream_valid => dec_stream_valid,
--------------------------------------------------------------------------
-- User interface MGT clock
--------------------------------------------------------------------------
o_usr_events => usr_events,
o_usr_events_ext => open,
o_sos_event => open
);
evr320_data_filter_inst: entity work.evr320_data_filter
generic map (
ADDRESS => FILTER_ADDRESS,
NUM_BYTES => 8
)
port map (
i_stream_clk => usr_clk,
i_stream_data => dec_stream_data,
i_stream_addr => dec_stream_addr,
i_stream_valid => dec_stream_valid,
o_data => filter_data,
o_valid => filter_valid
);
-----------------------------------------------------------------------------
-- MGT / User clock
-----------------------------------------------------------------------------
clock_generator(rxusrclk, C_RXUSRCLK_CYCLE);
clock_generator(usr_clk, C_USRCLK_CYCLE);
-----------------------------------------------------------------------------
-- Decoder reset due to MGT main status
-----------------------------------------------------------------------------
process
begin
rxlos <= '1';
wait for 50 ns;
wait until (falling_edge(rxusrclk));
rxlos <= '0';
wait ;
end process;
---------------------------------------------------------
-- Receive decoder data stream
---------------------------------------------------------
process
variable addr : std_logic_vector(10 downto 0);
variable data : std_logic_vector(7 downto 0);
variable i : integer := 0;
begin
wait until rising_edge(usr_clk);
if (dec_stream_valid = '1') then
addr := dec_stream_addr;
data := dec_stream_data;
i := to_integer(unsigned(addr)) - to_integer(unsigned(segment_addr))*16;
-- save stream for later comparision:
dec_stream_check(i).addr <= addr;
dec_stream_check(i).data <= data;
log(ID_SEGMENT_DATA, "Recv Decoder Stream: count=" & integer'image(i) & " addr=0x" & to_string(addr, HEX) & " data=0x" & to_string(data, HEX));
i := i + 1;
dec_stream_recv_bytes <= i;
end if;
end process;
---------------------------------------------------------
-- Wait for Event
---------------------------------------------------------
process
begin
wait until rising_edge(usr_clk);
for i in 0 to 3 loop
if (usr_events(i) = '1') then
log(ID_CTRL, "Event Received: 0x" & to_string(evr_params.event_numbers(i), HEX) );
received_events <= received_events + 1;
end if;
end loop;
end process;
---------------------------------------------------------
-- Fetch filter data
---------------------------------------------------------
process
begin
wait until rising_edge(usr_clk);
if (filter_valid = '1') then
filter_data_check <= filter_data;
log(ID_SEGMENT_DATA, "Filter Valid: data=0x" & to_string(filter_data, HEX));
end if;
end process;
-----------------------------------------------------------------------------
-- Read stimuli file
-----------------------------------------------------------------------------
file_blk : block
file file_stimuli : text;
type parse_fsm_state is (idle, seg_start, seg_addr, seg_Wait, seg_payload, seg_payload_wait, seg_done);
begin
process
variable file_line : line;
variable data, event : std_logic_vector(7 downto 0);
variable data_k, event_k : std_logic_vector(0 downto 0);
variable space : character;
variable i : integer;
variable parse_fsm : parse_fsm_state := idle;
variable payload_cnt : integer range 0 to 2047;
variable event_cnt : integer := 0;
begin
file_open(file_stimuli, "../tb/stimuli_mgt.dat", read_mode);
readline(file_stimuli, file_line); -- comment
readline(file_stimuli, file_line); -- comment
i := 0;
-- read line by line from .dat file:
while not endfile(file_stimuli) loop
readline(file_stimuli, file_line);
hread(file_line, event);
read(file_line, event_k);
read(file_line, space);
read(file_line, space);
hread(file_line, data);
read(file_line, space);
read(file_line, data_k);
-- write to array:
mgt_stream(i).data <= data;
mgt_stream(i).data_k <= data_k;
mgt_stream(i).event <= event;
mgt_stream(i).event_k <= event_k;
mgt_stream_index <= i;
--debug output:
--log(ID_SEGMENT_DATA, "stimuli file: i=" & integer'image(i) & " event=0x" & to_string(event, HEX) & " k=" & to_string(event_k, HEX)
-- & " data=0x" & to_string(data, HEX) & " k=" & to_string(data_k, HEX) & " ");
-- Count Events:
----------------
if (event /= x"00" and event_k = "0") then
event_cnt := event_cnt + 1;
end if;
expect_num_events <= event_cnt * STIMULI_RUNS;
-- Parse only segment:
----------------------
case (parse_fsm) is
when idle =>
if (data = x"5C" and data_k = "1") then -- check if frame start
parse_fsm := seg_start;
end if;
when seg_start =>
parse_fsm := seg_addr;
when seg_addr =>
segment_addr <= data;
parse_fsm := seg_wait;
when seg_wait =>
parse_fsm := seg_payload;
payload_cnt := 0;
when seg_payload =>
if (data = x"3C" and data_k = "1") then -- check if frame end
parse_fsm := seg_done;
else
segment_data(payload_cnt) <= data;
parse_fsm := seg_payload_wait;
segment_length <= payload_cnt+1;
end if;
when seg_payload_wait =>
payload_cnt := payload_cnt + 1;
parse_fsm := seg_payload;
when seg_done =>
-- done
end case;
i := i + 1;
end loop;
file_close(file_stimuli);
wait;
end process;
end block;
-----------------------------------------------------------------------------
-- Stimulus CPU interface
-----------------------------------------------------------------------------
process
constant C_SCOPE : string := C_TB_SCOPE_DEFAULT;
constant c_TB_NAME : string := "evr320_decoder_tb";
variable mgt_stream_rep_var : integer := 0;
variable mgt_stream_index_var : integer := 0;
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 var_filter_offset : integer range 0 to 2047;
variable var_filter_word : std_logic_vector(FILTER_NUM_BYTES*8-1 downto 0);
begin
-- init uvvm:
set_log_file_name(c_TB_NAME & "_LOG.txt");
set_alert_file_name(c_TB_NAME & "_ALERT.txt");
set_alert_stop_limit(ERROR, 0); -- never(0) pause simulator on error
set_alert_stop_limit(TB_ERROR, 0); -- never(0) pause simulator on error
enable_log_msg(ALL_MESSAGES);
log(ID_LOG_HDR, "Start Simulation of evr320 decoder", C_SCOPE);
--------------------------------------------------------------------------
-- Get out of reset, enable events
--------------------------------------------------------------------------
evr_params.event_enable( 0) <= '1';
evr_params.event_enable( 1) <= '0';
evr_params.event_enable( 2) <= '0';
evr_params.event_enable( 3) <= '0';
evr_params.event_numbers( 0)<= X"0F";
evr_params.event_numbers( 1)<= X"00";
evr_params.event_numbers( 2)<= X"00";
evr_params.event_numbers( 3)<= X"00";
evr_params.cs_min_cnt <= X"00000000";
evr_params.cs_min_time <= X"00000000";
mem_addr <= x"000";
await_value(rxlos, '0', 0 ns, 10 us, FAILURE, "wait for release RX LOS");
--wait until (rxlos = '0');
--------------------------------------------------------------------------
-- Stimuli MGT
--------------------------------------------------------------------------
wait until rising_edge(rxusrclk);
for b in 0 to STIMULI_RUNS-1 loop
log(ID_DATA, "Send stimuli stream to MGT");
for idx in 0 to mgt_stream_index loop
--log(ID_FRAME_DATA, to_string(mgt_stream(idx).data, HEX), to_string(mgt_stream(idx).event, HEX));
wait until rising_edge(rxusrclk);
rxdata <= mgt_stream(idx).data & mgt_stream(idx).event;
rxcharisk <= mgt_stream(idx).data_k & mgt_stream(idx).event_k;
end loop;
end loop;
--------------------------------------------------------------------------
-- Check if decoder stream is correct
--------------------------------------------------------------------------
await_value(dec_stream_recv_bytes, segment_length, 0 ns, 5 us, ERROR, "Wait for right number of bytes streamed");
-- loop through segment and compare frame bytes with received decoder-stream:
for idx in 0 to segment_length-1 loop
check_value(dec_stream_check(idx).data, segment_data(idx), ERROR, "Compare Sent and Received Decoder Stream Data");
end loop;
--------------------------------------------------------------------------
-- Check if filter data is correct
--------------------------------------------------------------------------
var_filter_offset := to_integer(unsigned(FILTER_ADDRESS)) - (to_integer(unsigned(segment_addr))*16);
--log(ID_CTRL, "var_filter_offset=" & integer'image(var_filter_offset) & " : " & to_string(FILTER_ADDRESS,HEX) & " : " & to_string(segment_addr, HEX));
for idx in 0 to FILTER_NUM_BYTES-1 loop
var_filter_word := var_filter_word(var_filter_word'high-8 downto 0) & segment_data(var_filter_offset + idx);
end loop;
check_value(filter_data_check, var_filter_word, ERROR, "Check Data Stream Filter "
& "addr=0x" & to_string(FILTER_ADDRESS, HEX)
& " bytes=" & integer'image(FILTER_NUM_BYTES));
--------------------------------------------------------------------------
-- Check if correct number of events has been detected
--------------------------------------------------------------------------
check_value(received_events, expect_num_events, ERROR, "Check correct number of received events");
--------------------------------------------------------------------------
-- Read DPRAM buffer
--------------------------------------------------------------------------
wait for 1 us;
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;
--------------------------------------------------------------------------
-- Test Done
--------------------------------------------------------------------------
log(ID_LOG_HDR, "SIMULATION COMPLETED", C_SCOPE);
report_alert_counters(VOID);
assert shared_uvvm_status.found_unexpected_simulation_warnings_or_worse = 0
report "UVVM Found unexpected warnings or worse" severity ERROR;
stop(0);
-- finish(0); -- wants to close modelsim!?
wait;
end process;
end architecture testbench;
--------------------------------------------------------------------------------
-- End of file
--------------------------------------------------------------------------------

131
tb/stimuli_mgt.dat Normal file
View File

@@ -0,0 +1,131 @@
# stimuli timing master frame, hex
# event k data k comment
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 5C 1 frame start
00 0 00 0 gap
00 0 02 0 frame byte
BC 1 00 0 align
00 0 DB 0 frame byte
00 0 00 0 gap
00 0 93 0 frame byte
BC 1 00 0 align
00 0 36 0 frame byte
00 0 00 0 gap
00 0 41 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 A3 0 frame byte
00 0 00 0 gap
00 0 1D 0 frame byte
BC 1 00 0 align
00 0 7F 0 frame byte
00 0 00 0 gap
00 0 33 0 frame byte
BC 1 00 0 align
00 0 9B 0 frame byte
00 0 00 0 gap
00 0 F3 0 frame byte
BC 1 00 0 align
00 0 51 0 frame byte
00 0 00 0 gap
00 0 04 0 frame byte
BC 1 00 0 align
00 0 6B 0 frame byte
00 0 00 0 gap
00 0 7C 0 frame byte
BC 1 00 0 align
00 0 16 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 00 0 frame byte
00 0 00 0 gap
00 0 00 0 frame byte
BC 1 00 0 align
00 0 3C 1 frame end
00 0 00 0 gap
00 0 F9 0 check sum MSB
BC 1 00 0 align
00 0 C6 0 check sum LSB
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
00 0 00 0 gap
00 0 00 0 gap
BC 1 00 0 align
00 0 00 0 gap
0F 0 00 0 BPM event
00 0 00 0 gap