Skip to content
Snippets Groups Projects
Select Git revision
  • 52b790db13c24cbe20031e93ffc29a64d0b78f04
  • master default protected
  • dev
  • fix
  • feat-merge-filter
  • to_fwk
  • integrate
  • 1.3
  • 1.2.1
  • 1.2
  • 1.1.1
  • 1.1.0
12 results

top_combpm_electron.vhd

Blame
  • 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;