18 Commits

Author SHA1 Message Date
05ae75f812 new address map, changed recorder and segment memory 2019-02-17 22:26:17 +01:00
1e554877ad removed additional data buffers for user events 2019-02-11 14:34:12 +01:00
4f9e87b16d readme: add dependencies 2018-12-06 10:46:24 +01:00
82c023c610 change: split streaming port to data and address 2018-12-06 10:00:53 +01:00
84f23d13ab event event reception check in simulation, fix stimuli 2018-12-05 17:14:04 +01:00
c52673a8ca simulate stream filter, integrated to if1210 wrapper, syntax fixes 2018-12-05 10:08:52 +01:00
d7e669cb75 extended ifc1210_wrapper with data streaming port and replaced frequency
measurement by common lib
2018-12-04 21:13:51 +01:00
84440ce6a0 added data filter from decoder stream 2018-12-04 17:02:10 +01:00
5e79f3f426 self checking segment sent/recv comparison 2018-12-04 17:01:38 +01:00
35077a9d84 self checking testbench: read MGT frame from file and compare data
stream
2018-12-03 17:15:39 +01:00
2634412bd0 added decoder streaming output and UVVM simulation 2018-11-30 16:25:00 +01:00
da6ab3236a added constrain template 2018-11-29 14:07:45 +01:00
6b512782f3 migrate decoder sim from cvs: prints transfered data buffer to terminal 2018-11-29 13:05:15 +01:00
426fa8bc1c added new GTX for Virtex-6 in HIPA Timing System 2018-07-16 15:00:47 +02:00
Oliver Bruendler
30d692b872 Repository was moved from git@git.psi.ch:DigitaleSignalVerarbeitung/Libraries/VHDL/evr320.git 2018-07-09 08:34:33 +02:00
5f1af19d28 signal name updated to introduced sync stage. 2018-06-26 14:52:06 +02:00
77adb7b9e2 reg sync, clean-up comments 2018-06-08 11:25:56 +02:00
4aecb89683 generate pdf from updated documentation 2018-05-03 13:55:23 +02:00
23 changed files with 36273 additions and 29868 deletions

View File

@@ -1,11 +1,24 @@
## 2.1
## 3.0
* Added Simulation
* Added Decoder streaming output
* Changed Register and Memory Address Map
* Added Features
* Event Recorder functionality implemented as an option
* IFC1210 bindings for tosca2
* Bugfixes
* None
## 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

View File

