Select Git revision
top_combpm_electron.vhd
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
top_combpm_electron.vhd 16.56 KiB
-- PROJECT FOFB
-- COMBPM ELECTRON TOP LEVEL
-- RBR
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library xpm;
use xpm.vcomponents.all;
library desyrdl;
use desyrdl.common.all;
use desyrdl.pkg_combpm.all;
use work.pkg_combpm_version.all;
use work.pkg_combpm.all;
entity top_combpm_electron is
port(
rst_n : in std_logic; -- Asynchronous reset
free_100_clk : in std_logic; -- Freerunning clock for GT
pps : in std_logic; -- A pulse per second signal, sync to clk domain
mc_time : in std_logic_vector(39 downto 0);
-- Transceiver QPLL interface
qpll_out_clk : in std_logic; -- QPLL clock for transceivers
qpll_ref_clk : in std_logic; -- QPLL ref clock
qpll_reset : out std_logic; -- QPLL reset
qpll_lock : in std_logic; -- QPLL is locked
-- Debug output
debug_datarx : out std_logic_vector(15 downto 0);
debug_status : out std_logic_vector(6 downto 0);
error_detect : out std_logic;
-- SFP interfaces
sfp_txp : out std_logic;
sfp_txn : out std_logic;
sfp_rxp : in std_logic;
sfp_rxn : in std_logic;
sfp_rx_los : in std_logic;
sfp_mod_abs : in std_logic;
sfp_tx_disable : out std_logic;
sfp_tx_fault : in std_logic;
-- AXIS interface
m_axis_aclk : out std_logic;
m_axis_tdata_posx : out std_logic_vector(C_W_POS-1 downto 0);
m_axis_tdata_posy : out std_logic_vector(C_W_POS-1 downto 0);
m_axis_tdata_bpmid : out std_logic_vector(C_W_BPMID-1 downto 0);
m_axis_tdata_seq : out std_logic_vector(C_W_SEQ-1 downto 0);
m_axis_tdest : out std_logic_vector(C_W_TDEST-1 downto 0);
m_axis_tvalid : out std_logic;
-- AXI bus interface
s_axi_aclk : in std_logic;
s_axi_m2s : in t_combpm_m2s;
s_axi_s2m : out t_combpm_s2m
);
end top_combpm_electron;
architecture struct of top_combpm_electron is
------------------------
-- SIGNAL DECLARATION --
------------------------
signal sync_resetn : std_logic; -- This is async reset with sync deassertion
signal sync_reset : std_logic; -- This is async reset with sync deassertion
signal usrclk : std_logic;
signal rst : std_logic;
signal pps_resync : std_logic;
signal frame_seq_cnt : std_logic_vector(15 downto 0);
signal frame_valid_cnt : std_logic_vector(31 downto 0);
signal frame_invalid_cnt : std_logic_vector(31 downto 0);
signal frame_valid_rate : std_logic_vector(31 downto 0);
signal frame_invalid_rate : std_logic_vector(31 downto 0);
signal cnt_seq_mismatch : std_logic;
signal seq_discontinuity : std_logic;
signal frame_error : std_logic;
signal flag_reset : std_logic;
signal gt_datarx : std_logic_vector(15 downto 0);
signal gt_powergood : std_logic;
signal gt_rxcdrlock : std_logic;
signal gt_rxresetdone : std_logic;
signal gt_rxbyteisaligned : std_logic;
signal gt_rxbyterealign : std_logic;
signal gt_rxcommadet : std_logic;
signal addrmap_w : t_addrmap_combpm_in;
signal addrmap_r : t_addrmap_combpm_out;
signal cdc_status_array_axi : std_logic_vector(155 downto 0); -- CDC, clock axi side
signal cdc_status_array_bpm : std_logic_vector(155 downto 0); -- CDC, clock bpm side
signal cdc_control_array_axi : std_logic_vector(2 downto 0); -- CDC, clock axi side
signal cdc_control_array_bpm : std_logic_vector(2 downto 0); -- CDC, clock bpm side
signal m_axis_decoded_tvalid : std_logic;
signal m_axis_decoded_tdata : std_logic_vector(2*C_W_POS+C_W_BPMID+C_W_SEQ-1 downto 0);
signal m_axis_decoded_tdata_posx : std_logic_vector(C_W_POS-1 downto 0);
signal m_axis_decoded_tdata_posy : std_logic_vector(C_W_POS-1 downto 0);
signal m_axis_decoded_tdata_bpmid : std_logic_vector(C_W_BPMID-1 downto 0);
signal m_axis_decoded_tdata_faseq : std_logic_vector(C_W_SEQ-1 downto 0);
signal m_axis_filt_tdata : std_logic_vector(2*C_W_POS+C_W_BPMID+C_W_SEQ-1 downto 0);
begin
-- This CDC is used to deassert async reset in sync with the transceiver clock.
xpm_cdc_async_rst_inst : xpm_cdc_async_rst
generic map (
DEST_SYNC_FF => 4,
INIT_SYNC_FF => 0,
RST_ACTIVE_HIGH => 0 -- DECIMAL; 0=active low reset, 1=active high reset
)
port map (
dest_arst => sync_resetn,
dest_clk => usrclk,
src_arst => rst_n
);
xpm_cdc_pps_inst: xpm_cdc_pulse
generic map (
RST_USED => 0,
DEST_SYNC_FF => 4,
INIT_SYNC_FF => 0
)
port map (
dest_clk => usrclk,
dest_pulse => pps_resync,
src_rst => '0',
dest_rst => '0',
src_clk => free_100_clk,
src_pulse => pps
);
-- Reset invert polarity
rst <= not rst_n;
sync_reset <= not sync_resetn;
-- Debug
debug_datarx <= gt_datarx;
debug_status(0) <= gt_rxcommadet;
debug_status(1) <= gt_rxcdrlock;
debug_status(2) <= gt_rxbyterealign;
debug_status(3) <= gt_rxbyteisaligned;
debug_status(4) <= frame_error;
debug_status(5) <= cnt_seq_mismatch;
debug_status(6) <= seq_discontinuity;
error_detect <= frame_error or cnt_seq_mismatch or seq_discontinuity;
-- Output clock
m_axis_aclk <= usrclk;
-- SFP direct connexion
sfp_tx_disable <= '1';
----------------------
-- AXI-MM INTERFACE --
----------------------
blk_desyrdl: block
begin
inst_aximm: entity desyrdl.combpm
port map(
pi_clock => s_axi_aclk,
pi_reset => sync_reset,
pi_s_top => s_axi_m2s,
po_s_top => s_axi_s2m,
pi_addrmap => addrmap_w,
po_addrmap => addrmap_r
);
addrmap_w.VERSION.data.data <= C_VERSION;
cdc_status_array_bpm(0) <= sfp_rx_los;
cdc_status_array_bpm(1) <= sfp_mod_abs;
cdc_status_array_bpm(2) <= gt_powergood;
cdc_status_array_bpm(3) <= qpll_lock;
cdc_status_array_bpm(4) <= gt_rxcdrlock;
cdc_status_array_bpm(5) <= gt_rxresetdone;
cdc_status_array_bpm(6) <= gt_rxbyteisaligned;
cdc_status_array_bpm(7) <= gt_rxbyterealign;
cdc_status_array_bpm(8) <= gt_rxcommadet;
cdc_status_array_bpm(9) <= frame_error;
cdc_status_array_bpm(10) <= cnt_seq_mismatch;
cdc_status_array_bpm(11) <= seq_discontinuity;
cdc_status_array_bpm(43 downto 12) <= frame_valid_cnt;
cdc_status_array_bpm(75 downto 44) <= frame_invalid_cnt;
cdc_status_array_bpm(107 downto 76) <= frame_valid_rate;
cdc_status_array_bpm(139 downto 108) <= frame_invalid_rate;
cdc_status_array_bpm(155 downto 140) <= frame_seq_cnt;
inst_xpm_cdc_status_array_single: xpm_cdc_array_single
generic map (
DEST_SYNC_FF => 4,
INIT_SYNC_FF => 0,
SIM_ASSERT_CHK => 0,
SRC_INPUT_REG => 1,
WIDTH => cdc_status_array_axi'length
)
port map (
dest_out => cdc_status_array_axi,
dest_clk => s_axi_aclk,
src_clk => usrclk,
src_in => cdc_status_array_bpm
);
inst_xpm_cdc_control_array_single: xpm_cdc_array_single
generic map (
DEST_SYNC_FF => 4,
INIT_SYNC_FF => 0,
SIM_ASSERT_CHK => 0,
SRC_INPUT_REG => 1,
WIDTH => cdc_control_array_axi'length
)
port map (
dest_out => cdc_control_array_bpm,
dest_clk => usrclk,
src_clk => s_axi_aclk,
src_in => cdc_control_array_axi
);
addrmap_w.SFP.RXLOS.data(0) <= cdc_status_array_axi(0);
addrmap_w.SFP.MODABS.data(0) <= cdc_status_array_axi(1);
addrmap_w.GT_STATUS.POWERGOOD.data(0) <= cdc_status_array_axi(2);
addrmap_w.GT_STATUS.QPLLLOCK.data(0) <= cdc_status_array_axi(3);
addrmap_w.GT_STATUS.RXCDRLOCK.data(0) <= cdc_status_array_axi(4);
addrmap_w.GT_STATUS.RXRESETDONE.data(0) <= cdc_status_array_axi(5);
addrmap_w.GT_STATUS.RXBYTEISALIGNED.data(0) <= cdc_status_array_axi(6);
addrmap_w.GT_STATUS.RXBYTEREALIGN.data(0) <= cdc_status_array_axi(7);
addrmap_w.GT_STATUS.RXCOMMADET.data(0) <= cdc_status_array_axi(8);
addrmap_w.PROTOCOL_ERROR.FRAMEERROR.data(0) <= cdc_status_array_axi(9);
addrmap_w.PROTOCOL_ERROR.SEQFRAMECNTERROR.data(0) <= cdc_status_array_axi(10);
addrmap_w.PROTOCOL_ERROR.SEQFRAMEDISCONT.data(0) <= cdc_status_array_axi(11);
addrmap_w.VALIDFRAMECNT.data.data <= cdc_status_array_axi(43 downto 12);
addrmap_w.INVALIDFRAMECNT.data.data <= cdc_status_array_axi(75 downto 44);
addrmap_w.VALIDFRAMERATE.data.data <= cdc_status_array_axi(107 downto 76);
addrmap_w.INVALIDFRAMERATE.data.data <= cdc_status_array_axi(139 downto 108);
addrmap_w.FRAMESEQ.data.data <= cdc_status_array_axi(155 downto 140);
cdc_control_array_axi(0) <= addrmap_r.GT_CONTROL.RXRSTDATAPATH.data(0);
cdc_control_array_axi(1) <= addrmap_r.GT_CONTROL.RXRSTPLLDATAPATH.data(0);
cdc_control_array_axi(2) <= addrmap_r.GT_CONTROL.RXCOMMADETEN.data(0);
end block blk_desyrdl;
--------------------------------------
-- LIBERA ELECTRON PROCOTOL DECODER --
--------------------------------------
protocol_inst: entity work.combpm_protocol_electron
port map(
rst_n => sync_resetn,
clk => usrclk,
pps => pps_resync,
gt_datarx => gt_datarx,
m_axis_tvalid => m_axis_decoded_tvalid,
m_axis_tdata_posx => m_axis_decoded_tdata_posx,
m_axis_tdata_posy => m_axis_decoded_tdata_posy,
m_axis_tdata_bpmid => m_axis_decoded_tdata_bpmid,
m_axis_tdata_faseq => m_axis_decoded_tdata_faseq,
m_axis_tuser_mcts => open,
mc_time => mc_time,
soft_reset => addrmap_r.RESET.SOFTRESET.data(0),
seq_offset => signed(addrmap_r.SEQ_OFFSET.data.data),
frame_seq_cnt => frame_seq_cnt,
frame_valid_cnt => frame_valid_cnt,
frame_invalid_cnt => frame_invalid_cnt,
frame_valid_rate => frame_valid_rate,
frame_invalid_rate => frame_invalid_rate,
flag_cnt_seq_mismatch => cnt_seq_mismatch,
flag_seq_discontinuity => seq_discontinuity,
flag_frame_error => frame_error,
flag_reset => addrmap_r.RESET_ERROR.SOFTRESET.data(0)
);
-- Pack fo convenience
m_axis_decoded_tdata <= m_axis_decoded_tdata_posx & m_axis_decoded_tdata_posy &
m_axis_decoded_tdata_bpmid & m_axis_decoded_tdata_faseq;
---------------
-- GT WIZARD --
---------------
gtwizard_inst : combpm_gtwizard
PORT MAP (
-- Async reset
gtwiz_reset_all_in(0) => rst,
gtwiz_userclk_tx_reset_in(0) => rst,
gtwiz_userclk_rx_reset_in(0) => rst,
-- Free run clock
gtwiz_reset_clk_freerun_in(0) => free_100_clk,
-- Clock and data
gtwiz_userclk_rx_usrclk2_out(0) => usrclk,
gtwiz_userdata_tx_in => (others => '0'),
gtwiz_userdata_rx_out => gt_datarx,
-- QPLL COMMON
gtwiz_reset_qpll1lock_in(0) => qpll_lock,
gtwiz_reset_qpll1reset_out(0) => qpll_reset,
qpll1clk_in(0) => qpll_out_clk,
qpll1refclk_in(0) => qpll_ref_clk,
-- Control
gtwiz_reset_rx_datapath_in(0) => cdc_control_array_bpm(0),
gtwiz_reset_rx_pll_and_datapath_in(0) => cdc_control_array_bpm(1),
rxbufreset_in => "0",
rxcommadeten_in(0) => cdc_control_array_bpm(2),
rx8b10ben_in => "1",
rxmcommaalignen_in => "1",
rxpcommaalignen_in => "1",
tx8b10ben_in => "1",
gtwiz_reset_tx_pll_and_datapath_in => "0",
gtwiz_reset_tx_datapath_in => "0",
-- Status
gtwiz_userclk_tx_active_out => open,
gtwiz_userclk_rx_active_out => addrmap_w.GT_STATUS.RXCLKACTIVE.data,
gtwiz_reset_tx_done_out => open,
gtwiz_reset_rx_done_out(0) => gt_rxresetdone,
gtpowergood_out(0) => gt_powergood,
rxbyteisaligned_out(0) => gt_rxbyteisaligned,
rxbyterealign_out(0) => gt_rxbyterealign,
rxcdrlock_out(0) => gt_rxcdrlock,
rxcommadet_out(0) => gt_rxcommadet,
rxbufstatus_out => open,
rxclkcorcnt_out => open,
rxpmaresetdone_out => open,
txpmaresetdone_out => open,
-- SFP
gthrxn_in(0) => sfp_rxn,
gthrxp_in(0) => sfp_rxp,
gthtxn_out(0) => sfp_txn,
gthtxp_out(0) => sfp_txp,
-- Not used
qpll0clk_in => "0", -- not used
qpll0refclk_in => "0", -- not used
gtwiz_reset_rx_cdr_stable_out => open, -- Do not use
gtwiz_userclk_rx_srcclk_out => open,
gtwiz_userclk_rx_usrclk_out => open,
rxctrl0_out => open,
rxctrl1_out => open,
rxctrl2_out => open,
rxctrl3_out => open,
txctrl0_in => (others => '0'),
txctrl1_in => (others => '0'),
txctrl2_in => (others => '0'),
gtwiz_userclk_tx_srcclk_out => open,
gtwiz_userclk_tx_usrclk_out => open,
gtwiz_userclk_tx_usrclk2_out => open
);
-------------------
-- PACKET FILTER --
-------------------
inst_filter:entity work.combpm_packet_filter
generic map(
G_W_ADDR_TABLE => C_W_ADDR_TABLE,
G_W_TDATA => m_axis_decoded_tdata'length
)
port map(
axis_clk => usrclk,
axi_clk => s_axi_aclk,
axis_rst_n => sync_resetn,
-- AXIS SLAVE INTERFACE
s_axis_tdata => m_axis_decoded_tdata,
s_axis_tuser_bpmid => m_axis_decoded_tdata_bpmid,
s_axis_tvalid => m_axis_decoded_tvalid,
-- AXIS SLAVE INTERFACE
m_axis_tdest => m_axis_tdest,
m_axis_tdata => m_axis_filt_tdata,
m_axis_tvalid => m_axis_tvalid,
-- Table configuration interface
pi_table_en => addrmap_r.filtertable.en,
pi_table_we => addrmap_r.filtertable.we,
pi_table_addr => addrmap_r.filtertable.addr(C_W_ADDR_TABLE-1 downto 0),
pi_table_data => addrmap_r.filtertable.data(7 downto 0),
po_table_data => addrmap_w.filtertable.data(7 downto 0)
);
addrmap_w.filtertable.data(31 downto 8) <= (others => '0');
-- unpack
m_axis_tdata_posx <= m_axis_filt_tdata(2*C_W_POS+C_W_BPMID+C_W_SEQ-1 downto C_W_POS+C_W_BPMID+C_W_SEQ);
m_axis_tdata_posy <= m_axis_filt_tdata(C_W_POS+C_W_BPMID+C_W_SEQ-1 downto C_W_BPMID+C_W_SEQ);
m_axis_tdata_bpmid <= m_axis_filt_tdata(C_W_BPMID+C_W_SEQ-1 downto C_W_SEQ);
m_axis_tdata_seq <= m_axis_filt_tdata(C_W_SEQ-1 downto 0);
end architecture struct;