From: Michael Boehmer Date: Mon, 4 Jul 2022 14:07:18 +0000 (+0200) Subject: raw GbE media interface for potential hubs X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=97f859d180dc697b2b5f26046c9962620bd80f41;p=trbnet.git raw GbE media interface for potential hubs --- diff --git a/gbe_trb_ecp3/base/gbe_med_raw.vhd b/gbe_trb_ecp3/base/gbe_med_raw.vhd new file mode 100644 index 0000000..573f3ed --- /dev/null +++ b/gbe_trb_ecp3/base/gbe_med_raw.vhd @@ -0,0 +1,617 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net_gbe_components.all; +use work.med_sync_define_RS.all; + +entity gbe_med_raw is + generic( + LINKS_ACTIVE : std_logic_vector(3 downto 0) := "1111" + ); + port( + RESET : in std_logic; + GSR_N : in std_logic; + CLK_SYS : in std_logic; + CLK_125 : in std_logic; + CLK_125_RX : out std_logic_vector(3 downto 0); + -- MAC status and config + MAC_READY_CONF_OUT : out std_logic_vector(3 downto 0); + MAC_RECONF_IN : in std_logic_vector(3 downto 0) := (others => '0'); + MAC_AN_READY_OUT : out std_logic_vector(3 downto 0); + -- MAC data interface + MAC_FIFOAVAIL_IN : in std_logic_vector(3 downto 0) := (others => '0'); + MAC_FIFOEOF_IN : in std_logic_vector(3 downto 0) := (others => '0'); + MAC_FIFOEMPTY_IN : in std_logic_vector(3 downto 0) := (others => '0'); + MAC_RX_FIFOFULL_IN : in std_logic_vector(3 downto 0) := (others => '0'); + -- MAC TX interface + MAC_TX_DATA_IN : in std_logic_vector(4 * 8 - 1 downto 0) := (others => '0'); + MAC_TX_READ_OUT : out std_logic_vector(3 downto 0); + MAC_TX_DISCRFRM_OUT : out std_logic_vector(3 downto 0); + MAC_TX_STAT_EN_OUT : out std_logic_vector(3 downto 0); + MAC_TX_STATS_OUT : out std_logic_vector(4 * 31 - 1 downto 0); + MAC_TX_DONE_OUT : out std_logic_vector(3 downto 0); + -- MAC RX interface + MAC_RX_FIFO_ERR_OUT : out std_logic_vector(3 downto 0); + MAC_RX_STATS_OUT : out std_logic_vector(4 * 32 - 1 downto 0); + MAC_RX_DATA_OUT : out std_logic_vector(4 * 8 - 1 downto 0); + MAC_RX_WRITE_OUT : out std_logic_vector(3 downto 0); + MAC_RX_STAT_EN_OUT : out std_logic_vector(3 downto 0); + MAC_RX_EOF_OUT : out std_logic_vector(3 downto 0); + MAC_RX_ERROR_OUT : out std_logic_vector(3 downto 0); + -- SFP Connection + SD_PRSNT_N_IN : in std_logic_vector(3 downto 0) := (others => '0'); + SD_LOS_IN : in std_logic_vector(3 downto 0) := (others => '0'); + SD_TXDIS_OUT : out std_logic_vector(3 downto 0); + -- SerDes control + TX_PLOL_LOL_OUT : out std_logic; + TX_PCS_RST_IN : in std_logic; + RX_LINK_READY_OUT : out std_logic_vector(3 downto 0); + TX_LINK_READY_IN : in std_logic; + -- Debug + STATUS_OUT : out std_logic_vector(4 * 8 - 1 downto 0); + DEBUG_OUT : out std_logic_vector(63 downto 0) + ); +end entity gbe_med_raw; + +architecture RTL of gbe_med_raw is + + component sgmii_gbe_pcs42 + port( + rst_n : in std_logic; + signal_detect : in std_logic; + gbe_mode : in std_logic; + sgmii_mode : in std_logic; + operational_rate : in std_logic_vector(1 downto 0); + debug_link_timer_short : in std_logic; + + force_isolate : in std_logic; + force_loopback : in std_logic; + force_unidir : in std_logic; + + rx_compensation_err : out std_logic; + + ctc_drop_flag : out std_logic; + ctc_add_flag : out std_logic; + an_link_ok : out std_logic; + + tx_clk_125 : in std_logic; + tx_clock_enable_source : out std_logic; + tx_clock_enable_sink : in std_logic; + tx_d : in std_logic_vector(7 downto 0); + tx_en : in std_logic; + tx_er : in std_logic; + rx_clk_125 : in std_logic; + rx_clock_enable_source : out std_logic; + rx_clock_enable_sink : in std_logic; + rx_d : out std_logic_vector(7 downto 0); + rx_dv : out std_logic; + rx_er : out std_logic; + col : out std_logic; + crs : out std_logic; + tx_data : out std_logic_vector(7 downto 0); + tx_kcntl : out std_logic; + tx_disparity_cntl : out std_logic; + + xmit_autoneg : out std_logic; + + serdes_recovered_clk : in std_logic; + rx_data : in std_logic_vector(7 downto 0); + rx_even : in std_logic; + rx_kcntl : in std_logic; + rx_disp_err : in std_logic; + rx_cv_err : in std_logic; + rx_err_decode_mode : in std_logic; + mr_an_complete : out std_logic; + mr_page_rx : out std_logic; + mr_lp_adv_ability : out std_logic_vector(15 downto 0); + mr_main_reset : in std_logic; + mr_an_enable : in std_logic; + mr_restart_an : in std_logic; + mr_adv_ability : in std_logic_vector(15 downto 0) + ); + end component; + + component tsmac41 + port( + --------------- clock and reset port declarations ------------------ + hclk : in std_logic; + txmac_clk : in std_logic; + rxmac_clk : in std_logic; + reset_n : in std_logic; + ------------------- Input signals to the GMII ---------------- + rxd : in std_logic_vector(7 downto 0); + rx_dv : in std_logic; + rx_er : in std_logic; + -------------------- Input signals to the CPU I/F ------------------- + haddr : in std_logic_vector(7 downto 0); + hdatain : in std_logic_vector(7 downto 0); + hcs_n : in std_logic; + hwrite_n : in std_logic; + hread_n : in std_logic; + ---------------- Input signals to the Tx MAC FIFO I/F --------------- + tx_fifodata : in std_logic_vector(7 downto 0); + tx_fifoavail : in std_logic; + tx_fifoeof : in std_logic; + tx_fifoempty : in std_logic; + tx_sndpaustim : in std_logic_vector(15 downto 0); + tx_sndpausreq : in std_logic; + tx_fifoctrl : in std_logic; + ---------------- Input signals to the Rx MAC FIFO I/F --------------- + rx_fifo_full : in std_logic; + ignore_pkt : in std_logic; + -------------------- Output signals from the GMII ----------------------- + txd : out std_logic_vector(7 downto 0); + tx_en : out std_logic; + tx_er : out std_logic; + -------------------- Output signals from the CPU I/F ------------------- + hdataout : out std_logic_vector(7 downto 0); + hdataout_en_n : out std_logic; + hready_n : out std_logic; + cpu_if_gbit_en : out std_logic; + ---------------- Output signals from the Tx MAC FIFO I/F --------------- + tx_macread : out std_logic; + tx_discfrm : out std_logic; + tx_staten : out std_logic; + tx_done : out std_logic; + tx_statvec : out std_logic_vector(30 downto 0); + ---------------- Output signals from the Rx MAC FIFO I/F --------------- + rx_fifo_error : out std_logic; + rx_stat_vector : out std_logic_vector(31 downto 0); + rx_dbout : out std_logic_vector(7 downto 0); + rx_write : out std_logic; + rx_stat_en : out std_logic; + rx_eof : out std_logic; + rx_error : out std_logic + ); + end component; + + signal sd_rx_clk : std_logic_vector(3 downto 0); + signal sd_tx_kcntl : std_logic_vector(3 downto 0); + signal sd_tx_data : std_logic_vector(4 * 8 - 1 downto 0); + signal xmit : std_logic_vector(3 downto 0); + signal sd_tx_correct_disp : std_logic_vector(3 downto 0); + signal sd_rx_data : std_logic_vector(4 * 8 - 1 downto 0); + signal sd_rx_kcntl : std_logic_vector(3 downto 0); + signal sd_rx_disp_error : std_logic_vector(3 downto 0); + signal sd_rx_cv_error : std_logic_vector(3 downto 0); + signal lsm_status : std_logic_vector(3 downto 0); + signal rx_clk_en : std_logic_vector(3 downto 0); + signal tx_clk_en : std_logic_vector(3 downto 0); + signal operational_rate : std_logic_vector(4 * 2 - 1 downto 0); + signal an_complete : std_logic_vector(3 downto 0); + signal mr_page_rx : std_logic_vector(3 downto 0); + signal mr_lp_adv_ability : std_logic_vector(4 * 16 - 1 downto 0); + signal mr_main_reset : std_logic_vector(3 downto 0); + signal mr_restart_an : std_logic_vector(3 downto 0); + signal mr_adv_ability : std_logic_vector(4 * 16 - 1 downto 0); + signal mr_an_enable : std_logic_vector(3 downto 0); + signal an_link_ok : std_logic_vector(3 downto 0); + signal pcs_rxd : std_logic_vector(4 * 8 - 1 downto 0); + signal pcs_rx_en : std_logic_vector(3 downto 0); + signal pcs_rx_er : std_logic_vector(3 downto 0); + signal pcs_txd : std_logic_vector(4 * 8 - 1 downto 0); + signal pcs_tx_en : std_logic_vector(3 downto 0); + signal pcs_tx_er : std_logic_vector(3 downto 0); + signal tsm_hdataout_en_n : std_logic_vector(3 downto 0); + signal tsm_hready_n : std_logic_vector(3 downto 0); + signal tsm_hread_n : std_logic_vector(3 downto 0); + signal tsm_hwrite_n : std_logic_vector(3 downto 0); + signal tsm_hcs_n : std_logic_vector(3 downto 0); + signal tsm_hdata : std_logic_vector(4 * 8 - 1 downto 0); + signal tsm_haddr : std_logic_vector(4 * 8 - 1 downto 0); + + signal synced_rst : std_logic; + + signal powerup_ch : std_logic_vector(3 downto 0); + signal link_rx_ready : std_logic_vector(3 downto 0); + signal rx_los_low : std_logic_vector(3 downto 0); + signal rx_cdr_lol : std_logic_vector(3 downto 0); + signal rx_pcs_rst : std_logic_vector(3 downto 0); + signal rx_pcs_rst_q : std_logic_vector(3 downto 0); + signal rx_serdes_rst : std_logic_vector(3 downto 0); + signal rx_serdes_rst_q : std_logic_vector(3 downto 0); + signal init_quad : std_logic; + signal tx_plol_lol : std_logic; + + signal debug : std_logic_vector(63 downto 0); + + -- for replacing register interface + signal delay_q : std_logic_vector(4 * 8 - 1 downto 0); + signal pulse : std_logic_vector(3 downto 0); + + signal SD_RXD_P_IN, SD_RXD_N_IN, SD_TXD_P_OUT, SD_TXD_N_OUT : std_logic_vector(3 downto 0); + + signal led_timer : unsigned(19 downto 0); + signal led_timer_done_x : std_logic; + signal led_timer_done : std_logic; + signal led_activity_x : std_logic_vector(3 downto 0); + signal led_activity : std_logic_vector(4 * 2 - 1 downto 0); + +begin + + init_quad <= not GSR_N; + + gbe_serdes: entity serdes_gbe_4ch_ds + port map( + -- CH0 -- + hdinp_ch0 => SD_RXD_P_IN(0), + hdinn_ch0 => SD_RXD_N_IN(0), + hdoutp_ch0 => SD_TXD_P_OUT(0), + hdoutn_ch0 => SD_TXD_N_OUT(0), + rxiclk_ch0 => sd_rx_clk(0), + txiclk_ch0 => CLK_125, + rx_full_clk_ch0 => sd_rx_clk(0), + rx_half_clk_ch0 => open, + tx_full_clk_ch0 => open, + tx_half_clk_ch0 => open, + fpga_rxrefclk_ch0 => CLK_125, + txdata_ch0 => sd_tx_data(7 downto 0), + tx_k_ch0 => sd_tx_kcntl(0), + xmit_ch0 => xmit(0), + tx_disp_correct_ch0 => sd_tx_correct_disp(0), + rxdata_ch0 => sd_rx_data(7 downto 0), + rx_k_ch0 => sd_rx_kcntl(0), + rx_disp_err_ch0 => sd_rx_disp_error(0), + rx_cv_err_ch0 => sd_rx_cv_error(0), + rx_serdes_rst_ch0_c => rx_serdes_rst(0), + sb_felb_ch0_c => '0', + sb_felb_rst_ch0_c => '0', + tx_pcs_rst_ch0_c => TX_PCS_RST_IN, + tx_pwrup_ch0_c => powerup_ch(0), + rx_pcs_rst_ch0_c => rx_pcs_rst(0), + rx_pwrup_ch0_c => powerup_ch(0), + rx_los_low_ch0_s => rx_los_low(0), + lsm_status_ch0_s => lsm_status(0), + rx_cdr_lol_ch0_s => rx_cdr_lol(0), + -- CH1 -- + hdinp_ch1 => SD_RXD_P_IN(1), + hdinn_ch1 => SD_RXD_N_IN(1), + hdoutp_ch1 => SD_TXD_P_OUT(1), + hdoutn_ch1 => SD_TXD_N_OUT(1), + rxiclk_ch1 => sd_rx_clk(1), + txiclk_ch1 => CLK_125, + rx_full_clk_ch1 => sd_rx_clk(1), + rx_half_clk_ch1 => open, + tx_full_clk_ch1 => open, + tx_half_clk_ch1 => open, + fpga_rxrefclk_ch1 => CLK_125, + txdata_ch1 => sd_tx_data(15 downto 8), + tx_k_ch1 => sd_tx_kcntl(1), + xmit_ch1 => xmit(1), + tx_disp_correct_ch1 => sd_tx_correct_disp(1), + rxdata_ch1 => sd_rx_data(15 downto 8), + rx_k_ch1 => sd_rx_kcntl(1), + rx_disp_err_ch1 => sd_rx_disp_error(1), + rx_cv_err_ch1 => sd_rx_cv_error(1), + rx_serdes_rst_ch1_c => rx_serdes_rst(1), + sb_felb_ch1_c => '0', + sb_felb_rst_ch1_c => '0', + tx_pcs_rst_ch1_c => TX_PCS_RST_IN, + tx_pwrup_ch1_c => powerup_ch(1), + rx_pcs_rst_ch1_c => rx_pcs_rst(1), + rx_pwrup_ch1_c => powerup_ch(1), + rx_los_low_ch1_s => rx_los_low(1), + lsm_status_ch1_s => lsm_status(1), + rx_cdr_lol_ch1_s => rx_cdr_lol(1), + -- CH2 -- + hdinp_ch2 => SD_RXD_P_IN(2), + hdinn_ch2 => SD_RXD_N_IN(2), + hdoutp_ch2 => SD_TXD_P_OUT(2), + hdoutn_ch2 => SD_TXD_N_OUT(2), + rxiclk_ch2 => sd_rx_clk(2), + txiclk_ch2 => CLK_125, + rx_full_clk_ch2 => sd_rx_clk(2), + rx_half_clk_ch2 => open, + tx_full_clk_ch2 => open, + tx_half_clk_ch2 => open, + fpga_rxrefclk_ch2 => CLK_125, + txdata_ch2 => sd_tx_data(23 downto 16), + tx_k_ch2 => sd_tx_kcntl(2), + xmit_ch2 => xmit(2), + tx_disp_correct_ch2 => sd_tx_correct_disp(2), + rxdata_ch2 => sd_rx_data(23 downto 16), + rx_k_ch2 => sd_rx_kcntl(2), + rx_disp_err_ch2 => sd_rx_disp_error(2), + rx_cv_err_ch2 => sd_rx_cv_error(2), + rx_serdes_rst_ch2_c => rx_serdes_rst(2), + sb_felb_ch2_c => '0', + sb_felb_rst_ch2_c => '0', + tx_pcs_rst_ch2_c => TX_PCS_RST_IN, + tx_pwrup_ch2_c => powerup_ch(2), + rx_pcs_rst_ch2_c => rx_pcs_rst(2), + rx_pwrup_ch2_c => powerup_ch(2), + rx_los_low_ch2_s => rx_los_low(2), + lsm_status_ch2_s => lsm_status(2), + rx_cdr_lol_ch2_s => rx_cdr_lol(2), + -- CH3 -- + hdinp_ch3 => SD_RXD_P_IN(3), + hdinn_ch3 => SD_RXD_N_IN(3), + hdoutp_ch3 => SD_TXD_P_OUT(3), + hdoutn_ch3 => SD_TXD_N_OUT(3), + rxiclk_ch3 => sd_rx_clk(3), + txiclk_ch3 => CLK_125, + rx_full_clk_ch3 => sd_rx_clk(3), + rx_half_clk_ch3 => open, + tx_full_clk_ch3 => open, + tx_half_clk_ch3 => open, + fpga_rxrefclk_ch3 => CLK_125, + txdata_ch3 => sd_tx_data(31 downto 24), + tx_k_ch3 => sd_tx_kcntl(3), + xmit_ch3 => xmit(3), + tx_disp_correct_ch3 => sd_tx_correct_disp(3), + rxdata_ch3 => sd_rx_data(31 downto 24), + rx_k_ch3 => sd_rx_kcntl(3), + rx_disp_err_ch3 => sd_rx_disp_error(3), + rx_cv_err_ch3 => sd_rx_cv_error(3), + rx_serdes_rst_ch3_c => rx_serdes_rst(3), + sb_felb_ch3_c => '0', + sb_felb_rst_ch3_c => '0', + tx_pcs_rst_ch3_c => TX_PCS_RST_IN, + tx_pwrup_ch3_c => powerup_ch(3), + rx_pcs_rst_ch3_c => rx_pcs_rst(3), + rx_pwrup_ch3_c => powerup_ch(3), + rx_los_low_ch3_s => rx_los_low(3), + lsm_status_ch3_s => lsm_status(3), + rx_cdr_lol_ch3_s => rx_cdr_lol(3), + ---- Miscallaneous ports + fpga_txrefclk => CLK_125, + tx_serdes_rst_c => '0', + tx_pll_lol_qd_s => tx_plol_lol, + rst_qd_c => init_quad, + serdes_rst_qd_c => '0', + tx_sync_qd_c => '0' + ); + + TX_PLOL_LOL_OUT <= tx_plol_lol; + + CHANNEL_GEN : for i in 0 to 3 generate + + CHANNEL_ACTIVE_GEN : if LINKS_ACTIVE(i) = '1' generate + + powerup_ch(i) <= '1'; + SD_TXDIS_OUT(i) <= '0'; + + -- RSL for RX of SerDes, based on extRSL logic + -- CAVEAT: reset signals MUST BE sync'ed to recovered RX clock! + THE_MAIN_RX_RST: main_rx_reset_RS + port map( + CLEAR => init_quad, + CLK_REF => CLK_125, + CDR_LOL_IN => rx_cdr_lol(i), + CV_IN => sd_rx_cv_error(i), + LSM_IN => lsm_status(i), + LOS_IN => rx_los_low(i), + WAP_ZERO_IN => '1', -- not needed here + -- outputs + WAP_REQ_OUT => open, -- not needed here + RX_SERDES_RST_OUT => rx_serdes_rst(i), -- CLK_REF based + RX_PCS_RST_OUT => rx_pcs_rst(i), -- CLK_REF based + LINK_RX_READY_OUT => link_rx_ready(i), -- CLK_REF based + STATE_OUT => open + ); + + -- reset signals for RX SerDes need to be sync'ed to real RX clock for ECP5 + SYNC_RST_SIGS: entity work.signal_sync + generic map( WIDTH => 2 ) + port map( + RESET => '0', + CLK0 => sd_rx_clk(i), + CLK1 => sd_rx_clk(i), + D_IN(0) => rx_pcs_rst(i), + D_IN(1) => rx_serdes_rst(i), + D_OUT(0) => rx_pcs_rst_q(i), + D_OUT(1) => rx_serdes_rst_q(i) + ); + + CLK_125_RX(i) <= sd_rx_clk(i); + + -- SGMII core + SGMII_GBE_PCS : sgmii_gbe_pcs42 + port map( + rst_n => GSR_N, + signal_detect => link_rx_ready(i), + gbe_mode => '1', + sgmii_mode => '0', + operational_rate => operational_rate((i + 1) * 2 - 1 downto i * 2), + debug_link_timer_short => '0', + force_isolate => '0', + force_loopback => '0', + force_unidir => '0', + rx_compensation_err => open, + ctc_drop_flag => open, + ctc_add_flag => open, + an_link_ok => open, + -- MAC interface + tx_clk_125 => CLK_125, + tx_clock_enable_source => tx_clk_en(i), + tx_clock_enable_sink => tx_clk_en(i), + tx_d => pcs_txd((i + 1) * 8 - 1 downto i * 8), -- TX data from MAC + tx_en => pcs_tx_en(i), -- TX data enable from MAC + tx_er => pcs_tx_er(i), -- TX error from MAC + rx_clk_125 => CLK_125, + rx_clock_enable_source => rx_clk_en(i), + rx_clock_enable_sink => rx_clk_en(i), + rx_d => pcs_rxd((i + 1 ) * 8 - 1 downto i * 8), -- RX data to MAC + rx_dv => pcs_rx_en(i), -- RX data enable to MAC + rx_er => pcs_rx_er(i), -- RX error to MAC + col => open, + crs => open, + -- SerDes interface + tx_data => sd_tx_data((i + 1) * 8 - 1 downto i * 8), -- TX data to SerDes + tx_kcntl => sd_tx_kcntl(i), -- TX komma control to SerDes + tx_disparity_cntl => sd_tx_correct_disp(i), -- idle parity state control in IPG (to SerDes) + xmit_autoneg => xmit(i), + serdes_recovered_clk => sd_rx_clk(i), -- 125MHz recovered from receive bit stream + rx_data => sd_rx_data((i + 1) * 8 - 1 downto i * 8), -- RX data from SerDes + rx_kcntl => sd_rx_kcntl(i), -- RX komma control from SerDes + rx_err_decode_mode => '0', -- receive error control mode fixed to normal + rx_even => '0', -- unused (receive error control mode = normal, tie to GND) + rx_disp_err => sd_rx_disp_error(i), -- RX disparity error from SerDes + rx_cv_err => sd_rx_cv_error(i), -- RX code violation error from SerDes + -- Autonegotiation stuff + mr_an_complete => an_complete(i), + mr_page_rx => mr_page_rx(i), + mr_lp_adv_ability => mr_lp_adv_ability((i + 1) * 16 - 1 downto i * 16), + mr_main_reset => mr_main_reset(i), + mr_an_enable => mr_an_enable(i), + mr_restart_an => mr_restart_an(i), + mr_adv_ability => mr_adv_ability((i + 1) * 16 - 1 downto i * 16) + ); + + MAC_AN_READY_OUT(i) <= an_complete(i); + + operational_rate((i + 1) * 2 - 1 downto i * 2) <= b"10"; + + mr_main_reset(i) <= init_quad; + mr_restart_an(i) <= pulse(i); + mr_an_enable(i) <= link_rx_ready(i); + mr_adv_ability((i + 1) * 16 - 1 downto i * 16) <= x"0020"; + + SYNC_PROC: process( CLK_125 ) + begin + if( rising_edge(CLK_125) ) then + delay_q((i + 1) * 8 - 1 downto i * 8) <= delay_q((i + 1) * 8 - 2 downto i * 8) & link_rx_ready(i); + end if; + end process SYNC_PROC; + + pulse(i) <= not delay_q((i + 1) * 8 - 1) and delay_q((i + 1) * 8 - 2); + + MAC: tsmac41 + port map( + ----------------- clock and reset port declarations ------------------ + hclk => CLK_SYS, + txmac_clk => CLK_125, + rxmac_clk => CLK_125, + reset_n => GSR_N, + ------------------- Input signals to the GMII ---------------- + rxd => pcs_rxd((i + 1) * 8 - 1 downto i * 8), + rx_dv => pcs_rx_en(i), + rx_er => pcs_rx_er(i), + -------------------- Input signals to the CPU I/F ------------------- + haddr => tsm_haddr((i + 1) * 8 - 1 downto i * 8), + hdatain => tsm_hdata((i + 1) * 8 - 1 downto i * 8), + hcs_n => tsm_hcs_n(i), + hwrite_n => tsm_hwrite_n(i), + hread_n => tsm_hread_n(i), + ---------------- Input signals to the Tx MAC FIFO I/F --------------- + tx_fifodata => MAC_TX_DATA_IN((i + 1) * 8 - 1 downto i * 8), + tx_fifoavail => MAC_FIFOAVAIL_IN(i), + tx_fifoeof => MAC_FIFOEOF_IN(i), + tx_fifoempty => MAC_FIFOEMPTY_IN(i), + tx_sndpaustim => x"0000", + tx_sndpausreq => '0', + tx_fifoctrl => '0', -- always data frame + ---------------- Input signals to the Rx MAC FIFO I/F --------------- + rx_fifo_full => MAC_RX_FIFOFULL_IN(i), + ignore_pkt => '0', + ---------------- Output signals from the GMII ----------------------- + txd => pcs_txd((i + 1) * 8 - 1 downto i * 8), + tx_en => pcs_tx_en(i), + tx_er => pcs_tx_er(i), + ----------------- Output signals from the CPU I/F ------------------- + hdataout => open, + hdataout_en_n => tsm_hdataout_en_n(i), + hready_n => tsm_hready_n(i), + cpu_if_gbit_en => open, + ------------- Output signals from the Tx MAC FIFO I/F --------------- + tx_macread => MAC_TX_READ_OUT(i), + tx_discfrm => MAC_TX_DISCRFRM_OUT(i), + tx_staten => MAC_TX_STAT_EN_OUT(i), + tx_statvec => MAC_TX_STATS_OUT((i + 1) * 31 - 1 downto i * 31), + tx_done => MAC_TX_DONE_OUT(i), + ------------- Output signals from the Rx MAC FIFO I/F --------------- + rx_fifo_error => MAC_RX_FIFO_ERR_OUT(i), + rx_stat_vector => MAC_RX_STATS_OUT((i + 1) * 32 - 1 downto i * 32), + rx_dbout => MAC_RX_DATA_OUT((i + 1) * 8 - 1 downto i * 8), + rx_write => MAC_RX_WRITE_OUT(i), + rx_stat_en => MAC_RX_STAT_EN_OUT(i), + rx_eof => MAC_RX_EOF_OUT(i), + rx_error => MAC_RX_ERROR_OUT(i) + ); + + TSMAC_CONTROLLER : trb_net16_gbe_mac_control + port map( + CLK => CLK_SYS, + RESET => RESET, + -- signals to/from main controller + MC_TSMAC_READY_OUT => MAC_READY_CONF_OUT(i), + MC_RECONF_IN => MAC_RECONF_IN(i), + MC_GBE_EN_IN => '1', + MC_RX_DISCARD_FCS => '0', + MC_PROMISC_IN => '1', + MC_MAC_ADDR_IN => (others => '0'), + -- signal to/from Host interface of TriSpeed MAC + TSM_HADDR_OUT => tsm_haddr((i + 1) * 8 - 1 downto i * 8), + TSM_HDATA_OUT => tsm_hdata((i + 1) * 8 - 1 downto i * 8), + TSM_HCS_N_OUT => tsm_hcs_n(i), + TSM_HWRITE_N_OUT => tsm_hwrite_n(i), + TSM_HREAD_N_OUT => tsm_hread_n(i), + TSM_HREADY_N_IN => tsm_hready_n(i), + TSM_HDATA_EN_N_IN => tsm_hdataout_en_n(i), + -- Debug + DEBUG_OUT => open + ); + + led_activity_x(i) <= pcs_rx_en(i) or pcs_tx_en(i); + + THE_LED_ACT_PROC: process( CLK_125 ) + begin + if( rising_edge(CLK_125) ) then + if( led_activity_x(i) = '1' ) then + led_activity((i + 1) * 2 - 2) <= '1'; + end if; + if( led_timer_done = '1' ) then + led_activity((i + 1) * 2 - 1 downto (i + 1) * 2 - 2) <= led_activity((i + 1) * 2 - 2) & '0'; + end if; + end if; + end process THE_LED_ACT_PROC; + + -- Status signals + STATUS_OUT(i * 8 + 7) <= '0'; -- unused + STATUS_OUT(i * 8 + 6) <= '0'; -- unused + STATUS_OUT(i * 8 + 5) <= led_activity((i + 1) * 2 - 1); -- long LED signal for activity + STATUS_OUT(i * 8 + 4) <= pcs_rx_en(i); -- SerDes RX activity + STATUS_OUT(i * 8 + 3) <= pcs_tx_en(i); -- SerDes TX activity + STATUS_OUT(i * 8 + 2) <= an_complete(i); -- GbE Autonegotiation completed + STATUS_OUT(i * 8 + 1) <= link_rx_ready(i); -- SerDes Rx channel operational + STATUS_OUT(i * 8 + 0) <= TX_LINK_READY_IN; -- SerDes Tx channel operational + + end generate CHANNEL_ACTIVE_GEN; + + CHANNEL_INACTIVE_GEN : if LINKS_ACTIVE(i) = '0' generate + + SD_TXDIS_OUT(i) <= '1'; + powerup_ch(i) <= '0'; + rx_pcs_rst_q(i) <= '1'; + rx_serdes_rst_q(i) <= '1'; + + -- Status signals + STATUS_OUT(i * 8 + 7) <= '0'; -- unused + STATUS_OUT(i * 8 + 6) <= '0'; -- unused + STATUS_OUT(i * 8 + 5) <= '0'; -- long LED signal for activity + STATUS_OUT(i * 8 + 4) <= '0'; -- SerDes RX activity + STATUS_OUT(i * 8 + 3) <= '0'; -- SerDes TX activity + STATUS_OUT(i * 8 + 2) <= '0'; -- GbE Autonegotiation completed + STATUS_OUT(i * 8 + 1) <= '0'; -- SerDes Rx channel operational + STATUS_OUT(i * 8 + 0) <= '0'; -- SerDes Tx channel operational + + end generate CHANNEL_INACTIVE_GEN; + + end generate CHANNEL_GEN; + + THE_LED_TIMER_PROC: process( CLK_125 ) + begin + if( rising_edge(CLK_125) ) then + led_timer_done <= led_timer_done_x; + led_timer <= led_timer + 1; + end if; + end process THE_LED_TIMER_PROC; + + led_timer_done_x <= '1' when (std_logic_vector(led_timer) = x"fffff") else '0'; + +end architecture RTL;