@@ -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
View File

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

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -18,9 +18,9 @@ use ieee.std_logic_misc.all;
library unisim;
use unisim.vcomponents.all;
library work;
use work.evr320_pkg.all;
entity evr320_decoder is
generic
(
@@ -48,9 +48,16 @@ entity evr320_decoder is
i_evr_params : in typ_evr320_params;
o_event_recorder_stat : out typ_evt_rec_status;
i_event_recorder_ctrl : in typ_evt_rec_ctrl;
i_mem_addr : in std_logic_vector(11 downto 0);
i_mem_addr : in std_logic_vector(13 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);
@@ -165,17 +172,13 @@ architecture behavioral of evr320_decoder is
constant mem_ctrl_rd : std_logic_vector( 1 downto 0) := "11";
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 : std_logic_vector(13 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');
signal mem_data_wr_byte : std_logic_vector( 7 downto 0) := (others => '0');
-- Data memory read
signal mem_data_dpram : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_event0 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_event1 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_event2 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
signal mem_data_event3 : std_logic_vector(MEM_DATA_WIDTH - 1 downto 0) := (others => '0');
-- Event Recorder
signal sos_event : std_logic_vector( 3 downto 0) := (others => '0');
signal usr_events_save : std_logic := '0';
@@ -203,7 +206,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";
@@ -220,7 +223,7 @@ 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( 23 downto 18) <= (others=>'0');
debug( 31 downto 24) <= (others => '0');
debug( 35 downto 32) <= "0001" when (frame_fsm = frame_idle ) else
"0010" when (frame_fsm = frame_addr_gap) else
@@ -265,7 +268,7 @@ begin
-- Address Alignment for 32/64-bit Data Width
-----------------------------------------------------------------------------
gen_addr_align64: if MEM_DATA_WIDTH = 64 generate
mem_addr <= i_mem_addr(10 downto 0) & '0';
mem_addr <= i_mem_addr(12 downto 0) & '0';
end generate gen_addr_align64;
gen_addr_align32: if MEM_DATA_WIDTH = 32 generate
@@ -700,12 +703,12 @@ begin
-----------------------------------------------------------------------------
-- 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
mem_data_event_recorder;
-- Memory Map (byte-address):
-- * Segmented Data Buffer: 0x9000 - 0x97FF
-- * Event Recorder: 0xB000 - 0xBFFF
o_mem_data <= mem_data_dpram when (mem_addr(13 downto 9) = "10010") else
mem_data_event_recorder when (mem_addr(13 downto 10) = "1011") else
x"DEADC0DE";
-----------------------------------------------------------------------------
-- Data Memory
@@ -733,100 +736,54 @@ begin
dob => mem_data_dpram
);
-----------------------------------------------------------------------------
-- Data Memory
-- write port - timing decoder
-- read port - usr domain
-----------------------------------------------------------------------------
evr320_event0_inst: entity work.evr320_buffer
generic map
(
MEM_SIZE_BYTE => 2048,
MEM_DOB_WIDTH => MEM_DATA_WIDTH
)
port map
(
-- port a
clka => i_mgt_rx_clk,
ena => HIGH,
wea => mem_data_wren,
addra => mem_data_wr_addr,
dia => mem_data_wr_byte,
page => usr_events( 0)( 3),
-- port b
clkb => i_usr_clk,
enb => HIGH,
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
dob => mem_data_event0
);
-------------------------------------------------------------------------
-- 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
);
evr320_event1_inst: entity work.evr320_buffer
generic map
(
MEM_SIZE_BYTE => 2048,
MEM_DOB_WIDTH => MEM_DATA_WIDTH
)
port map
(
-- port a
clka => i_mgt_rx_clk,
ena => HIGH,
wea => mem_data_wren,
addra => mem_data_wr_addr,
dia => mem_data_wr_byte,
page => usr_events( 1)( 3),
-- port b
clkb => i_usr_clk,
enb => HIGH,
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
dob => mem_data_event1
);
evr320_event2_inst: entity work.evr320_buffer
generic map
(
MEM_SIZE_BYTE => 2048,
MEM_DOB_WIDTH => MEM_DATA_WIDTH
)
port map
(
-- port a
clka => i_mgt_rx_clk,
ena => HIGH,
wea => mem_data_wren,
addra => mem_data_wr_addr,
dia => mem_data_wr_byte,
page => usr_events( 2)( 3),
-- port b
clkb => i_usr_clk,
enb => HIGH,
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
dob => mem_data_event2
);
evr320_event3_inst: entity work.evr320_buffer
generic map
(
MEM_SIZE_BYTE => 2048,
MEM_DOB_WIDTH => MEM_DATA_WIDTH
)
port map
(
-- port a
clka => i_mgt_rx_clk,
ena => HIGH,
wea => mem_data_wren,
addra => mem_data_wr_addr,
dia => mem_data_wr_byte,
page => usr_events( 3)( 3),
-- port b
clkb => i_usr_clk,
enb => HIGH,
addrb => mem_addr( 8 downto MEM_ADDR_LSB),
dob => mem_data_event3
);
o_stream_data <= stream_raw(7 downto 0);
o_stream_addr <= stream_raw(18 downto 8);
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- EVENT RECORDER
@@ -970,11 +927,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(13 downto 9) = B"1011_0") else -- 2K
mem_data_event_nr_timestamp when (mem_addr(13 downto 8) = B"1011_10") else -- 1K
mem_data_segment_timestamp when (mem_addr(13 downto 7) = B"1011_110") else -- 512B
mem_data_event_nr when (mem_addr(13 downto 6) = B"1011_1110") else -- 256B
mem_data_event_flag when (mem_addr(13 downto 6) = B"1011_1111") else -- 256B
(others => '0');
@@ -1081,7 +1038,6 @@ begin
dob => mem_data_event_nr
);
--------------------------------------------------------------------------
-- Event Flags of all Events
--------------------------------------------------------------------------
@@ -1127,4 +1083,4 @@ end behavioral;
--------------------------------------------------------------------------------
-- End of file
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

View File

