Skip to content
Snippets Groups Projects
Commit 4115bc43 authored by Julian Maxime Mendez's avatar Julian Maxime Mendez
Browse files

[v.1.0.0] First commit

- Repository creation
- Add README.md file
- Add LpGBT-FPGA submodule
- Add KCU105 test bench firmware and project
parents
Branches
Tags
No related merge requests found
Showing
with 1437 additions and 0 deletions
[submodule "LpGBT-FPGA"]
path = LpGBT-FPGA
url = https://gitlab.cern.ch/gbt-fpga/lpgbt-fpga.git
##===================================================================================================##
##========================================= CLOCKS ================================================##
##===================================================================================================##
##==============##
## FABRIC CLOCK ##
##==============##
# IO_L13P_T2_MRCC_15
set_property IOSTANDARD LVDS [get_ports USER_CLOCK_P]
# IO_L13N_T2_MRCC_15
set_property PACKAGE_PIN F10 [get_ports USER_CLOCK_N]
set_property PACKAGE_PIN G10 [get_ports USER_CLOCK_P]
set_property IOSTANDARD LVDS [get_ports USER_CLOCK_N]
create_clock -period 8.000 -name USER_CLOCK [get_ports USER_CLOCK_P]
set_clock_groups -asynchronous -group USER_CLOCK
##===========##
## MGT CLOCK ##
##===========##
## Comment: * The MGT reference clock MUST be provided by an external clock generator.
##
## * The MGT reference clock frequency must be 320MHz for the latency-optimized GBT Bank.
# MGTREFCLK1P_117
# MGTREFCLK1N_117
set_property PACKAGE_PIN V6 [get_ports SMA_MGT_REFCLK_P]
set_property PACKAGE_PIN V5 [get_ports SMA_MGT_REFCLK_N]
create_clock -period 3.125 -name SMA_MGT_REFCLK [get_ports SMA_MGT_REFCLK_P]
set_property RXSLIDE_MODE PMA [get_cells -hier -filter {NAME =~ *GTHE3_CHANNEL_PRIM_INST}]
set_property LOC GTHE3_CHANNEL_X0Y9 [get_cells -hierarchical -filter {NAME =~ *lpgbtemul_top_inst*gen_channel_container[0].*gen_gthe3_channel_inst[0].GTHE3_CHANNEL_PRIM_INST}]
set_property LOC GTHE3_CHANNEL_X0Y10 [get_cells -hierarchical -filter {NAME =~ *lpgbtFpga_top_inst*gen_channel_container[0].*gen_gthe3_channel_inst[0].GTHE3_CHANNEL_PRIM_INST}]
##===================================================================================================##
##===================================================================================================##
set_multicycle_path 3 -from [get_pins {lpgbtFpga_top_inst/LpGBT_FPGA_Uplink_datapath_inst/uplinkFrame_pipelined_s_reg[*]/C}] -setup
set_multicycle_path 2 -from [get_pins {lpgbtFpga_top_inst/LpGBT_FPGA_Uplink_datapath_inst/uplinkFrame_pipelined_s_reg[*]/C}] -hold
set_multicycle_path 3 -from [get_pins -hierarchical -filter {NAME =~ lpgbtFpga_top_inst/LpGBT_FPGA_Uplink_datapath_inst*descrambledData_reg[*]/C}] -setup
set_multicycle_path 2 -from [get_pins -hierarchical -filter {NAME =~ lpgbtFpga_top_inst/LpGBT_FPGA_Uplink_datapath_inst*descrambledData_reg[*]/C}] -hold
#Debug: no need to constraint the design for debug
set_false_path -to [get_pins -hierarchical -filter {NAME =~ *ila_core_inst*/D}]
#Debug: no need to constraint the design for static signal (status)
set_false_path -to [get_pins uplinkstimulis_top_inst/uplink_error_o_reg/D]
#Ready status: false route - timing is not critical for asynchronous reset (long duration)
set_false_path -from [get_pins lpgbtemul_top_inst/mgt_framealigner_inst/sta_headerLocked_s_reg/C]
set_multicycle_path 5 -from [get_pins {lpgbtemul_top_inst/rxGearbox_inst/dat_outFrame_o_reg[*]/C}] -setup
set_multicycle_path 4 -from [get_pins {lpgbtemul_top_inst/rxGearbox_inst/dat_outFrame_o_reg[*]/C}] -hold
set_multicycle_path 2 -from [get_pins -hierarchical -filter {NAME =~ lpgbtemul_top_inst*LpGBT_Model_dataPath_inst*scrambledData_reg[*]/C}] -setup
set_multicycle_path 1 -from [get_pins -hierarchical -filter {NAME =~ lpgbtemul_top_inst*LpGBT_Model_dataPath_inst*scrambledData_reg[*]/C}] -hold
##===================================================================================================##
##======================================== I/O PINS ===============================================##
##===================================================================================================##
##=======##
## RESET ##
##=======##
# IO_25_VRP_34
set_property PACKAGE_PIN AN8 [get_ports CPU_RESET]
set_property IOSTANDARD LVCMOS18 [get_ports CPU_RESET]
##==========##
## MGT(GTX) ##
##==========##
## SERIAL LANES:
##--------------
# MGTXTXP2_117
# MGTXTXN2_117
# MGTXRXP2_117
# MGTXRXN2_117
set_property PACKAGE_PIN U3 [get_ports SFP0_TX_N]
set_property PACKAGE_PIN T2 [get_ports SFP0_RX_P]
set_property PACKAGE_PIN T1 [get_ports SFP0_RX_N]
set_property PACKAGE_PIN U4 [get_ports SFP0_TX_P]
set_property PACKAGE_PIN V2 [get_ports SFP1_RX_P]
set_property PACKAGE_PIN V1 [get_ports SFP1_RX_N]
set_property PACKAGE_PIN W4 [get_ports SFP1_TX_P]
set_property PACKAGE_PIN W3 [get_ports SFP1_TX_N]
## SFP CONTROL:
##-------------
# IO_0_12
set_property PACKAGE_PIN AL8 [get_ports SFP0_TX_DISABLE]
set_property IOSTANDARD LVCMOS18 [get_ports SFP0_TX_DISABLE]
set_property PACKAGE_PIN AM9 [get_ports SFP1_TX_DISABLE]
set_property IOSTANDARD LVCMOS18 [get_ports SFP1_TX_DISABLE]
##====================##
## SIGNALS FORWARDING ##
##====================##
## SMA OUTPUT:
##------------
# IO_L1P_T0_12
set_property PACKAGE_PIN H27 [get_ports USER_SMA_GPIO_P]
set_property IOSTANDARD LVCMOS18 [get_ports USER_SMA_GPIO_P]
set_property SLEW FAST [get_ports USER_SMA_GPIO_P]
set_property PACKAGE_PIN G27 [get_ports USER_SMA_GPIO_N]
set_property IOSTANDARD LVCMOS18 [get_ports USER_SMA_GPIO_N]
set_property SLEW FAST [get_ports USER_SMA_GPIO_N]
##===================================================================================================##
##===================================================================================================##
#set_false_path -to [get_pins -hier -filter {NAME =~ *debug*/D}]
#set_false_path -to [get_pins -hier -filter {NAME =~ *debug*/D}]
#set_false_path -from [get_pins -hier -filter {NAME =~ vio*}]
#set_false_path -to [get_pins -hier -filter {NAME =~ vio*}]
#set_multicycle_path -end -from [get_pins -hier -filter {NAME =~lpgbtFpga_top_inst/rxGearbox_5g12_inst/dat_outFrame_o_reg[*]/C}] -to [get_pins -hier -filter {NAME =~uplinkstimulis_top_inst/*/D}] 8
\ No newline at end of file
Subproject commit b0e08d9d45d926f097f521cb1e559d48f6e47d97
-------------------------------------------------------
--! @file
--! @author Julian Mendez <julian.mendez@cern.ch> (CERN - EP-ESE-BE)
--! @version 6.0
--! @brief GBT-FPGA IP - Device specific transceiver
-------------------------------------------------------
--! IEEE VHDL standard library:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--! Xilinx devices library:
library unisim;
use unisim.vcomponents.all;
--! @brief MGT - Transceiver
--! @details
--! The MGT module provides the interface to the transceivers to send the GBT-links via
--! high speed links (@4.8Gbps)
entity mgt is
port (
--=============--
-- Clocks --
--=============--
MGT_REFCLK_i : in std_logic;
MGT_FREEDRPCLK_i : in std_logic;
MGT_RXUSRCLK_o : out std_logic;
MGT_TXUSRCLK_o : out std_logic;
--=============--
-- Resets --
--=============--
MGT_TXRESET_i : in std_logic;
MGT_RXRESET_i : in std_logic;
--=============--
-- Control --
--=============--
MGT_RXSlide_i : in std_logic;
MGT_ENTXCALIBIN_i : in std_logic;
MGT_TXCALIB_i : in std_logic_vector(6 downto 0);
--=============--
-- Status --
--=============--
MGT_TXREADY_o : out std_logic;
MGT_RXREADY_o : out std_logic;
MGT_TX_ALIGNED_o : out std_logic;
MGT_TX_PIPHASE_o : out std_logic_vector(6 downto 0);
--==============--
-- Data --
--==============--
MGT_USRWORD_i : in std_logic_vector(31 downto 0);
MGT_USRWORD_o : out std_logic_vector(31 downto 0);
--===============--
-- Serial intf. --
--===============--
RXn_i : in std_logic;
RXp_i : in std_logic;
TXn_o : out std_logic;
TXp_o : out std_logic
);
end mgt;
--! @brief MGT - Transceiver
--! @details The MGT module implements all the logic required to send the GBT frame on high speed
--! links: resets modules for the transceiver, Tx PLL and alignement logic to align the received word with the
--! GBT frame header.
architecture structural of mgt is
--================================ Signal Declarations ================================--
COMPONENT xlx_ku_mgt_ip
PORT (
gtwiz_userclk_tx_active_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_userclk_rx_active_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_buffbypass_rx_reset_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_buffbypass_rx_start_user_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_buffbypass_rx_done_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_buffbypass_rx_error_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_clk_freerun_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_all_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_tx_pll_and_datapath_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_tx_datapath_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_rx_pll_and_datapath_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_rx_datapath_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_rx_cdr_stable_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_tx_done_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_reset_rx_done_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gtwiz_userdata_tx_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
gtwiz_userdata_rx_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
drpaddr_in : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
drpclk_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
drpdi_in : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
drpen_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
drpwe_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gthrxn_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gthrxp_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
gtrefclk0_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
rxslide_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
rxusrclk_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
rxusrclk2_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txpippmen_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txpippmovrden_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txpippmpd_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txpippmsel_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txpippmstepsize_in : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
txusrclk_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
txusrclk2_in : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
drpdo_out : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
drprdy_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gthtxn_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
gthtxp_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
rxoutclk_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
rxpmaresetdone_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
txbufstatus_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
txoutclk_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
txpmaresetdone_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0)
--xprgdivresetdone_out : OUT STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT;
-- Reset signals
signal tx_reset_done : std_logic;
signal tx_rdy_done : std_logic;
signal txfsm_reset_done : std_logic;
signal rx_reset_done : std_logic;
signal rxfsm_reset_done : std_logic;
signal rxBuffBypassRst : std_logic;
signal gtwiz_userclk_rx_active_int : std_logic;
signal gtwiz_buffbypass_rx_reset_in_s : std_logic;
signal gtwiz_userclk_tx_active_int : std_logic;
signal gtwiz_buffbypass_tx_reset_in_s : std_logic;
signal gtwiz_userclk_tx_reset_int : std_logic;
signal gtwiz_userclk_rx_reset_int : std_logic;
signal txpmaresetdone : std_logic;
signal rxpmaresetdone : std_logic;
signal rx_reset_sig : std_logic;
signal tx_reset_sig : std_logic;
signal MGT_USRWORD_s : std_logic_vector(31 downto 0);
-- Clock signals
signal rx_wordclk_sig : std_logic;
signal tx_wordclk_sig : std_logic;
signal rxoutclk_sig : std_logic;
signal txoutclk_sig : std_logic;
-- Tx phase aligner signals
signal txbufstatus_s : std_logic_vector(1 downto 0);
signal txpippmen_s : std_logic;
signal txpippmovrden_s : std_logic;
signal txpippmsel_s : std_logic;
signal txpippmpd_s : std_logic;
signal txpippmstepsize_in : std_logic_vector(4 downto 0);
signal drpaddr_s : std_logic_vector(8 downto 0);
signal drpen_s : std_logic;
signal drpdi_s : std_logic_vector(15 downto 0);
signal drprdy_s : std_logic;
signal drpdo_s : std_logic_vector(15 downto 0);
signal drpwe_s : std_logic;
signal mgt_rst_phaligner_s : std_logic;
signal MGT_TX_ALIGNED_s : std_logic;
--=================================================================================================--
begin --========#### Architecture Body ####========--
--=================================================================================================--
--==================================== User Logic =====================================--
--=============--
-- Assignments --
--=============--
MGT_TXREADY_o <= tx_reset_done and MGT_TX_ALIGNED_s; -- and txfsm_reset_done;
tx_rdy_done <= not(tx_reset_done);
MGT_TX_ALIGNED_o <= MGT_TX_ALIGNED_s;
MGT_RXREADY_o <= rx_reset_done and rxfsm_reset_done;
MGT_RXUSRCLK_o <= rx_wordclk_sig;
MGT_TXUSRCLK_o <= tx_wordclk_sig;
rx_reset_sig <= MGT_RXRESET_i or not(tx_reset_done and MGT_TX_ALIGNED_s); -- and txfsm_reset_done);
tx_reset_sig <= MGT_TXRESET_i;
rxBuffBypassRst <= not(gtwiz_userclk_rx_active_int) or (not(tx_reset_done) and not(MGT_TX_ALIGNED_s));
resetDoneSynch_rx: entity work.xlx_ku_mgt_ip_reset_synchronizer
PORT MAP(
clk_in => rx_wordClk_sig,
rst_in => rxBuffBypassRst,
rst_out => gtwiz_buffbypass_rx_reset_in_s
);
-- resetSynch_tx: entity work.xlx_ku_mgt_ip_reset_synchronizer
-- PORT MAP(
-- clk_in => tx_wordclk_sig,
-- rst_in => not(gtwiz_userclk_tx_active_int),
-- rst_out => gtwiz_buffbypass_tx_reset_in_s
-- );
gtwiz_userclk_tx_reset_int <= not(txpmaresetdone);
gtwiz_userclk_rx_reset_int <= not(rxpmaresetdone);
rxWordClkBuf_inst: bufg_gt
port map (
O => rx_wordclk_sig,
I => rxoutclk_sig,
CE => not(gtwiz_userclk_rx_reset_int),
DIV => "000",
CLR => '0',
CLRMASK => '0',
CEMASK => '0'
);
txWordClkBuf_inst: bufg_gt
port map (
O => tx_wordclk_sig,
I => txoutclk_sig,
CE => not(gtwiz_userclk_tx_reset_int),
DIV => "000",
CLR => '0',
CLRMASK => '0',
CEMASK => '0'
);
activetxUsrClk_proc: process(gtwiz_userclk_tx_reset_int, tx_wordclk_sig)
begin
if gtwiz_userclk_tx_reset_int = '1' then
gtwiz_userclk_tx_active_int <= '0';
elsif rising_edge(tx_wordclk_sig) then
gtwiz_userclk_tx_active_int <= '1';
end if;
end process;
activerxUsrClk_proc: process(gtwiz_userclk_rx_reset_int, rx_wordclk_sig)
begin
if gtwiz_userclk_rx_reset_int = '1' then
gtwiz_userclk_rx_active_int <= '0';
elsif rising_edge(rx_wordclk_sig) then
gtwiz_userclk_rx_active_int <= '1';
end if;
end process;
rxWordPipeline_proc: process(rx_reset_done, rx_wordclk_sig)
begin
if rx_reset_done = '0' then
MGT_USRWORD_o <= (others => '0');
elsif rising_edge(rx_wordclk_sig) then
MGT_USRWORD_o <= MGT_USRWORD_s;
end if;
end process;
xlx_ku_mgt_std_i: xlx_ku_mgt_ip
PORT MAP (
rxusrclk_in(0) => rx_wordclk_sig,
rxusrclk2_in(0) => rx_wordclk_sig,
rxoutclk_out(0) => rxoutclk_sig,
txusrclk_in(0) => tx_wordclk_sig,
txusrclk2_in(0) => tx_wordclk_sig,
txoutclk_out(0) => txoutclk_sig,
gtwiz_userclk_tx_active_in(0) => gtwiz_userclk_tx_active_int,
gtwiz_userclk_rx_active_in(0) => gtwiz_userclk_rx_active_int,
--gtwiz_buffbypass_tx_reset_in(0) => gtwiz_buffbypass_tx_reset_in_s,
--gtwiz_buffbypass_tx_start_user_in(0) => '0',
--gtwiz_buffbypass_tx_done_out(0) => txfsm_reset_done,
--gtwiz_buffbypass_tx_error_out => open,
gtwiz_buffbypass_rx_reset_in(0) => gtwiz_buffbypass_rx_reset_in_s,
gtwiz_buffbypass_rx_start_user_in(0) => '0',
gtwiz_buffbypass_rx_done_out(0) => rxfsm_reset_done,
gtwiz_buffbypass_rx_error_out => open,
gtwiz_reset_clk_freerun_in(0) => MGT_FREEDRPCLK_i,
gtwiz_reset_all_in(0) => '0',
gtwiz_reset_tx_pll_and_datapath_in(0) => tx_reset_sig,
gtwiz_reset_tx_datapath_in(0) => '0',
gtwiz_reset_tx_done_out(0) => tx_reset_done,
gtwiz_reset_rx_pll_and_datapath_in(0) => '0',
gtwiz_reset_rx_datapath_in(0) => rx_reset_sig,
gtwiz_reset_rx_cdr_stable_out => open,
gtwiz_reset_rx_done_out(0) => rx_reset_done,
gtwiz_userdata_tx_in => MGT_USRWORD_i,
gtwiz_userdata_rx_out => MGT_USRWORD_s,
drpclk_in(0) => MGT_FREEDRPCLK_i,
gthrxn_in(0) => RXn_i,
gthrxp_in(0) => RXp_i,
gthtxn_out(0) => TXn_o,
gthtxp_out(0) => TXp_o,
gtrefclk0_in(0) => MGT_REFCLK_i,
rxslide_in(0) => MGT_RXSlide_i,
rxpmaresetdone_out(0) => rxpmaresetdone,
txpmaresetdone_out(0) => txpmaresetdone,
-- DRP bus (used by the tx phase aligner)
drpaddr_in => drpaddr_s,
drpdi_in => drpdi_s,
drpen_in(0) => drpen_s,
drpwe_in(0) => drpwe_s,
drpdo_out => drpdo_s,
drprdy_out(0) => drprdy_s,
-- PI control / monitoring signals
txpippmen_in(0) => txpippmen_s,
txpippmovrden_in(0) => txpippmovrden_s,
txpippmpd_in(0) => txpippmpd_s,
txpippmsel_in(0) => txpippmsel_s,
txpippmstepsize_in => txpippmstepsize_in,
-- Tx buffer status
txbufstatus_out => txbufstatus_s
--txprgdivresetdone_out => open
);
txpippmen_s <= '0';
txpippmovrden_s <= '0';
txpippmsel_s <= '0';
txpippmpd_s <= '0';
txpippmstepsize_in <= (others => '0');
drpaddr_s <= (others => '0');
drpen_s <= '0';
drpdi_s <= (others => '0');
drpwe_s <= '0';
MGT_TX_ALIGNED_s <= not(tx_reset_done);
end structural;
--=================================================================================================--
--#################################################################################################--
--=================================================================================================--
\ No newline at end of file
This diff is collapsed.
-------------------------------------------------------
--! @file
--! @author Julian Mendez <julian.mendez@cern.ch> (CERN - EP-ESE-BE)
--! @version 6.0
--! @brief GBT-FPGA IP - Transceiver reset synchronizer
-------------------------------------------------------
--! IEEE VHDL standard library:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--! @brief xlx_ku_mgt_ip_reset_synchronizer - Transceiver reset synchronizer
--! @details
--! The xlx_ku_mgt_ip_reset_synchronizer synchronizes the resets with a specific clock domain
entity xlx_ku_mgt_ip_reset_synchronizer is
port (
CLK_IN : in std_logic;
RST_IN : in std_logic;
RST_OUT : out std_logic
);
end xlx_ku_mgt_ip_reset_synchronizer;
--! @brief xlx_ku_mgt_ip_reset_synchronizer - Transceiver reset
--! @details The xlx_ku_mgt_ip_reset_synchronizer implements a reset bridge system
architecture Behavioral of xlx_ku_mgt_ip_reset_synchronizer is
signal rst_in_meta: std_logic;
signal rst_in_sync1: std_logic;
signal rst_in_sync2: std_logic;
signal rst_in_sync3: std_logic;
signal rst_in_out: std_logic;
begin
rstFsm_proc: process(clk_in, rst_in)
begin
if rst_in = '1' then
rst_in_meta <= '1';
rst_in_sync1 <= '1';
rst_in_sync2 <= '1';
rst_in_sync3 <= '1';
rst_in_out <= '1';
elsif rising_edge(clk_in) then
rst_in_meta <= '0';
rst_in_sync1 <= rst_in_meta;
rst_in_sync2 <= rst_in_sync1;
rst_in_sync3 <= rst_in_sync2;
rst_in_out <= rst_in_sync3;
end if;
end process;
rst_out <= rst_in_out;
end Behavioral;
# LpGBT-FPGA IP
The LpGBT ASIC (Low Power GigaBit Transceiver) is a new 65nm-CMOS radiation tolerant serializer/deserializer
device that can be used on the front-end electronics of the HL-LHC detectors. This component is foreseen to
be used by CMS and ATLAS for their system upgrades and offers a set of encoding and decoding schemes specifically
tailored to meet their needs in terms of radiation-hardness and data bandwidth.
The LpGBT-FPGA project started in 2018 as a natural evolution of the existing GBT-FPGA to provide a back-end
counterpart to the future LpGBT ASIC. The new FPGA IP implements the encoding/decoding schemes supported by
the front-end ASIC, meaning that it can be configured using 4 different combinations for the upstream link
(from Front-end to Back-end): two decoding schemes (FEC5 or FEC12) based on Reed-Solomon techniques to configure
the encoding robustness and two line rates (10.24 or 5.12Gbps) depending on the required bandwidth. Additionally,
the LpGBT-FPGA core features an asymmetric architecture to match the LpGBT ASIC specificities: the transmitter
part of the IP, as opposed to the configurable receiver part, proposes a single encoding scheme (FEC12) and a
lower line rate of 2.56Gbps. Such an asymmetry prevents the IP to be used in loopback mode for self-testing.
<div style="border: 1px solid #faebcc; background:#fcf8e3; color:#8a6d3b; padding: .75rem 1.25rem; border-radius: .25rem;"><b>Warning:</b> Philosophy changed since the GBT-FPGA: the LpGBT-FPGA is not
anymore given as a generic module that can be implemented in one block. It is now proposed as a set of modules with implementation example and reference notes
to help the user in designing its own system in the most efficient way.</div>
## Links
- [Gitlab repo - LpGBT-FPGA IP](https://gitlab.cern.ch/gbt-fpga/lpgbt-fpga)
- [Documentation](http://lpgbt-fpga.web.cern.ch)
- [LpGBT Sharepoint] (https://espace.cern.ch/GBT-Project/LpGBT/default.aspx)
## Repository architecture
* **LpGBT-FPGA**: This folder contains the VHDL files that describe the logic of the different modules required to implements the IP (Encoder/Decoder, Scrambler/Descrambler, Gearboxes, Frame aligner)
* **Mgt**: This folder contains the Mgt module used to serialize/deserialize the data. In the case of the KCU105 design, it contains a GTH Transceiver (Xilinx).
* **TCL**: This folder contains the TCL script that defines the procedure to compile and simulate the project
* **TestBench_sim**: This folder contains all of the file required to implement the LpGBT-FPGA modules within a complete testbench (LpGBT-FPGA top level, Stimulis, Codecs from the LpGBT Asic model, ...).
## KCU105 testbench
The KCU105 test bench is used to validate the routing feasibility of the LpGBT-FPGA. Especially from the timing point of view. Additionally. it used to qualify the IP by measuring the coding gain and latency.
<div style="border: 1px solid #faebcc; background:#fcf8e3; color:#8a6d3b; padding: .75rem 1.25rem; border-radius: .25rem;"><b>Warning:</b> The HPTD module was removed from this design as we are waiting for its official release. Therefore, the position of the word inside of the transmitter gearbox is not monitored and controlled, meaning that the latency deviation can go up to 3.125ns. Nevertheless, measurements were carried out using the module and they show a stability of 12ps.</div>
<img src='http://lpgbt-fpga.web.cern.ch/img/kcu105BlockDiagram.png' />
# Copied from Echo_Server example design in Tcl / modif. by EBSM
# LPGBT_SOFT_Server --
# Open the server listening socket
# and enter the Tcl event loop
#
# Arguments:
# port The server's port number
proc GBTFPGA_SOFT_Server {port} {
global forever
set s [socket -server GBTFPGA_SOFTAccept $port]
vwait forever
}
# LPGBT_SOFT_Accept --
# Accept a connection from a new client.
# This is called after a new socket connection
# has been created by Tcl.
#
# Arguments:
# sock The new socket connection to the client
# addr The client's IP address
# port The client's port number
proc GBTFPGA_SOFTAccept {sock addr port} {
global gbtfpga
# Record the client's information
puts "Accept $sock from $addr port $port"
set gbtfpga(addr,$sock) [list $addr $port]
# Ensure that each "puts" by the server
# results in a network transmission
fconfigure $sock -buffering line
# Set up a callback for when the client sends data
fileevent $sock readable [list LPGBT_SOFT $sock]
}
# LPGBT_SOFT --
# This procedure is called when the server
# can read data from the client
#
# Arguments:
# sock The socket connection to the client
proc LPGBT_SOFT {sock} {
global gbtfpga
global forever
set gpio_rt gpio_rt
set gpio_wt gpio_wt
# Check end of file or abnormal connection drop,
# then gbtfpga data back to the client.
if {[eof $sock] || [catch {gets $sock line}]} {
close $sock
set forever 0
#exit 0
} else {
################################ Process Data #################################
set rcvd_cmd $line
set ope [lindex $rcvd_cmd 0]
set addr [lindex $rcvd_cmd 1]
set data [lindex $rcvd_cmd 2]
switch $ope {
"r" {
puts "Read register command"
#Rd
set_property CMD.ADDR $addr [get_hw_axi_txns $gpio_rt]
run_hw_axi [get_hw_axi_txns $gpio_rt]
set data [get_property DATA [get_hw_axi_txns $gpio_rt]]
puts $sock $data
}
"w" {
puts "Write register command"
#Wr
set_property CMD.ADDR $addr [get_hw_axi_txns $gpio_wt]
set_property DATA $data [get_hw_axi_txns $gpio_wt]
run_hw_axi [get_hw_axi_txns $gpio_wt]
set gpio_rt gpio_rt
set gpio_wt gpio_wt
create_hw_axi_txn $gpio_rt [get_hw_axis hw_axi_1] -type read -address 0x00000000
create_hw_axi_txn $gpio_wt [get_hw_axis hw_axi_1] -type write -address 0x00000000 -data {00000000}
proc resetLPGBT {} {
set_property CMD.ADDR 0x00000000 [get_hw_axi_txns $gpio_wt]
set_property DATA 0x00000001 [get_hw_axi_txns $gpio_wt]
run_hw_axi [get_hw_axi_txns $gpio_wt]
set_property CMD.ADDR 0x00000000 [get_hw_axi_txns $gpio_wt]
set_property DATA 0x00000000 [get_hw_axi_txns $gpio_wt]
run_hw_axi [get_hw_axi_txns $gpio_wt]
}
puts $sock 1
}
"wvio" {
puts "Write VIO"
set dataDec [expr $data]
startgroup
set_property OUTPUT_VALUE $dataDec [get_hw_probes $addr -of_objects [get_hw_vios -of_objects [lindex [get_hw_devices] 0] -filter {CELL_NAME=~"vio"}]]
commit_hw_vio [get_hw_vios -of_objects [lindex [get_hw_devices] 0] -filter {CELL_NAME=~"vio"}]
endgroup
puts $sock 1
}
"rvio" {
puts "Read VIO"
startgroup
set data [get_property INPUT_VALUE [get_hw_probes $addr]]
endgroup
puts $sock $data
}
"ping" {
puts $sock 1
}
"configure" {
#open_project $addr
#open_hw
#connect_hw_server -url localhost:3121
#open_hw_target
#current_hw_device [lindex [get_hw_devices] 0]
#refresh_hw_device [lindex [get_hw_devices] 0]
#set current_hw_device [lindex [get_hw_devices] 0]
#set_property PROGRAM.FILE $data $current_hw_device
#program_hw_devices $current_hw_device
#refresh_hw_device [lindex [get_hw_devices] 0]
set gpio_rt gpio_rt
set gpio_wt gpio_wt
create_hw_axi_txn $gpio_rt [get_hw_axis hw_axi_1] -type read -address 0x00000000
create_hw_axi_txn $gpio_wt [get_hw_axis hw_axi_1] -type write -address 0x00000000 -data {00000000}
puts $sock 1
}
"exit" {
exit 0
}
default {
puts "Command not recognizable"
puts $sock -1
}
}
################################# End Process Data #################################
# puts "Finished data processing"
# puts $sock $line
# puts $line
}
}
#Create Transactions
puts "############## GTFPGA_SOFT - TEST CONTROL ###############"
puts "# Socket Port: 8555 #"
puts "# IP Address (localhost): 127.0.0.1 #"
puts "#########################################################"
GBTFPGA_SOFT_Server 8555
#vwait forever
/* *****************************************************************************
* lpGBTX *
* Copyright (C) 2011-2016 GBTX Team, CERN *
* *
* This IP block is free for HEP experiments and other scientific research *
* purposes. Commercial exploitation of a chip containing the IP is not *
* permitted. You can not redistribute the IP without written permission *
* from the authors. Any modifications of the IP have to be communicated back *
* to the authors. The use of the IP should be acknowledged in publications, *
* public presentations, user manual, and other documents. *
* *
* This IP is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
* FOR A PARTICULAR PURPOSE. *
* *
*******************************************************************************
*
* file: downLinkDeinterleaver.v
*
* downLinkDeinterleaver
*
* History:
* 2016/05/20 Szymon Kulis : Created
* 2016/12/20 Szymon Kulis : Data muxing (bert) removed
*
**/
module LpGBT_Model_dataPath (
// Clocks inputs:
input downClki,
input upClki,
input upLinkDataPathEnable,
input downLinkDataPathEnable,
// -------------------------------------------------------------------------
// - Down link -------------------------------------------------------------
// -------------------------------------------------------------------------
// data input
input [63:0] downLinkFrame,
// data outputs
output [15:0] downLinkDataGroup0,
output [15:0] downLinkDataGroup1,
output [1:0] downLinkDataEc,
output [1:0] downLinkDataIc,
output [3:0] downLinkHeader,
// control signals
input downLinkBypassDeinterleaver,
input downLinkBypassFECDecoder,
input downLinkBypassDescsrambler,
// -- fec counter --
input enableFECErrCounter,
output [15:0] fecCorrectionCount,
// -------------------------------------------------------------------------
// - Up link ---------------------------------------------------------------
// -------------------------------------------------------------------------
// input data:
input [31:0] upLinkData0,
input [31:0] upLinkData1,
input [31:0] upLinkData2,
input [31:0] upLinkData3,
input [31:0] upLinkData4,
input [31:0] upLinkData5,
input [31:0] upLinkData6,
input [1:0] upLinkDataIC,
input [1:0] upLinkDataEC,
// controll signals
input upLinkScramblerBypass,
input upLinkScramblerReset,
input upLinkFecBypass,
input upLinkInterleaverBypass,
input fecMode,
input txDataRate,
// output data
output [255:0] upLinkFrame
);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg default triplicate
// tmrg do_not_triplicate upLinkFrame
// tmrg do_not_triplicate downLinkFrame
// -------------------------------------------------------------------------- //
wire upLinkClk = upClki & upLinkDataPathEnable;
wire downLinkClk = downClki & downLinkDataPathEnable;
wire [31:0] downLinkData;
assign downLinkDataGroup1=downLinkData[31:16];
assign downLinkDataGroup0=downLinkData[15:0];
downLinkDataPath DLDP (
.bypassDeinterleaver(downLinkBypassDeinterleaver),
.bypassDescrambler(downLinkBypassDescsrambler),
.bypassFECDecoder(downLinkBypassFECDecoder),
.clk(downLinkClk),
.dataEC(downLinkDataEc),
.dataIC(downLinkDataIc),
.dataOut(downLinkData),
.downLinkFrame(downLinkFrame),
.enableFECErrCounter(enableFECErrCounter),
.fecCorrectionCount(fecCorrectionCount),
.header(downLinkHeader)
);
wire [5:0] txDummyFec5 = 6'b001100;// TODO FIXME check the values !!
wire [9:0] txDummyFec12= 10'b0101010101;// TODO FIXME check the values !!
wire [111:0] upLinkDataLow, upLinkDataHigh;
assign upLinkDataLow[0+:16] = upLinkData0[0 +: 16];
assign upLinkDataLow[16+:16] = upLinkData1[0 +: 16];
assign upLinkDataLow[32+:16] = upLinkData2[0 +: 16];
assign upLinkDataLow[48+:16] = upLinkData3[0 +: 16];
assign upLinkDataLow[64+:16] = upLinkData4[0 +: 16];
assign upLinkDataLow[80+:16] = upLinkData5[0 +: 16];
assign upLinkDataLow[96+:16] = upLinkData6[0 +: 16];
assign upLinkDataHigh[0+:16] = upLinkData0[16+: 16];
assign upLinkDataHigh[16+:16] = upLinkData1[16+: 16];
assign upLinkDataHigh[32+:16] = upLinkData2[16+: 16];
assign upLinkDataHigh[48+:16] = upLinkData3[16+: 16];
assign upLinkDataHigh[64+:16] = upLinkData4[16+: 16];
assign upLinkDataHigh[80+:16] = upLinkData5[16+: 16];
assign upLinkDataHigh[96+:16] = upLinkData6[16+: 16];
upLinkDataPath ULDP (
.clk40M(upLinkClk),
.txData0(upLinkData0),
.txData1(upLinkData1),
.txData2(upLinkData2),
.txData3(upLinkData3),
.txData4(upLinkData4),
.txData5(upLinkData5),
.txData6(upLinkData6),
.txIC(upLinkDataIC),
.txEC(upLinkDataEC),
.txDummyFec5(6'd0),
.txDummyFec12(10'd0),
.scramblerBypass(upLinkScramblerBypass),
.interleaverBypass(upLinkInterleaverBypass),
.fecBypass(upLinkFecBypass),
.fecMode(fecMode),
.txDataRate(txDataRate),
.scramblerReset(upLinkScramblerReset),
.upLinkFrame(upLinkFrame)
);
endmodule
/** ****************************************************************************
* lpGBTX *
* Copyright (C) 2011-2016 GBTX Team, CERN *
* *
* This IP block is free for HEP experiments and other scientific research *
* purposes. Commercial exploitation of a chip containing the IP is not *
* permitted. You can not redistribute the IP without written permission *
* from the authors. Any modifications of the IP have to be communicated back *
* to the authors. The use of the IP should be acknowledged in publications, *
* public presentations, user manual, and other documents. *
* *
* This IP is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
* FOR A PARTICULAR PURPOSE. *
* *
*******************************************************************************
*
* file: upCounter.v
*
* upCounter
*
* History:
* 2016/05/21 Szymon Kulis : Created
*
**/
module dataPathFecCounter(
input enable,
input clk,
input [15:0] addValue,
output reg [15:0] count
);
// tmrg do_not_touch
reg clkGate;
wire rst=!enable;
wire clkGated=clk&clkGate;
wire enableVoted=enable;
reg [16:0] countNext;
wire [16:0] countNextVoted=countNext;
// latch for clock gate
always @(clk or enable)
if(!clk)
clkGate=enable;
// counter register
always @(posedge clk or posedge rst)
if (rst)
count <= 16'b0;
else
count <= countNextVoted;
// next state logic
always @(count or enable or addValue)
begin
if (!enable)
countNext=0;
else
countNext=count+addValue;
if (countNext>17'hffff)
countNext=17'hffff;
end
endmodule
/* Module: Descrambler36bitOrder36 */
/* Created: Paulo Moreira, 2015/09/15 */
/* Institute: CERN */
/* Version: 1.0 */
/* Descrambler width: 36 - bits */
/* Descrambler order: 36 */
/* Recursive equation used for the scrambler: Si = Di xnor Si-25 xnor Si-36 */
`timescale 1 ps / 1 ps
module descrambler36bitOrder36(
input [35:0] scrambledData,
input clock,
input bypass,
output reg [35:0] descrambledData
);
reg [35:0] memoryRegister;
wire [35:0] iMemoryRegister;
wire [35:0] iMemoryRegisterVoted = iMemoryRegister;
wire [35:0] iDescrambledData;
wire [35:0] iDescrambledDataVoted = iDescrambledData;
always @(posedge clock)
begin
memoryRegister <= iMemoryRegisterVoted;
descrambledData <= iDescrambledDataVoted;
end
// Descrambler polynomial and bypass mux
assign
iDescrambledData[35:25] = (bypass)? scrambledData[35:25] : scrambledData[35:25] ~^ scrambledData[10:0] ~^ memoryRegister[35:25],
iDescrambledData[24:0] = (bypass)? scrambledData[34:0] : scrambledData[24:0] ~^ memoryRegister[35:11] ~^ memoryRegister[24:0],
iMemoryRegister[35:0] = (bypass)? 36'h000000000 : scrambledData[35:0];
endmodule
/** ****************************************************************************
* lpGBTX *
* Copyright (C) 2011-2016 GBTX Team, CERN *
* *
* This IP block is free for HEP experiments and other scientific research *
* purposes. Commercial exploitation of a chip containing the IP is not *
* permitted. You can not redistribute the IP without written permission *
* from the authors. Any modifications of the IP have to be communicated back *
* to the authors. The use of the IP should be acknowledged in publications, *
* public presentations, user manual, and other documents. *
* *
* This IP is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
* FOR A PARTICULAR PURPOSE. *
* *
*******************************************************************************
*
* file: downLinkDeinterleaver.v
*
* downLinkDeinterleaver
*
* History:
* 2016/05/20 Szymon Kulis : Created
* 2016/11/02 José Fonseca : Modified
*
**/
module downLinkDataPath (
// Clocks inputs:
input clk,
// data input
input [63:0] downLinkFrame,
// data outputs
output [31:0] dataOut,
output [1:0] dataEC,
output [1:0] dataIC,
output [3:0] header,
// control signals
input bypassDeinterleaver,
input bypassFECDecoder,
input bypassDescrambler,
// -- fec counter --
input enableFECErrCounter,
output [15:0] fecCorrectionCount
);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg default triplicate
// tmrg do_not_triplicate downLinkFrame
// -------------------------------------------------------------------------- //
wire [35:0] dataDeint;
wire [23:0] fecDeint;
wire [35:0] decData;
reg [35:0] decDataReg;
wire [35:0] descrambledData;
reg [63:0] downLinkFrameReg;
downLinkDeinterleaver DLD (
.bypass(bypassDeinterleaver),
.downLinkFrame(downLinkFrame),
.data(dataDeint),
.fec(fecDeint)
);
downLinkFECDecoder DLFD (
.clk(clk),
.bypass(bypassFECDecoder),
.enableFECErrCounter(enableFECErrCounter),
.data(dataDeint),
.fec(fecDeint),
.dataOut(decData),
.fecCorrectionCount(fecCorrectionCount)
);
descrambler36bitOrder36 DES (
.bypass(bypassDescrambler),
.clock(clk),
.scrambledData(decData),
.descrambledData(descrambledData)
);
/*
downLinkBERT DLBERT(
.enable(enableBERT),
.clk(clk40M),
.dataIn(descrambledData[31:0]),
.pattern(bertPattern),
.errCount(bertCount)
);
*/
assign dataOut = descrambledData[31:0];
assign dataEC = descrambledData[33:32];
assign dataIC = descrambledData[35:34];
// assign header = downLinkFrame[63:60]; // version with the header in front
assign header = {downLinkFrame[63],downLinkFrame[61],downLinkFrame[59],downLinkFrame[57]}; // header interleaved with data for DC balance
endmodule
/** ****************************************************************************
* lpGBTX *
* Copyright (C) 2011-2016 GBTX Team, CERN *
* *
* This IP block is free for HEP experiments and other scientific research *
* purposes. Commercial exploitation of a chip containing the IP is not *
* permitted. You can not redistribute the IP without written permission *
* from the authors. Any modifications of the IP have to be communicated back *
* to the authors. The use of the IP should be acknowledged in publications, *
* public presentations, user manual, and other documents. *
* *
* This IP is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
* FOR A PARTICULAR PURPOSE. *
* *
*******************************************************************************
*
* file: downLinkDeinterleaver.v
*
* downLinkDeinterleaver
*
* History:
* 2016/05/20 Szymon Kulis : Created
* 2016/11/02 José Fonseca : Modified
*
**/
module downLinkDeinterleaver (
input bypass,
input [63:0] downLinkFrame,
output [35:0] data,
output [23:0] fec
);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// -------------------------------------------------------------------------- //
// Code 0
assign data[8:0] = (bypass) ? downLinkFrame[32:24] : {downLinkFrame[50:48], downLinkFrame[38:36], downLinkFrame[26:24]};
assign fec[5:0] = (bypass) ? downLinkFrame[5:0] : {downLinkFrame[14:12], downLinkFrame[2:0]};
// Code 1
assign data[17:9] = (bypass) ? downLinkFrame[41:33] : {downLinkFrame[53:51], downLinkFrame[41:39], downLinkFrame[29:27]};
assign fec[11:6] = (bypass) ? downLinkFrame[11:6] : {downLinkFrame[17:15], downLinkFrame[5:3]};
// Code 2
assign data[26:18] = (bypass) ? downLinkFrame[50:42] : {downLinkFrame[56:54], downLinkFrame[44:42], downLinkFrame[32:30]};
assign fec[17:12] = (bypass) ? downLinkFrame[17:12] : {downLinkFrame[20:18], downLinkFrame[8:6]};
// Code 3
assign data[35:27] = (bypass) ? {downLinkFrame[62], downLinkFrame[60], downLinkFrame[58], downLinkFrame[56:51]} : {downLinkFrame[62], downLinkFrame[60], downLinkFrame[58], downLinkFrame[47:45], downLinkFrame[35:33]};
assign fec[23:18] = (bypass) ? downLinkFrame[23:18] : {downLinkFrame[23:21], downLinkFrame[11:9]};
endmodule
/** ****************************************************************************
* lpGBTX *
* Copyright (C) 2011-2016 GBTX Team, CERN *
* *
* This IP block is free for HEP experiments and other scientific research *
* purposes. Commercial exploitation of a chip containing the IP is not *
* permitted. You can not redistribute the IP without written permission *
* from the authors. Any modifications of the IP have to be communicated back *
* to the authors. The use of the IP should be acknowledged in publications, *
* public presentations, user manual, and other documents. *
* *
* This IP is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
* FOR A PARTICULAR PURPOSE. *
* *
*******************************************************************************
*
* file: downLinkFECDecoder.v
*
* downLinkFECDecoder
*
* History:
* 2016/05/20 Szymon Kulis : Created
* 2016/11/02 José Fonseca : Modified
*
**/
module downLinkFECDecoder (
input clk,
input bypass,
input enableFECErrCounter,
input [35:0] data,
input [23:0] fec,
output [35:0] dataOut,
output [15:0] fecCorrectionCount
);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg do_not_touch
// -------------------------------------------------------------------------- //
wire [20:0] virtualFrame_C0;
wire [20:0] virtualFrame_C1;
wire [20:0] virtualFrame_C2;
wire [20:0] virtualFrame_C3;
wire [14:0] decData_C0;
wire [14:0] decData_C1;
wire [14:0] decData_C2;
wire [14:0] decData_C3;
wire [1:0] fecErrorSub0;
wire [1:0] fecErrorSub1;
wire [1:0] fecErrorSub2;
wire [1:0] fecErrorSub3;
assign virtualFrame_C0 = {fec[5:0], 6'b0, data[8:0]};
assign virtualFrame_C1 = {fec[11:6], 6'b0, data[17:9]};
assign virtualFrame_C2 = {fec[17:12], 6'b0, data[26:18]};
assign virtualFrame_C3 = {fec[23:18], 6'b0, data[35:27]};
rs_decoder_N7K5 RSD0 (
.msgInput(virtualFrame_C0),
.error(fecErrorSub0),
.decMsg(decData_C0)
);
rs_decoder_N7K5 RSD1 (
.msgInput(virtualFrame_C1),
.error(fecErrorSub1),
.decMsg(decData_C1)
);
rs_decoder_N7K5 RSD2 (
.msgInput(virtualFrame_C2),
.error(fecErrorSub2),
.decMsg(decData_C2)
);
rs_decoder_N7K5 RSD3 (
.msgInput(virtualFrame_C3),
.error(fecErrorSub3),
.decMsg(decData_C3)
);
wire [15:0] fecCounterAddValue = fecErrorSub0+fecErrorSub1+fecErrorSub2+fecErrorSub3;
dataPathFecCounter EC(
.enable(enableFECErrCounter),
.clk(clk),
.addValue(fecCounterAddValue),
.count(fecCorrectionCount)
);
assign dataOut = (bypass) ? data : {decData_C3[8:0], decData_C2[8:0], decData_C1[8:0], decData_C0[8:0]};
endmodule
module gf_add_3(op1, op2, res);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg do_not_touch
// -------------------------------------------------------------------------- //
input [2:0] op1;
input [2:0] op2;
output [2:0] res;
assign res = op1 ^ op2;
endmodule
module gf_add_4(op1, op2, res);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg do_not_touch
// -------------------------------------------------------------------------- //
input [3:0] op1;
input [3:0] op2;
output [3:0] res;
assign res = op1 ^ op2;
endmodule
module gf_add_5(op1, op2, res);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg do_not_touch
// -------------------------------------------------------------------------- //
input [4:0] op1;
input [4:0] op2;
output [4:0] res;
assign res = op1 ^ op2;
endmodule
module gf_inv_3(op, res);
// -------------------------------------------------------------------------- //
// ------------- Triple Modular Redundancy Generator Directives ------------- //
// -------------------------------------------------------------------------- //
// tmrg do_not_touch
// -------------------------------------------------------------------------- //
input [2:0] op;
output reg [2:0] res;
always @(op) begin
case(op)
3'd0 :
res = 3'd0;
3'd1 :
res = 3'd1;
3'd2 :
res = 3'd5;
3'd3 :
res = 3'd6;
3'd4 :
res = 3'd7;
3'd5 :
res = 3'd2;
3'd6 :
res = 3'd3;
3'd7 :
res = 3'd4;
endcase
end
endmodule
module gf_inv_5(op, res);
input [4:0] op;
output reg [4:0] res;
always @(*) begin
case(op)
5'd0 :
res = 5'd0;
5'd1 :
res = 5'd1;
5'd2 :
res = 5'd18;
5'd3 :
res = 5'd28;
5'd4 :
res = 5'd9;
5'd5 :
res = 5'd23;
5'd6 :
res = 5'd14;
5'd7 :
res = 5'd12;
5'd8 :
res = 5'd22;
5'd9 :
res = 5'd4;
5'd10 :
res = 5'd25;
5'd11 :
res = 5'd16;
5'd12 :
res = 5'd7;
5'd13 :
res = 5'd15;
5'd14 :
res = 5'd6;
5'd15 :
res = 5'd13;
5'd16 :
res = 5'd11;
5'd17 :
res = 5'd24;
5'd18 :
res = 5'd2;
5'd19 :
res = 5'd29;
5'd20 :
res = 5'd30;
5'd21 :
res = 5'd26;
5'd22 :
res = 5'd8;
5'd23 :
res = 5'd5;
5'd24 :
res = 5'd17;
5'd25 :
res = 5'd10;
5'd26 :
res = 5'd21;
5'd27 :
res = 5'd31;
5'd28 :
res = 5'd3;
5'd29 :
res = 5'd19;
5'd30 :
res = 5'd20;
5'd31 :
res = 5'd27;
endcase
end
endmodule
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment