-- 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_bpmpacket_stream.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 : out std_logic_vector(C_TDATA_W-1 downto 0); m_axis_tdest : out std_logic_vector(C_TDEST_W-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 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 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_m2s : t_bpmpacket_axis_m2s; 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 ); -- 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.POWERGOOD.data(0) <= cdc_status_array_axi(2); addrmap_w.GT.QPLLLOCK.data(0) <= cdc_status_array_axi(3); addrmap_w.GT.RXCDRLOCK.data(0) <= cdc_status_array_axi(4); addrmap_w.GT.RXRESETDONE.data(0) <= cdc_status_array_axi(5); addrmap_w.GT.RXBYTEISALIGNED.data(0) <= cdc_status_array_axi(6); addrmap_w.GT.RXBYTEREALIGN.data(0) <= cdc_status_array_axi(7); addrmap_w.GT.RXCOMMADET.data(0) <= cdc_status_array_axi(8); addrmap_w.PROTOCOL.FRAMEERROR.data(0) <= cdc_status_array_axi(9); addrmap_w.PROTOCOL.SEQFRAMECNTERROR.data(0) <= cdc_status_array_axi(10); addrmap_w.PROTOCOL.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.RXRSTDATAPATH.data(0); cdc_control_array_axi(1) <= addrmap_r.GT.RXRSTPLLDATAPATH.data(0); cdc_control_array_axi(2) <= addrmap_r.GT.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, gt_datarx => gt_datarx, m_axis_m2s => m_axis_decoded_m2s, mc_time => mc_time, soft_reset => addrmap_w.PROTOCOL.SOFTRESET.data(0), 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, cnt_seq_mismatch => cnt_seq_mismatch, seq_discontinuity => seq_discontinuity, frame_error => frame_error ); --------------- -- 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.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 ) port map( axis_clk => usrclk, axi_clk => s_axi_aclk, axis_rst_n => sync_resetn, -- AXIS SLAVE INTERFACE s_axis_tdest => m_axis_decoded_m2s.tdest, s_axis_tdata => m_axis_decoded_m2s.tdata, s_axis_tvalid => m_axis_decoded_m2s.tvalid, -- AXIS SLAVE INTERFACE m_axis_tdest => m_axis_tdest, m_axis_tdata => m_axis_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'); end architecture struct;