@@ -6,24 +6,26 @@
-- ---------------------------------------------------------------------------
-- 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.math_real.all;
use work.tosca2_glb_pkg.all;
library tosca2;
use tosca2.tosca2_glb_pkg.all;
use work.evr320_pkg.all;
use work.pkg_v6vlx_gtxe1.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;
@@ -35,13 +37,13 @@ entity evr320_ifc1210_wrapper is
-- ------------------------------------------------------------------------
-- 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(15 downto 3);
xuser_TMEM_DATW: in std_logic_vector(63 downto 0);
xuser_TMEM_DATR: out std_logic_vector(63 downto 0);
-- ------------------------------------------------------------------------
-- MGT Interface
-- ------------------------------------------------------------------------
@@ -59,7 +61,14 @@ entity evr320_ifc1210_wrapper is
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
sos_event_o : out std_logic; -- Start-of-Sequence Event
--------------------------------------------------------------------------
-- Decoder axi stream interface, User clock
--------------------------------------------------------------------------
stream_clk_i : in std_logic := '0';
stream_data_o : out std_logic_vector(7 downto 0);
stream_addr_o : out std_logic_vector(10 downto 0);
stream_valid_o : out std_logic
);
end evr320_ifc1210_wrapper;
@@ -69,11 +78,9 @@ 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_EVR_REG64_COUNT : integer := 16; -- unused, only documentation
constant c_EVR_MEM_SIZE : integer := 16384; -- unused, only documentation
-- --------------------------------------------------------------------------
@@ -83,33 +90,27 @@ architecture rtl of evr320_ifc1210_wrapper is
--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_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 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_addr_evr : std_logic_vector(13 downto 0);
signal mem_addr_tosca : std_logic_vector(12 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_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);
@@ -142,33 +143,23 @@ begin
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;
-- --------------------------------------------------------------------------
@@ -194,6 +185,11 @@ begin
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,
@@ -207,7 +203,7 @@ begin
mgt_wrapper_inst: entity work.v6vlx_gtxe1_wrapper
generic map(
g_MGT_LOCATION => g_MGT_LOCATION,
g_USE_MMCM => g_USE_MMCM )
g_FACILITY => g_FACILITY )
port map(
-- MGT serial interface
i_mgt_refclk => mgt_refclk_i,
@@ -239,10 +235,10 @@ begin
xuser_TMEM_DATW => xuser_TMEM_DATW,
xuser_TMEM_DATR => xuser_TMEM_DATR,
-- EVR320 Memory/Parameter Interface
evr_params_o => evr_params,
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,
evr_evt_rec_control_o => event_recorder_control_xuser,
mgt_status_i => mgt_status,
mgt_reset_o => mgt_reset_tmem_evr,
mem_clk_o => mem_clk,
@@ -250,24 +246,20 @@ begin
mem_data_i => mem_data
);
-- --------------------------------------------------------------------------
-- Measure EVR Clock (based on xuser_CLK)
-- --------------------------------------------------------------------------
prc_count_cycles: process(clk_evr)
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";
end if;
-- sync reset and detect edge
evr_counter_rst <= evr_counter_rst(1 downto 0) & tick1sec_i;
end if;
end process;
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
);
-- --------------------------------------------------------------------------
-- port mapping
@@ -281,4 +273,4 @@ begin
end rtl;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------

View File

@@ -60,7 +60,10 @@ 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');
-- --------------------------------------------------------------------------
-- Function Prototypes
-- --------------------------------------------------------------------------
@@ -95,4 +98,4 @@ package body evr320_pkg is
end package body evr320_pkg;
--------------------------------------------------------------------------------
-- End of file
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

View File

@@ -6,7 +6,7 @@
-- ---------------------------------------------------------------------------
-- Copyright© PSI, Section DSV
-- ---------------------------------------------------------------------------
-- Comment :
-- Comment : TMEM address decoding for register and memory access to evr320.
-- ---------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
@@ -14,7 +14,9 @@ use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.tosca2_glb_pkg.all;
library tosca2;
use tosca2.tosca2_glb_pkg.all;
use work.evr320_pkg.all;
@@ -27,7 +29,7 @@ entity evr320_tmem is
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_ADD : in std_logic_vector(15 downto 3);
xuser_TMEM_DATW : in std_logic_vector(63 downto 0);
xuser_TMEM_DATR : out std_logic_vector(63 downto 0);
---------------------------------------------------------------------------
@@ -40,7 +42,7 @@ entity evr320_tmem is
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_addr_o : out std_logic_vector(12 downto 0);
mem_data_i : in std_logic_vector(63 downto 0)
);
end evr320_tmem;
@@ -56,7 +58,6 @@ architecture rtl of evr320_tmem is
constant TMEM_ADDR_LSB : integer := 3; -- 64 bit
constant REG_ADDR_WIDTH : integer := integer(ceil(log2(real(NUM_REG64)))) + TMEM_ADDR_LSB;
constant REG_ADDR_MSB : integer := REG_ADDR_WIDTH - 1;
constant MEM_ADDR_START : std_logic_vector(7 downto 0) := X"10";
@@ -66,7 +67,7 @@ architecture rtl of evr320_tmem is
-- xuser tmem signals
signal xuser_TMEM_WE_reg : std_logic_vector( 7 downto 0) := (others => '0');
signal xuser_TMEM_ENA_reg : std_logic := '0';
signal xuser_TMEM_ADD_reg : std_logic_vector(13 downto 3) := (others => '0');
signal xuser_TMEM_ADD_reg : std_logic_vector(15 downto 3) := (others => '0');
signal xuser_TMEM_DATW_reg : std_logic_vector(63 downto 0) := (others => '0');
-- evr params
@@ -144,7 +145,7 @@ begin
begin
if (rising_edge(xuser_CLK)) then
if (xuser_TMEM_ENA_reg = '1') then
if (xuser_TMEM_ADD_reg(13 downto REG_ADDR_WIDTH) = 0) then
if (xuser_TMEM_ADD_reg(15 downto REG_ADDR_WIDTH) = 0) 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
@@ -178,7 +179,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(15 downto REG_ADDR_WIDTH) = 0) 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;
@@ -244,7 +245,7 @@ begin
-- Port mapping
-- --------------------------------------------------------------------------
mem_clk_o <= xuser_CLK;
mem_addr_o <= xuser_TMEM_ADD - MEM_ADDR_START;
mem_addr_o <= xuser_TMEM_ADD;
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;
@@ -254,4 +255,4 @@ begin
end rtl;
-- ----------------------------------------------------------------------------
-- ////////////////////////////////////////////////////////////////////////////
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------

