Compare commits
41 Commits
2.1
...
hipa_debug
| Author | SHA1 | Date | |
|---|---|---|---|
| a68b5e6bba | |||
| 3049e28ea7 | |||
| f440f95c8d | |||
| 8f830624c0 | |||
| 95a88cbba0 | |||
| 287bfde2e0 | |||
| 3f1b7acc50 | |||
| fdcadda6ed | |||
| 0d6457cb77 | |||
| 83a4435e41 | |||
| b77484c659 | |||
| 071cf50ded | |||
| 5a060a160c | |||
| 6b1f4fbcbc | |||
| ffb3eb6331 | |||
| d5b3545ef2 | |||
| 2ce1941a6c | |||
| 99e2fe462a | |||
| 16e7d3e9f6 | |||
| 60ad0be56e | |||
| 740c93fd7a | |||
| c846a32902 | |||
| b171096b8a | |||
| a3ff15adec | |||
| bc987bee99 | |||
| 4f9e87b16d | |||
| 82c023c610 | |||
| 84f23d13ab | |||
| c52673a8ca | |||
| d7e669cb75 | |||
| 84440ce6a0 | |||
| 5e79f3f426 | |||
| 35077a9d84 | |||
| 2634412bd0 | |||
| da6ab3236a | |||
| 6b512782f3 | |||
| 426fa8bc1c | |||
|
|
30d692b872 | ||
| 5f1af19d28 | |||
| 77adb7b9e2 | |||
| 4aecb89683 |
26
Changelog.md
26
Changelog.md
@@ -1,11 +1,23 @@
|
||||
## 2.1
|
||||
|
||||
## 2.3
|
||||
* Added Features
|
||||
* Event Recorder functionality implemented as an option
|
||||
* IFC1210 bindings for tosca2
|
||||
* Bugfixes
|
||||
* None
|
||||
* 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.
|
||||
|
||||
## 2.2
|
||||
|
||||
* Added Features
|
||||
* HIPA option for Virtex-6 GTX -> pkg_v6vlx_gtxe1.vhd separated to different files to avoid duplicated code.
|
||||
* use_MMCM generic is derived from FACILITY generic which implicitly contains line rate (use MMCM when line rate > 2.5Gbps).
|
||||
* Bugfixes
|
||||
* signal names in added sync stage were not adapted.
|
||||
|
||||
## 2.1
|
||||
|
||||
* Added Features
|
||||
* Event Recorder functionality implemented as an option
|
||||
* IFC1210 bindings for tosca2
|
||||
* Bugfixes
|
||||
* None
|
||||
|
||||
## 2.0
|
||||
|
||||
* Migration from CVS /G/GPAC/Lib/Vivado_Lib/axi_evr320_2.0
|
||||
* Migration from CVS /G/GPAC/Lib/Vivado_Lib/axi_evr320_2.0
|
||||
|
||||
54
README.md
54
README.md
@@ -1,43 +1,47 @@
|
||||
## General Information
|
||||
|
||||
The EVR320 Embedded Event Receiver (EEVR) is able to connect with a MRF Timing System.
|
||||
# General Information
|
||||
The EVR320 Embedded Event Receiver (EEVR) is able to connect with a MRF Timing System.
|
||||
Mainly the EEVR is used to decode configurable events and use them in firmware as triggers.
|
||||
|
||||
## Maintainer
|
||||
|
||||
Patric Bucher [patric.bucher@psi.ch]
|
||||
Patric Bucher [patric.bucher@psi.ch]
|
||||
Jonas Purtschert [jonas.purtschert@psi.ch]
|
||||
|
||||
## Authors
|
||||
|
||||
Waldemar Koprek [waldemar.koprek@psi.ch]
|
||||
|
||||
Goran Marinkovic [goran.marinkovic@psi.ch]
|
||||
|
||||
Patric Bucher [patric.bucher@psi.ch]
|
||||
Waldemar Koprek [waldemar.koprek@psi.ch]
|
||||
Goran Marinkovic [goran.marinkovic@psi.ch]
|
||||
Patric Bucher [patric.bucher@psi.ch]
|
||||
Jonas Purtschert [jonas.purtschert@psi.ch]
|
||||
|
||||
## Documentation
|
||||
|
||||
See [EVR320 Documentation](doc/evr320.pdf "doc/evr320.pdf")
|
||||
See [EVR320 Documentation](doc/evr320.pdf "doc/evr320.pdf")
|
||||
|
||||
## Changelog
|
||||
|
||||
See [Changelog](Changelog.md)
|
||||
See [Changelog](Changelog.md)
|
||||
|
||||
## What belongs into this Library
|
||||
All components and wrappers to connect various buses (AXI4, TOSCA-II, ..) and to use on different Xilinx FPGA's.
|
||||
|
||||
All components and wrappers to connect various buses (AXI4, TOSCA-II, ..) and to use on different Xilinx FPGA's.
|
||||
Examples for things that belong into this library:
|
||||
- Event Decoder / Core Functionality
|
||||
- Different MGT types
|
||||
|
||||
Examples for things that belong into this library:
|
||||
* Event Decoder / Core Functionality
|
||||
* Different MGT types
|
||||
|
||||
Examples for things that do not belong into this library:
|
||||
* Vivado IP Packager related files -> belong to separate git repo
|
||||
Examples for things that do not belong into this library:
|
||||
- Vivado IP Packager related files -> belong to separate git repo
|
||||
|
||||
## Dependencies
|
||||
### Library
|
||||
* Libraries/TCL/PsiSim
|
||||
* Libraries/BoardSupport/ifc1210/tosca2 (with tosca2 only)
|
||||
|
||||
### Synthesis
|
||||
- Libraries/Firmware/VHDL/psi\_common (https://github.com/paulscherrerinstitute/psi_common)
|
||||
|
||||
### Simulation
|
||||
- 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
|
||||
- Libraries/BoardSupport/IFC1210/tosca2
|
||||
|
||||
|
||||
|
||||
|
||||
6
constraints/eevr.ucf
Normal file
6
constraints/eevr.ucf
Normal 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>
|
||||
|
||||
BIN
doc/evr320.pdf
BIN
doc/evr320.pdf
Binary file not shown.
14059
doc/evr320.rtf
14059
doc/evr320.rtf
File diff suppressed because it is too large
Load Diff
BIN
doc/evr320.vsd
BIN
doc/evr320.vsd
Binary file not shown.
@@ -11,7 +11,7 @@
|
||||
--------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ begin
|
||||
if rising_edge(clka) then
|
||||
if (ena = '1') then
|
||||
if (wea = '1') then
|
||||
RAM(conv_integer(page_addr_clka & addra)) := dia;
|
||||
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra)))) := dia;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -99,10 +99,10 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(15 downto 8) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(23 downto 16) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(31 downto 24) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(23 downto 16) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(31 downto 24) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -117,9 +117,9 @@ begin
|
||||
if (ena = '1') then
|
||||
if (wea = '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(std_logic_vector'(page_addr_clka & addra(addra'high downto 1))))) := dia;
|
||||
else
|
||||
RAM_EVEN(conv_integer(page_addr_clka & addra(addra'high downto 1))) := dia;
|
||||
RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra(addra'high downto 1))))) := dia;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -130,14 +130,14 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(15 downto 8) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(23 downto 16) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(31 downto 24) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(39 downto 32) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(47 downto 40) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(55 downto 48) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob(63 downto 56) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
92
hdl/evr320_data_filter.vhd
Normal file
92
hdl/evr320_data_filter.vhd
Normal file
@@ -0,0 +1,92 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- 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:
|
||||
-- Modif: Benoit Stef
|
||||
-- not based on counter anymore but map to LSB into a generic array
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.psi_common_math_pkg.all;
|
||||
|
||||
entity evr320_data_filter is
|
||||
generic (NUM_BYTES : integer := 8;
|
||||
SWAP : boolean := false ); -- if true byte are swpped at output
|
||||
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;
|
||||
i_address : in std_logic_vector(11 downto 0);
|
||||
-- filter output:
|
||||
o_data : out std_logic_vector(NUM_BYTES*8-1 downto 0) := (others=>'0');
|
||||
o_valid : out std_logic := '0'
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture behavioral of evr320_data_filter is
|
||||
-- array to store data value prior to map to output
|
||||
type byte_array_t is array (NUM_BYTES-1 downto 0) of std_logic_vector(i_stream_data'range);
|
||||
signal table_s : byte_array_t;
|
||||
--pipe help
|
||||
signal addr_dff_s : std_logic_vector(10 downto 0) := (others=>'0');
|
||||
signal data_dff_s : std_logic_vector(i_stream_data'range) := (others=>'0');
|
||||
signal filt_dff_s : std_logic_vector(i_address'range);
|
||||
--helper
|
||||
constant low_bd_c : integer := log2ceil(NUM_BYTES); --compute LSB for address decoding
|
||||
signal ena_s : std_logic_vector(1 downto 0); --clock enable vector
|
||||
|
||||
begin
|
||||
|
||||
p : process(i_stream_clk)
|
||||
begin
|
||||
if (rising_edge(i_stream_clk)) then
|
||||
|
||||
--*** 1st pipe stage ***
|
||||
ena_s(0) <= i_stream_valid;
|
||||
filt_dff_s <= i_address;
|
||||
if (i_stream_valid = '1') then
|
||||
addr_dff_s <= i_stream_addr;
|
||||
data_dff_s <= i_stream_data;
|
||||
end if;
|
||||
|
||||
--*** filling the array ***
|
||||
if ena_s(0) = '1' then
|
||||
if addr_dff_s(10 downto low_bd_c) = filt_dff_s(10 downto low_bd_c) then
|
||||
--*** spatial loop ***
|
||||
ena_s(1) <= '1';
|
||||
for i in 0 to NUM_BYTES-1 loop
|
||||
if addr_dff_s(low_bd_c-1 downto 0) = to_uslv(i,low_bd_c) then
|
||||
table_s(i) <= data_dff_s ;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
else
|
||||
ena_s(1) <= '0';
|
||||
end if;
|
||||
|
||||
--*** set the output & valid accordingly***
|
||||
if ena_s(1) = '1' then
|
||||
if (from_uslv(addr_dff_s) = (from_uslv(filt_dff_s) + NUM_BYTES -1)) then
|
||||
o_valid <= '1';
|
||||
--*** spatial loop map output ***
|
||||
for i in 0 to NUM_BYTES-1 loop
|
||||
if SWAP then
|
||||
o_data(NUM_BYTES+i*NUM_BYTES-1 downto 0+i*NUM_BYTES) <= table_s(NUM_BYTES-1-i);
|
||||
else
|
||||
o_data(NUM_BYTES+i*NUM_BYTES-1 downto 0+i*NUM_BYTES) <= table_s(i);
|
||||
end if;
|
||||
end loop;
|
||||
else
|
||||
o_valid <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
@@ -12,20 +12,22 @@
|
||||
--------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
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;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
library work;
|
||||
use work.evr320_pkg.all;
|
||||
|
||||
|
||||
entity evr320_decoder is
|
||||
generic
|
||||
(
|
||||
FACILITY : string := "SFEL"; -- "HIPA" | "SFEL"
|
||||
EVENT_RECORDER : boolean := false;
|
||||
MEM_DATA_WIDTH : integer := 32
|
||||
MEM_DATA_WIDTH : integer := 32;
|
||||
EXP_REC_CLK_FREQ : natural := 142_800_000 -- in Hz
|
||||
);
|
||||
port
|
||||
(
|
||||
@@ -51,11 +53,20 @@ entity evr320_decoder is
|
||||
i_mem_addr : in std_logic_vector(11 downto 0);
|
||||
o_mem_data : out std_logic_vector(MEM_DATA_WIDTH - 1 downto 0);
|
||||
--------------------------------------------------------------------------
|
||||
-- User stream interface User clock
|
||||
--------------------------------------------------------------------------
|
||||
i_stream_clk : in std_logic;
|
||||
o_stream_data : out std_logic_vector(7 downto 0);
|
||||
o_stream_addr : out std_logic_vector(10 downto 0);
|
||||
o_stream_valid : out std_logic;
|
||||
--------------------------------------------------------------------------
|
||||
-- User interface MGT clock
|
||||
--------------------------------------------------------------------------
|
||||
o_usr_events : out std_logic_vector( 3 downto 0);
|
||||
o_usr_events_ext : out std_logic_vector( 3 downto 0);
|
||||
o_sos_event : out std_logic
|
||||
o_sos_event : out std_logic;
|
||||
o_event : out std_logic_vector( 7 downto 0);
|
||||
o_event_valid : out std_logic
|
||||
);
|
||||
end evr320_decoder;
|
||||
|
||||
@@ -64,6 +75,7 @@ architecture behavioral of evr320_decoder is
|
||||
-----------------------------------------------------------------------------
|
||||
-- Constant
|
||||
-----------------------------------------------------------------------------
|
||||
--
|
||||
constant HIGH : std_logic := '1';
|
||||
constant LOW : std_logic := '0';
|
||||
constant LOW_slv : std_logic_vector(15 downto 0) := (others => '0');
|
||||
@@ -87,9 +99,9 @@ architecture behavioral of evr320_decoder is
|
||||
-- Events received
|
||||
type usr_events_type is array (0 to 3) of std_logic_vector( 3 downto 0);
|
||||
signal usr_events : usr_events_type := (others => (others => '0'));
|
||||
signal cs_timeout_cnt : std_logic_vector(23 downto 0) := (others => '0');
|
||||
signal cs_min_cnt : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal cs_min_time : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal cs_timeout_cnt : unsigned(23 downto 0) := (others => '0');
|
||||
signal cs_min_cnt : unsigned(31 downto 0) := (others => '0');
|
||||
signal cs_min_time : unsigned(31 downto 0) := (others => '0');
|
||||
signal evr_stable : std_logic := '0';
|
||||
|
||||
-- Frame fsm
|
||||
@@ -117,7 +129,7 @@ architecture behavioral of evr320_decoder is
|
||||
constant frame_chk2 : std_logic_vector( 3 downto 0) := "1000";
|
||||
signal frame_fsm : std_logic_vector( 3 downto 0) := "0000";
|
||||
-- Frame checksum
|
||||
signal frame_chk : std_logic_vector(15 downto 0) := X"FFFF";
|
||||
signal frame_chk : unsigned(15 downto 0) := X"FFFF";
|
||||
signal frame_chk_ok : std_logic := '0';
|
||||
signal frame_chk1_ok : std_logic := '0';
|
||||
signal frame_chk2_ok : std_logic := '0';
|
||||
@@ -142,8 +154,8 @@ architecture behavioral of evr320_decoder is
|
||||
signal frame_data_rden : std_logic := '0';
|
||||
signal frame_data_do : std_logic_vector(63 downto 0) := (others => '0');
|
||||
-- Frame data FIFO write port
|
||||
signal frame_data_wr_id : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
signal frame_data_wr_addr_cnt: std_logic_vector(15 downto 0) := (others => '0');
|
||||
signal frame_data_wr_id : unsigned( 7 downto 0) := (others => '0');
|
||||
signal frame_data_wr_addr_cnt: unsigned(15 downto 0) := (others => '0');
|
||||
signal frame_data_wr_addr : std_logic_vector(10 downto 0) := (others => '0');
|
||||
signal frame_data_wr_byte : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
-- Frame data FIFO read port
|
||||
@@ -166,6 +178,7 @@ architecture behavioral of evr320_decoder is
|
||||
signal mem_fsm : std_logic_vector( 1 downto 0) := "00";
|
||||
-- Data memory address
|
||||
signal mem_addr : std_logic_vector(11 downto 0);
|
||||
signal mem_addr_dly : std_logic_vector(11 downto 0);
|
||||
-- Data memory write
|
||||
signal mem_data_wren : std_logic := '0';
|
||||
signal mem_data_wr_addr : std_logic_vector(10 downto 0) := (others => '0');
|
||||
@@ -182,16 +195,16 @@ architecture behavioral of evr320_decoder is
|
||||
signal usr_events_save_dly : std_logic := '0';
|
||||
signal usr_events_nr : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
signal usr_events_nr_dly : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
signal usr_events_addr : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
signal usr_events_addr : unsigned( 7 downto 0) := (others => '0');
|
||||
signal usr_events_addr_dly : std_logic_vector( 7 downto 0) := (others => '0');
|
||||
signal usr_events_cnt : std_logic_vector( 31 downto 0) := (others => '0');
|
||||
signal usr_events_cnt_d : std_logic_vector( 31 downto 0) := (others => '0');
|
||||
signal usr_events_cnt : unsigned( 31 downto 0) := (others => '0');
|
||||
signal usr_events_cnt_d : unsigned( 31 downto 0) := (others => '0');
|
||||
signal all_events_flags : std_logic_vector(255 downto 0) := (others => '0');
|
||||
signal all_events_flags_d : std_logic_vector(255 downto 0) := (others => '0');
|
||||
signal all_events_flags_sync1 : std_logic_vector(255 downto 0) := (others => '0');
|
||||
signal all_events_flags_sync2 : std_logic_vector(255 downto 0) := (others => '0');
|
||||
signal timestamp_cnt : std_logic_vector( 31 downto 0) := (others => '0');
|
||||
signal timestamp_cnt_dly : std_logic_vector( 31 downto 0) := (others => '0');
|
||||
signal timestamp_cnt : unsigned( 31 downto 0) := (others => '0');
|
||||
signal timestamp_cnt_dly : unsigned( 31 downto 0) := (others => '0');
|
||||
signal segment_addr_wren : std_logic;
|
||||
signal mem_data_valid : std_logic;
|
||||
signal mem_data_error : std_logic;
|
||||
@@ -203,7 +216,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_dpram_sos : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
||||
signal mem_data_segment_timestamp : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
|
||||
|
||||
signal stream_raw : std_logic_vector(18 downto 0);
|
||||
-- attribute safe_implementation: string;
|
||||
-- attribute safe_implementation of frame_fsm : signal is "yes";
|
||||
-- attribute safe_implementation of mem_fsm : signal is "yes";
|
||||
@@ -211,7 +224,9 @@ architecture behavioral of evr320_decoder is
|
||||
-- attribute fsm_safe_state : string;
|
||||
-- attribute fsm_safe_state of frame_fsm : signal is "default_state";
|
||||
-- attribute fsm_safe_state of mem_fsm : signal is "default_state";
|
||||
|
||||
|
||||
constant evr_stable_time_int_c : natural := EXP_REC_CLK_FREQ/100;
|
||||
constant evr_stable_time_slv_c : std_logic_vector(cs_timeout_cnt'range):= std_logic_vector(to_unsigned(evr_stable_time_int_c, cs_timeout_cnt'length));
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -220,9 +235,10 @@ begin
|
||||
debug_clk <= i_mgt_rx_clk;
|
||||
debug( 15 downto 0) <= i_mgt_rx_data;
|
||||
debug( 17 downto 16) <= i_mgt_rx_charisk;
|
||||
debug( 18) <= '0';
|
||||
debug( 31 downto 24) <= (others => '0');
|
||||
debug( 35 downto 32) <= "0001" when (frame_fsm = frame_idle ) else
|
||||
debug(18) <= evr_stable;--new
|
||||
debug(26 downto 19) <= i_evr_params.event_numbers(1);
|
||||
debug(34 downto 27) <= i_evr_params.event_numbers(2);
|
||||
debug(38 downto 35) <= "0001" when (frame_fsm = frame_idle ) else
|
||||
"0010" when (frame_fsm = frame_addr_gap) else
|
||||
"0011" when (frame_fsm = frame_addr ) else
|
||||
"0100" when (frame_fsm = frame_data_gap) else
|
||||
@@ -232,7 +248,7 @@ begin
|
||||
"1000" when (frame_fsm = frame_chk2_gap) else
|
||||
"1001" when (frame_fsm = frame_chk2 ) else
|
||||
"0000";
|
||||
debug( 39 downto 36) <= (others => '0');
|
||||
debug( 39) <= '0';
|
||||
debug( 40) <= usr_events( 0)( 3);
|
||||
debug( 41) <= usr_events( 1)( 3);
|
||||
debug( 42) <= usr_events( 2)( 3);
|
||||
@@ -246,18 +262,18 @@ begin
|
||||
debug( 65) <= usr_events_save_dly;
|
||||
debug( 73 downto 66) <= usr_events_nr_dly;
|
||||
debug( 81 downto 74) <= usr_events_addr_dly;
|
||||
debug(113 downto 82) <= timestamp_cnt_dly;
|
||||
debug(113 downto 82) <= std_logic_vector(timestamp_cnt_dly);
|
||||
debug(114) <= segment_addr_wren;
|
||||
debug(115) <= mem_data_valid;
|
||||
debug(116) <= mem_data_error;
|
||||
debug(117) <= mem_data_read_ack(0);
|
||||
debug(118) <= mem_data_error_ack(0);
|
||||
debug(119) <= all_events_flags(27); -- event code 27 (photonics)
|
||||
debug(127 downto 120) <= usr_events_cnt(7 downto 0);
|
||||
debug(127 downto 120) <= std_logic_vector(usr_events_cnt(7 downto 0));
|
||||
end generate dbg_evt_rec;
|
||||
|
||||
dbg_no_evt_rec: if not(EVENT_RECORDER) generate
|
||||
debug(127 downto 64) <= (others => '0');
|
||||
|
||||
end generate dbg_no_evt_rec;
|
||||
|
||||
|
||||
@@ -279,6 +295,7 @@ begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- evr stable state
|
||||
-- TODO: Perform the sync according to k28.5
|
||||
-----------------------------------------------------------------------------
|
||||
prc_evr_stable : process(i_mgt_rx_clk)
|
||||
begin
|
||||
@@ -286,7 +303,9 @@ begin
|
||||
if (i_mgt_rst = '1') then
|
||||
evr_stable <= '0';
|
||||
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 ((std_logic_vector(cs_min_cnt) > i_evr_params.cs_min_cnt) and
|
||||
(std_logic_vector(cs_min_time) > i_evr_params.cs_min_time) and
|
||||
(std_logic_vector(cs_timeout_cnt) < evr_stable_time_slv_c)) then -- make generics depending on recovery_clock
|
||||
evr_stable <= '1';
|
||||
else
|
||||
evr_stable <= '0';
|
||||
@@ -305,13 +324,21 @@ begin
|
||||
if (i_mgt_rst = '1') then
|
||||
usr_events <= (others => (others => '0'));
|
||||
else
|
||||
for i in 0 to 3 loop
|
||||
if ((i_evr_params.event_enable(i) = '1') and (i_mgt_rx_charisk( 0) = '0') and (i_mgt_rx_data( 7 downto 0) = i_evr_params.event_numbers(i)) and (evr_stable = '1')) then
|
||||
for i in 0 to 3 loop
|
||||
if FACILITY = "HIPA" then
|
||||
if ((i_evr_params.event_enable(i) = '1') and (i_mgt_rx_charisk( 0) = '0') and (i_mgt_rx_data( 7 downto 0) = i_evr_params.event_numbers(i))) then
|
||||
usr_events(i) <= "1111";
|
||||
else
|
||||
usr_events(i) <= usr_events(i)( 2 downto 0) & '0';
|
||||
end if;
|
||||
end loop;
|
||||
else
|
||||
if ((i_evr_params.event_enable(i) = '1') and (i_mgt_rx_charisk( 0) = '0') and (i_mgt_rx_data( 7 downto 0) = i_evr_params.event_numbers(i))and (evr_stable = '1')) then
|
||||
usr_events(i) <= "1111";
|
||||
else
|
||||
usr_events(i) <= usr_events(i)( 2 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -448,7 +475,7 @@ begin
|
||||
frame_data_wr_addr_cnt <= (others => '0');
|
||||
when frame_addr =>
|
||||
frame_data_wr_id <= frame_data_wr_id + X"01";
|
||||
frame_data_wr_addr_cnt <= "0000" & i_mgt_rx_data(15 downto 8) & "0000";
|
||||
frame_data_wr_addr_cnt <= "0000" & unsigned(i_mgt_rx_data(15 downto 8)) & "0000";
|
||||
segment_addr_wren <= '1';
|
||||
when frame_data =>
|
||||
if (((i_mgt_rx_charisk( 1) = '1') and (i_mgt_rx_data(15 downto 8) = C_KCHAR_END)) or
|
||||
@@ -457,7 +484,7 @@ begin
|
||||
else
|
||||
frame_data_wren <= not frame_data_full;
|
||||
frame_data_wr_addr_cnt <= frame_data_wr_addr_cnt + X"0001";
|
||||
frame_data_wr_addr <= frame_data_wr_addr_cnt(10 downto 0);
|
||||
frame_data_wr_addr <= std_logic_vector(frame_data_wr_addr_cnt(10 downto 0));
|
||||
frame_data_wr_byte <= i_mgt_rx_data(15 downto 8);
|
||||
end if;
|
||||
when others =>
|
||||
@@ -478,7 +505,7 @@ begin
|
||||
frame_chk <= X"FFFF";
|
||||
when frame_addr | frame_data =>
|
||||
if (i_mgt_rx_charisk = "00") then
|
||||
frame_chk <= frame_chk - (X"00" & i_mgt_rx_data(15 downto 8));
|
||||
frame_chk <= frame_chk - (X"00" & unsigned(i_mgt_rx_data(15 downto 8)));
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
@@ -494,11 +521,11 @@ begin
|
||||
frame_chk1_ok <= '0';
|
||||
frame_chk2_ok <= '0';
|
||||
when frame_chk1 =>
|
||||
if (frame_chk(15 downto 8) = i_mgt_rx_data(15 downto 8)) then
|
||||
if (frame_chk(15 downto 8) = unsigned(i_mgt_rx_data(15 downto 8))) then
|
||||
frame_chk1_ok <= '1';
|
||||
end if;
|
||||
when frame_chk2 =>
|
||||
if (frame_chk( 7 downto 0) = i_mgt_rx_data(15 downto 8)) then
|
||||
if (frame_chk( 7 downto 0) = unsigned(i_mgt_rx_data(15 downto 8))) then
|
||||
frame_chk2_ok <= '1';
|
||||
end if;
|
||||
when others =>
|
||||
@@ -524,7 +551,7 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
frame_ctrl_wr_id <= frame_data_wr_id;
|
||||
frame_ctrl_wr_id <= std_logic_vector(frame_data_wr_id);
|
||||
frame_ctrl_wr_ok <= frame_chk_ok;
|
||||
|
||||
frame_ctrl_di( 7 downto 0) <= frame_ctrl_wr_id;
|
||||
@@ -586,7 +613,7 @@ begin
|
||||
frame_ctrl_rd_ok <= frame_ctrl_do( 8);
|
||||
|
||||
-- Frame data received
|
||||
frame_data_di( 7 downto 0) <= frame_data_wr_id;
|
||||
frame_data_di( 7 downto 0) <= std_logic_vector(frame_data_wr_id);
|
||||
frame_data_di(18 downto 8) <= frame_data_wr_addr;
|
||||
frame_data_di(23 downto 19) <= "00000";
|
||||
frame_data_di(31 downto 24) <= frame_data_wr_byte;
|
||||
@@ -697,14 +724,24 @@ begin
|
||||
mem_data_wr_addr <= frame_data_rd_addr;
|
||||
mem_data_wr_byte <= frame_data_rd_byte;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Address delay for read data mux
|
||||
-----------------------------------------------------------------------------
|
||||
process(i_usr_clk)
|
||||
begin
|
||||
if (i_usr_clk'event and (i_usr_clk = '1')) then
|
||||
mem_addr_dly <= mem_addr;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Data memory selector
|
||||
-----------------------------------------------------------------------------
|
||||
o_mem_data <= mem_data_dpram when (mem_addr(11 downto 9) = "000") else
|
||||
mem_data_event0 when (mem_addr(11 downto 9) = "001") else
|
||||
mem_data_event1 when (mem_addr(11 downto 9) = "010") else
|
||||
mem_data_event2 when (mem_addr(11 downto 9) = "011") else
|
||||
mem_data_event3 when (mem_addr(11 downto 9) = "100") else
|
||||
o_mem_data <= mem_data_dpram when (mem_addr_dly(11 downto 9) = "000") else
|
||||
mem_data_event0 when (mem_addr_dly(11 downto 9) = "001") else
|
||||
mem_data_event1 when (mem_addr_dly(11 downto 9) = "010") else
|
||||
mem_data_event2 when (mem_addr_dly(11 downto 9) = "011") else
|
||||
mem_data_event3 when (mem_addr_dly(11 downto 9) = "100") else
|
||||
mem_data_event_recorder;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -826,7 +863,71 @@ begin
|
||||
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);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Raw Event Output
|
||||
-----------------------------------------------------------------------------
|
||||
raw_event_output_proc : process(i_mgt_rx_clk)
|
||||
begin
|
||||
if (rising_edge(i_mgt_rx_clk)) then
|
||||
o_event_valid <= '0';
|
||||
o_event <= (others=>'0');
|
||||
|
||||
if ((i_mgt_rx_charisk(0) = '0') and (evr_stable = '1')) then
|
||||
o_event_valid <= '1';
|
||||
o_event <= i_mgt_rx_data(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
-- EVENT RECORDER
|
||||
@@ -906,7 +1007,7 @@ begin
|
||||
end if;
|
||||
|
||||
-- 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;
|
||||
@@ -923,7 +1024,7 @@ begin
|
||||
timestamp_cnt_dly <= timestamp_cnt;
|
||||
usr_events_save_dly <= usr_events_save;
|
||||
usr_events_nr_dly <= usr_events_nr;
|
||||
usr_events_addr_dly <= usr_events_addr;
|
||||
usr_events_addr_dly <= std_logic_vector(usr_events_addr);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -970,11 +1071,11 @@ begin
|
||||
--------------------------------------------------------------------------
|
||||
-- Memory Selector Event Recorder
|
||||
--------------------------------------------------------------------------
|
||||
mem_data_event_recorder <= mem_data_dpram_sos when (mem_addr(11 downto 9) = B"101") else -- 2K
|
||||
mem_data_event_nr_timestamp when (mem_addr(11 downto 8) = B"1100") else -- 1K
|
||||
mem_data_segment_timestamp when (mem_addr(11 downto 7) = B"1101_0") else -- 512B
|
||||
mem_data_event_nr when (mem_addr(11 downto 6) = B"1101_10") else -- 256B
|
||||
mem_data_event_flag when (mem_addr(11 downto 6) = B"1101_11") else -- 256B
|
||||
mem_data_event_recorder <= mem_data_dpram_sos when (mem_addr_dly(11 downto 9) = B"101") else -- 2K
|
||||
mem_data_event_nr_timestamp when (mem_addr_dly(11 downto 8) = B"1100") else -- 1K
|
||||
mem_data_segment_timestamp when (mem_addr_dly(11 downto 7) = B"1101_0") else -- 512B
|
||||
mem_data_event_nr when (mem_addr_dly(11 downto 6) = B"1101_10") else -- 256B
|
||||
mem_data_event_flag when (mem_addr_dly(11 downto 6) = B"1101_11") else -- 256B
|
||||
(others => '0');
|
||||
|
||||
|
||||
@@ -1021,8 +1122,8 @@ begin
|
||||
clka => i_mgt_rx_clk,
|
||||
ena => HIGH,
|
||||
wea => segment_addr_wren,
|
||||
addra => frame_data_wr_addr_cnt(10 downto 4),
|
||||
dia => timestamp_cnt,
|
||||
addra => std_logic_vector(frame_data_wr_addr_cnt(10 downto 4)),
|
||||
dia => std_logic_vector(timestamp_cnt),
|
||||
page => sos_event(3),
|
||||
-- port b
|
||||
clkb => i_usr_clk,
|
||||
@@ -1047,7 +1148,7 @@ begin
|
||||
ena => HIGH,
|
||||
wea => usr_events_save_dly,
|
||||
addra => usr_events_addr_dly,
|
||||
dia => timestamp_cnt_dly,
|
||||
dia => std_logic_vector(timestamp_cnt_dly),
|
||||
page => sos_event(3),
|
||||
-- port b
|
||||
clkb => i_usr_clk,
|
||||
@@ -1081,7 +1182,6 @@ begin
|
||||
dob => mem_data_event_nr
|
||||
);
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Event Flags of all Events
|
||||
--------------------------------------------------------------------------
|
||||
@@ -1094,7 +1194,7 @@ begin
|
||||
all_events_flags_sync2 <= all_events_flags_sync1;
|
||||
|
||||
-- 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 := to_integer(unsigned(std_logic_vector'(mem_addr(5 downto MEM_ADDR_LSB) & LOW_slv(1 + MEM_ADDR_LSB downto 0))));
|
||||
mem_data_event_flag <= bit2byte(all_events_flags_sync2(v_addr + MEM_DATA_BYTES - 1 downto v_addr));
|
||||
end if;
|
||||
end process;
|
||||
@@ -1104,7 +1204,7 @@ begin
|
||||
-- port mapping
|
||||
--------------------------------------------------------------------------
|
||||
o_sos_event <= sos_event(3);
|
||||
o_event_recorder_stat.usr_events_counter <= usr_events_cnt_d;
|
||||
o_event_recorder_stat.usr_events_counter <= std_logic_vector(usr_events_cnt_d);
|
||||
o_event_recorder_stat.data_valid <= mem_data_valid;
|
||||
o_event_recorder_stat.data_error <= mem_data_error;
|
||||
|
||||
@@ -1127,4 +1227,4 @@ end behavioral;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- End of file
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
--------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity evr320_dpram is
|
||||
@@ -59,7 +59,7 @@ begin
|
||||
if rising_edge(clka) then
|
||||
if (ena = '1') then
|
||||
if (wea = '1') then
|
||||
RAM(conv_integer(addra)) := dia;
|
||||
RAM(to_integer(unsigned(addra))) := dia;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -69,10 +69,10 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM(conv_integer(addrb & "00"));
|
||||
dob(15 downto 8) <= RAM(conv_integer(addrb & "01"));
|
||||
dob(23 downto 16) <= RAM(conv_integer(addrb & "10"));
|
||||
dob(31 downto 24) <= RAM(conv_integer(addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM(to_integer(unsigned(std_logic_vector'(addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM(to_integer(unsigned(std_logic_vector'(addrb & "01"))));
|
||||
dob(23 downto 16) <= RAM(to_integer(unsigned(std_logic_vector'(addrb & "10"))));
|
||||
dob(31 downto 24) <= RAM(to_integer(unsigned(std_logic_vector'(addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -87,9 +87,9 @@ begin
|
||||
if (ena = '1') then
|
||||
if (wea = '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
|
||||
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;
|
||||
@@ -100,14 +100,14 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM_EVEN(conv_integer(addrb & "00"));
|
||||
dob(15 downto 8) <= RAM_ODD (conv_integer(addrb & "00"));
|
||||
dob(23 downto 16) <= RAM_EVEN(conv_integer(addrb & "01"));
|
||||
dob(31 downto 24) <= RAM_ODD (conv_integer(addrb & "01"));
|
||||
dob(39 downto 32) <= RAM_EVEN(conv_integer(addrb & "10"));
|
||||
dob(47 downto 40) <= RAM_ODD (conv_integer(addrb & "10"));
|
||||
dob(55 downto 48) <= RAM_EVEN(conv_integer(addrb & "11"));
|
||||
dob(63 downto 56) <= RAM_ODD (conv_integer(addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(addrb & "00"))));
|
||||
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(addrb & "01"))));
|
||||
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(addrb & "01"))));
|
||||
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(addrb & "10"))));
|
||||
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(addrb & "10"))));
|
||||
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(addrb & "11"))));
|
||||
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -2,283 +2,399 @@
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Unit : evr320_ifc1210_wrapper.vhd
|
||||
-- Author : Patric Bucher
|
||||
-- Author : Patric Bucher, Benoit Stef
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Copyright© PSI, Section DSV
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Comment :
|
||||
-- Comment : Wraps evr320 decoder together with GTX component and TMEM registers.
|
||||
-- ---------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
use work.tosca2_glb_pkg.all;
|
||||
use work.evr320_pkg.all;
|
||||
use work.pkg_v6vlx_gtxe1.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";
|
||||
g_REFCLK_MHZ : real := 142.8;
|
||||
g_USE_MMCM : boolean := false;
|
||||
g_EVENT_RECORDER : boolean := false
|
||||
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(
|
||||
tick1sec_i : in std_logic;
|
||||
-- ------------------------------------------------------------------------
|
||||
-- Debug interface
|
||||
-- ------------------------------------------------------------------------
|
||||
debug_clk : out std_logic;
|
||||
debug : out std_logic_vector(127 downto 0);
|
||||
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);
|
||||
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_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
|
||||
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
|
||||
sos_event_o : out std_logic -- Start-of-Sequence Event
|
||||
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_BYTE : integer := 8;
|
||||
constant c_TOSCA2_DATA_WIDTH : integer := 64;
|
||||
-- constant c_EVR_REG64_COUNT : integer := 16;
|
||||
-- constant c_EVR_MEM_SIZE : integer := 16384;
|
||||
-- constant c_EVR_ADDR_WIDTH : integer := integer(ceil(log2(real(c_EVR_MEM_SIZE/(c_TOSCA2_DATA_WIDTH/c_BYTE)))));
|
||||
|
||||
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_control_sync : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal mgt_control_sync2 : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal mgt_sfp_los : std_logic := '0';
|
||||
signal mgt_sfp_los_sync : std_logic := '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 mgt_reset_tmem_evr_sync1 : std_logic := '0';
|
||||
signal mgt_reset_tmem_evr_sync2 : std_logic := '0';
|
||||
|
||||
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 event_recorder_status : typ_evt_rec_status;
|
||||
signal event_recorder_control : 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 debug_data : std_logic_vector(127 downto 0);
|
||||
|
||||
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";
|
||||
|
||||
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- //////////////////// Main Body /////////////////////////
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------------------
|
||||
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 <= mgt_status(15);
|
||||
mem_addr_evr <= '0' & mem_addr_tosca;
|
||||
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);
|
||||
|
||||
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
|
||||
-- ---
|
||||
-- -- mgt_sfp_los_sync <= mgt_sfp_los_i;
|
||||
-- -- mgt_sfp_los <= mgt_sfp_los_sync;
|
||||
-- ---
|
||||
-- -- mgt_control_sync <= mgt_control_i;
|
||||
-- -- mgt_control_sync2 <= mgt_control_sync;
|
||||
-- ---
|
||||
-- -- mgt_reset_tmem_evr_sync1 <= mgt_reset_tmem_evr;
|
||||
-- -- mgt_reset_tmem_evr_sync2 <= mgt_reset_tmem_evr_sync1;
|
||||
-- ---
|
||||
-- -- evr_params and event_recorder_control add sync here or in evr320_decoder
|
||||
-- ---
|
||||
-- -- mgt_control(c_GTXRESET) <= mgt_control_sync2(c_GTXRESET);
|
||||
-- -- -- mgt_control(c_GTXRESET) <= mgt_control_sync2(c_GTXRESET) or mgt_sfp_los or mgt_reset_tmem_evr_sync2;
|
||||
-- -- mgt_control( 4 downto 1) <= mgt_control_sync2( 4 downto 1);
|
||||
-- -- mgt_control(c_RXCDRRESET) <= mgt_control_sync2(c_RXCDRRESET);
|
||||
-- -- mgt_control(31 downto 6) <= mgt_control_sync2(31 downto 6);
|
||||
-- ---
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
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
|
||||
evr320_decoder_inst : entity work.evr320_decoder
|
||||
generic map(
|
||||
EVENT_RECORDER => g_EVENT_RECORDER,
|
||||
MEM_DATA_WIDTH => c_TOSCA2_DATA_WIDTH )
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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_o,
|
||||
o_usr_events_ext => usr_events_ext_o,
|
||||
o_sos_event => sos_event_o
|
||||
);
|
||||
|
||||
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
|
||||
mgt_wrapper_inst : entity work.v6vlx_gtxe1_wrapper
|
||||
generic map(
|
||||
g_MGT_LOCATION => g_MGT_LOCATION,
|
||||
g_USE_MMCM => g_USE_MMCM )
|
||||
port 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,
|
||||
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
|
||||
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
|
||||
-- --------------------------------------------------------------------------
|
||||
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,
|
||||
evr_frequency_i => evr_frequency,
|
||||
evr_evt_rec_status_i => event_recorder_status,
|
||||
evr_evt_rec_control_o => event_recorder_control,
|
||||
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
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
--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)
|
||||
-- --------------------------------------------------------------------------
|
||||
prc_count_cycles: process(clk_evr)
|
||||
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
|
||||
if rising_edge(clk_evr) then
|
||||
if (evr_counter_rst(2 downto 1) = "01") then
|
||||
evr_frequency <= evr_clk_counter;
|
||||
evr_clk_counter <= (others => '0');
|
||||
else
|
||||
evr_clk_counter <= evr_clk_counter + X"0000_0001";
|
||||
|
||||
-- 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;
|
||||
-- sync reset and detect edge
|
||||
evr_counter_rst <= evr_counter_rst(1 downto 0) & tick1sec_i;
|
||||
end if;
|
||||
end process;
|
||||
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;
|
||||
clk_evr_o <= clk_evr;
|
||||
mgt_status_o <= mgt_status;
|
||||
debug <= debug_data;
|
||||
|
||||
|
||||
|
||||
end rtl;
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ////////////////////////////////////////////////////////////////////////////
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
--------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use work.psi_common_math_pkg.all;
|
||||
|
||||
package evr320_pkg is
|
||||
|
||||
@@ -22,7 +23,7 @@ package evr320_pkg is
|
||||
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
|
||||
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- Type Definitions
|
||||
-- --------------------------------------------------------------------------
|
||||
@@ -52,6 +53,20 @@ package evr320_pkg is
|
||||
error_ack : std_logic;
|
||||
end record typ_evt_rec_ctrl;
|
||||
|
||||
type typ_rec_latency_measure_ctrl is record
|
||||
event_nr : std_logic_vector(7 downto 0);
|
||||
counter_arm : std_logic;
|
||||
end record;
|
||||
|
||||
type typ_rec_latency_measure_stat is record
|
||||
counter_val : std_logic_vector(31 downto 0);
|
||||
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
|
||||
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
|
||||
@@ -60,7 +75,14 @@ package evr320_pkg is
|
||||
data_error => '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');
|
||||
|
||||
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'));
|
||||
-- --------------------------------------------------------------------------
|
||||
-- Function Prototypes
|
||||
-- --------------------------------------------------------------------------
|
||||
@@ -95,4 +117,4 @@ package body evr320_pkg is
|
||||
end package body evr320_pkg;
|
||||
--------------------------------------------------------------------------------
|
||||
-- End of file
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
--------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
|
||||
@@ -95,10 +95,10 @@ begin
|
||||
if rising_edge(clka) then
|
||||
if (ena = '1') then
|
||||
if (wea = '1') then
|
||||
RAM(conv_integer(page_addr_clka & addra & "00")) := dia( 7 downto 0);
|
||||
RAM(conv_integer(page_addr_clka & addra & "01")) := dia(15 downto 8);
|
||||
RAM(conv_integer(page_addr_clka & addra & "10")) := dia(23 downto 16);
|
||||
RAM(conv_integer(page_addr_clka & addra & "11")) := dia(31 downto 24);
|
||||
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & "00")))) := dia( 7 downto 0);
|
||||
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & "01")))) := dia(15 downto 8);
|
||||
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & "10")))) := dia(23 downto 16);
|
||||
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & "11")))) := dia(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -108,10 +108,10 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(15 downto 8) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(23 downto 16) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(31 downto 24) <= RAM(conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(23 downto 16) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(31 downto 24) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -125,10 +125,10 @@ begin
|
||||
if rising_edge(clka) then
|
||||
if (ena = '1') then
|
||||
if (wea = '1') then
|
||||
RAM_EVEN(conv_integer(page_addr_clka & addra & '0')) := dia( 7 downto 0);
|
||||
RAM_ODD (conv_integer(page_addr_clka & addra & '0')) := dia(15 downto 8);
|
||||
RAM_EVEN(conv_integer(page_addr_clka & addra & '1')) := dia(23 downto 16);
|
||||
RAM_ODD (conv_integer(page_addr_clka & addra & '1')) := dia(31 downto 24);
|
||||
RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & '0')))) := dia( 7 downto 0);
|
||||
RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & '0')))) := dia(15 downto 8);
|
||||
RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & '1')))) := dia(23 downto 16);
|
||||
RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clka & addra & '1')))) := dia(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -138,14 +138,14 @@ begin
|
||||
begin
|
||||
if rising_edge(clkb) then
|
||||
if (enb = '1') then
|
||||
dob( 7 downto 0) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(15 downto 8) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "00"));
|
||||
dob(23 downto 16) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(31 downto 24) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "01"));
|
||||
dob(39 downto 32) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(47 downto 40) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "10"));
|
||||
dob(55 downto 48) <= RAM_EVEN(conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob(63 downto 56) <= RAM_ODD (conv_integer(page_addr_clkb( 3) & addrb & "11"));
|
||||
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
|
||||
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
|
||||
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
|
||||
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Unit : evr320_tmem.vhd
|
||||
-- Author : Patric Bucher
|
||||
-- Author : Patric Bucher, Benoit Stef
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Copyright© PSI, Section DSV
|
||||
-- Copyright (c) PSI, Section DSV
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Comment :
|
||||
-- Comment : TMEM address decoding for register and memory access to evr320.
|
||||
-- ---------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
use work.tosca2_glb_pkg.all;
|
||||
use work.evr320_pkg.all;
|
||||
library tosca2;
|
||||
use tosca2.tosca2_glb_pkg.all;
|
||||
|
||||
use work.evr320_pkg.all;
|
||||
|
||||
entity evr320_tmem is
|
||||
port(
|
||||
@@ -37,11 +37,20 @@ entity evr320_tmem is
|
||||
evr_frequency_i : in std_logic_vector(31 downto 0);
|
||||
evr_evt_rec_status_i : in typ_evt_rec_status;
|
||||
evr_evt_rec_control_o : out typ_evt_rec_ctrl;
|
||||
evr_latency_measure_stat_i : in typ_rec_latency_measure_stat;
|
||||
evr_latency_measure_ctrl_o : out typ_rec_latency_measure_ctrl;
|
||||
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)
|
||||
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;
|
||||
|
||||
@@ -52,6 +61,7 @@ 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;
|
||||
@@ -91,11 +101,19 @@ architecture rtl of evr320_tmem is
|
||||
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')));
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------------------
|
||||
@@ -110,9 +128,10 @@ begin
|
||||
event_numbers_concat <= event_numbers(3) & event_numbers(2) & event_numbers(1) & event_numbers(0);
|
||||
er_handshake_status <= X"0000" & bit2byte(er_status.data_error) & bit2byte(er_status.data_valid);
|
||||
er_control_concat <= X"0000" & er_event_number & bit2byte(er_event_enable);
|
||||
|
||||
lat_counter_val <= evr_latency_measure_stat_i.counter_val;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- TODO: proper CDC
|
||||
-- Synchronisation to xuser_CLK
|
||||
-- --------------------------------------------------------------------------
|
||||
prc_sync_xuser: process (xuser_CLK)
|
||||
@@ -136,26 +155,29 @@ begin
|
||||
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) = 0) 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 <= reserved(63 downto 0); -- 64bit / ByteAddr 030
|
||||
when X"7" => xuser_TMEM_DATR <= reserved(63 downto 0); -- 64bit / ByteAddr 038
|
||||
when X"8" => xuser_TMEM_DATR <= er_handshake_status & er_control_concat; -- 64bit / ByteAddr 040
|
||||
when X"9" => xuser_TMEM_DATR <= reserved(63 downto 32) & er_status.usr_events_counter; -- 64bit / ByteAddr 048
|
||||
when X"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
|
||||
@@ -178,7 +200,7 @@ begin
|
||||
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 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;
|
||||
@@ -224,6 +246,17 @@ begin
|
||||
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;
|
||||
@@ -235,6 +268,24 @@ begin
|
||||
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;
|
||||
@@ -243,15 +294,110 @@ begin
|
||||
-- --------------------------------------------------------------------------
|
||||
-- Port mapping
|
||||
-- --------------------------------------------------------------------------
|
||||
mem_clk_o <= xuser_CLK;
|
||||
mem_addr_o <= xuser_TMEM_ADD - MEM_ADDR_START;
|
||||
evr_params_o <= (event_numbers, event_enable, cs_min_cnt, cs_min_time);
|
||||
evr_evt_rec_control_o <= (er_event_number, er_event_enable, er_data_ack(3), er_error_ack(3));
|
||||
mgt_reset_o <= mgt_reset;
|
||||
|
||||
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;
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ////////////////////////////////////////////////////////////////////////////
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
494
hdl/v6vlx_gtxe1_101MHz27_1Gbps0127.vhd
Normal file
494
hdl/v6vlx_gtxe1_101MHz27_1Gbps0127.vhd
Normal file
@@ -0,0 +1,494 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
------------------------------------------------------------------------------
|
||||
-- Unit : v6vlx_gtxe1_101MHz27_1Gbps0127.vhd
|
||||
-- Author : Goran Marinkovic, Section Diagnostic
|
||||
-- : Waldemar Koprek, Section Diagnostic
|
||||
-- : Patric Bucher, Section DSV
|
||||
-- Version : $Revision: 1.1 $
|
||||
------------------------------------------------------------------------------
|
||||
-- Copyright<68> PSI, Section Diagnostic
|
||||
------------------------------------------------------------------------------
|
||||
-- Comment : Virtex-6 GTXE1 primitive configured for HIPA 50.63282 MHz
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
use work.v6vlx_gtxe1_pkg.all;
|
||||
|
||||
entity v6vlx_gtxe1_101MHz27_1Gbps0127 is
|
||||
generic(
|
||||
g_MGT_LOCATION : string
|
||||
);
|
||||
port (
|
||||
i_mgt : in gtxe_in_type;
|
||||
o_mgt : out gtxe_out_type
|
||||
);
|
||||
end v6vlx_gtxe1_101MHz27_1Gbps0127;
|
||||
|
||||
|
||||
architecture RTL of v6vlx_gtxe1_101MHz27_1Gbps0127 is
|
||||
|
||||
--**************************** Signal Declarations ****************************
|
||||
|
||||
-- ground and tied_to_vcc_i signals
|
||||
signal tied_to_ground_i : std_logic;
|
||||
signal tied_to_ground_vec_i : std_logic_vector(63 downto 0);
|
||||
signal tied_to_vcc_i : std_logic;
|
||||
|
||||
--***************************** Main Body of Code *****************************
|
||||
signal slv_mgtrefclk : std_logic_vector(1 downto 0);
|
||||
signal debug_refclk : std_logic_vector(1 downto 0);
|
||||
|
||||
--************************** Attribute Declarations ***************************
|
||||
attribute LOC : string;
|
||||
attribute LOC of gtxe1_i : label is g_MGT_LOCATION;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
--------------------------- Static signal Assignments ---------------------
|
||||
|
||||
tied_to_ground_i <= '0';
|
||||
tied_to_ground_vec_i(63 downto 0) <= (others => '0');
|
||||
tied_to_vcc_i <= '1';
|
||||
|
||||
slv_mgtrefclk <= "0" & i_mgt.ctrl.CLKIN;
|
||||
|
||||
o_mgt.ctrl.REFCLKOUT <= debug_refclk(1);
|
||||
|
||||
|
||||
--------------------------------- GTX Instance -----------------------------
|
||||
|
||||
gtxe1_i :GTXE1
|
||||
generic map (
|
||||
--_______________________ Simulation-Only Attributes ___________________
|
||||
SIM_RECEIVER_DETECT_PASS => (TRUE),
|
||||
SIM_GTXRESET_SPEEDUP => (1), --(GTX_SIM_GTXRESET_SPEEDUP),
|
||||
SIM_TX_ELEC_IDLE_LEVEL => ("X"),
|
||||
SIM_VERSION => ("2.0"),
|
||||
SIM_TXREFCLK_SOURCE => ("000"),
|
||||
SIM_RXREFCLK_SOURCE => ("000"),
|
||||
----------------------------TX PLL----------------------------
|
||||
TX_CLK_SOURCE => "RXPLL", --
|
||||
TX_OVERSAMPLE_MODE => FALSE, --
|
||||
TXPLL_COM_CFG => X"21680A", --
|
||||
TXPLL_CP_CFG => X"0D", --
|
||||
TXPLL_DIVSEL_FB => 4, -- 1.2GHz < Fpll < 2.7GHz
|
||||
TXPLL_DIVSEL_OUT => 4, --
|
||||
TXPLL_DIVSEL_REF => 1, -- RXPLL_DIVSEL_FB * RXPLL_DIVSEL45_FB
|
||||
TXPLL_DIVSEL45_FB => 5, -- Fpll = Fclkin -----------------------------------
|
||||
TXPLL_LKDET_CFG => "111", -- RXPLL_DIVSEL_REF
|
||||
TX_CLK25_DIVIDER => 4, --
|
||||
TXPLL_SATA => "00", -- Fpll * 2
|
||||
TX_TDCC_CFG => "00", -- Flinerate = ------------------
|
||||
PMA_CAS_CLK_EN => FALSE, -- RXPLL_DIVSEL_OUT(FALSE)
|
||||
POWER_SAVE => "0000110100", -- [4] '1' = bypass trasmit delay aligner, [5] '1' = bypass receive delay aligner
|
||||
|
||||
-------------------------TX Interface-------------------------
|
||||
GEN_TXUSRCLK => (TRUE), --
|
||||
TX_DATA_WIDTH => (20), --
|
||||
TX_USRCLK_CFG => (X"00"), --
|
||||
TXOUTCLK_CTRL => ("TXOUTCLKPMA_DIV2"), --
|
||||
TXOUTCLK_DLY => ("0000000000"), --
|
||||
|
||||
--------------TX Buffering and Phase Alignment----------------
|
||||
TX_PMADATA_OPT => ('0'), --
|
||||
PMA_TX_CFG => (x"80082"), --
|
||||
TX_BUFFER_USE => (TRUE), --
|
||||
TX_BYTECLK_CFG => (x"00"), --
|
||||
TX_EN_RATE_RESET_BUF => (TRUE), --
|
||||
TX_XCLK_SEL => ("TXOUT"), --
|
||||
TX_DLYALIGN_CTRINC => ("0100"), --
|
||||
TX_DLYALIGN_LPFINC => ("0110"), --
|
||||
TX_DLYALIGN_MONSEL => ("000"), --
|
||||
TX_DLYALIGN_OVRDSETTING => ("10000000"), --
|
||||
|
||||
-------------------------TX Gearbox--------------------------- --
|
||||
GEARBOX_ENDEC => ("000"), --
|
||||
TXGEARBOX_USE => (FALSE), --
|
||||
--
|
||||
----------------TX Driver and OOB Signalling------------------ --
|
||||
TX_DRIVE_MODE => ("DIRECT"), --
|
||||
TX_IDLE_ASSERT_DELAY => ("100"), --
|
||||
TX_IDLE_DEASSERT_DELAY => ("010"), --
|
||||
TXDRIVE_LOOPBACK_HIZ => (FALSE), --
|
||||
TXDRIVE_LOOPBACK_PD => (FALSE), --
|
||||
--
|
||||
--------------TX Pipe Control for PCI Express/SATA------------ --
|
||||
COM_BURST_VAL => ("1111"), --
|
||||
--
|
||||
------------------TX Attributes for PCI Express--------------- --
|
||||
TX_DEEMPH_0 => ("11010"), --
|
||||
TX_DEEMPH_1 => ("10000"), --
|
||||
TX_MARGIN_FULL_0 => ("1001110"), --
|
||||
TX_MARGIN_FULL_1 => ("1001001"), --
|
||||
TX_MARGIN_FULL_2 => ("1000101"), --
|
||||
TX_MARGIN_FULL_3 => ("1000010"), --
|
||||
TX_MARGIN_FULL_4 => ("1000000"), --
|
||||
TX_MARGIN_LOW_0 => ("1000110"), --
|
||||
TX_MARGIN_LOW_1 => ("1000100"), --
|
||||
TX_MARGIN_LOW_2 => ("1000010"), --
|
||||
TX_MARGIN_LOW_3 => ("1000000"), --
|
||||
TX_MARGIN_LOW_4 => ("1000000"), --
|
||||
|
||||
----------------------------RX PLL----------------------------
|
||||
RX_OVERSAMPLE_MODE => FALSE, -- 1.2GHz < Fpll < 2.7GHz
|
||||
RXPLL_COM_CFG => (x"21680a"), --
|
||||
RXPLL_CP_CFG => (x"0D"), -- RXPLL_DIVSEL_FB * RXPLL_DIVSEL45_FB
|
||||
RXPLL_DIVSEL_FB => 4, -- Fpll = Fclkin -----------------------------------
|
||||
RXPLL_DIVSEL_OUT => 4, -- RXPLL_DIVSEL_REF
|
||||
RXPLL_DIVSEL_REF => 1, --
|
||||
RXPLL_DIVSEL45_FB => 5, -- Fpll * 2
|
||||
RXPLL_LKDET_CFG => ("111"), -- Flinerate = ------------------
|
||||
RX_CLK25_DIVIDER => 4, -- RXPLL_DIVSEL_OUT
|
||||
|
||||
-------------------------RX Interface-------------------------
|
||||
GEN_RXUSRCLK => (TRUE), --
|
||||
RX_DATA_WIDTH => (20), --
|
||||
RXRECCLK_CTRL => ("RXRECCLKPMA_DIV2"), --
|
||||
RXRECCLK_DLY => ("0000000000"), --
|
||||
RXUSRCLK_DLY => (x"0000"), --
|
||||
|
||||
----------RX Driver,OOB signalling,Coupling and Eq.,CDR-------
|
||||
AC_CAP_DIS => (FALSE), --
|
||||
CDR_PH_ADJ_TIME => ("10100"), --
|
||||
OOBDETECT_THRESHOLD => ("011"), --
|
||||
PMA_CDR_SCAN => (x"640404C"), --
|
||||
PMA_RX_CFG => (x"05ce008"), --
|
||||
RCV_TERM_GND => (FALSE), --
|
||||
RCV_TERM_VTTRX => (TRUE), --
|
||||
RX_EN_IDLE_HOLD_CDR => (FALSE), --
|
||||
RX_EN_IDLE_RESET_FR => (FALSE), --
|
||||
RX_EN_IDLE_RESET_PH => (FALSE), --
|
||||
TX_DETECT_RX_CFG => (x"1832"), --
|
||||
TERMINATION_CTRL => ("00000"), --
|
||||
TERMINATION_OVRD => (FALSE), --
|
||||
CM_TRIM => ("01"), --
|
||||
PMA_RXSYNC_CFG => (x"00"), --
|
||||
PMA_CFG => (x"0040000040000000003"), --
|
||||
BGTEST_CFG => ("00"), --
|
||||
BIAS_CFG => (x"00000"), --
|
||||
|
||||
--------------RX Decision Feedback Equalizer(DFE)-------------
|
||||
DFE_CAL_TIME => ("01100"), --
|
||||
DFE_CFG => ("00011011"), --
|
||||
RX_EN_IDLE_HOLD_DFE => (TRUE), --
|
||||
RX_EYE_OFFSET => (x"4C"), --
|
||||
RX_EYE_SCANMODE => ("00"), --
|
||||
|
||||
-------------------------PRBS Detection-----------------------
|
||||
RXPRBSERR_LOOPBACK => ('0'), --
|
||||
|
||||
------------------Comma Detection and Alignment---------------
|
||||
ALIGN_COMMA_WORD => (2), --(1),
|
||||
COMMA_10B_ENABLE => ("1111111111"), --
|
||||
COMMA_DOUBLE => (FALSE), --
|
||||
DEC_MCOMMA_DETECT => (TRUE), --(FALSE),
|
||||
DEC_PCOMMA_DETECT => (TRUE), --(FALSE),
|
||||
DEC_VALID_COMMA_ONLY => (FALSE), --
|
||||
MCOMMA_10B_VALUE => ("1010000011"), --
|
||||
MCOMMA_DETECT => (TRUE), --
|
||||
PCOMMA_10B_VALUE => ("0101111100"), --
|
||||
PCOMMA_DETECT => (TRUE), --
|
||||
RX_DECODE_SEQ_MATCH => (FALSE), --
|
||||
RX_SLIDE_AUTO_WAIT => (5), --
|
||||
RX_SLIDE_MODE => ("PMA"), --
|
||||
SHOW_REALIGN_COMMA => (FALSE), --
|
||||
|
||||
-----------------RX Loss-of-sync State Machine----------------
|
||||
RX_LOS_INVALID_INCR => (8), --
|
||||
RX_LOS_THRESHOLD => (128), --
|
||||
RX_LOSS_OF_SYNC_FSM => (TRUE), --(FALSE),
|
||||
|
||||
-------------------------RX Gearbox---------------------------
|
||||
RXGEARBOX_USE => (FALSE), --
|
||||
|
||||
-------------RX Elastic Buffer and Phase alignment------------
|
||||
RX_BUFFER_USE => (FALSE), --
|
||||
RX_EN_IDLE_RESET_BUF => (FALSE), --
|
||||
RX_EN_MODE_RESET_BUF => (TRUE), --
|
||||
RX_EN_RATE_RESET_BUF => (TRUE), --
|
||||
RX_EN_REALIGN_RESET_BUF => (FALSE), --
|
||||
RX_EN_REALIGN_RESET_BUF2 => (FALSE), --
|
||||
RX_FIFO_ADDR_MODE => ("FAST"), --
|
||||
RX_IDLE_HI_CNT => ("1000"), --
|
||||
RX_IDLE_LO_CNT => ("0000"), --
|
||||
RX_XCLK_SEL => ("RXUSR"), --
|
||||
RX_DLYALIGN_CTRINC => ("1110"), --
|
||||
RX_DLYALIGN_EDGESET => ("00010"), --
|
||||
RX_DLYALIGN_LPFINC => ("1110"), --
|
||||
RX_DLYALIGN_MONSEL => ("000"), --
|
||||
RX_DLYALIGN_OVRDSETTING => ("10000000"), --
|
||||
|
||||
------------------------Clock Correction---------------------- --
|
||||
CLK_COR_ADJ_LEN => (1), --
|
||||
CLK_COR_DET_LEN => (1), --
|
||||
CLK_COR_INSERT_IDLE_FLAG => (FALSE), --
|
||||
CLK_COR_KEEP_IDLE => (FALSE), --
|
||||
CLK_COR_MAX_LAT => (16), --
|
||||
CLK_COR_MIN_LAT => (14), --
|
||||
CLK_COR_PRECEDENCE => (TRUE), --
|
||||
CLK_COR_REPEAT_WAIT => (0), --
|
||||
CLK_COR_SEQ_1_1 => ("0000000000"), --
|
||||
CLK_COR_SEQ_1_2 => ("0000000000"), --
|
||||
CLK_COR_SEQ_1_3 => ("0000000000"), --
|
||||
CLK_COR_SEQ_1_4 => ("0000000000"), --
|
||||
CLK_COR_SEQ_1_ENABLE => ("1111"), --
|
||||
CLK_COR_SEQ_2_1 => ("0000000000"), --
|
||||
CLK_COR_SEQ_2_2 => ("0000000000"), --
|
||||
CLK_COR_SEQ_2_3 => ("0000000000"), --
|
||||
CLK_COR_SEQ_2_4 => ("0000000000"), --
|
||||
CLK_COR_SEQ_2_ENABLE => ("1111"), --
|
||||
CLK_COR_SEQ_2_USE => (FALSE), --
|
||||
CLK_CORRECT_USE => (FALSE), --
|
||||
--
|
||||
------------------------Channel Bonding---------------------- --
|
||||
CHAN_BOND_1_MAX_SKEW => (1), --
|
||||
CHAN_BOND_2_MAX_SKEW => (1), --
|
||||
CHAN_BOND_KEEP_ALIGN => (FALSE), --
|
||||
CHAN_BOND_SEQ_1_1 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_1_2 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_1_3 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_1_4 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_1_ENABLE => ("1111"), --
|
||||
CHAN_BOND_SEQ_2_1 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_2_2 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_2_3 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_2_4 => ("0000000000"), --
|
||||
CHAN_BOND_SEQ_2_CFG => ("00000"), --
|
||||
CHAN_BOND_SEQ_2_ENABLE => ("1111"), --
|
||||
CHAN_BOND_SEQ_2_USE => (FALSE), --
|
||||
CHAN_BOND_SEQ_LEN => (1), --
|
||||
PCI_EXPRESS_MODE => (FALSE), --
|
||||
--
|
||||
-------------RX Attributes for PCI Express/SATA/SAS---------- --
|
||||
SAS_MAX_COMSAS => (52), --
|
||||
SAS_MIN_COMSAS => (40), --
|
||||
SATA_BURST_VAL => ("100"), --
|
||||
SATA_IDLE_VAL => ("100"),
|
||||
SATA_MAX_BURST => (9),
|
||||
SATA_MAX_INIT => (27),
|
||||
SATA_MAX_WAKE => (9),
|
||||
SATA_MIN_BURST => (5),
|
||||
SATA_MIN_INIT => (15),
|
||||
SATA_MIN_WAKE => (5),
|
||||
TRANS_TIME_FROM_P2 => (x"03c"),
|
||||
TRANS_TIME_NON_P2 => (x"19"), --
|
||||
TRANS_TIME_RATE => (x"ff"), --
|
||||
TRANS_TIME_TO_P2 => (x"064") --
|
||||
)
|
||||
port map (
|
||||
------------------------ Loopback and Powerdown Ports ----------------------
|
||||
LOOPBACK => i_mgt.CTRL.LOOPBACK, --tied_to_ground_vec_i(2 downto 0),
|
||||
RXPOWERDOWN => "00", --
|
||||
TXPOWERDOWN => "00", --
|
||||
-------------- Receive Ports - 64b66b and 64b67b Gearbox Ports -------------
|
||||
RXDATAVALID => open, --
|
||||
RXGEARBOXSLIP => tied_to_ground_i, --
|
||||
RXHEADER => open, --
|
||||
RXHEADERVALID => open, --
|
||||
RXSTARTOFSEQ => open, --
|
||||
----------------------- Receive Ports - 8b10b Decoder ----------------------
|
||||
RXCHARISCOMMA => o_mgt.rx.RXCHARISCOMMA, --
|
||||
RXCHARISK => o_mgt.rx.RXCHARISK, --
|
||||
RXDEC8B10BUSE => '1', --tied_to_ground_i,
|
||||
RXDISPERR => o_mgt.rx.RXDISPERR, --rxdisperr_i,
|
||||
RXNOTINTABLE => o_mgt.rx.RXNOTINTABLE, --
|
||||
RXRUNDISP => o_mgt.rx.RXRUNDISP, --
|
||||
USRCODEERR => tied_to_ground_i, --
|
||||
------------------- Receive Ports - Channel Bonding Ports ------------------
|
||||
RXCHANBONDSEQ => open, --
|
||||
RXCHBONDI => tied_to_ground_vec_i(3 downto 0), --
|
||||
RXCHBONDLEVEL => tied_to_ground_vec_i(2 downto 0), --
|
||||
RXCHBONDMASTER => tied_to_ground_i, --
|
||||
RXCHBONDO => open, --
|
||||
RXCHBONDSLAVE => tied_to_ground_i, --
|
||||
RXENCHANSYNC => tied_to_ground_i, --
|
||||
------------------- Receive Ports - Clock Correction Ports -----------------
|
||||
RXCLKCORCNT => open, --
|
||||
--------------- Receive Ports - Comma Detection and Alignment --------------
|
||||
RXBYTEISALIGNED => o_mgt.rx.RXBYTEISALIGNED, --RXBYTEISALIGNED_OUT,
|
||||
RXBYTEREALIGN => o_mgt.rx.RXBYTEREALIGN, --RXBYTEREALIGN_OUT,
|
||||
RXCOMMADET => o_mgt.rx.RXCOMMADET, --RXCOMMADET_OUT,
|
||||
RXCOMMADETUSE => '1', --tied_to_vcc_i,
|
||||
RXENMCOMMAALIGN => i_mgt.rx.RXENMCOMMAALIGN, --tied_to_ground_i,
|
||||
RXENPCOMMAALIGN => i_mgt.rx.RXENPCOMMAALIGN, --tied_to_ground_i,
|
||||
RXSLIDE => i_mgt.rx.RXSLIDE,
|
||||
----------------------- Receive Ports - PRBS Detection ---------------------
|
||||
PRBSCNTRESET => tied_to_ground_i, --
|
||||
RXENPRBSTST => tied_to_ground_vec_i(2 downto 0), --
|
||||
RXPRBSERR => open, --
|
||||
------------------- Receive Ports - RX Data Path interface -----------------
|
||||
RXDATA => o_mgt.rx.RXDATA, --rxdata_i,
|
||||
RXRECCLK => o_mgt.rx.RXRECCLK, --RXRECCLK_OUT,
|
||||
RXRECCLKPCS => open,
|
||||
RXRESET => i_mgt.rx.RXRESET, --tied_to_ground_i,
|
||||
RXUSRCLK => i_mgt.rx.RXUSRCLK, --tied_to_ground_i,
|
||||
RXUSRCLK2 => i_mgt.rx.RXUSRCLK2, --RXUSRCLK2_IN,
|
||||
------------ Receive Ports - RX Decision Feedback Equalizer(DFE) -----------
|
||||
DFECLKDLYADJ => tied_to_ground_vec_i(5 downto 0), --
|
||||
DFECLKDLYADJMON => open, --
|
||||
DFEDLYOVRD => tied_to_ground_i, --
|
||||
DFEEYEDACMON => open, --
|
||||
DFESENSCAL => open, --
|
||||
DFETAP1 => tied_to_ground_vec_i(4 downto 0), --
|
||||
DFETAP1MONITOR => open, --
|
||||
DFETAP2 => tied_to_ground_vec_i(4 downto 0), --
|
||||
DFETAP2MONITOR => open, --
|
||||
DFETAP3 => tied_to_ground_vec_i(3 downto 0), --
|
||||
DFETAP3MONITOR => open, --
|
||||
DFETAP4 => tied_to_ground_vec_i(3 downto 0), --
|
||||
DFETAP4MONITOR => open, --
|
||||
DFETAPOVRD => tied_to_vcc_i, --
|
||||
------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------
|
||||
GATERXELECIDLE => tied_to_vcc_i, --
|
||||
IGNORESIGDET => tied_to_vcc_i, --
|
||||
RXCDRRESET => i_mgt.rx.RXCDRRESET, --
|
||||
RXELECIDLE => o_mgt.rx.RXELECIDLE, --open,
|
||||
RXEQMIX(9 downto 3) => tied_to_ground_vec_i(6 downto 0), --
|
||||
RXEQMIX(2 downto 0) => "000", --RXEQMIX_IN,
|
||||
RXN => i_mgt.rx.RXP, --RXN_IN,
|
||||
RXP => i_mgt.rx.RXN, --RXP_IN,
|
||||
-------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports -------
|
||||
RXBUFRESET => tied_to_ground_i, --
|
||||
RXBUFSTATUS => open, --
|
||||
RXCHANISALIGNED => open, --
|
||||
RXCHANREALIGN => open, --
|
||||
RXDLYALIGNDISABLE => i_mgt.rx.RXDLYALIGNDISABLE, --
|
||||
RXDLYALIGNMONENB => i_mgt.rx.RXDLYALIGNMONENB, --
|
||||
RXDLYALIGNMONITOR => o_mgt.rx.RXDLYALIGNMONITOR, --
|
||||
RXDLYALIGNOVERRIDE => i_mgt.rx.RXDLYALIGNOVERRIDE, --
|
||||
RXDLYALIGNRESET => i_mgt.rx.RXDLYALIGNRESET, --
|
||||
RXDLYALIGNSWPPRECURB => tied_to_vcc_i, --
|
||||
RXDLYALIGNUPDSW => tied_to_ground_i, --
|
||||
RXENPMAPHASEALIGN => i_mgt.rx.RXENPMAPHASEALIGN, --RXENPMAPHASEALIGN_IN,
|
||||
RXPMASETPHASE => i_mgt.rx.RXPMASETPHASE, --RXPMASETPHASE_IN,
|
||||
RXSTATUS => open,
|
||||
--------------- Receive Ports - RX Loss-of-sync State Machine --------------
|
||||
RXLOSSOFSYNC => o_mgt.rx.RXLOSSOFSYNC, --
|
||||
---------------------- Receive Ports - RX Oversampling ---------------------
|
||||
RXENSAMPLEALIGN => tied_to_ground_i, --
|
||||
RXOVERSAMPLEERR => open, --
|
||||
------------------------ Receive Ports - RX PLL Ports ----------------------
|
||||
GREFCLKRX => '0', --
|
||||
GTXRXRESET => i_mgt.ctrl.GTXRESET, --GTXRXRESET_IN,
|
||||
MGTREFCLKRX => slv_mgtrefclk, --MGTREFCLKRX_IN,
|
||||
NORTHREFCLKRX => "00", --
|
||||
PERFCLKRX => '0', --
|
||||
PLLRXRESET => i_mgt.ctrl.PLLRXRESET, --PLLRXRESET_IN,
|
||||
RXPLLLKDET => o_mgt.ctrl.RXPLLLKDET , --RXPLLLKDET_OUT,
|
||||
RXPLLLKDETEN => '1', --
|
||||
RXPLLPOWERDOWN => '0', --
|
||||
RXPLLREFSELDY => "000", --GREFCLKRX
|
||||
RXRATE => "00", --
|
||||
RXRATEDONE => open, --
|
||||
RXRESETDONE => o_mgt.ctrl.RXRESETDONE , --RXRESETDONE_OUT,
|
||||
SOUTHREFCLKRX => "00", --
|
||||
-------------- Receive Ports - RX Pipe Control for PCI Express ------------- --
|
||||
PHYSTATUS => open, --
|
||||
RXVALID => open, --
|
||||
----------------- Receive Ports - RX Polarity Control Ports ---------------- --
|
||||
RXPOLARITY => tied_to_ground_i, --
|
||||
--------------------- Receive Ports - RX Ports for SATA -------------------- --
|
||||
COMINITDET => open, --
|
||||
COMSASDET => open, --
|
||||
COMWAKEDET => open, --
|
||||
----------------------------------------------------------------------------
|
||||
------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ --
|
||||
----------------------------------------------------------------------------
|
||||
DADDR => tied_to_ground_vec_i(7 downto 0), --
|
||||
DCLK => tied_to_ground_i, --
|
||||
DEN => tied_to_ground_i, --
|
||||
DI => tied_to_ground_vec_i(15 downto 0), --
|
||||
DRDY => open, --
|
||||
DRPDO => open, --
|
||||
DWE => tied_to_ground_i, --
|
||||
----------------------------------------------------------------------------
|
||||
-------------- Transmit Ports - 64b66b and 64b67b Gearbox Ports ------------
|
||||
----------------------------------------------------------------------------
|
||||
TXGEARBOXREADY => open, --
|
||||
TXHEADER => tied_to_ground_vec_i(2 downto 0), --
|
||||
TXSEQUENCE => tied_to_ground_vec_i(6 downto 0), --
|
||||
TXSTARTSEQ => tied_to_ground_i, --
|
||||
---------------- Transmit Ports - 8b10b Encoder Control Ports --------------
|
||||
TXBYPASS8B10B => i_mgt.tx.TXBYPASS8B10B, --tied_to_ground_vec_i(3 downto 0),
|
||||
TXCHARDISPMODE => i_mgt.tx.TXCHARDISPMODE, --txchardispmode_i,
|
||||
TXCHARDISPVAL => i_mgt.tx.TXCHARDISPVAL , --txchardispval_i,
|
||||
TXCHARISK => i_mgt.tx.TXCHARISK , --tied_to_ground_vec_i(3 downto 0),
|
||||
TXENC8B10BUSE => '1', --tied_to_ground_i,
|
||||
TXKERR => o_mgt.tx.TXKERR , --open,
|
||||
TXRUNDISP => o_mgt.tx.TXRUNDISP, --open,
|
||||
------------------------- Transmit Ports - GTX Ports -----------------------
|
||||
GTXTEST => "1000000000000", --
|
||||
MGTREFCLKFAB => debug_refclk, --
|
||||
TSTCLK0 => tied_to_ground_i, --
|
||||
TSTCLK1 => tied_to_ground_i, --
|
||||
TSTIN => "11111111111111111111", --
|
||||
TSTOUT => open, --
|
||||
------------------ Transmit Ports - TX Data Path interface -----------------
|
||||
TXDATA => i_mgt.tx.TXDATA, --txdata_i,
|
||||
TXOUTCLK => o_mgt.tx.TXOUTCLK, --TXOUTCLK_OUT,
|
||||
TXOUTCLKPCS => open, --
|
||||
TXRESET => i_mgt.tx.TXRESET, --tied_to_ground_i,
|
||||
TXUSRCLK => i_mgt.tx.TXUSRCLK, --tied_to_ground_i,
|
||||
TXUSRCLK2 => i_mgt.tx.TXUSRCLK2, --TXUSRCLK2_IN,
|
||||
---------------- Transmit Ports - TX Driver and OOB signaling --------------
|
||||
TXBUFDIFFCTRL => "100", --
|
||||
TXDIFFCTRL => i_mgt.tx.TXDIFFCTRL, --TXDIFFCTRL_IN,
|
||||
TXINHIBIT => tied_to_ground_i, --
|
||||
TXN => o_mgt.tx.TXP, --TXN_OUT,
|
||||
TXP => o_mgt.tx.TXN, --TXP_OUT,
|
||||
TXPOSTEMPHASIS => i_mgt.tx.TXPOSTEMPHASIS, --TXPOSTEMPHASIS_IN,
|
||||
--------------- Transmit Ports - TX Driver and OOB signalling --------------
|
||||
TXPREEMPHASIS => i_mgt.tx.TXPREEMPHASIS, --TXPREEMPHASIS_IN,
|
||||
----------- Transmit Ports - TX Elastic Buffer and Phase Alignment ---------
|
||||
TXBUFSTATUS => open,
|
||||
-------- Transmit Ports - TX Elastic Buffer and Phase Alignment Ports ------
|
||||
TXDLYALIGNDISABLE => tied_to_vcc_i, --
|
||||
TXDLYALIGNMONENB => tied_to_ground_i, --
|
||||
TXDLYALIGNMONITOR => open, --
|
||||
TXDLYALIGNOVERRIDE => tied_to_ground_i, --
|
||||
TXDLYALIGNRESET => tied_to_ground_i, --
|
||||
TXDLYALIGNUPDSW => tied_to_vcc_i, --
|
||||
TXENPMAPHASEALIGN => tied_to_ground_i, --
|
||||
TXPMASETPHASE => tied_to_ground_i, --
|
||||
----------------------- Transmit Ports - TX PLL Ports ----------------------
|
||||
GREFCLKTX => '0', --
|
||||
GTXTXRESET => i_mgt.ctrl.GTXRESET, --GTXTXRESET_IN,
|
||||
MGTREFCLKTX => slv_mgtrefclk, --MGTREFCLKTX_IN,
|
||||
NORTHREFCLKTX => "00", --
|
||||
PERFCLKTX => '0', --
|
||||
PLLTXRESET => i_mgt.ctrl.PLLTXRESET, --PLLTXRESET_IN,
|
||||
SOUTHREFCLKTX => "00", --
|
||||
TXPLLLKDET => o_mgt.ctrl.TXPLLLKDET, --TXPLLLKDET_OUT,
|
||||
TXPLLLKDETEN => '1', --
|
||||
TXPLLPOWERDOWN => '0', --
|
||||
TXPLLREFSELDY => "000", --
|
||||
TXRATE => "00", --
|
||||
TXRATEDONE => open, --
|
||||
TXRESETDONE => o_mgt.ctrl.TXRESETDONE, --TXRESETDONE_OUT,
|
||||
--------------------- Transmit Ports - TX PRBS Generator ------------------- --
|
||||
TXENPRBSTST => tied_to_ground_vec_i(2 downto 0), --
|
||||
TXPRBSFORCEERR => tied_to_ground_i, --
|
||||
-------------------- Transmit Ports - TX Polarity Control ------------------ --
|
||||
TXPOLARITY => tied_to_ground_i, --
|
||||
----------------- Transmit Ports - TX Ports for PCI Express ---------------- --
|
||||
TXDEEMPH => tied_to_ground_i, --
|
||||
TXDETECTRX => tied_to_ground_i, --
|
||||
TXELECIDLE => tied_to_ground_i, --
|
||||
TXMARGIN => tied_to_ground_vec_i(2 downto 0), --
|
||||
TXPDOWNASYNCH => tied_to_ground_i, --
|
||||
TXSWING => tied_to_ground_i, --
|
||||
--------------------- Transmit Ports - TX Ports for SATA ------------------- --
|
||||
COMFINISH => open, --
|
||||
TXCOMINIT => tied_to_ground_i, --
|
||||
TXCOMSAS => tied_to_ground_i, --
|
||||
TXCOMWAKE => tied_to_ground_i --
|
||||
);
|
||||
|
||||
end RTL;
|
||||
@@ -1,218 +1,26 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
------------------------------------------------------------------------------
|
||||
-- Unit : pkg_v6vlx_gtxe1.vhd
|
||||
-- Unit : v6vlx_gtxe1_142MHz8_2Gbps856.vhd
|
||||
-- Author : Goran Marinkovic, Section Diagnostic
|
||||
-- : Waldemar Koprek, Section Diagnostic
|
||||
-- : Patric Bucher, Section DSV
|
||||
-- Version : $Revision: 1.1 $
|
||||
------------------------------------------------------------------------------
|
||||
-- Copyright© PSI, Section Diagnostic
|
||||
------------------------------------------------------------------------------
|
||||
-- Comment :
|
||||
-- Comment : Virtex-6 GTXE1 primitive configured for SwissFEL 142.8 MHz
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
|
||||
--***************************** Entity Declaration ****************************
|
||||
package pkg_v6vlx_gtxe1 is
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Types
|
||||
---------------------------------------------------------------------------
|
||||
type gtxe_ctrl_in_type is record
|
||||
GTXRESET : std_ulogic;
|
||||
LOOPBACK : std_logic_vector( 2 downto 0);
|
||||
CLKIN : std_ulogic;
|
||||
PLLRXRESET : std_ulogic;
|
||||
PLLTXRESET : std_ulogic;
|
||||
end record gtxe_ctrl_in_type;
|
||||
use work.v6vlx_gtxe1_pkg.all;
|
||||
|
||||
type gtxe_ctrl_out_type is record
|
||||
RXPLLLKDET : std_ulogic;
|
||||
RXRESETDONE : std_ulogic;
|
||||
TXPLLLKDET : std_ulogic;
|
||||
TXRESETDONE : std_ulogic;
|
||||
REFCLKOUT : std_ulogic;
|
||||
end record gtxe_ctrl_out_type;
|
||||
|
||||
-- type mgt_drp_in_type is record
|
||||
-- -- Dynamic Reconfiguration Port (DRP)
|
||||
-- DCLK : std_ulogic;
|
||||
-- DEN : std_ulogic;
|
||||
-- DWE : std_ulogic;
|
||||
-- DADDR : std_logic_vector( 6 downto 0);
|
||||
-- DI : std_logic_vector(15 downto 0);
|
||||
-- end record mgt_drp_in_type;
|
||||
--
|
||||
-- type mgt_drp_out_type is record
|
||||
-- -- Dynamic Reconfiguration Port (DRP)
|
||||
-- DO : std_logic_vector(15 downto 0);
|
||||
-- DRDY : std_ulogic;
|
||||
-- end record mgt_drp_out_type;
|
||||
|
||||
type gtxe_rx_in_type is record
|
||||
-- Comma Detection and Alignment ------------------------
|
||||
RXENMCOMMAALIGN : std_ulogic;
|
||||
RXENPCOMMAALIGN : std_ulogic;
|
||||
-- RX resets
|
||||
RXRESET : std_ulogic;
|
||||
RXCDRRESET : std_ulogic;
|
||||
-- RX user clocks
|
||||
RXUSRCLK : std_ulogic;
|
||||
RXUSRCLK2 : std_ulogic;
|
||||
-- RX serial ports
|
||||
RXP : std_ulogic;
|
||||
RXN : std_ulogic;
|
||||
-- RX Elastic Buffer and Phase Alignment Ports
|
||||
RXDLYALIGNDISABLE : std_logic;
|
||||
RXDLYALIGNMONENB : std_logic;
|
||||
RXDLYALIGNOVERRIDE : std_logic;
|
||||
RXDLYALIGNRESET : std_logic;
|
||||
RXENPMAPHASEALIGN : std_logic;
|
||||
RXPMASETPHASE : std_logic;
|
||||
RXSLIDE : std_logic;
|
||||
end record gtxe_rx_in_type;
|
||||
|
||||
type gtxe_rx_out_type is record
|
||||
-- RX 8b10b Decoder
|
||||
RXCHARISCOMMA : std_logic_vector( 3 downto 0);
|
||||
RXCHARISK : std_logic_vector( 3 downto 0);
|
||||
RXDISPERR : std_logic_vector( 3 downto 0);
|
||||
RXNOTINTABLE : std_logic_vector( 3 downto 0);
|
||||
RXRUNDISP : std_logic_vector( 3 downto 0);
|
||||
-- Comma Detection and Alignment
|
||||
RXBYTEISALIGNED : std_ulogic;
|
||||
RXBYTEREALIGN : std_ulogic;
|
||||
RXCOMMADET : std_ulogic;
|
||||
-- RX data ports
|
||||
RXDATA : std_logic_vector(31 downto 0);
|
||||
-- RX user clocks
|
||||
RXRECCLK : std_ulogic;
|
||||
-- RX Out Of Band (OOB)
|
||||
RXELECIDLE : std_ulogic;
|
||||
-- RX Elastic Buffer and Phase Alignment Ports
|
||||
RXDLYALIGNMONITOR : std_logic_vector(7 downto 0);
|
||||
-- RX loss of sync fsm
|
||||
RXLOSSOFSYNC : std_logic_vector( 1 downto 0);
|
||||
end record gtxe_rx_out_type;
|
||||
|
||||
type gtxe_tx_in_type is record
|
||||
-- 8b10b Encoder Control Ports
|
||||
TXBYPASS8B10B : std_logic_vector( 3 downto 0);
|
||||
TXCHARDISPMODE : std_logic_vector( 3 downto 0);
|
||||
TXCHARDISPVAL : std_logic_vector( 3 downto 0);
|
||||
TXCHARISK : std_logic_vector( 3 downto 0);
|
||||
-- TX data ports
|
||||
TXDATA : std_logic_vector(31 downto 0);
|
||||
-- TX resets
|
||||
TXRESET : std_ulogic;
|
||||
-- TX user clocks
|
||||
TXUSRCLK : std_ulogic;
|
||||
TXUSRCLK2 : std_ulogic;
|
||||
-- TX driver
|
||||
TXDIFFCTRL : std_logic_vector( 3 downto 0);
|
||||
TXPOSTEMPHASIS : std_logic_vector( 4 downto 0);
|
||||
TXPREEMPHASIS : std_logic_vector( 3 downto 0);
|
||||
end record gtxe_tx_in_type;
|
||||
|
||||
|
||||
type gtxe_tx_out_type is record
|
||||
-- TX serial ports
|
||||
TXP : std_ulogic;
|
||||
TXN : std_ulogic;
|
||||
-- TX 8b10b encoder
|
||||
TXKERR : std_logic_vector( 3 downto 0);
|
||||
TXRUNDISP : std_logic_vector( 3 downto 0);
|
||||
-- TX user clocks
|
||||
TXOUTCLK : std_ulogic;
|
||||
end record gtxe_tx_out_type;
|
||||
|
||||
|
||||
type gtxe_in_type is record
|
||||
ctrl : gtxe_ctrl_in_type;
|
||||
--drp : mgt_drp_in_type;
|
||||
rx : gtxe_rx_in_type;
|
||||
tx : gtxe_tx_in_type;
|
||||
end record gtxe_in_type;
|
||||
|
||||
type gtxe_out_type is record
|
||||
ctrl : gtxe_ctrl_out_type;
|
||||
--drp : mgt_drp_out_type;
|
||||
rx : gtxe_rx_out_type;
|
||||
tx : gtxe_tx_out_type;
|
||||
end record gtxe_out_type;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Module virtex6 GTXE
|
||||
---------------------------------------------------------------------------
|
||||
component v6vlx_gtxe1
|
||||
generic(
|
||||
g_MGT_LOCATION : string
|
||||
);
|
||||
port
|
||||
(
|
||||
i_mgt : in gtxe_in_type;
|
||||
o_mgt : out gtxe_out_type
|
||||
);
|
||||
end component;
|
||||
|
||||
component virtex6_gtxe_sync is
|
||||
port
|
||||
(
|
||||
RXENPMAPHASEALIGN : out std_logic;
|
||||
RXPMASETPHASE : out std_logic;
|
||||
RXDLYALIGNDISABLE : out std_logic;
|
||||
RXDLYALIGNOVERRIDE : out std_logic;
|
||||
RXDLYALIGNRESET : out std_logic;
|
||||
SYNC_DONE : out std_logic;
|
||||
USER_CLK : in std_logic;
|
||||
RESET : in std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
component v6vlx_gtxe1_wrapper is
|
||||
generic(
|
||||
g_MGT_LOCATION : string;
|
||||
g_USE_MMCM : boolean := false
|
||||
);
|
||||
port
|
||||
(
|
||||
-- MGT serial interface
|
||||
i_mgt_refclk : in std_logic;
|
||||
o_mgt_refclk : out std_logic;
|
||||
i_mgt_rx_p : in std_logic;
|
||||
i_mgt_rx_n : in std_logic;
|
||||
o_mgt_tx_p : out std_logic;
|
||||
o_mgt_tx_n : out std_logic;
|
||||
-- MGT parallel interface
|
||||
o_mgt_status : out std_logic_vector(31 downto 0); -- see lines 134-139 for details
|
||||
i_mgt_control : in std_logic_vector(31 downto 0); -- see lines 127-131 for details
|
||||
o_mgt_recclk : out std_logic;
|
||||
o_mgt_rx_data : out std_logic_vector(15 downto 0);
|
||||
o_mgt_rx_charisk : out std_logic_vector( 1 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end package pkg_v6vlx_gtxe1;
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- virtex6_gtxe --------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.pkg_v6vlx_gtxe1.all;
|
||||
|
||||
entity v6vlx_gtxe1 is
|
||||
entity v6vlx_gtxe1_142MHz8_2Gbps856 is
|
||||
generic(
|
||||
g_MGT_LOCATION : string
|
||||
);
|
||||
@@ -220,9 +28,10 @@ entity v6vlx_gtxe1 is
|
||||
i_mgt : in gtxe_in_type;
|
||||
o_mgt : out gtxe_out_type
|
||||
);
|
||||
end v6vlx_gtxe1;
|
||||
end v6vlx_gtxe1_142MHz8_2Gbps856;
|
||||
|
||||
architecture RTL of v6vlx_gtxe1 is
|
||||
|
||||
architecture RTL of v6vlx_gtxe1_142MHz8_2Gbps856 is
|
||||
|
||||
--**************************** Signal Declarations ****************************
|
||||
|
||||
@@ -258,8 +67,8 @@ begin
|
||||
gtxe1_i :GTXE1
|
||||
generic map (
|
||||
--_______________________ Simulation-Only Attributes ___________________
|
||||
SIM_RECEIVER_DETECT_PASS => TRUE,
|
||||
SIM_GTXRESET_SPEEDUP => 1, --(GTX_SIM_GTXRESET_SPEEDUP),
|
||||
SIM_RECEIVER_DETECT_PASS => (TRUE),
|
||||
SIM_GTXRESET_SPEEDUP => (1), --(GTX_SIM_GTXRESET_SPEEDUP),
|
||||
SIM_TX_ELEC_IDLE_LEVEL => ("X"),
|
||||
SIM_VERSION => ("2.0"),
|
||||
SIM_TXREFCLK_SOURCE => ("000"),
|
||||
@@ -281,39 +90,39 @@ begin
|
||||
POWER_SAVE => "0000110100", -- [4] '1' = bypass trasmit delay aligner, [5] '1' = bypass receive delay aligner
|
||||
|
||||
-------------------------TX Interface-------------------------
|
||||
GEN_TXUSRCLK => TRUE, --(TRUE),
|
||||
TX_DATA_WIDTH => 20, --(20),
|
||||
TX_USRCLK_CFG => X"00", --(x"00"),
|
||||
TXOUTCLK_CTRL => "TXOUTCLKPMA_DIV2", --("TXOUTCLKPMA_DIV2"),
|
||||
TXOUTCLK_DLY => "0000000000", --("0000000000"),
|
||||
GEN_TXUSRCLK => (TRUE), --
|
||||
TX_DATA_WIDTH => (20), --
|
||||
TX_USRCLK_CFG => (X"00"), --
|
||||
TXOUTCLK_CTRL => ("TXOUTCLKPMA_DIV2"), --
|
||||
TXOUTCLK_DLY => ("0000000000"), --
|
||||
|
||||
--------------TX Buffering and Phase Alignment----------------
|
||||
TX_PMADATA_OPT => '0', --('0'),
|
||||
PMA_TX_CFG => x"80082", --(x"80082"),
|
||||
TX_BUFFER_USE => TRUE, --(TRUE),
|
||||
TX_BYTECLK_CFG => x"00", --(x"00"),
|
||||
TX_EN_RATE_RESET_BUF => TRUE, --(TRUE),
|
||||
TX_XCLK_SEL => "TXOUT", --("TXOUT"),
|
||||
TX_DLYALIGN_CTRINC => "0100", --("0100"),
|
||||
TX_DLYALIGN_LPFINC => "0110", --("0110"),
|
||||
TX_DLYALIGN_MONSEL => "000", --("000"),
|
||||
TX_DLYALIGN_OVRDSETTING => "10000000", --("10000000"),
|
||||
TX_PMADATA_OPT => ('0'), --
|
||||
PMA_TX_CFG => (x"80082"), --
|
||||
TX_BUFFER_USE => (TRUE), --
|
||||
TX_BYTECLK_CFG => (x"00"), --
|
||||
TX_EN_RATE_RESET_BUF => (TRUE), --
|
||||
TX_XCLK_SEL => ("TXOUT"), --
|
||||
TX_DLYALIGN_CTRINC => ("0100"), --
|
||||
TX_DLYALIGN_LPFINC => ("0110"), --
|
||||
TX_DLYALIGN_MONSEL => ("000"), --
|
||||
TX_DLYALIGN_OVRDSETTING => ("10000000"), --
|
||||
|
||||
-------------------------TX Gearbox--------------------------- --
|
||||
-------------------------TX Gearbox--------------------------- --
|
||||
GEARBOX_ENDEC => ("000"), --
|
||||
TXGEARBOX_USE => (FALSE), --
|
||||
--
|
||||
----------------TX Driver and OOB Signalling------------------ --
|
||||
----------------TX Driver and OOB Signalling------------------ --
|
||||
TX_DRIVE_MODE => ("DIRECT"), --
|
||||
TX_IDLE_ASSERT_DELAY => ("100"), --
|
||||
TX_IDLE_DEASSERT_DELAY => ("010"), --
|
||||
TXDRIVE_LOOPBACK_HIZ => (FALSE), --
|
||||
TXDRIVE_LOOPBACK_PD => (FALSE), --
|
||||
--
|
||||
--------------TX Pipe Control for PCI Express/SATA------------ --
|
||||
--------------TX Pipe Control for PCI Express/SATA------------ --
|
||||
COM_BURST_VAL => ("1111"), --
|
||||
--
|
||||
------------------TX Attributes for PCI Express--------------- --
|
||||
------------------TX Attributes for PCI Express--------------- --
|
||||
TX_DEEMPH_0 => ("11010"), --
|
||||
TX_DEEMPH_1 => ("10000"), --
|
||||
TX_MARGIN_FULL_0 => ("1001110"), --
|
||||
@@ -346,7 +155,7 @@ begin
|
||||
RXUSRCLK_DLY => (x"0000"), --
|
||||
|
||||
----------RX Driver,OOB signalling,Coupling and Eq.,CDR-------
|
||||
AC_CAP_DIS => FALSE, --(FALSE),
|
||||
AC_CAP_DIS => (FALSE), --
|
||||
CDR_PH_ADJ_TIME => ("10100"), --
|
||||
OOBDETECT_THRESHOLD => ("011"), --
|
||||
PMA_CDR_SCAN => (x"640404C"), --
|
||||
@@ -354,10 +163,10 @@ begin
|
||||
RCV_TERM_GND => (FALSE), --
|
||||
RCV_TERM_VTTRX => (TRUE), --
|
||||
RX_EN_IDLE_HOLD_CDR => (FALSE), --
|
||||
RX_EN_IDLE_RESET_FR => FALSE, --(FALSE),
|
||||
RX_EN_IDLE_RESET_PH => FALSE, --(FALSE),
|
||||
RX_EN_IDLE_RESET_FR => (FALSE), --
|
||||
RX_EN_IDLE_RESET_PH => (FALSE), --
|
||||
TX_DETECT_RX_CFG => (x"1832"), --
|
||||
TERMINATION_CTRL => "00000", --("00000"),
|
||||
TERMINATION_CTRL => ("00000"), --
|
||||
TERMINATION_OVRD => (FALSE), --
|
||||
CM_TRIM => ("01"), --
|
||||
PMA_RXSYNC_CFG => (x"00"), --
|
||||
@@ -376,11 +185,11 @@ begin
|
||||
RXPRBSERR_LOOPBACK => ('0'), --
|
||||
|
||||
------------------Comma Detection and Alignment---------------
|
||||
ALIGN_COMMA_WORD => 2, --(1),
|
||||
ALIGN_COMMA_WORD => (2), --(1),
|
||||
COMMA_10B_ENABLE => ("1111111111"), --
|
||||
COMMA_DOUBLE => (FALSE), --
|
||||
DEC_MCOMMA_DETECT => TRUE, --(FALSE),
|
||||
DEC_PCOMMA_DETECT => TRUE, --(FALSE),
|
||||
DEC_MCOMMA_DETECT => (TRUE), --(FALSE),
|
||||
DEC_PCOMMA_DETECT => (TRUE), --(FALSE),
|
||||
DEC_VALID_COMMA_ONLY => (FALSE), --
|
||||
MCOMMA_10B_VALUE => ("1010000011"), --
|
||||
MCOMMA_DETECT => (TRUE), --
|
||||
@@ -389,12 +198,12 @@ begin
|
||||
RX_DECODE_SEQ_MATCH => (FALSE), --
|
||||
RX_SLIDE_AUTO_WAIT => (5), --
|
||||
RX_SLIDE_MODE => ("PMA"), --
|
||||
SHOW_REALIGN_COMMA => (FALSE), --
|
||||
SHOW_REALIGN_COMMA => (FALSE), --
|
||||
|
||||
-----------------RX Loss-of-sync State Machine----------------
|
||||
RX_LOS_INVALID_INCR => (8), --
|
||||
RX_LOS_THRESHOLD => (128), --
|
||||
RX_LOSS_OF_SYNC_FSM => TRUE, --(FALSE),
|
||||
RX_LOSS_OF_SYNC_FSM => (TRUE), --(FALSE),
|
||||
|
||||
-------------------------RX Gearbox---------------------------
|
||||
RXGEARBOX_USE => (FALSE), --
|
||||
@@ -416,7 +225,7 @@ begin
|
||||
RX_DLYALIGN_MONSEL => ("000"), --
|
||||
RX_DLYALIGN_OVRDSETTING => ("10000000"), --
|
||||
|
||||
------------------------Clock Correction---------------------- --
|
||||
------------------------Clock Correction---------------------- --
|
||||
CLK_COR_ADJ_LEN => (1), --
|
||||
CLK_COR_DET_LEN => (1), --
|
||||
CLK_COR_INSERT_IDLE_FLAG => (FALSE), --
|
||||
@@ -438,7 +247,7 @@ begin
|
||||
CLK_COR_SEQ_2_USE => (FALSE), --
|
||||
CLK_CORRECT_USE => (FALSE), --
|
||||
--
|
||||
------------------------Channel Bonding---------------------- --
|
||||
------------------------Channel Bonding---------------------- --
|
||||
CHAN_BOND_1_MAX_SKEW => (1), --
|
||||
CHAN_BOND_2_MAX_SKEW => (1), --
|
||||
CHAN_BOND_KEEP_ALIGN => (FALSE), --
|
||||
@@ -457,7 +266,7 @@ begin
|
||||
CHAN_BOND_SEQ_LEN => (1), --
|
||||
PCI_EXPRESS_MODE => (FALSE), --
|
||||
--
|
||||
-------------RX Attributes for PCI Express/SATA/SAS---------- --
|
||||
-------------RX Attributes for PCI Express/SATA/SAS---------- --
|
||||
SAS_MAX_COMSAS => (52), --
|
||||
SAS_MIN_COMSAS => (40), --
|
||||
SATA_BURST_VAL => ("100"), --
|
||||
@@ -682,473 +491,4 @@ begin
|
||||
TXCOMWAKE => tied_to_ground_i --
|
||||
);
|
||||
|
||||
end RTL;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- virtex6_gtxe_sync-----------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
|
||||
entity virtex6_gtxe_sync is
|
||||
port
|
||||
(
|
||||
RXENPMAPHASEALIGN : out std_logic;
|
||||
RXPMASETPHASE : out std_logic;
|
||||
RXDLYALIGNDISABLE : out std_logic;
|
||||
RXDLYALIGNOVERRIDE : out std_logic;
|
||||
RXDLYALIGNRESET : out std_logic;
|
||||
SYNC_DONE : out std_logic;
|
||||
USER_CLK : in std_logic;
|
||||
RESET : in std_logic
|
||||
);
|
||||
|
||||
|
||||
end virtex6_gtxe_sync;
|
||||
|
||||
architecture RTL of virtex6_gtxe_sync is
|
||||
--***********************************Parameter Declarations********************
|
||||
|
||||
constant DLY : time := 1 ns;
|
||||
|
||||
--*******************************Register Declarations************************
|
||||
|
||||
signal begin_r : std_logic;
|
||||
signal phase_align_r : std_logic;
|
||||
signal ready_r : std_logic;
|
||||
signal sync_counter_r : unsigned(5 downto 0);
|
||||
signal sync_done_count_r : unsigned(5 downto 0);
|
||||
signal align_reset_counter_r : unsigned(4 downto 0);
|
||||
signal wait_after_sync_r : std_logic;
|
||||
signal wait_before_setphase_counter_r : unsigned(5 downto 0);
|
||||
signal wait_before_setphase_r : std_logic;
|
||||
signal align_reset_r : std_logic;
|
||||
|
||||
--*******************************Wire Declarations****************************
|
||||
|
||||
signal count_32_setphase_complete_r : std_logic;
|
||||
signal count_32_wait_complete_r : std_logic;
|
||||
signal count_align_reset_complete_r : std_logic;
|
||||
signal next_phase_align_c : std_logic;
|
||||
signal next_align_reset_c : std_logic;
|
||||
signal next_ready_c : std_logic;
|
||||
signal next_wait_after_sync_c : std_logic;
|
||||
signal next_wait_before_setphase_c : std_logic;
|
||||
signal sync_32_times_done_r : std_logic;
|
||||
|
||||
attribute max_fanout:string;
|
||||
attribute max_fanout of ready_r : signal is "2";
|
||||
|
||||
begin
|
||||
--*******************************Main Body of Code****************************
|
||||
|
||||
--________________________________ State machine __________________________
|
||||
-- This state machine manages the phase alingment procedure of the GTX on the
|
||||
-- receive side. The module is held in reset till the usrclk source is stable
|
||||
-- and RXRESETDONE is asserted. In the case that a MMCM is used to generate
|
||||
-- rxusrclk, the mmcm_locked signal is used to indicate a stable usrclk source.
|
||||
-- Once RXRESETDONE and mmcm_locked are asserted, the state machine goes
|
||||
-- into the align_reset_r state where RXDLYALIGNRESET is asserted for 20 cycles.
|
||||
-- After this, it goes into the wait_before_setphase_r state for 32 cycles.
|
||||
-- After asserting RXENPMAPHASEALIGN and waiting 32 cycles, it enters the
|
||||
-- phase_align_r state where RXPMASETPHASE is asserted for 32 clock cycles.
|
||||
-- After the port is deasserted, the state machine goes into a wait state for
|
||||
-- 32 cycles. This procedure is repeated 32 times.
|
||||
|
||||
-- State registers
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if(RESET='1') then
|
||||
begin_r <= '1' after DLY;
|
||||
align_reset_r <= '0' after DLY;
|
||||
wait_before_setphase_r <= '0' after DLY;
|
||||
phase_align_r <= '0' after DLY;
|
||||
wait_after_sync_r <= '0' after DLY;
|
||||
ready_r <= '0' after DLY;
|
||||
else
|
||||
begin_r <= '0' after DLY;
|
||||
align_reset_r <= next_align_reset_c after DLY;
|
||||
wait_before_setphase_r <= next_wait_before_setphase_c after DLY;
|
||||
phase_align_r <= next_phase_align_c after DLY;
|
||||
wait_after_sync_r <= next_wait_after_sync_c after DLY;
|
||||
ready_r <= next_ready_c after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Next state logic
|
||||
next_align_reset_c <= begin_r or
|
||||
(align_reset_r and not count_align_reset_complete_r);
|
||||
|
||||
next_wait_before_setphase_c <= (align_reset_r and count_align_reset_complete_r) or
|
||||
(wait_before_setphase_r and not count_32_wait_complete_r);
|
||||
|
||||
next_phase_align_c <= (wait_before_setphase_r and count_32_wait_complete_r) or
|
||||
(phase_align_r and not count_32_setphase_complete_r) or
|
||||
(wait_after_sync_r and count_32_wait_complete_r and not sync_32_times_done_r);
|
||||
|
||||
next_wait_after_sync_c <= (phase_align_r and count_32_setphase_complete_r) or
|
||||
(wait_after_sync_r and not count_32_wait_complete_r);
|
||||
|
||||
next_ready_c <= (wait_after_sync_r and count_32_wait_complete_r and sync_32_times_done_r) or
|
||||
ready_r;
|
||||
|
||||
--______ Counter for holding RXDLYALIGNRESET for 20 RXUSRCLK2 cycles ______
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (align_reset_r='0') then
|
||||
align_reset_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
align_reset_counter_r <= align_reset_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if ;
|
||||
end process;
|
||||
|
||||
count_align_reset_complete_r <= align_reset_counter_r(4)
|
||||
and align_reset_counter_r(2);
|
||||
|
||||
--_______Counter for waiting 32 clock cycles before RXPMASETPHASE _________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if ((wait_before_setphase_r='0') and (wait_after_sync_r='0')) then
|
||||
wait_before_setphase_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
wait_before_setphase_counter_r <= wait_before_setphase_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
count_32_wait_complete_r <= wait_before_setphase_counter_r(5);
|
||||
|
||||
--_______________ Counter for holding SYNC for SYNC_CYCLES ________________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (phase_align_r='0') then
|
||||
sync_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
sync_counter_r <= sync_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
count_32_setphase_complete_r <= sync_counter_r(5);
|
||||
|
||||
--__________ Counter for counting number of times sync is done ____________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (RESET='1') then
|
||||
sync_done_count_r <= (others=>'0') after DLY;
|
||||
elsif((count_32_wait_complete_r ='1') and (phase_align_r = '1')) then
|
||||
sync_done_count_r <= sync_done_count_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sync_32_times_done_r <= sync_done_count_r(5);
|
||||
|
||||
--_______________ Assign the phase align ports into the GTX _______________
|
||||
|
||||
RXDLYALIGNRESET <= align_reset_r;
|
||||
RXENPMAPHASEALIGN <= (not begin_r) and (not align_reset_r);
|
||||
RXPMASETPHASE <= phase_align_r;
|
||||
RXDLYALIGNDISABLE <= '1';
|
||||
RXDLYALIGNOVERRIDE <= '1';
|
||||
|
||||
--_______________________ Assign the sync_done port _______________________
|
||||
|
||||
SYNC_DONE <= ready_r;
|
||||
|
||||
|
||||
end RTL;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- ioxos_mgt_v1 ---------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
use work.pkg_v6vlx_gtxe1.all;
|
||||
|
||||
entity v6vlx_gtxe1_wrapper is
|
||||
generic(
|
||||
g_MGT_LOCATION : string;
|
||||
g_USE_MMCM : boolean := false
|
||||
);
|
||||
port(
|
||||
-- MGT serial interface
|
||||
i_mgt_refclk : in std_logic;
|
||||
o_mgt_refclk : out std_logic;
|
||||
i_mgt_rx_p : in std_logic;
|
||||
i_mgt_rx_n : in std_logic;
|
||||
o_mgt_tx_p : out std_logic;
|
||||
o_mgt_tx_n : out std_logic;
|
||||
-- MGT parallel interface
|
||||
o_mgt_status : out std_logic_vector(31 downto 0); -- see lines 134-139 for details
|
||||
i_mgt_control : in std_logic_vector(31 downto 0); -- see lines 127-131 for details
|
||||
o_mgt_recclk : out std_logic;
|
||||
o_mgt_rx_data : out std_logic_vector(15 downto 0);
|
||||
o_mgt_rx_charisk : out std_logic_vector( 1 downto 0)
|
||||
);
|
||||
end v6vlx_gtxe1_wrapper;
|
||||
|
||||
architecture RTL of v6vlx_gtxe1_wrapper is
|
||||
|
||||
type typ_align_fsm is (
|
||||
align_idle,
|
||||
align_slide ,
|
||||
align_wait_for_sync
|
||||
);
|
||||
|
||||
signal s_align_fsm : typ_align_fsm := align_idle;
|
||||
|
||||
-- GTXE
|
||||
signal i_mgt : gtxe_in_type;
|
||||
signal o_mgt : gtxe_out_type;
|
||||
signal sl_txoutclk : std_logic;
|
||||
--fifo
|
||||
signal sl_cpu_rx_empty : std_logic;
|
||||
signal sl_gtxe_fifo_rst : std_logic;
|
||||
signal sl_gtxe_rx_sync_done : std_logic;
|
||||
|
||||
signal slv_rxresetdone : std_logic_vector(7 downto 0);
|
||||
signal sl_rx_sync_rst : std_logic;
|
||||
signal sl_rxrecclk : std_logic;
|
||||
|
||||
signal sl_rx0_slide : std_logic;
|
||||
|
||||
signal slv_cnt : std_logic_vector(5 downto 0);
|
||||
|
||||
-- MMCM
|
||||
signal mmcm_CLKFB : std_logic;
|
||||
signal mmcm_CLKFBOUT : std_logic;
|
||||
signal mmcm_LOCKED : std_logic;
|
||||
signal mmcm_RESET : std_logic;
|
||||
signal mmcm_CLOCK : std_logic;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
-- inst_mgt_refclk_bufg: BUFG
|
||||
-- port map
|
||||
-- (
|
||||
-- I => o_mgt.ctrl.REFCLKOUT,
|
||||
-- O => o_mgt_refclk
|
||||
-- );
|
||||
|
||||
-- GTXE INSTANCE ------------------------------------------------------------------
|
||||
ins_v6vlx_gtxe1: v6vlx_gtxe1
|
||||
generic map (
|
||||
g_MGT_LOCATION => g_MGT_LOCATION )
|
||||
port map (
|
||||
i_mgt => i_mgt,
|
||||
o_mgt => o_mgt
|
||||
);
|
||||
|
||||
|
||||
-- GTXE CONTROL IF ----------------------------------------------------------------
|
||||
i_mgt.ctrl.GTXRESET <= i_mgt_control(0);
|
||||
i_mgt.ctrl.PLLRXRESET <= '0';
|
||||
i_mgt.ctrl.PLLTXRESET <= '0';
|
||||
i_mgt.ctrl.LOOPBACK <= "100"; -- Far-End PMA Loopback --> UG366 page 125
|
||||
i_mgt.ctrl.CLKIN <= i_mgt_refclk;
|
||||
|
||||
-- GTXE STATUS IF (adapted to PSI generic part) -----------------------------------
|
||||
o_mgt_status( 0) <= o_mgt.ctrl.TXPLLLKDET;
|
||||
o_mgt_status( 1) <= o_mgt.ctrl.RXPLLLKDET;
|
||||
o_mgt_status( 2) <= mmcm_LOCKED;
|
||||
o_mgt_status( 3) <= o_mgt.ctrl.TXRESETDONE;
|
||||
o_mgt_status( 4) <= o_mgt.ctrl.RXRESETDONE;
|
||||
o_mgt_status( 5) <= '0'; -- TX_polarity inverted
|
||||
o_mgt_status( 6) <= '0'; -- RX_polarity inverted
|
||||
o_mgt_status( 7) <= '0'; -- reserved
|
||||
o_mgt_status(12 downto 8) <= "00000"; -- DFEEYEDACMON[4:0]
|
||||
o_mgt_status(13) <= '0'; -- RXPRBSERR
|
||||
o_mgt_status(14) <= o_mgt.rx.RXBYTEISALIGNED;
|
||||
o_mgt_status(15) <= o_mgt.rx.RXLOSSOFSYNC(1);
|
||||
---------- additional status -------------
|
||||
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(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 ---------------------------------------------------------------------
|
||||
-- MMCM use model based on AR#39430
|
||||
gen_MMCM: if g_USE_MMCM generate
|
||||
begin
|
||||
-- Use Core Generator to define parameters -> actual frequency 142.8 MHz
|
||||
mmcm_rxclk : MMCM_BASE
|
||||
generic map (
|
||||
CLKFBOUT_MULT_F => 33.000 , -- Counter multiply value, Now supports non-integer values
|
||||
CLKIN1_PERIOD => 7.002 , -- The reference clock frequency is required for properly configuring the
|
||||
-- LOCK detect circuit and checking to make sure the VCO is operating within
|
||||
-- the allowed range. If no value is specified, a warning should be issued
|
||||
-- stating it was not provided so no error checking will be done.
|
||||
CLKOUT0_DIVIDE_F => 8.250 , -- Counter divide value, Now supports non-integer values but you lose CLKOUT5
|
||||
DIVCLK_DIVIDE => 4 -- Counter divide value, always configured for 50% duty cycle
|
||||
)
|
||||
port map (
|
||||
CLKFBOUT => mmcm_CLKFBOUT, -- 1-bit MMCM Feedback clock output
|
||||
CLKFBOUTB => open, -- 1-bit Inverted MMCM feedback clock output
|
||||
CLKOUT0 => mmcm_CLOCK, -- 1-bit MMCM clock output 0
|
||||
CLKOUT0B => open, -- 1-bit Inverted MMCM clock output 0
|
||||
CLKOUT1 => open, -- 1-bit MMCM clock output 1
|
||||
CLKOUT1B => open, -- 1-bit Inverted MMCM clock output 1
|
||||
CLKOUT2 => open, -- 1-bit MMCM clock output 2
|
||||
CLKOUT2B => open, -- 1-bit Inverted MMCM clock output 2
|
||||
CLKOUT3 => open, -- 1-bit MMCM clock output 3
|
||||
CLKOUT3B => open, -- 1-bit Inverted MMCM clock output 3
|
||||
CLKOUT4 => open, -- 1-bit MMCM clock output 4
|
||||
CLKOUT5 => open, -- 1-bit MMCM clock output 5, not used if CLKOUT0 is not an integer
|
||||
CLKOUT6 => open, -- 1-bit MMCM clock output 6, not used if CLKFBOUT_MULT is not an integer
|
||||
LOCKED => mmcm_LOCKED, -- 1-bit MMC locked signal
|
||||
CLKFBIN => mmcm_CLKFB, -- 1-bit Feedback clock pin to the MMCM
|
||||
CLKIN1 => o_mgt.rx.RXRECCLK, -- 1-bit Reference clock pin 1 to the MMCM
|
||||
PWRDWN => '0', -- 1-bit Power down
|
||||
RST => mmcm_RESET -- 1-bit MMCM global reset pin
|
||||
);
|
||||
|
||||
mmcm_RESET <= not o_mgt.ctrl.RXPLLLKDET;
|
||||
|
||||
rxoutCLKFB_bufg0_i : BUFG
|
||||
port map (
|
||||
I => mmcm_CLKFBOUT,
|
||||
O => mmcm_CLKFB
|
||||
);
|
||||
|
||||
rxoutclk_bufg1_i : BUFG
|
||||
port map (
|
||||
I => mmcm_CLOCK,
|
||||
O => sl_rxrecclk
|
||||
);
|
||||
end generate;
|
||||
|
||||
gen_BUFG: if not(g_USE_MMCM) generate
|
||||
begin
|
||||
rxoutclk_bufg0_i : BUFG
|
||||
port map (
|
||||
I => o_mgt.rx.RXRECCLK,
|
||||
O => sl_rxrecclk
|
||||
);
|
||||
|
||||
-- forward lock state
|
||||
mmcm_LOCKED <= o_mgt.ctrl.RXPLLLKDET;
|
||||
|
||||
-- unused without mmcm
|
||||
mmcm_CLKFB <= '0';
|
||||
mmcm_CLKFBOUT <= '0';
|
||||
mmcm_RESET <= '0';
|
||||
mmcm_CLOCK <= '0';
|
||||
end generate;
|
||||
|
||||
o_mgt_recclk <= sl_rxrecclk;
|
||||
|
||||
ins_virtex6_gtxe_sync : virtex6_gtxe_sync
|
||||
port map (
|
||||
RXENPMAPHASEALIGN => i_mgt.rx.RXENPMAPHASEALIGN ,
|
||||
RXPMASETPHASE => i_mgt.rx.RXPMASETPHASE ,
|
||||
RXDLYALIGNDISABLE => i_mgt.rx.RXDLYALIGNDISABLE ,
|
||||
RXDLYALIGNOVERRIDE => i_mgt.rx.RXDLYALIGNOVERRIDE,
|
||||
RXDLYALIGNRESET => i_mgt.rx.RXDLYALIGNRESET ,
|
||||
SYNC_DONE => sl_gtxe_rx_sync_done,
|
||||
USER_CLK => sl_rxrecclk,
|
||||
RESET => sl_rx_sync_rst
|
||||
);
|
||||
|
||||
|
||||
prc_rx_reset_done_delay : process ( sl_rxrecclk )
|
||||
begin
|
||||
if rising_edge( sl_rxrecclk ) then
|
||||
slv_rxresetdone <= slv_rxresetdone(6 downto 0) & o_mgt.ctrl.RXRESETDONE;
|
||||
end if;
|
||||
end process ;
|
||||
|
||||
sl_rx_sync_rst <= not slv_rxresetdone(7);
|
||||
|
||||
i_mgt.rx.RXUSRCLK <= sl_rxrecclk;
|
||||
i_mgt.rx.RXUSRCLK2 <= sl_rxrecclk;
|
||||
i_mgt.rx.RXP <= i_mgt_rx_p;
|
||||
i_mgt.rx.RXN <= i_mgt_rx_n;
|
||||
|
||||
i_mgt.rx.RXENMCOMMAALIGN <= '0';
|
||||
i_mgt.rx.RXENPCOMMAALIGN <= '0';
|
||||
i_mgt.rx.RXRESET <= not mmcm_LOCKED;
|
||||
i_mgt.rx.RXCDRRESET <= i_mgt_control(5);
|
||||
i_mgt.rx.RXDLYALIGNMONENB <= '0';
|
||||
|
||||
o_mgt_rx_data <= o_mgt.rx.RXDATA(15 downto 0);
|
||||
o_mgt_rx_charisk <= o_mgt.rx.RXCHARISK( 1 downto 0);
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--RX comma alignment
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
prc_comma_align : process ( sl_rxrecclk )
|
||||
begin
|
||||
if rising_edge( sl_rxrecclk ) then
|
||||
if o_mgt.ctrl.RXRESETDONE = '0' then
|
||||
s_align_fsm <= align_idle;
|
||||
else
|
||||
case s_align_fsm is
|
||||
when align_idle =>
|
||||
if o_mgt.rx.RXLOSSOFSYNC( 1) = '1' then
|
||||
s_align_fsm <= align_slide;
|
||||
end if;
|
||||
when align_slide =>
|
||||
slv_cnt <= (others => '0');
|
||||
s_align_fsm <= align_wait_for_sync;
|
||||
when align_wait_for_sync =>
|
||||
if slv_cnt(slv_cnt'left) = '1' then
|
||||
if o_mgt.rx.RXLOSSOFSYNC( 1) = '0' and o_mgt.rx.RXBYTEISALIGNED = '1' then
|
||||
s_align_fsm <= align_idle;
|
||||
else
|
||||
s_align_fsm <= align_slide;
|
||||
end if;
|
||||
else
|
||||
slv_cnt <= slv_cnt + X"1";
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process ;
|
||||
|
||||
sl_rx0_slide <= '1' when s_align_fsm = align_slide or i_mgt_control(2) = '1' else '0';
|
||||
|
||||
i_mgt.rx.RXSLIDE <= sl_rx0_slide;
|
||||
|
||||
-- GTXE TX IF ---------------------------------------------------------------------
|
||||
o_mgt_tx_p <= o_mgt.tx.TXP;
|
||||
o_mgt_tx_n <= o_mgt.tx.TXN;
|
||||
|
||||
-- txoutclk_bufg0_i : BUFG
|
||||
-- port map (
|
||||
-- I => o_mgt.tx.TXOUTCLK,
|
||||
-- O => sl_txoutclk
|
||||
-- );
|
||||
|
||||
i_mgt.tx.TXRESET <= not mmcm_LOCKED;
|
||||
i_mgt.tx.TXBYPASS8B10B <= X"0";
|
||||
i_mgt.tx.TXCHARDISPMODE <= X"0";
|
||||
i_mgt.tx.TXCHARDISPVAL <= X"0";
|
||||
i_mgt.tx.TXUSRCLK <= sl_rxrecclk;
|
||||
i_mgt.tx.TXUSRCLK2 <= sl_rxrecclk;
|
||||
i_mgt.tx.TXDIFFCTRL <= "0110";
|
||||
i_mgt.tx.TXPOSTEMPHASIS <= "00000";
|
||||
i_mgt.tx.TXPREEMPHASIS <= "0000";
|
||||
|
||||
end RTL;
|
||||
207
hdl/v6vlx_gtxe1_pkg.vhd
Normal file
207
hdl/v6vlx_gtxe1_pkg.vhd
Normal file
@@ -0,0 +1,207 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
------------------------------------------------------------------------------
|
||||
-- Unit : v6vlx_gtxe1_pkg.vhd
|
||||
-- Author : Goran Marinkovic, Section Diagnostic
|
||||
-- : Waldemar Koprek, Section Diagnostic
|
||||
-- : Patric Bucher, Section DSV
|
||||
-- Version : $Revision: 1.1 $
|
||||
------------------------------------------------------------------------------
|
||||
-- Copyright© PSI, Section Diagnostic
|
||||
------------------------------------------------------------------------------
|
||||
-- Comment :
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package v6vlx_gtxe1_pkg is
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Types
|
||||
---------------------------------------------------------------------------
|
||||
type gtxe_ctrl_in_type is record
|
||||
GTXRESET : std_ulogic;
|
||||
LOOPBACK : std_logic_vector( 2 downto 0);
|
||||
CLKIN : std_ulogic;
|
||||
PLLRXRESET : std_ulogic;
|
||||
PLLTXRESET : std_ulogic;
|
||||
end record gtxe_ctrl_in_type;
|
||||
|
||||
type gtxe_ctrl_out_type is record
|
||||
RXPLLLKDET : std_ulogic;
|
||||
RXRESETDONE : std_ulogic;
|
||||
TXPLLLKDET : std_ulogic;
|
||||
TXRESETDONE : std_ulogic;
|
||||
REFCLKOUT : std_ulogic;
|
||||
end record gtxe_ctrl_out_type;
|
||||
|
||||
-- type mgt_drp_in_type is record
|
||||
-- -- Dynamic Reconfiguration Port (DRP)
|
||||
-- DCLK : std_ulogic;
|
||||
-- DEN : std_ulogic;
|
||||
-- DWE : std_ulogic;
|
||||
-- DADDR : std_logic_vector( 6 downto 0);
|
||||
-- DI : std_logic_vector(15 downto 0);
|
||||
-- end record mgt_drp_in_type;
|
||||
--
|
||||
-- type mgt_drp_out_type is record
|
||||
-- -- Dynamic Reconfiguration Port (DRP)
|
||||
-- DO : std_logic_vector(15 downto 0);
|
||||
-- DRDY : std_ulogic;
|
||||
-- end record mgt_drp_out_type;
|
||||
|
||||
type gtxe_rx_in_type is record
|
||||
-- Comma Detection and Alignment ------------------------
|
||||
RXENMCOMMAALIGN : std_ulogic;
|
||||
RXENPCOMMAALIGN : std_ulogic;
|
||||
-- RX resets
|
||||
RXRESET : std_ulogic;
|
||||
RXCDRRESET : std_ulogic;
|
||||
-- RX user clocks
|
||||
RXUSRCLK : std_ulogic;
|
||||
RXUSRCLK2 : std_ulogic;
|
||||
-- RX serial ports
|
||||
RXP : std_ulogic;
|
||||
RXN : std_ulogic;
|
||||
-- RX Elastic Buffer and Phase Alignment Ports
|
||||
RXDLYALIGNDISABLE : std_logic;
|
||||
RXDLYALIGNMONENB : std_logic;
|
||||
RXDLYALIGNOVERRIDE : std_logic;
|
||||
RXDLYALIGNRESET : std_logic;
|
||||
RXENPMAPHASEALIGN : std_logic;
|
||||
RXPMASETPHASE : std_logic;
|
||||
RXSLIDE : std_logic;
|
||||
end record gtxe_rx_in_type;
|
||||
|
||||
type gtxe_rx_out_type is record
|
||||
-- RX 8b10b Decoder
|
||||
RXCHARISCOMMA : std_logic_vector( 3 downto 0);
|
||||
RXCHARISK : std_logic_vector( 3 downto 0);
|
||||
RXDISPERR : std_logic_vector( 3 downto 0);
|
||||
RXNOTINTABLE : std_logic_vector( 3 downto 0);
|
||||
RXRUNDISP : std_logic_vector( 3 downto 0);
|
||||
-- Comma Detection and Alignment
|
||||
RXBYTEISALIGNED : std_ulogic;
|
||||
RXBYTEREALIGN : std_ulogic;
|
||||
RXCOMMADET : std_ulogic;
|
||||
-- RX data ports
|
||||
RXDATA : std_logic_vector(31 downto 0);
|
||||
-- RX user clocks
|
||||
RXRECCLK : std_ulogic;
|
||||
-- RX Out Of Band (OOB)
|
||||
RXELECIDLE : std_ulogic;
|
||||
-- RX Elastic Buffer and Phase Alignment Ports
|
||||
RXDLYALIGNMONITOR : std_logic_vector(7 downto 0);
|
||||
-- RX loss of sync fsm
|
||||
RXLOSSOFSYNC : std_logic_vector( 1 downto 0);
|
||||
end record gtxe_rx_out_type;
|
||||
|
||||
type gtxe_tx_in_type is record
|
||||
-- 8b10b Encoder Control Ports
|
||||
TXBYPASS8B10B : std_logic_vector( 3 downto 0);
|
||||
TXCHARDISPMODE : std_logic_vector( 3 downto 0);
|
||||
TXCHARDISPVAL : std_logic_vector( 3 downto 0);
|
||||
TXCHARISK : std_logic_vector( 3 downto 0);
|
||||
-- TX data ports
|
||||
TXDATA : std_logic_vector(31 downto 0);
|
||||
-- TX resets
|
||||
TXRESET : std_ulogic;
|
||||
-- TX user clocks
|
||||
TXUSRCLK : std_ulogic;
|
||||
TXUSRCLK2 : std_ulogic;
|
||||
-- TX driver
|
||||
TXDIFFCTRL : std_logic_vector( 3 downto 0);
|
||||
TXPOSTEMPHASIS : std_logic_vector( 4 downto 0);
|
||||
TXPREEMPHASIS : std_logic_vector( 3 downto 0);
|
||||
end record gtxe_tx_in_type;
|
||||
|
||||
|
||||
type gtxe_tx_out_type is record
|
||||
-- TX serial ports
|
||||
TXP : std_ulogic;
|
||||
TXN : std_ulogic;
|
||||
-- TX 8b10b encoder
|
||||
TXKERR : std_logic_vector( 3 downto 0);
|
||||
TXRUNDISP : std_logic_vector( 3 downto 0);
|
||||
-- TX user clocks
|
||||
TXOUTCLK : std_ulogic;
|
||||
end record gtxe_tx_out_type;
|
||||
|
||||
|
||||
type gtxe_in_type is record
|
||||
ctrl : gtxe_ctrl_in_type;
|
||||
--drp : mgt_drp_in_type;
|
||||
rx : gtxe_rx_in_type;
|
||||
tx : gtxe_tx_in_type;
|
||||
end record gtxe_in_type;
|
||||
|
||||
type gtxe_out_type is record
|
||||
ctrl : gtxe_ctrl_out_type;
|
||||
--drp : mgt_drp_out_type;
|
||||
rx : gtxe_rx_out_type;
|
||||
tx : gtxe_tx_out_type;
|
||||
end record gtxe_out_type;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Components
|
||||
---------------------------------------------------------------------------
|
||||
component v6vlx_gtxe1_142MHz8_2Gbps856
|
||||
generic(
|
||||
g_MGT_LOCATION : string
|
||||
);
|
||||
port
|
||||
(
|
||||
i_mgt : in gtxe_in_type;
|
||||
o_mgt : out gtxe_out_type
|
||||
);
|
||||
end component;
|
||||
|
||||
component v6vlx_gtxe1_101MHz27_1Gbps0127
|
||||
generic(
|
||||
g_MGT_LOCATION : string
|
||||
);
|
||||
port
|
||||
(
|
||||
i_mgt : in gtxe_in_type;
|
||||
o_mgt : out gtxe_out_type
|
||||
);
|
||||
end component;
|
||||
|
||||
component v6vlx_gtxe1_sync is
|
||||
port
|
||||
(
|
||||
RXENPMAPHASEALIGN : out std_logic;
|
||||
RXPMASETPHASE : out std_logic;
|
||||
RXDLYALIGNDISABLE : out std_logic;
|
||||
RXDLYALIGNOVERRIDE : out std_logic;
|
||||
RXDLYALIGNRESET : out std_logic;
|
||||
SYNC_DONE : out std_logic;
|
||||
USER_CLK : in std_logic;
|
||||
RESET : in std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component v6vlx_gtxe1_wrapper is
|
||||
generic(
|
||||
g_MGT_LOCATION : string;
|
||||
g_USE_MMCM : boolean := false
|
||||
);
|
||||
port
|
||||
(
|
||||
-- MGT serial interface
|
||||
i_mgt_refclk : in std_logic;
|
||||
o_mgt_refclk : out std_logic;
|
||||
i_mgt_rx_p : in std_logic;
|
||||
i_mgt_rx_n : in std_logic;
|
||||
o_mgt_tx_p : out std_logic;
|
||||
o_mgt_tx_n : out std_logic;
|
||||
-- MGT parallel interface
|
||||
o_mgt_status : out std_logic_vector(31 downto 0); -- see lines 134-139 for details
|
||||
i_mgt_control : in std_logic_vector(31 downto 0); -- see lines 127-131 for details
|
||||
o_mgt_recclk : out std_logic;
|
||||
o_mgt_rx_data : out std_logic_vector(15 downto 0);
|
||||
o_mgt_rx_charisk : out std_logic_vector( 1 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end package v6vlx_gtxe1_pkg;
|
||||
191
hdl/v6vlx_gtxe1_sync.vhd
Normal file
191
hdl/v6vlx_gtxe1_sync.vhd
Normal file
@@ -0,0 +1,191 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
------------------------------------------------------------------------------
|
||||
-- Unit : v6vlx_gtxe1_sync.vhd
|
||||
-- Author : Goran Marinkovic, Section Diagnostic
|
||||
-- : Waldemar Koprek, Section Diagnostic
|
||||
-- Version : $Revision: 1.1 $
|
||||
------------------------------------------------------------------------------
|
||||
-- Copyright© PSI, Section Diagnostic
|
||||
------------------------------------------------------------------------------
|
||||
-- Comment : GTX synchronisation and alignment process.
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
|
||||
entity v6vlx_gtxe1_sync is
|
||||
port
|
||||
(
|
||||
RXENPMAPHASEALIGN : out std_logic;
|
||||
RXPMASETPHASE : out std_logic;
|
||||
RXDLYALIGNDISABLE : out std_logic;
|
||||
RXDLYALIGNOVERRIDE : out std_logic;
|
||||
RXDLYALIGNRESET : out std_logic;
|
||||
SYNC_DONE : out std_logic;
|
||||
USER_CLK : in std_logic;
|
||||
RESET : in std_logic
|
||||
);
|
||||
end v6vlx_gtxe1_sync;
|
||||
|
||||
|
||||
architecture RTL of v6vlx_gtxe1_sync is
|
||||
--***********************************Parameter Declarations********************
|
||||
|
||||
constant DLY : time := 1 ns;
|
||||
|
||||
--*******************************Register Declarations************************
|
||||
|
||||
signal begin_r : std_logic;
|
||||
signal phase_align_r : std_logic;
|
||||
signal ready_r : std_logic;
|
||||
signal sync_counter_r : unsigned(5 downto 0);
|
||||
signal sync_done_count_r : unsigned(5 downto 0);
|
||||
signal align_reset_counter_r : unsigned(4 downto 0);
|
||||
signal wait_after_sync_r : std_logic;
|
||||
signal wait_before_setphase_counter_r : unsigned(5 downto 0);
|
||||
signal wait_before_setphase_r : std_logic;
|
||||
signal align_reset_r : std_logic;
|
||||
|
||||
--*******************************Wire Declarations****************************
|
||||
|
||||
signal count_32_setphase_complete_r : std_logic;
|
||||
signal count_32_wait_complete_r : std_logic;
|
||||
signal count_align_reset_complete_r : std_logic;
|
||||
signal next_phase_align_c : std_logic;
|
||||
signal next_align_reset_c : std_logic;
|
||||
signal next_ready_c : std_logic;
|
||||
signal next_wait_after_sync_c : std_logic;
|
||||
signal next_wait_before_setphase_c : std_logic;
|
||||
signal sync_32_times_done_r : std_logic;
|
||||
|
||||
attribute max_fanout:string;
|
||||
attribute max_fanout of ready_r : signal is "2";
|
||||
|
||||
begin
|
||||
--*******************************Main Body of Code****************************
|
||||
|
||||
--________________________________ State machine __________________________
|
||||
-- This state machine manages the phase alingment procedure of the GTX on the
|
||||
-- receive side. The module is held in reset till the usrclk source is stable
|
||||
-- and RXRESETDONE is asserted. In the case that a MMCM is used to generate
|
||||
-- rxusrclk, the mmcm_locked signal is used to indicate a stable usrclk source.
|
||||
-- Once RXRESETDONE and mmcm_locked are asserted, the state machine goes
|
||||
-- into the align_reset_r state where RXDLYALIGNRESET is asserted for 20 cycles.
|
||||
-- After this, it goes into the wait_before_setphase_r state for 32 cycles.
|
||||
-- After asserting RXENPMAPHASEALIGN and waiting 32 cycles, it enters the
|
||||
-- phase_align_r state where RXPMASETPHASE is asserted for 32 clock cycles.
|
||||
-- After the port is deasserted, the state machine goes into a wait state for
|
||||
-- 32 cycles. This procedure is repeated 32 times.
|
||||
|
||||
-- State registers
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if(RESET='1') then
|
||||
begin_r <= '1' after DLY;
|
||||
align_reset_r <= '0' after DLY;
|
||||
wait_before_setphase_r <= '0' after DLY;
|
||||
phase_align_r <= '0' after DLY;
|
||||
wait_after_sync_r <= '0' after DLY;
|
||||
ready_r <= '0' after DLY;
|
||||
else
|
||||
begin_r <= '0' after DLY;
|
||||
align_reset_r <= next_align_reset_c after DLY;
|
||||
wait_before_setphase_r <= next_wait_before_setphase_c after DLY;
|
||||
phase_align_r <= next_phase_align_c after DLY;
|
||||
wait_after_sync_r <= next_wait_after_sync_c after DLY;
|
||||
ready_r <= next_ready_c after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Next state logic
|
||||
next_align_reset_c <= begin_r or
|
||||
(align_reset_r and not count_align_reset_complete_r);
|
||||
|
||||
next_wait_before_setphase_c <= (align_reset_r and count_align_reset_complete_r) or
|
||||
(wait_before_setphase_r and not count_32_wait_complete_r);
|
||||
|
||||
next_phase_align_c <= (wait_before_setphase_r and count_32_wait_complete_r) or
|
||||
(phase_align_r and not count_32_setphase_complete_r) or
|
||||
(wait_after_sync_r and count_32_wait_complete_r and not sync_32_times_done_r);
|
||||
|
||||
next_wait_after_sync_c <= (phase_align_r and count_32_setphase_complete_r) or
|
||||
(wait_after_sync_r and not count_32_wait_complete_r);
|
||||
|
||||
next_ready_c <= (wait_after_sync_r and count_32_wait_complete_r and sync_32_times_done_r) or
|
||||
ready_r;
|
||||
|
||||
--______ Counter for holding RXDLYALIGNRESET for 20 RXUSRCLK2 cycles ______
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (align_reset_r='0') then
|
||||
align_reset_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
align_reset_counter_r <= align_reset_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if ;
|
||||
end process;
|
||||
|
||||
count_align_reset_complete_r <= align_reset_counter_r(4)
|
||||
and align_reset_counter_r(2);
|
||||
|
||||
--_______Counter for waiting 32 clock cycles before RXPMASETPHASE _________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if ((wait_before_setphase_r='0') and (wait_after_sync_r='0')) then
|
||||
wait_before_setphase_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
wait_before_setphase_counter_r <= wait_before_setphase_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
count_32_wait_complete_r <= wait_before_setphase_counter_r(5);
|
||||
|
||||
--_______________ Counter for holding SYNC for SYNC_CYCLES ________________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (phase_align_r='0') then
|
||||
sync_counter_r <= (others=>'0') after DLY;
|
||||
else
|
||||
sync_counter_r <= sync_counter_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
count_32_setphase_complete_r <= sync_counter_r(5);
|
||||
|
||||
--__________ Counter for counting number of times sync is done ____________
|
||||
process( USER_CLK )
|
||||
begin
|
||||
if(USER_CLK'event and USER_CLK = '1') then
|
||||
if (RESET='1') then
|
||||
sync_done_count_r <= (others=>'0') after DLY;
|
||||
elsif((count_32_wait_complete_r ='1') and (phase_align_r = '1')) then
|
||||
sync_done_count_r <= sync_done_count_r + 1 after DLY;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sync_32_times_done_r <= sync_done_count_r(5);
|
||||
|
||||
--_______________ Assign the phase align ports into the GTX _______________
|
||||
|
||||
RXDLYALIGNRESET <= align_reset_r;
|
||||
RXENPMAPHASEALIGN <= (not begin_r) and (not align_reset_r);
|
||||
RXPMASETPHASE <= phase_align_r;
|
||||
RXDLYALIGNDISABLE <= '1';
|
||||
RXDLYALIGNOVERRIDE <= '1';
|
||||
|
||||
--_______________________ Assign the sync_done port _______________________
|
||||
|
||||
SYNC_DONE <= ready_r;
|
||||
|
||||
|
||||
end RTL;
|
||||
308
hdl/v6vlx_gtxe1_wrapper.vhd
Normal file
308
hdl/v6vlx_gtxe1_wrapper.vhd
Normal file
@@ -0,0 +1,308 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Paul Scherrer Institute (PSI)
|
||||
------------------------------------------------------------------------------
|
||||
-- Unit : v6vlx_gtxe1_wrapper.vhd
|
||||
-- Author : Goran Marinkovic, Section Diagnostic
|
||||
-- : Waldemar Koprek, Section Diagnostic
|
||||
-- : Patric Bucher, Section DSV
|
||||
-- Version : $Revision: 1.1 $
|
||||
------------------------------------------------------------------------------
|
||||
-- Copyright<68> PSI, Section Diagnostic
|
||||
------------------------------------------------------------------------------
|
||||
-- Comment : Wrapper vor Virtex-6 GTX ready to use in HIPA and SwissFEL (SFEL)
|
||||
------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
use work.v6vlx_gtxe1_pkg.all;
|
||||
|
||||
entity v6vlx_gtxe1_wrapper is
|
||||
generic(
|
||||
g_MGT_LOCATION : string; -- "GTXE1_X0Y0" to "GTXE1_X0Y11" | "GTXE1_X0Y16" to "GTXE1_X0Y19"
|
||||
g_FACILITY : string -- "HIPA" | "SFEL"
|
||||
);
|
||||
port(
|
||||
-- MGT serial interface
|
||||
i_mgt_refclk : in std_logic;
|
||||
o_mgt_refclk : out std_logic;
|
||||
i_mgt_rx_p : in std_logic;
|
||||
i_mgt_rx_n : in std_logic;
|
||||
o_mgt_tx_p : out std_logic;
|
||||
o_mgt_tx_n : out std_logic;
|
||||
-- MGT parallel interface
|
||||
o_mgt_status : out std_logic_vector(31 downto 0); -- see lines 134-139 for details
|
||||
i_mgt_control : in std_logic_vector(31 downto 0); -- see lines 127-131 for details
|
||||
o_mgt_recclk : out std_logic;
|
||||
o_mgt_rx_data : out std_logic_vector(15 downto 0);
|
||||
o_mgt_rx_charisk : out std_logic_vector( 1 downto 0)
|
||||
);
|
||||
end v6vlx_gtxe1_wrapper;
|
||||
|
||||
|
||||
architecture RTL of v6vlx_gtxe1_wrapper is
|
||||
|
||||
type typ_align_fsm is (
|
||||
align_idle,
|
||||
align_slide ,
|
||||
align_wait_for_sync
|
||||
);
|
||||
|
||||
signal s_align_fsm : typ_align_fsm := align_idle;
|
||||
|
||||
-- GTXE
|
||||
signal i_mgt : gtxe_in_type;
|
||||
signal o_mgt : gtxe_out_type;
|
||||
signal sl_txoutclk : std_logic;
|
||||
--fifo
|
||||
signal sl_cpu_rx_empty : std_logic;
|
||||
signal sl_gtxe_fifo_rst : std_logic;
|
||||
signal sl_gtxe_rx_sync_done : std_logic;
|
||||
|
||||
signal slv_rxresetdone : std_logic_vector(7 downto 0);
|
||||
signal sl_rx_sync_rst : std_logic;
|
||||
signal sl_rxrecclk : std_logic;
|
||||
|
||||
signal sl_rx0_slide : std_logic;
|
||||
|
||||
signal slv_cnt : unsigned(5 downto 0);
|
||||
|
||||
-- MMCM
|
||||
signal mmcm_CLKFB : std_logic;
|
||||
signal mmcm_CLKFBOUT : std_logic;
|
||||
signal mmcm_LOCKED : std_logic;
|
||||
signal mmcm_RESET : std_logic;
|
||||
signal mmcm_CLOCK : std_logic;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
-- inst_mgt_refclk_bufg: BUFG
|
||||
-- port map
|
||||
-- (
|
||||
-- I => o_mgt.ctrl.REFCLKOUT,
|
||||
-- O => o_mgt_refclk
|
||||
-- );
|
||||
|
||||
-- GTXE INSTANCE ------------------------------------------------------------------
|
||||
gen_gtxe1_sfel: if g_FACILITY = "SFEL" generate
|
||||
ins_v6vlx_gtxe1_sfel: entity work.v6vlx_gtxe1_142MHz8_2Gbps856
|
||||
generic map (
|
||||
g_MGT_LOCATION => g_MGT_LOCATION )
|
||||
port map (
|
||||
i_mgt => i_mgt,
|
||||
o_mgt => o_mgt
|
||||
);
|
||||
end generate;
|
||||
|
||||
gen_gtxe1_hipa: if g_FACILITY = "HIPA" generate
|
||||
ins_v6vlx_gtxe1_hipa: entity work.v6vlx_gtxe1_101MHz27_1Gbps0127
|
||||
generic map (
|
||||
g_MGT_LOCATION => g_MGT_LOCATION )
|
||||
port map (
|
||||
i_mgt => i_mgt,
|
||||
o_mgt => o_mgt
|
||||
);
|
||||
end generate;
|
||||
|
||||
assert not(g_FACILITY /= "HIPA" and g_FACILITY /= "SFEL")
|
||||
report "Invalid value for g_FACILITY, valid values are 'HIPA'|'SFEL'"
|
||||
severity failure;
|
||||
|
||||
|
||||
-- GTXE CONTROL IF ----------------------------------------------------------------
|
||||
i_mgt.ctrl.GTXRESET <= i_mgt_control(0);
|
||||
i_mgt.ctrl.PLLRXRESET <= '0';
|
||||
i_mgt.ctrl.PLLTXRESET <= '0';
|
||||
i_mgt.ctrl.LOOPBACK <= "100"; -- Far-End PMA Loopback --> UG366 page 125
|
||||
i_mgt.ctrl.CLKIN <= i_mgt_refclk;
|
||||
|
||||
-- GTXE STATUS IF (adapted to PSI generic part) -----------------------------------
|
||||
o_mgt_status( 0) <= o_mgt.ctrl.TXPLLLKDET;
|
||||
o_mgt_status( 1) <= o_mgt.ctrl.RXPLLLKDET;
|
||||
o_mgt_status( 2) <= mmcm_LOCKED;
|
||||
o_mgt_status( 3) <= o_mgt.ctrl.TXRESETDONE;
|
||||
o_mgt_status( 4) <= o_mgt.ctrl.RXRESETDONE;
|
||||
o_mgt_status( 5) <= '0'; -- TX_polarity inverted
|
||||
o_mgt_status( 6) <= '0'; -- RX_polarity inverted
|
||||
o_mgt_status( 7) <= '0'; -- reserved
|
||||
o_mgt_status(12 downto 8) <= "00000"; -- DFEEYEDACMON[4:0]
|
||||
o_mgt_status(13) <= '0'; -- RXPRBSERR
|
||||
o_mgt_status(14) <= o_mgt.rx.RXBYTEISALIGNED;
|
||||
o_mgt_status(15) <= o_mgt.rx.RXLOSSOFSYNC(1);
|
||||
---------- additional status -------------
|
||||
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
|
||||
|
||||
|
||||
-- GTXE RX IF ---------------------------------------------------------------------
|
||||
-- MMCM use model based on AR#39430
|
||||
gen_MMCM: if g_FACILITY = "SFEL" generate
|
||||
begin
|
||||
-- Use Core Generator to define parameters -> actual frequency 142.8 MHz
|
||||
mmcm_rxclk : MMCM_BASE
|
||||
generic map (
|
||||
CLKFBOUT_MULT_F => 33.000 , -- Counter multiply value, Now supports non-integer values
|
||||
CLKIN1_PERIOD => 7.002 , -- The reference clock frequency is required for properly configuring the
|
||||
-- LOCK detect circuit and checking to make sure the VCO is operating within
|
||||
-- the allowed range. If no value is specified, a warning should be issued
|
||||
-- stating it was not provided so no error checking will be done.
|
||||
CLKOUT0_DIVIDE_F => 8.250 , -- Counter divide value, Now supports non-integer values but you lose CLKOUT5
|
||||
DIVCLK_DIVIDE => 4 -- Counter divide value, always configured for 50% duty cycle
|
||||
)
|
||||
port map (
|
||||
CLKFBOUT => mmcm_CLKFBOUT, -- 1-bit MMCM Feedback clock output
|
||||
CLKFBOUTB => open, -- 1-bit Inverted MMCM feedback clock output
|
||||
CLKOUT0 => mmcm_CLOCK, -- 1-bit MMCM clock output 0
|
||||
CLKOUT0B => open, -- 1-bit Inverted MMCM clock output 0
|
||||
CLKOUT1 => open, -- 1-bit MMCM clock output 1
|
||||
CLKOUT1B => open, -- 1-bit Inverted MMCM clock output 1
|
||||
CLKOUT2 => open, -- 1-bit MMCM clock output 2
|
||||
CLKOUT2B => open, -- 1-bit Inverted MMCM clock output 2
|
||||
CLKOUT3 => open, -- 1-bit MMCM clock output 3
|
||||
CLKOUT3B => open, -- 1-bit Inverted MMCM clock output 3
|
||||
CLKOUT4 => open, -- 1-bit MMCM clock output 4
|
||||
CLKOUT5 => open, -- 1-bit MMCM clock output 5, not used if CLKOUT0 is not an integer
|
||||
CLKOUT6 => open, -- 1-bit MMCM clock output 6, not used if CLKFBOUT_MULT is not an integer
|
||||
LOCKED => mmcm_LOCKED, -- 1-bit MMC locked signal
|
||||
CLKFBIN => mmcm_CLKFB, -- 1-bit Feedback clock pin to the MMCM
|
||||
CLKIN1 => o_mgt.rx.RXRECCLK, -- 1-bit Reference clock pin 1 to the MMCM
|
||||
PWRDWN => '0', -- 1-bit Power down
|
||||
RST => mmcm_RESET -- 1-bit MMCM global reset pin
|
||||
);
|
||||
|
||||
mmcm_RESET <= not o_mgt.ctrl.RXPLLLKDET;
|
||||
|
||||
rxoutCLKFB_bufg0_i : BUFG
|
||||
port map (
|
||||
O => mmcm_CLKFB,
|
||||
I => mmcm_CLKFBOUT
|
||||
);
|
||||
|
||||
rxoutclk_bufg1_i : BUFG
|
||||
port map (
|
||||
O => sl_rxrecclk,
|
||||
I => mmcm_CLOCK
|
||||
);
|
||||
end generate;
|
||||
|
||||
gen_BUFG: if g_FACILITY = "HIPA" generate
|
||||
begin
|
||||
rxoutclk_bufg0_i : BUFG
|
||||
port map (
|
||||
O => sl_rxrecclk,
|
||||
I => o_mgt.rx.RXRECCLK
|
||||
);
|
||||
|
||||
-- forward lock state
|
||||
mmcm_LOCKED <= o_mgt.ctrl.RXPLLLKDET;
|
||||
|
||||
-- unused without mmcm
|
||||
mmcm_CLKFB <= '0';
|
||||
mmcm_CLKFBOUT <= '0';
|
||||
mmcm_RESET <= '0';
|
||||
mmcm_CLOCK <= '0';
|
||||
end generate;
|
||||
|
||||
o_mgt_recclk <= sl_rxrecclk;
|
||||
|
||||
ins_v6vlx_gtxe1_sync : entity work.v6vlx_gtxe1_sync
|
||||
port map (
|
||||
RXENPMAPHASEALIGN => i_mgt.rx.RXENPMAPHASEALIGN ,
|
||||
RXPMASETPHASE => i_mgt.rx.RXPMASETPHASE ,
|
||||
RXDLYALIGNDISABLE => i_mgt.rx.RXDLYALIGNDISABLE ,
|
||||
RXDLYALIGNOVERRIDE => i_mgt.rx.RXDLYALIGNOVERRIDE,
|
||||
RXDLYALIGNRESET => i_mgt.rx.RXDLYALIGNRESET ,
|
||||
SYNC_DONE => sl_gtxe_rx_sync_done,
|
||||
USER_CLK => sl_rxrecclk,
|
||||
RESET => sl_rx_sync_rst
|
||||
);
|
||||
|
||||
|
||||
prc_rx_reset_done_delay : process ( sl_rxrecclk )
|
||||
begin
|
||||
if rising_edge( sl_rxrecclk ) then
|
||||
slv_rxresetdone <= slv_rxresetdone(6 downto 0) & o_mgt.ctrl.RXRESETDONE;
|
||||
end if;
|
||||
end process ;
|
||||
|
||||
sl_rx_sync_rst <= not slv_rxresetdone(7);
|
||||
|
||||
i_mgt.rx.RXUSRCLK <= sl_rxrecclk;
|
||||
i_mgt.rx.RXUSRCLK2 <= sl_rxrecclk;
|
||||
i_mgt.rx.RXP <= i_mgt_rx_p;
|
||||
i_mgt.rx.RXN <= i_mgt_rx_n;
|
||||
|
||||
i_mgt.rx.RXENMCOMMAALIGN <= '0';
|
||||
i_mgt.rx.RXENPCOMMAALIGN <= '0';
|
||||
i_mgt.rx.RXRESET <= not mmcm_LOCKED;
|
||||
i_mgt.rx.RXCDRRESET <= i_mgt_control(5);
|
||||
i_mgt.rx.RXDLYALIGNMONENB <= '0';
|
||||
|
||||
o_mgt_rx_data <= o_mgt.rx.RXDATA(15 downto 0);
|
||||
o_mgt_rx_charisk <= o_mgt.rx.RXCHARISK( 1 downto 0);
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--RX comma alignment
|
||||
------------------------------------------------------------------------------
|
||||
prc_comma_align : process ( sl_rxrecclk )
|
||||
begin
|
||||
if rising_edge( sl_rxrecclk ) then
|
||||
if o_mgt.ctrl.RXRESETDONE = '0' then
|
||||
s_align_fsm <= align_idle;
|
||||
else
|
||||
case s_align_fsm is
|
||||
when align_idle =>
|
||||
if o_mgt.rx.RXLOSSOFSYNC( 1) = '1' then
|
||||
s_align_fsm <= align_slide;
|
||||
end if;
|
||||
when align_slide =>
|
||||
slv_cnt <= (others => '0');
|
||||
s_align_fsm <= align_wait_for_sync;
|
||||
when align_wait_for_sync =>
|
||||
if slv_cnt(slv_cnt'left) = '1' then
|
||||
if o_mgt.rx.RXLOSSOFSYNC( 1) = '0' and o_mgt.rx.RXBYTEISALIGNED = '1' then
|
||||
s_align_fsm <= align_idle;
|
||||
else
|
||||
s_align_fsm <= align_slide;
|
||||
end if;
|
||||
else
|
||||
slv_cnt <= slv_cnt + X"1";
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process ;
|
||||
|
||||
sl_rx0_slide <= '1' when s_align_fsm = align_slide or i_mgt_control(2) = '1' else '0';
|
||||
|
||||
i_mgt.rx.RXSLIDE <= sl_rx0_slide;
|
||||
|
||||
-- GTXE TX IF ---------------------------------------------------------------------
|
||||
o_mgt_tx_p <= o_mgt.tx.TXP;
|
||||
o_mgt_tx_n <= o_mgt.tx.TXN;
|
||||
|
||||
-- txoutclk_bufg0_i : BUFG
|
||||
-- port map (
|
||||
-- I => o_mgt.tx.TXOUTCLK,
|
||||
-- O => sl_txoutclk
|
||||
-- );
|
||||
|
||||
i_mgt.tx.TXRESET <= not mmcm_LOCKED;
|
||||
i_mgt.tx.TXBYPASS8B10B <= X"0";
|
||||
i_mgt.tx.TXCHARDISPMODE <= X"0";
|
||||
i_mgt.tx.TXCHARDISPVAL <= X"0";
|
||||
i_mgt.tx.TXUSRCLK <= sl_rxrecclk;
|
||||
i_mgt.tx.TXUSRCLK2 <= sl_rxrecclk;
|
||||
i_mgt.tx.TXDIFFCTRL <= "0110";
|
||||
i_mgt.tx.TXPOSTEMPHASIS <= "00000";
|
||||
i_mgt.tx.TXPREEMPHASIS <= "0000";
|
||||
|
||||
end RTL;
|
||||
14
sigasi/.library_mapping.xml
Normal file
14
sigasi/.library_mapping.xml
Normal 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/IEEE Synopsys" Library="ieee"/>
|
||||
<Mappings Location="Common Libraries" 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_util" 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
75
sigasi/.project
Normal 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/readme.txt</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/IEEE</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/2008/IEEE</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/IEEE Synopsys</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/2008/IEEE%20Synopsys</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/STD</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/2008/STD</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/uvvm_util</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/UVVM/uvvm_util</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
1
sigasi/.settings/com.sigasi.hdt.vhdl.version.prefs
Normal file
1
sigasi/.settings/com.sigasi.hdt.vhdl.version.prefs
Normal file
@@ -0,0 +1 @@
|
||||
<project>=2008
|
||||
5
sigasi/.settings/org.eclipse.core.resources.prefs
Normal file
5
sigasi/.settings/org.eclipse.core.resources.prefs
Normal 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
|
||||
22
sim/.gitignore
vendored
Normal file
22
sim/.gitignore
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# ignore ModelSim generated files and directories (temp files and so on)
|
||||
[_@]*
|
||||
|
||||
*.txt
|
||||
*.mti
|
||||
*.dat
|
||||
*.dbs
|
||||
*.psm
|
||||
*.bak
|
||||
*.cmp
|
||||
*.jpg
|
||||
*.html
|
||||
*.bsf
|
||||
wlf*
|
||||
*.wlf
|
||||
*.vstf
|
||||
*.ucdb
|
||||
cov*/
|
||||
Transcript*
|
||||
transcript*
|
||||
sc_dpiheader.h
|
||||
vsim.dbg
|
||||
@@ -1,34 +1,84 @@
|
||||
#Constants
|
||||
set LibPath "../../.."
|
||||
|
||||
#Import psi::sim library
|
||||
namespace import psi::sim::*
|
||||
|
||||
#Set library
|
||||
add_library evr320
|
||||
|
||||
#suppress messages
|
||||
compile_suppress 135,1236
|
||||
run_suppress 8684,3479,3813,8009,3812
|
||||
|
||||
#Set library path relative to this config file
|
||||
variable fileLoc [file normalize [file dirname [info script]]]
|
||||
variable LibPath $fileLoc/../../../..
|
||||
|
||||
# EVR320 Library
|
||||
add_sources $LibPath/VHDL/evr320/hdl {
|
||||
# tosca2_glb_pkg dependency
|
||||
add_library tosca2
|
||||
|
||||
add_sources $LibPath/BoardSupport/IFC1210/tosca2/hdl/top_ip/src {
|
||||
tosca2_glb_pkg.vhd \
|
||||
} -version 2002
|
||||
|
||||
add_sources $LibPath/BoardSupport/IFC1210/tosca2/testbench/utilities {
|
||||
ifc1210_simu_mapping_xuser_pkg.vhd \
|
||||
ifc1210_simu_procedures_pkg.vhd \
|
||||
}
|
||||
|
||||
#Set library
|
||||
add_library evr320
|
||||
|
||||
# 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 \
|
||||
psi_common_pulse_shaper_cfg.vhd \
|
||||
psi_common_delay_cfg.vhd \
|
||||
psi_common_simple_cc.vhd \
|
||||
psi_common_status_cc.vhd \
|
||||
} -tag psi_common
|
||||
|
||||
# EVR320 Decoder
|
||||
add_sources $LibPath/Firmware/VHDL/evr320/hdl {
|
||||
evr320_pkg.vhd \
|
||||
evr320_buffer.vhd \
|
||||
evr320_dpram.vhd \
|
||||
evr320_timestamp.vhd \
|
||||
evr320_decoder.vhd \
|
||||
} -tag lib
|
||||
evr320_data_filter.vhd \
|
||||
} -tag evr320_decoder
|
||||
|
||||
# Lib tosca2 dependecies
|
||||
add_sources $LibPath/BoardSupport/IFC1210/tosca2/hdl/top_ip/src/ {
|
||||
tosca2_glb_pkg.vhd \
|
||||
} -tag tosca2
|
||||
|
||||
# Lib ifc1210
|
||||
add_sources $LibPath/VHDL/evr320/hdl {
|
||||
pkg_v6vlx_gtxe1.vhd \
|
||||
# IFC1210 Bindings
|
||||
add_sources $LibPath/Firmware/VHDL/evr320/hdl {
|
||||
v6vlx_gtxe1_pkg.vhd \
|
||||
v6vlx_gtxe1_101MHz27_1Gbps0127.vhd \
|
||||
v6vlx_gtxe1_142MHz8_2Gbps856.vhd \
|
||||
v6vlx_gtxe1_sync.vhd \
|
||||
v6vlx_gtxe1_wrapper.vhd \
|
||||
evr320_tmem.vhd \
|
||||
evr320_ifc1210_wrapper.vhd \
|
||||
} -tag ifc1210
|
||||
} -tag evr320_ifc1210
|
||||
|
||||
# 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
|
||||
#add_sources $LibPath/Firmware/VHDL/evr320/tb {
|
||||
# evr320_ifc1210_wrapper_tb.vhd \
|
||||
#} -tag evr320_ifc1210_wrapper_tb
|
||||
|
||||
# setup tb runs
|
||||
create_tb_run "evr320_decoder_tb"
|
||||
tb_run_add_arguments \
|
||||
"-gg_EVENT_NR_0=16#0F# -gg_EVENT_NR_1=0 -gg_EVENT_NR_2=0 -gg_EVENT_NR_3=0 -gg_EVENT_NR_SOS=0" \
|
||||
"-gg_EVENT_NR_0=2 -gg_EVENT_NR_1=4 -gg_EVENT_NR_2=0 -gg_EVENT_NR_3=3 -gg_EVENT_NR_SOS=0" \
|
||||
"-gg_EVENT_NR_0=0 -gg_EVENT_NR_1=0 -gg_EVENT_NR_2=5 -gg_EVENT_NR_3=0 -gg_EVENT_NR_SOS=6"
|
||||
add_tb_run
|
||||
|
||||
create_tb_run "evr320_ifc1210_wrapper_tb"
|
||||
add_tb_run
|
||||
|
||||
38
sim/run.tcl
38
sim/run.tcl
@@ -1,5 +1,16 @@
|
||||
#Load dependencies
|
||||
source ../../../TCL/PsiSim/PsiSim.tcl
|
||||
# Library Path
|
||||
set LibPath "../../../.."
|
||||
|
||||
# Configure UVVM -> until compile when not existing
|
||||
set uvvm_path $LibPath/Firmware/VHDL/UVVM/uvvm_util
|
||||
if {[file isdirectory uvvm_util]} {
|
||||
puts "UVVM directory evr320/sim/uvvm_util is present --> not compiled again!"
|
||||
} else {
|
||||
do $uvvm_path/script/compile_src.do $uvvm_path
|
||||
}
|
||||
|
||||
#Load dependencies TODO
|
||||
source $LibPath/Firmware/TCL/PsiSim/PsiSim.tcl
|
||||
|
||||
#Import psi::sim library
|
||||
namespace import psi::sim::*
|
||||
@@ -10,15 +21,20 @@ init
|
||||
#Configure
|
||||
source ./config.tcl
|
||||
|
||||
#Run Simulation
|
||||
# Run Simulation
|
||||
puts "------------------------------"
|
||||
puts "-- Compile EVR320 Core"
|
||||
puts "-- Compile"
|
||||
puts "------------------------------"
|
||||
compile_files -tag lib -clean
|
||||
#puts "------------------------------"
|
||||
#puts "-- Compile TOSCA2 Bindings"
|
||||
#puts "------------------------------"
|
||||
#compile_files -tag tosca2
|
||||
#compile_files -tag ifc1210
|
||||
clean_libraries -all
|
||||
compile_files -tag psi_common
|
||||
compile_files -lib tosca2
|
||||
compile_files -tag evr320_decoder
|
||||
compile_files -tag evr320_ifc1210
|
||||
#compile_files -tag evr320_decoder_tb
|
||||
compile_files -tag evr320_tb
|
||||
#compile_files -lib evr320
|
||||
|
||||
run_check_errors "###ERROR###"
|
||||
#run_tb -all
|
||||
run_tb -name evr320_decoder_tb
|
||||
run_tb -name evr320_ifc1210_wrapper_tb
|
||||
run_check_errors "###ERROR###"
|
||||
|
||||
290
tb/adaptations_pkg.vhd
Normal file
290
tb/adaptations_pkg.vhd
Normal file
@@ -0,0 +1,290 @@
|
||||
--========================================================================================================================
|
||||
-- Copyright (c) 2017 by Bitvis AS. All rights reserved.
|
||||
-- You should have received a copy of the license file containing the MIT License (see LICENSE.TXT), if not,
|
||||
-- contact Bitvis AS <support@bitvis.no>.
|
||||
--
|
||||
-- UVVM AND ANY PART THEREOF ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
-- WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
-- OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH UVVM OR THE USE OR OTHER DEALINGS IN UVVM.
|
||||
--========================================================================================================================
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
-- Description : See library quick reference (under 'doc') and README-file(s)
|
||||
------------------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
|
||||
use work.types_pkg.all;
|
||||
|
||||
package adaptations_pkg is
|
||||
constant C_ALERT_FILE_NAME : string := "_Alert.txt";
|
||||
constant C_LOG_FILE_NAME : string := "_Log.txt";
|
||||
|
||||
constant C_SHOW_UVVM_UTILITY_LIBRARY_INFO : boolean := false; -- Set this to false when you no longer need the initial info
|
||||
constant C_SHOW_UVVM_UTILITY_LIBRARY_RELEASE_INFO : boolean := false; -- Set this to false when you no longer need the release info
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Log format
|
||||
-------------------------------------------------------------------------------
|
||||
--UVVM: [<ID>] <time> <Scope> Msg
|
||||
--PPPPPPPPIIIIII TTTTTTTT SSSSSSSSSSSSSS MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
constant C_LOG_PREFIX : string := "UVVM: "; -- Note: ': ' is recommended as final characters
|
||||
|
||||
constant C_LOG_PREFIX_WIDTH : natural := C_LOG_PREFIX'length;
|
||||
constant C_LOG_MSG_ID_WIDTH : natural := 18;
|
||||
constant C_LOG_TIME_WIDTH : natural := 14; -- 3 chars used for unit eg. " ns"
|
||||
constant C_LOG_TIME_BASE : time := ns; -- Unit in which time is shown in log (ns | ps)
|
||||
constant C_LOG_TIME_DECIMALS : natural := 1; -- Decimals to show for given C_LOG_TIME_BASE
|
||||
constant C_LOG_SCOPE_WIDTH : natural := 16;
|
||||
constant C_LOG_LINE_WIDTH : natural := 200;
|
||||
constant C_LOG_INFO_WIDTH : natural := C_LOG_LINE_WIDTH - C_LOG_PREFIX_WIDTH;
|
||||
|
||||
constant C_USE_BACKSLASH_N_AS_LF : boolean := true; -- If true interprets '\n' as Line feed
|
||||
constant C_USE_BACKSLASH_R_AS_LF : boolean := true; -- If true, inserts an empty line if '\r'
|
||||
-- is the first character of the string.
|
||||
-- All others '\r' will be printed as is.
|
||||
|
||||
constant C_SINGLE_LINE_ALERT : boolean := false; -- If true prints alerts on a single line.
|
||||
constant C_SINGLE_LINE_LOG : boolean := false; -- If true prints log messages on a single line.
|
||||
|
||||
constant C_TB_SCOPE_DEFAULT : string := "TB_SCOPE"; -- Default scope in test sequencer
|
||||
|
||||
constant C_LOG_TIME_TRUNC_WARNING : boolean := false; -- Yields a single TB_WARNING if time stamp truncated. Otherwise none
|
||||
constant C_SHOW_LOG_ID : boolean := true; -- This constant has replaced the global_show_log_id
|
||||
constant C_SHOW_LOG_SCOPE : boolean := true; -- This constant has replaced the global_show_log_scope
|
||||
|
||||
constant C_WARNING_ON_LOG_ALERT_FILE_RUNTIME_RENAME : boolean := false;
|
||||
|
||||
constant C_USE_STD_STOP_ON_ALERT_STOP_LIMIT : boolean := true; -- true: break using std.env.stop, false: break using failure
|
||||
|
||||
shared variable shared_default_log_destination : t_log_destination := CONSOLE_AND_LOG;
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Verbosity control
|
||||
-- NOTE: Do not enter new IDs without proper evaluation:
|
||||
-- 1. Is it - or could it be covered by an existing ID
|
||||
-- 2. Could it be combined with other needs for a more general new ID
|
||||
-- Feel free to suggest new ID for future versions of UVVM Utility Library (support@bitvis.no)
|
||||
-------------------------------------------------------------------------------
|
||||
type t_msg_id is (
|
||||
-- Bitvis utility methods
|
||||
NO_ID, -- Used as default prior to setting actual ID when transfering ID as a field in a record
|
||||
ID_UTIL_BURIED, -- Used for buried log messages where msg and scope cannot be modified from outside
|
||||
ID_BITVIS_DEBUG, -- Bitvis internal ID used for UVVM debugging
|
||||
ID_UTIL_SETUP, -- Used for Utility setup
|
||||
ID_LOG_MSG_CTRL, -- Used inside Utility library only - when enabling/disabling msg IDs.
|
||||
ID_ALERT_CTRL, -- Used inside Utility library only - when setting IGNORE or REGARD on various alerts.
|
||||
ID_NEVER, -- Used for avoiding log entry. Cannot be enabled.
|
||||
ID_FINISH_OR_STOP, -- Used when terminating the complete simulation - independent of why
|
||||
ID_CLOCK_GEN, -- Used for logging when clock generators are enabled or disabled
|
||||
ID_GEN_PULSE, -- Used for logging when a gen_pulse procedure starts pulsing a signal
|
||||
ID_BLOCKING, -- Used for logging when using synchronisation flags
|
||||
-- General
|
||||
ID_POS_ACK, -- To write a positive acknowledge on a check
|
||||
-- Directly inside test sequencers
|
||||
ID_LOG_HDR, -- ONLY allowed in test sequencer, Log section headers
|
||||
ID_LOG_HDR_LARGE, -- ONLY allowed in test sequencer, Large log section headers
|
||||
ID_LOG_HDR_XL, -- ONLY allowed in test sequencer, Extra large log section headers
|
||||
ID_SEQUENCER, -- ONLY allowed in test sequencer, Normal log (not log headers)
|
||||
ID_SEQUENCER_SUB, -- ONLY allowed in test sequencer, Subprograms defined in sequencer
|
||||
-- BFMs
|
||||
ID_BFM, -- Used inside a BFM (to log BFM access)
|
||||
ID_BFM_WAIT, -- Used inside a BFM to indicate that it is waiting for something (e.g. for ready)
|
||||
ID_BFM_POLL, -- Used inside a BFM when polling until reading a given value. I.e. to show all reads until expected value found (e.g. for sbi_poll_until())
|
||||
ID_BFM_POLL_SUMMARY, -- Used inside a BFM when showing the summary of data that has been received while waiting for expected data.
|
||||
ID_TERMINATE_CMD, -- Typically used inside a loop in a procedure to end the loop (e.g. for sbi_poll_until() or any looped generation of random stimuli
|
||||
-- Packet related data Ids with three levels of granularity, for differentiating between frames, packets and segments.
|
||||
-- Segment Ids, finest granularity of packet data
|
||||
ID_SEGMENT_INITIATE, -- Notify that a packet is about to be transmitted or received
|
||||
ID_SEGMENT_COMPLETE, -- Notify that a packet has been transmitted or received
|
||||
ID_SEGMENT_HDR, -- AS ID_SEGMENT_COMPLETE, but also writes header info
|
||||
ID_SEGMENT_DATA, -- AS ID_SEGMENT_COMPLETE, but also writes packet data (could be huge)
|
||||
-- Packet Ids, medium granularity of packet data
|
||||
ID_PACKET_INITIATE, -- Notify that a packet is about to be transmitted or received
|
||||
ID_PACKET_COMPLETE, -- Notify that a packet has been transmitted or received
|
||||
ID_PACKET_HDR, -- AS ID_PACKET_COMPLETED, but also writes header info
|
||||
ID_PACKET_DATA, -- AS ID_PACKET_COMPLETED, but also writes packet data (could be huge)
|
||||
-- Frame Ids, roughest granularity of packet data
|
||||
ID_FRAME_INITIATE, -- Notify that a packet is about to be transmitted or received
|
||||
ID_FRAME_COMPLETE, -- Notify that a packet has been transmitted or received
|
||||
ID_FRAME_HDR, -- AS ID_FRAME_COMPLETE, but also writes header info
|
||||
ID_FRAME_DATA, -- AS ID_FRAME_COMPLETE, but also writes packet data (could be huge)
|
||||
-- OSVVM Ids
|
||||
ID_COVERAGE_MAKEBIN, -- Log messages from MakeBin (IllegalBin/GenBin/IgnoreBin)
|
||||
ID_COVERAGE_ADDBIN, -- Log messages from AddBin/AddCross
|
||||
ID_COVERAGE_ICOVER, -- ICover logging, NB: Very low level debugging. Can result in large amount of data.
|
||||
ID_COVERAGE_CONFIG, -- Logging of configuration in the coverage package
|
||||
ID_COVERAGE_SUMMARY, -- Report logging : Summary of coverage, with both covered bins and holes
|
||||
ID_COVERAGE_HOLES, -- Report logging : Holes only
|
||||
-- Distributed command systems
|
||||
ID_UVVM_SEND_CMD,
|
||||
ID_UVVM_CMD_ACK,
|
||||
ID_UVVM_CMD_RESULT,
|
||||
ID_CMD_INTERPRETER, -- Message from VVC interpreter about correctly received and queued/issued command
|
||||
ID_CMD_INTERPRETER_WAIT, -- Message from VVC interpreter that it is actively waiting for a command
|
||||
ID_IMMEDIATE_CMD, -- Message from VVC interpreter that an IMMEDIATE command has been executed
|
||||
ID_IMMEDIATE_CMD_WAIT, -- Message from VVC interpreter that an IMMEDIATE command is waiting for command to complete
|
||||
ID_CMD_EXECUTOR, -- Message from VVC executor about correctly received command - prior to actual execution
|
||||
ID_CMD_EXECUTOR_WAIT, -- Message from VVC executor that it is actively waiting for a command
|
||||
ID_INSERTED_DELAY, -- Message from VVC executor that it is waiting a given delay
|
||||
-- Distributed data
|
||||
ID_UVVM_DATA_QUEUE, -- Information about UVVM data FIFO/stack (initialization, put, get, etc)
|
||||
-- VVC system
|
||||
ID_CONSTRUCTOR, -- Constructor message from VVCs (or other components/process when needed)
|
||||
ID_CONSTRUCTOR_SUB, -- Constructor message for lower level constructor messages (like Queue-information and other limitations)
|
||||
-- SB package
|
||||
ID_DATA,
|
||||
ID_CTRL,
|
||||
-- Special purpose - Not really IDs
|
||||
ALL_MESSAGES -- Applies to ALL message ID apart from ID_NEVER
|
||||
);
|
||||
type t_msg_id_panel is array (t_msg_id'left to t_msg_id'right) of t_enabled;
|
||||
|
||||
constant C_TB_MSG_ID_DEFAULT : t_msg_id := ID_SEQUENCER; -- msg ID used when calling the log method without any msg ID switch.
|
||||
|
||||
-- Default message Id panel to be used for all message Id panels, except:
|
||||
-- - VVC message Id panels, see constant C_VVC_MSG_ID_PANEL_DEFAULT
|
||||
constant C_MSG_ID_PANEL_DEFAULT : t_msg_id_panel := (
|
||||
ID_NEVER => DISABLED,
|
||||
ID_UTIL_BURIED => DISABLED,
|
||||
ID_BITVIS_DEBUG => DISABLED,
|
||||
ID_COVERAGE_MAKEBIN => DISABLED,
|
||||
ID_COVERAGE_ADDBIN => DISABLED,
|
||||
ID_COVERAGE_ICOVER => DISABLED,
|
||||
others => ENABLED
|
||||
);
|
||||
|
||||
-- If false, OSVVM uses the default message id panel. If true, it uses a separate message id panel.
|
||||
constant C_USE_LOCAL_OSVVM_MSG_ID_PANELS : boolean := TRUE;
|
||||
|
||||
type t_msg_id_indent is array (t_msg_id'left to t_msg_id'right) of string(1 to 4);
|
||||
constant C_MSG_ID_INDENT : t_msg_id_indent := (
|
||||
ID_IMMEDIATE_CMD_WAIT => " ..",
|
||||
ID_CMD_INTERPRETER => " " & NUL & NUL,
|
||||
ID_CMD_INTERPRETER_WAIT => " ..",
|
||||
ID_CMD_EXECUTOR => " " & NUL & NUL,
|
||||
ID_CMD_EXECUTOR_WAIT => " ..",
|
||||
ID_UVVM_SEND_CMD => "->" & NUL & NUL,
|
||||
ID_UVVM_CMD_ACK => " ",
|
||||
others => "" & NUL & NUL & NUL & NUL
|
||||
);
|
||||
|
||||
constant C_MSG_DELIMITER : character := ''';
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- Alert counters
|
||||
-------------------------------------------------------------------------
|
||||
-- Default values. These can be overwritten in each sequencer by using
|
||||
-- set_alert_attention or set_alert_stop_limit (see quick ref).
|
||||
constant C_DEFAULT_ALERT_ATTENTION : t_alert_attention := (others => REGARD);
|
||||
|
||||
-- 0 = Never stop
|
||||
constant C_DEFAULT_STOP_LIMIT : t_alert_counters := (note to manual_check => 0,
|
||||
others => 1);
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- Hierarchical alerts
|
||||
-------------------------------------------------------------------------
|
||||
constant C_ENABLE_HIERARCHICAL_ALERTS : boolean := false;
|
||||
constant C_BASE_HIERARCHY_LEVEL : string(1 to 5) := "Total";
|
||||
|
||||
constant C_EMPTY_NODE : t_hierarchy_node := (" ",
|
||||
(others => (others => 0)),
|
||||
(others => 0),
|
||||
(others => true));
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- Deprecate
|
||||
-------------------------------------------------------------------------
|
||||
-- These values are used to indicate outdated sub-programs
|
||||
constant C_DEPRECATE_SETTING : t_deprecate_setting := DEPRECATE_ONCE;
|
||||
shared variable deprecated_subprogram_list : t_deprecate_list := (others=>(others => ' '));
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- UVVM VVC Framework adaptations
|
||||
------------------------------------------------------------------------
|
||||
constant C_SCOPE : string := C_TB_SCOPE_DEFAULT & "(uvvm)";
|
||||
|
||||
signal global_show_msg_for_uvvm_cmd : boolean := true;
|
||||
|
||||
constant C_CMD_QUEUE_COUNT_MAX : natural := 20; -- (VVC Command queue) May be overwritten for dedicated VVC
|
||||
constant C_CMD_QUEUE_COUNT_THRESHOLD_SEVERITY : t_alert_level := WARNING;
|
||||
constant C_CMD_QUEUE_COUNT_THRESHOLD : natural := 18;
|
||||
constant C_RESULT_QUEUE_COUNT_MAX : natural := 20; -- (VVC Result queue) May be overwritten for dedicated VVC
|
||||
constant C_RESULT_QUEUE_COUNT_THRESHOLD_SEVERITY : t_alert_level := WARNING;
|
||||
constant C_RESULT_QUEUE_COUNT_THRESHOLD : natural := 18;
|
||||
constant C_MAX_VVC_INSTANCE_NUM : natural := 20;
|
||||
constant C_MAX_NUM_SEQUENCERS : natural := 10; -- Max number of sequencers
|
||||
|
||||
-- Maximum allowed length of VVC names
|
||||
constant C_MAX_VVC_NAME_LENGTH : positive := 20;
|
||||
|
||||
-- Minimum width of vvc name and channel displayed in scope.
|
||||
-- These combined + the length of instance + 2 (commas), cannot exceed C_LOG_SCOPE_WIDTH.
|
||||
constant C_MINIMUM_CHANNEL_SCOPE_WIDTH : natural := 10;
|
||||
constant C_MINIMUM_VVC_NAME_SCOPE_WIDTH : natural := 10;
|
||||
|
||||
constant C_TOTAL_NUMBER_OF_BITS_IN_DATA_BUFFER : natural := 2048;
|
||||
constant C_NUMBER_OF_DATA_BUFFERS : natural := 10;
|
||||
|
||||
-- Default message Id panel intended for use in the VVCs
|
||||
constant C_VVC_MSG_ID_PANEL_DEFAULT : t_msg_id_panel := (
|
||||
ID_NEVER => DISABLED,
|
||||
ID_UTIL_BURIED => DISABLED,
|
||||
others => ENABLED
|
||||
);
|
||||
|
||||
type t_data_source is ( -- May add more types of random ++ later
|
||||
NA,
|
||||
FROM_BUFFER,
|
||||
RANDOM,
|
||||
RANDOM_TO_BUFFER
|
||||
);
|
||||
|
||||
type t_error_injection is ( -- May add more controlled error injection later
|
||||
NA,
|
||||
RANDOM_BIT_ERROR,
|
||||
RANDOM_DATA_ERROR,
|
||||
RANDOM_ADDRESS_ERROR
|
||||
);
|
||||
|
||||
constant C_CMD_IDX_PREFIX : string := " [";
|
||||
constant C_CMD_IDX_SUFFIX : string := "]";
|
||||
|
||||
type t_channel is ( -- NOTE: Add more types of channels when needed for a VVC
|
||||
NA, -- When channel is not relevant
|
||||
ALL_CHANNELS, -- When command shall be received by all channels
|
||||
RX,
|
||||
TX);
|
||||
|
||||
constant C_VVCT_ALL_INSTANCES, ALL_INSTANCES : integer := -2;
|
||||
constant ALL_ENABLED_INSTANCES : integer := -3;
|
||||
|
||||
constant C_NUM_SEMAPHORE_LOCK_TRIES : natural := 500;
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- Scoreboard adaptations
|
||||
------------------------------------------------------------------------
|
||||
constant C_MAX_QUEUE_INSTANCE_NUM : positive := 100; -- Maximum number of instances
|
||||
constant C_SB_TAG_WIDTH : positive := 128; -- Number of characters in SB tag
|
||||
constant C_SB_SOURCE_WIDTH : positive := 128; -- Number of characters in SB source element
|
||||
constant C_SB_SLV_WIDTH : positive := 8; -- Width of the SLV in the predefined SLV SB
|
||||
|
||||
-- Default message Id panel intended for use in SB
|
||||
constant C_SB_MSG_ID_PANEL_DEFAULT : t_msg_id_panel := (
|
||||
ID_CTRL => ENABLED,
|
||||
ID_DATA => DISABLED,
|
||||
others => DISABLED
|
||||
);
|
||||
|
||||
end package adaptations_pkg;
|
||||
|
||||
package body adaptations_pkg is
|
||||
end package body adaptations_pkg;
|
||||
567
tb/evr320_decoder_tb.vhd
Normal file
567
tb/evr320_decoder_tb.vhd
Normal file
@@ -0,0 +1,567 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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
|
||||
generic (
|
||||
g_EVENT_NR_0 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_1 : integer range 0 to 255 := 16#04#;
|
||||
g_EVENT_NR_2 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_3 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_SOS : integer range 0 to 255 := 16#20#
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture testbench of evr320_decoder_tb is
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- System
|
||||
---------------------------------------------------------------------------
|
||||
constant C_RXUSRCLK_CYCLE : time:= 7 ns;
|
||||
constant C_USRCLK_CYCLE : time:= 8 ns;
|
||||
constant C_EVT_NR : integer := 4;
|
||||
constant C_MEM_DATA_WIDTH : integer := 32; -- 32|64 (64 bit used for tosca2 on ifc1210)
|
||||
constant C_EVENT_RECORDER : boolean := true;
|
||||
constant C_EVENT_REC_FLAGS : std_logic_vector(11 downto 6) := B"1101_11";
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- 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;
|
||||
|
||||
constant FILTER_ADDRESS : std_logic_vector(11 downto 0) := x"028";
|
||||
constant FILTER_NUM_BYTES : integer := 8;
|
||||
constant STIMULI_RUNS : integer := 2;
|
||||
|
||||
signal filter_data, filter_data_check : std_logic_vector(63 downto 0) := (others => '0');
|
||||
signal filter_valid : std_logic := '0';
|
||||
|
||||
-- Events
|
||||
signal usr_events : std_logic_vector( 3 downto 0) := (others => '0');
|
||||
signal sos_event : std_logic := '0';
|
||||
|
||||
type typ_arrint is array (natural range <>) of integer;
|
||||
signal received_events : typ_arrint(0 to C_EVT_NR-1) := (others => 0);
|
||||
signal expect_events : typ_arrint(0 to C_EVT_NR-1) := (others => 0);
|
||||
signal expect_events_total : integer := 0;
|
||||
|
||||
-- Event Recorder
|
||||
signal event_recorder_status : typ_evt_rec_status;
|
||||
signal event_recorder_ctrl : typ_evt_rec_ctrl := c_INIT_EVT_REC_CTRL;
|
||||
signal check_evt_rec_events : std_logic := '0';
|
||||
signal all_expected_events : std_logic_vector(255 downto 0) := (others => '0');
|
||||
signal expected_user_events : integer range 0 to 255 := 0;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder
|
||||
-----------------------------------------------------------------------------
|
||||
evr320_decoder_inst: entity work.evr320_decoder
|
||||
generic map
|
||||
(
|
||||
EVENT_RECORDER => C_EVENT_RECORDER,
|
||||
MEM_DATA_WIDTH => C_MEM_DATA_WIDTH
|
||||
)
|
||||
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 => event_recorder_status,
|
||||
i_event_recorder_ctrl => event_recorder_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 => sos_event
|
||||
);
|
||||
|
||||
evr320_data_filter_inst: entity work.evr320_data_filter
|
||||
generic map (
|
||||
SWAP => false
|
||||
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,
|
||||
i_address => FILTER_ADDRESS,
|
||||
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;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- 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_total : integer := 0;
|
||||
variable event_cnt_0 : integer := 0;
|
||||
variable event_cnt_1 : integer := 0;
|
||||
variable event_cnt_2 : integer := 0;
|
||||
variable event_cnt_3 : integer := 0;
|
||||
variable event_cnt_user : 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_total := event_cnt_total + 1;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_0, 8))) then
|
||||
event_cnt_0 := event_cnt_0 + 1;
|
||||
end if;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_1, 8))) then
|
||||
event_cnt_1 := event_cnt_1 + 1;
|
||||
end if;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_2, 8))) then
|
||||
event_cnt_2 := event_cnt_2 + 1;
|
||||
end if;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_3, 8))) then
|
||||
event_cnt_3 := event_cnt_3 + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
expect_events_total <= event_cnt_total * STIMULI_RUNS;
|
||||
expect_events(0) <= event_cnt_0 * STIMULI_RUNS;
|
||||
expect_events(1) <= event_cnt_1 * STIMULI_RUNS;
|
||||
expect_events(2) <= event_cnt_2 * STIMULI_RUNS;
|
||||
expect_events(3) <= event_cnt_3 * STIMULI_RUNS;
|
||||
|
||||
-- Event Recorder:
|
||||
------------------
|
||||
if (event_k = "0") then
|
||||
all_expected_events(to_integer(unsigned(event))) <= '1';
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8))) then
|
||||
log("Start-of-Sequence Event in Stimuli present");
|
||||
end if;
|
||||
if (event /= X"00" and event(7 downto 4) /= X"7") then
|
||||
event_cnt_user := event_cnt_user + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
expected_user_events <= event_cnt_user;
|
||||
|
||||
-- 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;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- 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;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- 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=" & to_string(filter_data, HEX, AS_IS, INCL_RADIX));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for User Events
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(rxusrclk);
|
||||
for i in 0 to C_EVT_NR-1 loop
|
||||
if (usr_events(i) = '1') then
|
||||
log(ID_CTRL, "Event Received: " & to_string(evr_params.event_numbers(i), HEX, AS_IS, INCL_RADIX) );
|
||||
received_events(i) <= received_events(i) + 1;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for Start of Sequence Event
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(rxusrclk);
|
||||
if (sos_event = '1') then
|
||||
log(ID_CTRL, "Start of Sequence Event Received: "& to_string(std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8)), HEX, AS_IS, INCL_RADIX) ); -- change to await_value
|
||||
check_evt_rec_events <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- 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);
|
||||
variable expected_evt_rec_events : integer range 0 to 255 := 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) <= '0' when g_EVENT_NR_0 = 0 else '1';
|
||||
evr_params.event_enable( 1) <= '0' when g_EVENT_NR_1 = 0 else '1';
|
||||
evr_params.event_enable( 2) <= '0' when g_EVENT_NR_2 = 0 else '1';
|
||||
evr_params.event_enable( 3) <= '0' when g_EVENT_NR_3 = 0 else '1';
|
||||
event_recorder_ctrl.event_enable <= '0' when g_EVENT_NR_SOS = 0 else '1';
|
||||
evr_params.event_numbers( 0) <= std_logic_vector(to_unsigned(g_EVENT_NR_0, 8));
|
||||
evr_params.event_numbers( 1) <= std_logic_vector(to_unsigned(g_EVENT_NR_1, 8));
|
||||
evr_params.event_numbers( 2) <= std_logic_vector(to_unsigned(g_EVENT_NR_2, 8));
|
||||
evr_params.event_numbers( 3) <= std_logic_vector(to_unsigned(g_EVENT_NR_3, 8));
|
||||
event_recorder_ctrl.event_number <= std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8));
|
||||
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_LOG_HDR, "Send stimuli stream to MGT - RUN " & to_string(b+1));
|
||||
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;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "Check if decoder stream is correct", C_SCOPE);
|
||||
--------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "Check if filter data is correct", C_SCOPE);
|
||||
--------------------------------------------------------------------------
|
||||
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
|
||||
--------------------------------------------------------------------------
|
||||
for i in 0 to C_EVT_NR-1 loop
|
||||
check_value(received_events(i), expect_events(i), ERROR, "Event " & to_string(i) & ": received = " & to_string(received_events(i)) & ", expected = " & to_string(expect_events(i)));
|
||||
end loop;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "Event Recorder Checks", C_SCOPE);
|
||||
--------------------------------------------------------------------------
|
||||
wait for 1 us;
|
||||
if (C_EVENT_RECORDER) then
|
||||
if (check_evt_rec_events = '1' and STIMULI_RUNS > 1) then
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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
|
||||
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;
|
||||
|
||||
----------------------------------------------------------------------
|
||||
log(ID_DATA, "Check expected Event Recorder User Events");
|
||||
----------------------------------------------------------------------
|
||||
check_value(to_integer(unsigned(event_recorder_status.usr_events_counter)), expected_user_events, ERROR, "Total User Events: received = " & to_string(to_integer(unsigned(event_recorder_status.usr_events_counter))) & ", expected = " & to_string(expected_user_events));
|
||||
|
||||
end if;
|
||||
end if;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Test Done
|
||||
--------------------------------------------------------------------------
|
||||
wait for 1000 ns; -- to allow some time for completion
|
||||
report_alert_counters(FINAL); -- Report final counters and print conclusion for simulation (Success/Fail)
|
||||
-- ------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "SIMULATION COMPLETED", C_SCOPE);
|
||||
-- ------------------------------------------------------------------------
|
||||
-- assert error if UVVM mismatch flag is 1 => upstream info for scripts/jenkins
|
||||
assert shared_uvvm_status.mismatch_on_expected_simulation_errors_or_worse = 0 report "###ERROR### - UVVM Mismatch Errors with Expected Errors -> Check Log for details" severity ERROR;
|
||||
std.env.stop(0);
|
||||
wait; -- stop simulation
|
||||
|
||||
end process;
|
||||
|
||||
end architecture testbench;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- End of file
|
||||
--------------------------------------------------------------------------------
|
||||
596
tb/evr320_ifc1210_wrapper_tb.vhd
Normal file
596
tb/evr320_ifc1210_wrapper_tb.vhd
Normal file
@@ -0,0 +1,596 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- ifc1210_wrapper testbench
|
||||
--------------------------------------------------------------------------------
|
||||
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 tosca2;
|
||||
use tosca2.ifc1210_simu_procedures_pkg.all;
|
||||
|
||||
library uvvm_util;
|
||||
context uvvm_util.uvvm_util_context;
|
||||
|
||||
-- Work library (application) --------------------------------------------------
|
||||
library work;
|
||||
use work.evr320_pkg.all;
|
||||
use work.psi_common_math_pkg.all;
|
||||
|
||||
entity evr320_ifc1210_wrapper_tb is
|
||||
end entity;
|
||||
|
||||
architecture testbench of evr320_ifc1210_wrapper_tb is
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- System
|
||||
---------------------------------------------------------------------------
|
||||
constant C_RXUSRCLK_CYCLE : time := 7 ns;
|
||||
constant C_USRCLK_CYCLE : time := 8 ns;
|
||||
constant C_EVT_NR : integer := 4;
|
||||
constant C_MEM_DATA_WIDTH : integer := 32; -- 32|64 (64 bit used for tosca2 on ifc1210)
|
||||
constant C_EVENT_RECORDER : boolean := true;
|
||||
constant C_EVENT_REC_FLAGS : std_logic_vector(11 downto 6) := B"1101_11";
|
||||
constant g_EVENT_NR_SOS : integer range 0 to 255 := 16#20#;
|
||||
constant g_EVENT_NR_0 : integer range 0 to 255 := 16#00#;
|
||||
constant g_EVENT_NR_1 : integer range 0 to 255 := 16#04#;
|
||||
constant g_EVENT_NR_2 : integer range 0 to 255 := 16#00#;
|
||||
constant g_EVENT_NR_3 : integer range 0 to 255 := 16#00#;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- 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
|
||||
-----------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
constant FILTER_ADDRESS : std_logic_vector(11 downto 0) := x"028";
|
||||
constant FILTER_NUM_BYTES : integer := 8;
|
||||
constant STIMULI_RUNS : integer := 2;
|
||||
|
||||
signal filter_data, filter_data_check : std_logic_vector(63 downto 0) := (others => '0');
|
||||
signal filter_valid : std_logic := '0';
|
||||
|
||||
signal tmem_i : tmem_bus_in_t;
|
||||
signal tmem_o : tmem_bus_out_t;
|
||||
signal tmem_clk : std_logic;
|
||||
signal tmem_rst : std_logic;
|
||||
signal tmem_data_rd : std_logic_vector(63 downto 0);
|
||||
|
||||
signal tick1sec : std_logic;
|
||||
|
||||
alias rxlos is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.i_mgt_rst : std_logic>>;
|
||||
alias clk_evr is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.clk_evr : std_logic>>;
|
||||
alias rxdata is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.i_mgt_rx_data : std_logic_vector(15 downto 0)>>;
|
||||
alias rxcharisk is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.i_mgt_rx_charisk : std_logic_vector(1 downto 0)>>;
|
||||
alias sos_event is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.o_sos_event : std_logic>>;
|
||||
alias usr_events is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.o_usr_events : std_logic_vector(3 downto 0)>>;
|
||||
alias evr_stable is <<signal .evr320_ifc1210_wrapper_tb.evr320_ifc1210_wrapper_inst.evr320_decoder_inst.evr_stable : std_logic>>;
|
||||
|
||||
--*** stimuli for delay & pulse width ***
|
||||
signal usr_event_width_sti : typ_arr_width := (to_uslv(2, log2ceil(MaxDuration_c)), --sos set to 2
|
||||
to_uslv(3, log2ceil(MaxDuration_c)), --0
|
||||
to_uslv(4, log2ceil(MaxDuration_c)), --1
|
||||
to_uslv(5, log2ceil(MaxDuration_c)), --2
|
||||
to_uslv(6, log2ceil(MaxDuration_c)) --3
|
||||
);
|
||||
|
||||
signal usr_event_delay_sti : typ_arr_delay := (to_uslv(2, log2ceil(MaxDelay_c)), --sos set to 2
|
||||
to_uslv(3, log2ceil(MaxDelay_c)), --0
|
||||
to_uslv(4, log2ceil(MaxDelay_c)), --1
|
||||
to_uslv(5, log2ceil(MaxDelay_c)), --2
|
||||
to_uslv(6, log2ceil(MaxDelay_c)) --3
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
tmem_o.TMEM_BUSY_o <= '0';
|
||||
tmem_o.TMEM_PIPE_o <= "10";
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder
|
||||
-----------------------------------------------------------------------------
|
||||
evr320_ifc1210_wrapper_inst : entity work.evr320_ifc1210_wrapper
|
||||
generic map(
|
||||
g_MGT_LOCATION => "GTXE1_X0Y16", -- "GTXE1_X0Y0" to "GTXE1_X0Y11" | "GTXE1_X0Y16" to "GTXE1_X0Y19"
|
||||
g_FACILITY => "SFEL", -- "HIPA" | "SFEL"
|
||||
g_EVENT_RECORDER => C_EVENT_RECORDER, -- enable/disable Event Recorder functionality
|
||||
g_XUSER_CLK_FREQ => 125000000 -- Xuser Clk Frequency in Hz
|
||||
)
|
||||
port map(
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Debug interface
|
||||
--------------------------------------------------------------------------
|
||||
debug_clk => open,
|
||||
debug => open,
|
||||
--------------------------------------------------------------------------
|
||||
-- TOSCA2 TMEM interface
|
||||
--------------------------------------------------------------------------
|
||||
xuser_CLK => tmem_clk,
|
||||
xuser_RESET => tmem_rst,
|
||||
xuser_TMEM_ENA => tmem_i.TMEM_ENA_i,
|
||||
xuser_TMEM_WE => tmem_i.TMEM_WE_i,
|
||||
xuser_TMEM_ADD => tmem_i.TMEM_ADD_i(13 downto 3),
|
||||
xuser_TMEM_DATW => tmem_i.TMEM_DATW_i,
|
||||
xuser_TMEM_DATR => tmem_o.TMEM_DATR_o,
|
||||
-- ------------------------------------------------------------------------
|
||||
-- MGT Interface
|
||||
-- ------------------------------------------------------------------------
|
||||
mgt_refclk_i => '0',
|
||||
mgt_sfp_los_i => '0',
|
||||
mgt_rx_n => '0',
|
||||
mgt_rx_p => '0',
|
||||
mgt_tx_n => open,
|
||||
mgt_tx_p => open,
|
||||
mgt_status_o => open,
|
||||
mgt_control_i => (others => '0'),
|
||||
---------------------------------------------------------------------------
|
||||
-- User interface MGT clock
|
||||
---------------------------------------------------------------------------
|
||||
clk_evr_o => open,
|
||||
usr_events_o => open,
|
||||
sos_event_o => open,
|
||||
usr_events_adj_o => open,
|
||||
sos_events_adj_o => open,
|
||||
--------------------------------------------------------------------------
|
||||
-- Decoder axi stream interface, User clock
|
||||
--------------------------------------------------------------------------
|
||||
stream_clk_i => '1',
|
||||
stream_data_o => open,
|
||||
stream_addr_o => open,
|
||||
stream_valid_o => open
|
||||
);
|
||||
|
||||
gen_pulse(tick1sec, '1', usr_clk, 1, "");
|
||||
-----------------------------------------------------------------------------
|
||||
-- MGT / User clock
|
||||
-----------------------------------------------------------------------------
|
||||
clock_generator(usr_clk, C_USRCLK_CYCLE);
|
||||
tmem_clk <= usr_clk;
|
||||
|
||||
-- Simulate MGT Clock
|
||||
mgt_clk_proc : process
|
||||
begin
|
||||
clk_evr <= force in '0';
|
||||
loop
|
||||
wait for C_RXUSRCLK_CYCLE / 2;
|
||||
clk_evr <= force in not (clk_evr);
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Decoder reset due to MGT main status
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
rxlos <= force in '1';
|
||||
tmem_rst <= '1';
|
||||
wait for 50 ns;
|
||||
wait until (falling_edge(clk_evr));
|
||||
rxlos <= force in '0';
|
||||
tmem_rst <= '0';
|
||||
wait;
|
||||
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_total : integer := 0;
|
||||
variable event_cnt_0 : integer := 0;
|
||||
variable event_cnt_1 : integer := 0;
|
||||
variable event_cnt_2 : integer := 0;
|
||||
variable event_cnt_3 : integer := 0;
|
||||
variable event_cnt_user : 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) & " ");
|
||||
|
||||
-- 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;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for Start of Sequence Event
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(sos_event);
|
||||
log(ID_CTRL, "Start of Sequence Event Received: " & to_string(std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8)), HEX, AS_IS, INCL_RADIX)); -- change to await_value
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Stimuli MGT
|
||||
--------------------------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(clk_evr);
|
||||
for b in 0 to STIMULI_RUNS - 1 loop
|
||||
log(ID_LOG_HDR, "Send stimuli stream to MGT - RUN " & to_string(b + 1));
|
||||
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(clk_evr);
|
||||
rxdata <= force out mgt_stream(idx).data & mgt_stream(idx).event;
|
||||
rxcharisk <= force out mgt_stream(idx).data_k & mgt_stream(idx).event_k;
|
||||
end loop;
|
||||
wait for 3 us;
|
||||
end loop;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Main Process
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
constant C_SCOPE : string := C_TB_SCOPE_DEFAULT;
|
||||
constant c_TB_NAME : string := "evr320_decoder_tb";
|
||||
variable latency_cnt_val : unsigned(31 downto 0);
|
||||
|
||||
begin
|
||||
disable_log_msg(ID_GEN_PULSE);
|
||||
--------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "Start Simulation of evr320 decoder", C_SCOPE);
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Get out of reset, enable events
|
||||
--------------------------------------------------------------------------
|
||||
evr_params.event_enable(0) <= '0' when g_EVENT_NR_0 = 0 else '1';
|
||||
evr_params.event_enable(1) <= '0' when g_EVENT_NR_1 = 0 else '1';
|
||||
evr_params.event_enable(2) <= '0' when g_EVENT_NR_2 = 0 else '1';
|
||||
evr_params.event_enable(3) <= '0' when g_EVENT_NR_3 = 0 else '1';
|
||||
evr_params.event_numbers(0) <= std_logic_vector(to_unsigned(g_EVENT_NR_0, 8));
|
||||
evr_params.event_numbers(1) <= std_logic_vector(to_unsigned(g_EVENT_NR_1, 8));
|
||||
evr_params.event_numbers(2) <= std_logic_vector(to_unsigned(g_EVENT_NR_2, 8));
|
||||
evr_params.event_numbers(3) <= std_logic_vector(to_unsigned(g_EVENT_NR_3, 8));
|
||||
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");
|
||||
|
||||
-- overwrite evr_stable flag:
|
||||
evr_stable <= force '1';
|
||||
|
||||
-- enable sos event and set event number:
|
||||
TMEM_BUS_WRITE(seqid => "A00_001",
|
||||
tmem_add => x"00_0040",
|
||||
tmem_we => x"0F",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0000_0000_0000_2001",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back sos event and event number:
|
||||
TMEM_BUS_READ(seqid => "A00_001",
|
||||
tmem_add => x"00_0040",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
-- ---------------------------------------------------------
|
||||
-- send delay and width parameters:
|
||||
TMEM_BUS_WRITE(seqid => "A00_002",
|
||||
tmem_add => x"00_0050",
|
||||
tmem_we => x"FF",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0005_0004_0003_0002",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back delay parameters:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0050",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
check_value(tmem_data_rd, x"0005_0004_0003_0002", ERROR, "TMEM Write/Read check: EVR Puls delay Event Cfg");
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
-- ---------------------------------------------------------
|
||||
-- send width and width parameters:
|
||||
TMEM_BUS_WRITE(seqid => "A00_003",
|
||||
tmem_add => x"00_0058",
|
||||
tmem_we => x"FF",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0009_0008_0007_0006",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back delay parameters:
|
||||
TMEM_BUS_READ(seqid => "A00_003",
|
||||
tmem_add => x"00_0058",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
check_value(tmem_data_rd, x"0009_0008_0007_0006", ERROR, "TMEM Write/Read check: EVR Puls Width Event Cfg");
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
-- ---------------------------------------------------------
|
||||
-- send width and width parameters for SOS:
|
||||
TMEM_BUS_WRITE(seqid => "A00_004",
|
||||
tmem_add => x"00_0060",
|
||||
tmem_we => x"FF",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0000_0000_0001_0001",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back delay parameters:
|
||||
TMEM_BUS_READ(seqid => "A00_004",
|
||||
tmem_add => x"00_0060",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
check_value(tmem_data_rd, x"0000_0000_0001_0001", ERROR, "TMEM Write/Read check: SOS width & delay Event Cfg");
|
||||
-- ---------------------------------------------------------
|
||||
|
||||
-- latency measurement: set event nr:
|
||||
TMEM_BUS_WRITE(seqid => "A00_002",
|
||||
tmem_add => x"00_0030",
|
||||
tmem_we => x"0F",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0000_0000_0000_0020",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back sos event and event number:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0030",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- latency measurement: set event nr:
|
||||
TMEM_BUS_WRITE(seqid => "A00_002",
|
||||
tmem_add => x"00_0030",
|
||||
tmem_we => x"0F",
|
||||
tmem_burst => 1,
|
||||
tmem_data_wr => x"0000_0000_0000_0020",
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
-- read back sos event and event number:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0030",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
|
||||
wait for 20 ns;
|
||||
|
||||
check_value(tmem_data_rd, x"0000_0000_0000_0020", ERROR, "TMEM Write/Read check: lat. meas. event nr");
|
||||
|
||||
-- 1. check latency measurement counter:
|
||||
----------------------------------------
|
||||
await_value(sos_event, '1', 0 ns, 2 us, ERROR, "wait for sos event");
|
||||
wait for 2000 ns;
|
||||
latency_cnt_val := x"00000000";
|
||||
|
||||
-- read latency measurement counter without rearm:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0030",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
wait for 20 ns;
|
||||
latency_cnt_val := unsigned(tmem_data_rd(63 downto 32));
|
||||
|
||||
log(ID_CTRL, "Latency Counter: 0x" & to_string(latency_cnt_val, HEX));
|
||||
check_value_in_range(latency_cnt_val, x"000000F5", x"000000FE", ERROR, "Latency Counter Value (no-rearm) Check after 2us");
|
||||
|
||||
-- 2. read latency measurement counter again with rearm:
|
||||
--------------------------------------------------------
|
||||
latency_cnt_val := x"00000000";
|
||||
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0038",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
wait for 20 ns;
|
||||
latency_cnt_val := unsigned(tmem_data_rd(31 downto 0));
|
||||
|
||||
log(ID_CTRL, "Latency Counter: 0x" & to_string(latency_cnt_val, HEX));
|
||||
check_value_in_range(latency_cnt_val, x"000000FA", x"00000102", ERROR, "Latency Counter Value (rearm) Check directly after first read");
|
||||
|
||||
-- read 2. time rearm latency counter which should be cleared now:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0038",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
wait for 20 ns;
|
||||
latency_cnt_val := unsigned(tmem_data_rd(31 downto 0));
|
||||
check_value(latency_cnt_val, x"00000000", ERROR, "Check if counter is cleared");
|
||||
|
||||
-- 4. read latency measurement counter with rearm:
|
||||
--------------------------------------------------
|
||||
await_value(sos_event, '1', 0 ns, 3 us, ERROR, "wait for sos event");
|
||||
wait for 1 us;
|
||||
|
||||
-- read counter and rearm:
|
||||
TMEM_BUS_READ(seqid => "A00_002",
|
||||
tmem_add => x"00_0038",
|
||||
tmem_burst => 1,
|
||||
tmem_data_rd => tmem_data_rd,
|
||||
xuser_clk_i => tmem_clk,
|
||||
xuser_tmem_bus_o => tmem_i,
|
||||
xuser_tmem_bus_i => tmem_o);
|
||||
wait for 20 ns;
|
||||
latency_cnt_val := unsigned(tmem_data_rd(31 downto 0));
|
||||
log(ID_CTRL, "Latency Counter: 0x" & to_string(latency_cnt_val, HEX));
|
||||
check_value_in_range(latency_cnt_val, x"0000007A", x"00000080", ERROR, "Latency Counter Value (rearm) Check after 1us");
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Test Done
|
||||
--------------------------------------------------------------------------
|
||||
wait for 1000 ns; -- to allow some time for completion
|
||||
report_alert_counters(FINAL); -- Report final counters and print conclusion for simulation (Success/Fail)
|
||||
-- ------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "SIMULATION COMPLETED", C_SCOPE);
|
||||
-- ------------------------------------------------------------------------
|
||||
-- assert error if UVVM mismatch flag is 1 => upstream info for scripts/jenkins
|
||||
assert shared_uvvm_status.mismatch_on_expected_simulation_errors_or_worse = 0 report "###ERROR### - UVVM Mismatch Errors with Expected Errors -> Check Log for details" severity ERROR;
|
||||
std.env.stop(0);
|
||||
wait; -- stop simulation
|
||||
|
||||
end process;
|
||||
|
||||
end architecture testbench;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- End of file
|
||||
--------------------------------------------------------------------------------
|
||||
187
tb/stimuli_mgt.dat
Normal file
187
tb/stimuli_mgt.dat
Normal file
@@ -0,0 +1,187 @@
|
||||
# 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
|
||||
04 0 00 0 event 4
|
||||
00 0 00 0 gap
|
||||
BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
70 0 00 0 system event
|
||||
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
|
||||
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
|
||||
20 0 00 0 event Start-of-Sequence
|
||||
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
|
||||
01 0 00 0 event 1
|
||||
02 0 00 0 event 2
|
||||
03 0 00 0 event 3
|
||||
BC 1 00 0 align
|
||||
04 0 00 0 event 4
|
||||
05 0 00 0 event 5
|
||||
06 0 00 0 event 6
|
||||
BC 1 00 0 align
|
||||
07 0 00 0 event 7
|
||||
08 0 00 0 event 8
|
||||
09 0 00 0 event 9
|
||||
BC 1 00 0 align
|
||||
0A 0 00 0 event 10
|
||||
0B 0 00 0 event 11
|
||||
0C 0 00 0 event 12
|
||||
BC 1 00 0 align
|
||||
32 0 00 0 event 50
|
||||
33 0 00 0 event 51
|
||||
34 0 00 0 event 52
|
||||
BC 1 00 0 align
|
||||
35 0 00 0 event 53
|
||||
36 0 00 0 event 54
|
||||
37 0 00 0 event 55
|
||||
BC 1 00 0 align
|
||||
38 0 00 0 event 56
|
||||
39 0 00 0 event 57
|
||||
3A 0 00 0 event 58
|
||||
BC 1 00 0 align
|
||||
FA 0 00 0 event 250
|
||||
FB 0 00 0 event 251
|
||||
FC 0 00 0 event 252
|
||||
BC 1 00 0 align
|
||||
FD 0 00 0 event 253
|
||||
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
|
||||
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
|
||||
Reference in New Issue
Block a user