--====================================================================== -- IPBus control and status interfaces to the TCDS2 interface (with or -- without MGT). --====================================================================== library ieee; use ieee.std_logic_1164.all; use work.ipbus.all; use work.ipbus_reg_types.all; use work.ipbus_decode_ipbus_tcds2_interface_accessor.all; use work.tcds2_interface_pkg.all; --================================================== entity ipbus_tcds2_interface_accessor is generic ( -- Choice to include/exclude spy registers on the raw TX/RX frames -- and all TTC2/TTS2 information. G_INCLUDE_SPY_REGISTERS : boolean := true ); port ( -- IPBus interface. clk_ipb : in std_logic; rst_ipb : in std_logic; ipb_in : in ipb_wbus; ipb_out : out ipb_rbus; -- Control and status interfaces to the TCDS2 interface. ctrl_o : out tcds2_interface_ctrl_t; stat_i : in tcds2_interface_stat_t ); end ipbus_tcds2_interface_accessor; --================================================== architecture arch of ipbus_tcds2_interface_accessor is -- IPBus read/write buses. signal ipbw : ipb_wbus_array(N_SLAVES - 1 downto 0); signal ipbr : ipb_rbus_array(N_SLAVES - 1 downto 0); -- CSR signals. signal ctrl : ipb_reg_v(1 downto 0); signal stat : ipb_reg_v(5 downto 0); begin ------------------------------------------ -- IPBus address decoder. ------------------------------------------ fabric : entity work.ipbus_fabric_sel generic map ( NSLV => N_SLAVES, SEL_WIDTH => IPBUS_SEL_WIDTH ) port map ( ipb_in => ipb_in, ipb_out => ipb_out, sel => ipbus_sel_ipbus_tcds2_interface_accessor(ipb_in.ipb_addr), ipb_to_slaves => ipbw, ipb_from_slaves => ipbr ); ------------------------------------------ -- Control and status registers. ------------------------------------------ csr : entity work.ipbus_ctrlreg_v generic map ( N_CTRL => ctrl'length, N_STAT => stat'length ) port map ( clk => clk_ipb, reset => rst_ipb, ipbus_in => ipbw(N_SLV_CSR), ipbus_out => ipbr(N_SLV_CSR), q => ctrl, d => stat ); -- MGT resets. ctrl_o.mgt_reset_all <= ctrl(0)(0); ctrl_o.mgt_reset_tx <= ctrl(0)(1); ctrl_o.mgt_reset_rx <= ctrl(0)(2); ctrl_o.link_test_mode <= ctrl(0)(3); -- PRBS generator/checker resets. ctrl_o.prbsgen_reset <= ctrl(1)(0); ctrl_o.prbschk_reset <= ctrl(1)(1); ---------- -- Flags representing the implementation choices of the TCDS2 -- interface CSR. stat(0)(0) <= '1' when G_INCLUDE_SPY_REGISTERS else '0'; -- Flags representing the implementation choices of the TCDS2 -- interface. stat(0)(1) <= stat_i.is_link_speed_10g; stat(0)(2) <= stat_i.has_link_test_mode; -- 'Power good' flag for the MGT quad. stat(1)(0) <= stat_i.mgt_powergood; -- PLL lock flags for the MGT quad. stat(1)(1) <= stat_i.mgt_txpll_lock; stat(1)(2) <= stat_i.mgt_rxpll_lock; -- Reset status flags for the MGT quad. stat(1)(3) <= stat_i.mgt_reset_tx_done; stat(1)(4) <= stat_i.mgt_reset_rx_done; -- TCLink status. stat(1)(5) <= stat_i.mgt_tx_ready; stat(1)(6) <= stat_i.mgt_rx_ready; stat(1)(7) <= stat_i.rx_frame_locked; stat(2) <= stat_i.rx_frame_unlock_count; -- PRBS checker error flag. stat(3)(1) <= stat_i.prbschk_error; -- PRBS checker lock flag. stat(3)(2) <= stat_i.prbschk_locked; -- The corresponding unlock count. stat(4)(stat_i.prbschk_unlock_count'range) <= stat_i.prbschk_unlock_count; -- A sneak peek on the generator and checker data frames to see if -- things are ticking or not. stat(5)(7 downto 0) <= stat_i.prbsgen_o_hint(7 downto 0); stat(5)(15 downto 8) <= stat_i.prbschk_i_hint(7 downto 0); stat(5)(23 downto 16) <= stat_i.prbschk_o_hint(7 downto 0); ------------------------------------------ -- Optional: spy registers. ------------------------------------------ if_include_spy_regs : if G_INCLUDE_SPY_REGISTERS generate -- Spy on the raw TX (i.e., TTS2) frame. spy_tx : entity work.tcds2_frame_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_FRAME_TX), ipb_out => ipbr(N_SLV_SPY_FRAME_TX), frame_i => stat_i.frame_tx ); -- Spy on the raw RX (i.e., TTC2) frame. spy_rx : entity work.tcds2_frame_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_FRAME_RX), ipb_out => ipbr(N_SLV_SPY_FRAME_RX), frame_i => stat_i.frame_rx ); -- Spy access to both TTC2 channels. spy_ttc2_channel0 : entity work.tcds2_ttc2_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_TTC2_CHANNEL0), ipb_out => ipbr(N_SLV_SPY_TTC2_CHANNEL0), stream_i => stat_i.channel0_ttc2 ); spy_ttc2_channel1 : entity work.tcds2_ttc2_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_TTC2_CHANNEL1), ipb_out => ipbr(N_SLV_SPY_TTC2_CHANNEL1), stream_i => stat_i.channel1_ttc2 ); -- Spy access to both TTS2 channels. spy_tts2_channel0 : entity work.tcds2_tts2_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_TTS2_CHANNEL0), ipb_out => ipbr(N_SLV_SPY_TTS2_CHANNEL0), stream_i => stat_i.channel0_tts2 ); spy_tts2_channel1 : entity work.tcds2_tts2_spy port map ( clk_ipb => clk_ipb, rst_ipb => rst_ipb, ipb_in => ipbw(N_SLV_SPY_TTS2_CHANNEL1), ipb_out => ipbr(N_SLV_SPY_TTS2_CHANNEL1), stream_i => stat_i.channel1_tts2 ); end generate; end arch; --======================================================================