View 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© 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;

View File

@@ -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
View 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
View 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
View 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© 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.std_logic_unsigned.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 : 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 ------------------------------------------------------------------
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(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_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;

View File

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

View File

@@ -1,6 +1,3 @@
#Constants
set LibPath "../../.."
#Import psi::sim library
namespace import psi::sim::*
@@ -12,23 +9,51 @@ compile_suppress 135,1236
run_suppress 8684,3479,3813,8009,3812
# EVR320 Library
add_sources $LibPath/VHDL/evr320/hdl {
# 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
# EVR320 Decoder Testbench
add_sources $LibPath/Firmware/VHDL/evr320/tb {
evr320_decoder_tb.vhd \
} -tag evr320_decoder_tb
# Lib ifc1210
add_sources $LibPath/VHDL/evr320/hdl {
pkg_v6vlx_gtxe1.vhd \
# setup tb runs
create_tb_run "evr320_decoder_tb"
add_tb_run
# 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
# psi_common dependency:
add_sources $LibPath/Firmware/VHDL/psi_common/hdl {
psi_common_array_pkg.vhd \
psi_common_math_pkg.vhd \
psi_common_logic_pkg.vhd \
psi_common_sdp_ram.vhd \
psi_common_pulse_cc.vhd \
psi_common_async_fifo.vhd \
psi_common_clk_meas.vhd \
} -tag psi_common
# tosca2_glb_pkg dependency
add_library tosca2
add_sources $LibPath/BoardSupport/IFC1210/tosca2/hdl/top_ip/src {
tosca2_glb_pkg.vhd \
}

View File

@@ -1,5 +1,42 @@
#Load dependencies
source ../../../TCL/PsiSim/PsiSim.tcl
# Library Path
set LibPath "../../../.."
# Compile UVVM library (if necessary):
# -------------------------------------------------------
set uvvm_lib $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
# compile lib if folder not exist:
#if {![file isdirectory $uvvm_lib]} {
# copy adapted pkg:
file copy -force ../tb/adaptations_pkg.vhd $LibPath/Firmware/VHDL/UVVM/uvvm_util/src/
set last_dir [pwd]
cd $LibPath/Firmware/VHDL/UVVM/uvvm_util/script/
do compile_src.do
cd $last_dir
#}
vmap uvvm_util $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
# -------------------------------------------------------
# Check if running in jenkins environment
if [info exists env(JENKINS_HOME)] {
set jenkins 1
} else {
set jenkins 0
}
# map different libraries when running on jenkins machine:
if {$jenkins == 1} {
vmap unisim /home/modelsim/xilinx_libs/13.4/unisim
vmap xilinxcorelib /home/modelsim/xilinx_libs/13.4/xilinxcorelib
vmap secureip /home/modelsim/xilinx_libs/13.4/secureip
} else {
vmap unisim C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
vmap xilinxcorelib C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/xilinxcorelib
vmap secureip C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
}
#Load dependencies TODO
source $LibPath/Firmware/TCL/PsiSim/PsiSim.tcl
#Import psi::sim library
namespace import psi::sim::*
@@ -10,15 +47,17 @@ 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 -tag evr320_decoder
compile_files -tag evr320_decoder_tb
compile_files -lib tosca2
compile_files -tag evr320_ifc1210
#compile_files -lib evr320
run_check_errors "###ERROR###"
run_tb -all
run_check_errors "###ERROR###"

290
tb/adaptations_pkg.vhd Normal file
View 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;

426
tb/evr320_decoder_tb.vhd Normal file
View File

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

131
tb/stimuli_mgt.dat Normal file
View File

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