--====================================================================== library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.ipbus.all; use work.ipbus_reg_types.all; use work.loopback_tcds_pkg.all; --================================================== entity loopback_tcds is generic ( loopback_type : loopback_type ); port ( -- IPBus interface. clk_ipb : in std_logic; rst_ipb : in std_logic; ipb_in : in ipb_wbus; ipb_out : out ipb_rbus; -- The 100 MHz general purpose clock. clk_gp_100mhz : in std_logic; -- The 320 MHz MGT reference clock. mgt_refclk0_320mhz : in std_logic; -- The MGT connections. tcds_tx_p : out std_logic; tcds_tx_n : out std_logic; tcds_rx_p : in std_logic; tcds_rx_n : in std_logic; -- The recovered RX clock. rxoutclk : out std_logic ); end loopback_tcds; --================================================== -- NOTE: The reason behind all the apostrophes (i.e., qualified expressions) in the following -- is to allow this to compile without having to include each of the MGT IP -- cores also in projects that don't use them. architecture arch of loopback_tcds is -- MGT CSR signals. signal ctrl : ipb_reg_v(0 downto 0); signal stat : ipb_reg_v(0 downto 0); -- MGT control. signal mgt_reset : std_logic; -- MGT status. signal mgt_powergood : std_logic; signal mgt_userclk_tx_active : std_logic; signal mgt_userclk_rx_active : std_logic; signal mgt_reset_tx_done : std_logic; signal mgt_reset_rx_done : std_logic; begin mgt_frontpanel_a: if loopback_type = LOOPBACK_TYPE_FRONTPANEL_A generate mgt_loopback_tcds : entity work.gty_loopback_tcds_frontpanel_a port map ( gtwiz_reset_clk_freerun_in(0) => clk_gp_100mhz, gtrefclk00_in(0) => mgt_refclk0_320mhz, qpll0outclk_out => open, qpll0outrefclk_out => open, gtwiz_userclk_tx_srcclk_out => open, gtwiz_userclk_tx_usrclk_out => open, gtwiz_userclk_tx_usrclk2_out => open, gtwiz_userclk_rx_srcclk_out => open, gtwiz_userclk_rx_usrclk_out => open, gtwiz_userclk_rx_usrclk2_out => open, gtwiz_reset_all_in(0) => mgt_reset, gtwiz_reset_tx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_tx_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_datapath_in(0) => std_logic'('0'), gtwiz_userclk_tx_reset_in(0) => std_logic'('0'), gtwiz_userclk_rx_reset_in(0) => std_logic'('0'), gtpowergood_out(0) => mgt_powergood, gtwiz_reset_tx_done_out(0) => mgt_reset_tx_done, gtwiz_reset_rx_done_out(0) => mgt_reset_rx_done, -- NOTE: This one is 'Reserved; do not use.' according to PG182. gtwiz_reset_rx_cdr_stable_out => open, gtwiz_userclk_tx_active_out(0) => mgt_userclk_tx_active, gtwiz_userclk_rx_active_out(0) => mgt_userclk_rx_active, gtytxp_out(0) => tcds_tx_p, gtytxn_out(0) => tcds_tx_n, gtyrxp_in(0) => tcds_rx_p, gtyrxn_in(0) => tcds_rx_n, gtwiz_userdata_tx_in => std_logic_vector'(x"00000000"), gtwiz_userdata_rx_out => open, -- Far-end PCS loopback mode. -- NOTE: Hard-wired to 'far-end PMA loopback'. 'Far-end PCS -- loopback' is harder. loopback_in => std_logic_vector'(b"100"), -- Access to the DFE/LPM choice. rxlpmen_in(0) => std_logic'('0'), rxdfelpmreset_in(0) => std_logic'('0'), -- Recovered RX clock. -- 010 -> RXOUTCLKPMA rxoutclksel_in => std_logic_vector'(b"010"), rxoutclk_out(0) => rxoutclk, -- DRP port to the MGT COMMON. drpclk_common_in(0) => std_logic'('0'), drpaddr_common_in => std_logic_vector'(x"0000"), drpdi_common_in => std_logic_vector'(x"0000"), drpen_common_in(0) => std_logic'('0'), drpwe_common_in(0) => std_logic'('0'), drpdo_common_out => open, drprdy_common_out => open, -- DRP port to the MGT CHANNEL. drpclk_in(0) => std_logic'('0'), drpaddr_in => std_logic_vector'(b"0000000000"), drpdi_in => std_logic_vector'(x"0000"), drpen_in(0) => std_logic'('0'), drpwe_in(0) => std_logic'('0'), drpdo_out => open, drprdy_out => open, drprst_in(0) => std_logic'('0') ); end generate; mgt_frontpanel_b: if loopback_type = LOOPBACK_TYPE_FRONTPANEL_B generate mgt_loopback_tcds : entity work.gth_loopback_tcds_frontpanel_b port map ( gtwiz_reset_clk_freerun_in(0) => clk_gp_100mhz, gtrefclk00_in(0) => mgt_refclk0_320mhz, qpll0outclk_out => open, qpll0outrefclk_out => open, gtwiz_userclk_tx_srcclk_out => open, gtwiz_userclk_tx_usrclk_out => open, gtwiz_userclk_tx_usrclk2_out => open, gtwiz_userclk_rx_srcclk_out => open, gtwiz_userclk_rx_usrclk_out => open, gtwiz_userclk_rx_usrclk2_out => open, gtwiz_reset_all_in(0) => mgt_reset, gtwiz_reset_tx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_tx_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_datapath_in(0) => std_logic'('0'), gtwiz_userclk_tx_reset_in(0) => std_logic'('0'), gtwiz_userclk_rx_reset_in(0) => std_logic'('0'), gtpowergood_out(0) => mgt_powergood, gtwiz_reset_tx_done_out(0) => mgt_reset_tx_done, gtwiz_reset_rx_done_out(0) => mgt_reset_rx_done, -- NOTE: This one is 'Reserved; do not use.' according to PG182. gtwiz_reset_rx_cdr_stable_out => open, gtwiz_userclk_tx_active_out(0) => mgt_userclk_tx_active, gtwiz_userclk_rx_active_out(0) => mgt_userclk_rx_active, gthtxp_out(0) => tcds_tx_p, gthtxn_out(0) => tcds_tx_n, gthrxp_in(0) => tcds_rx_p, gthrxn_in(0) => tcds_rx_n, gtwiz_userdata_tx_in => std_logic_vector'(x"00000000"), gtwiz_userdata_rx_out => open, -- Far-end PCS loopback mode. -- NOTE: Hard-wired to 'far-end PMA loopback'. 'Far-end PCS -- loopback' is harder. loopback_in => std_logic_vector'(b"100"), -- Access to the DFE/LPM choice. rxlpmen_in(0) => std_logic'('0'), rxdfelpmreset_in(0) => std_logic'('0'), -- Recovered RX clock. -- 010 -> RXOUTCLKPMA rxoutclksel_in => std_logic_vector'(b"010"), rxoutclk_out(0) => rxoutclk, -- DRP port to the MGT COMMON. drpclk_common_in(0) => std_logic'('0'), drpaddr_common_in => std_logic_vector'(x"0000"), drpdi_common_in => std_logic_vector'(x"0000"), drpen_common_in(0) => std_logic'('0'), drpwe_common_in(0) => std_logic'('0'), drpdo_common_out => open, drprdy_common_out => open, -- DRP port to the MGT CHANNEL. drpclk_in(0) => std_logic'('0'), drpaddr_in => std_logic_vector'(b"0000000000"), drpdi_in => std_logic_vector'(x"0000"), drpen_in(0) => std_logic'('0'), drpwe_in(0) => std_logic'('0'), drpdo_out => open, drprdy_out => open, drprst_in(0) => std_logic'('0') ); end generate; mgt_backplane_node_slot: if loopback_type = LOOPBACK_TYPE_BACKPLANE_NODE_SLOT generate mgt_loopback_tcds : entity work.gth_loopback_tcds_backplane_node_slot port map ( gtwiz_reset_clk_freerun_in(0) => clk_gp_100mhz, gtrefclk00_in(0) => mgt_refclk0_320mhz, qpll0outclk_out => open, qpll0outrefclk_out => open, gtwiz_userclk_tx_srcclk_out => open, gtwiz_userclk_tx_usrclk_out => open, gtwiz_userclk_tx_usrclk2_out => open, gtwiz_userclk_rx_srcclk_out => open, gtwiz_userclk_rx_usrclk_out => open, gtwiz_userclk_rx_usrclk2_out => open, gtwiz_reset_all_in(0) => mgt_reset, gtwiz_reset_tx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_tx_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_pll_and_datapath_in(0) => std_logic'('0'), gtwiz_reset_rx_datapath_in(0) => std_logic'('0'), gtwiz_userclk_tx_reset_in(0) => std_logic'('0'), gtwiz_userclk_rx_reset_in(0) => std_logic'('0'), gtpowergood_out(0) => mgt_powergood, gtwiz_reset_tx_done_out(0) => mgt_reset_tx_done, gtwiz_reset_rx_done_out(0) => mgt_reset_rx_done, -- NOTE: This one is 'Reserved; do not use.' according to PG182. gtwiz_reset_rx_cdr_stable_out => open, gtwiz_userclk_tx_active_out(0) => mgt_userclk_tx_active, gtwiz_userclk_rx_active_out(0) => mgt_userclk_rx_active, gthtxp_out(0) => tcds_tx_p, gthtxn_out(0) => tcds_tx_n, gthrxp_in(0) => tcds_rx_p, gthrxn_in(0) => tcds_rx_n, gtwiz_userdata_tx_in => std_logic_vector'(x"00000000"), gtwiz_userdata_rx_out => open, -- Far-end PCS loopback mode. -- NOTE: Hard-wired to 'far-end PMA loopback'. 'Far-end PCS -- loopback' is harder. loopback_in => std_logic_vector'(b"100"), -- Access to the DFE/LPM choice. rxlpmen_in(0) => std_logic'('0'), rxdfelpmreset_in(0) => std_logic'('0'), -- Recovered RX clock. -- 010 -> RXOUTCLKPMA rxoutclksel_in => std_logic_vector'(b"010"), rxoutclk_out(0) => rxoutclk, -- DRP port to the MGT COMMON. drpclk_common_in(0) => std_logic'('0'), drpaddr_common_in => std_logic_vector'(x"0000"), drpdi_common_in => std_logic_vector'(x"0000"), drpen_common_in(0) => std_logic'('0'), drpwe_common_in(0) => std_logic'('0'), drpdo_common_out => open, drprdy_common_out => open, -- DRP port to the MGT CHANNEL. drpclk_in(0) => std_logic'('0'), drpaddr_in => std_logic_vector'(b"0000000000"), drpdi_in => std_logic_vector'(x"0000"), drpen_in(0) => std_logic'('0'), drpwe_in(0) => std_logic'('0'), drpdo_out => open, drprdy_out => open, drprst_in(0) => std_logic'('0') ); end generate; ------------------------------------------ csr_mgt_loopback_tcds : entity work.ipbus_ctrlreg_v generic map ( N_CTRL => 1, N_STAT => 1 ) port map ( clk => clk_ipb, reset => rst_ipb, ipbus_in => ipb_in, ipbus_out => ipb_out, q => ctrl, d => stat ); mgt_reset <= ctrl(0)(0); stat(0)(0) <= mgt_powergood; stat(0)(1) <= mgt_userclk_tx_active; stat(0)(2) <= mgt_userclk_rx_active; stat(0)(3) <= mgt_reset_tx_done; stat(0)(4) <= mgt_reset_rx_done; end arch; --======================================================================