diff --git a/apps/minimal/build/fb2cghh/Makefile b/apps/minimal/build/fb2cghh/Makefile index 8dd887342..f2966988e 100644 --- a/apps/minimal/build/fb2cghh/Makefile +++ b/apps/minimal/build/fb2cghh/Makefile @@ -14,9 +14,9 @@ CARD_BASE = $(COMBO_BASE)/cards/silicom/fb2cghh APP_CONF = app_conf.tcl OUTPUT_NAME = fb2cghh-minimal -.PHONY: all 100g2 40g2 +.PHONY: all 100g2 40g2 25g8 10g8 -all: 100g2 40g2 +all: 100g2 40g2 25g8 10g8 100g2: ETH_PORTS=2 100g2: ETH_PORT_SPEED=100 @@ -30,4 +30,16 @@ all: 100g2 40g2 40g2: OUTPUT_NAME:=$(OUTPUT_NAME)-40g2 40g2: build +25g8: ETH_PORTS=2 +25g8: ETH_PORT_SPEED=25 +25g8: ETH_PORT_CHAN=4 +25g8: OUTPUT_NAME:=$(OUTPUT_NAME)-25g8 +25g8: build + +10g8: ETH_PORTS=2 +10g8: ETH_PORT_SPEED=10 +10g8: ETH_PORT_CHAN=4 +10g8: OUTPUT_NAME:=$(OUTPUT_NAME)-10g8 +10g8: build + include $(CARD_BASE)/src/card.mk diff --git a/core/comp/eth/network_mod/Modules.tcl b/core/comp/eth/network_mod/Modules.tcl index 109676206..14e6a653b 100644 --- a/core/comp/eth/network_mod/Modules.tcl +++ b/core/comp/eth/network_mod/Modules.tcl @@ -13,6 +13,7 @@ set NETWORK_MOD_CORE_BASE "$NETWORK_MOD_COMP_BASE/network_mod_core" set NETWORK_MOD_LOG_BASE "$NETWORK_MOD_COMP_BASE/network_mod_logic" set I2C_BASE "$OFM_PATH/comp/ctrls/i2c_hw" set ASFIFOX_BASE "$OFM_PATH/comp/base/fifo/asfifox" +set NM_LOGIC_ARCHGRP "NO_CRC" # uncomment only for local synthesis # options: F_TILE, E_TILE, CMAC @@ -28,13 +29,16 @@ lappend MOD "$ENTITY_BASE/network_mod_ent.vhd" if {$ARCHGRP == "EMPTY"} { lappend MOD "$ENTITY_BASE/network_mod_empty.vhd" } else { - lappend COMPONENTS [list "ASYNC_OPENLOOP" $ASYNC_OPENLOOP_BASE "FULL" ] - lappend COMPONENTS [list "ASYNC_RESET" $ASYNC_RESET_BASE "FULL" ] - lappend COMPONENTS [list "MI_SPLITTER_PLUS_GEN" $MI_SPLITTER_BASE "FULL" ] - lappend COMPONENTS [list "NETWORK_MOD_CORE" $NETWORK_MOD_CORE_BASE $ARCHGRP] - lappend COMPONENTS [list "NETWORK_MOD_LOGIC" $NETWORK_MOD_LOG_BASE "FULL" ] - lappend COMPONENTS [list "I2C_CTRL" $I2C_BASE "FULL" ] - lappend COMPONENTS [list "ASFIFOX" $ASFIFOX_BASE "FULL" ] + if { $ARCHGRP == "10G4" || $ARCHGRP == "25G4" } { + set NM_LOGIC_ARCHGRP "FULL" + } + lappend COMPONENTS [list "ASYNC_OPENLOOP" $ASYNC_OPENLOOP_BASE "FULL" ] + lappend COMPONENTS [list "ASYNC_RESET" $ASYNC_RESET_BASE "FULL" ] + lappend COMPONENTS [list "MI_SPLITTER_PLUS_GEN" $MI_SPLITTER_BASE "FULL" ] + lappend COMPONENTS [list "NETWORK_MOD_CORE" $NETWORK_MOD_CORE_BASE $ARCHGRP ] + lappend COMPONENTS [list "NETWORK_MOD_LOGIC" $NETWORK_MOD_LOG_BASE $NM_LOGIC_ARCHGRP] + lappend COMPONENTS [list "I2C_CTRL" $I2C_BASE "FULL" ] + lappend COMPONENTS [list "ASFIFOX" $ASFIFOX_BASE "FULL" ] # Source files for implemented component lappend MOD "$ENTITY_BASE/qsfp_ctrl.vhd" diff --git a/core/comp/eth/network_mod/comp/network_mod_core/Modules.tcl b/core/comp/eth/network_mod/comp/network_mod_core/Modules.tcl index ca44e3d44..ba9fafaae 100644 --- a/core/comp/eth/network_mod/comp/network_mod_core/Modules.tcl +++ b/core/comp/eth/network_mod/comp/network_mod_core/Modules.tcl @@ -15,12 +15,15 @@ set DK_1SDX_IP_BASE "$CARDS_BASE/dk-dev-1sdx-p/src/ip" set DK_AGI_IP_BASE "$CARDS_BASE/dk-dev-agi027res/src/ip" set AGI_FH400G_IP_BASE "$CARDS_BASE/agi-fh400g/src/ip" set CMAC_IP_BASE "$CARDS_BASE/fb4cgg3/src/ip" +set PCSPMA_IP_BASE "$CARDS_BASE/fb2cghh/src/ip" set 40GE_BASE "$OFM_PATH/comp/nic/eth_phy/40ge" +set USP_PCS_PMA_BASE "$OFM_PATH/comp/nic/eth_phy/usp_phyx4_10g_25g" set LL10GE40GE_BASE "$OFM_PATH/../extra/hft/comp/net_mod/top" set FIFO_BASE "$OFM_PATH/comp/base/fifo" set MI_SPLITTER_BASE "$OFM_PATH/comp/mi_tools/splitter_plus_gen" set BASE_LOGIC_BASE "$OFM_PATH/comp/base/logic" set TSU_BASE "$OFM_PATH/comp/tsu" +set MFB_ASFIFOX_BASE "$OFM_PATH/comp/mfb_tools/storage/asfifox" # Packages lappend PACKAGES "$OFM_PATH/comp/base/pkg/math_pack.vhd" @@ -150,6 +153,36 @@ if { $ARCHGRP == "40GE" } { lappend MOD "$ENTITY_BASE/network_mod_core_40ge.vhd" } +if { $ARCHGRP == "10G4" } { + lappend COMPONENTS [list "ASYNC_RESET" "$ASYNC_BASE/reset" "FULL"] + lappend COMPONENTS [list "ASYNC_OPEN_LOOP" "$ASYNC_BASE/open_loop" "FULL"] + lappend COMPONENTS [list "RX_MII_ADAPTER" "$RX_ADAPTER_BASE/umii_dec" "FULL"] + lappend COMPONENTS [list "TX_MII_ADAPTER" "$TX_ADAPTER_BASE/umii_enc" "FULL"] + lappend COMPONENTS [list "MFB_ASFIFOX" "$MFB_ASFIFOX_BASE" "FULL"] + lappend COMPONENTS [list "USP_PCS_PMA_WRAPPER" "$USP_PCS_PMA_BASE" "FULL"] + + # IP are now in card top-level Modules.tcl + # Uncomment for network module synthesis only! + #lappend MOD "$PCSPMA_IP_BASE/pcs_pma_4x10g/pcs_pma_4x10g.xci" + + lappend MOD "$ENTITY_BASE/network_mod_core_usp_10g4.vhd" +} + +if { $ARCHGRP == "25G4" } { + lappend COMPONENTS [list "ASYNC_RESET" "$ASYNC_BASE/reset" "FULL"] + lappend COMPONENTS [list "ASYNC_OPEN_LOOP" "$ASYNC_BASE/open_loop" "FULL"] + lappend COMPONENTS [list "RX_MII_ADAPTER" "$RX_ADAPTER_BASE/umii_dec" "FULL"] + lappend COMPONENTS [list "TX_MII_ADAPTER" "$TX_ADAPTER_BASE/umii_enc" "FULL"] + lappend COMPONENTS [list "MFB_ASFIFOX" "$MFB_ASFIFOX_BASE" "FULL"] + lappend COMPONENTS [list "USP_PCS_PMA_WRAPPER" "$USP_PCS_PMA_BASE" "FULL"] + + # IP are now in card top-level Modules.tcl + # Uncomment for network module synthesis only! + #lappend MOD "$PCSPMA_IP_BASE/pcs_pma_4x25g/pcs_pma_4x25g.xci" + + lappend MOD "$ENTITY_BASE/network_mod_core_usp_25g4.vhd" +} + if { $ARCHGRP == "CESNET_LL10GE" || $ARCHGRP == "CESNET_LL40GE" } { if { [file exists "$LL10GE40GE_BASE/Modules.tcl"] == 1} { lappend COMPONENTS [list "CESNET_LL10GE40GE" $LL10GE40GE_BASE $ARCHGRP] diff --git a/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_ent.vhd b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_ent.vhd index 8e06c596b..dd9a1113b 100644 --- a/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_ent.vhd +++ b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_ent.vhd @@ -107,7 +107,7 @@ port( -- ===================================================================== -- RX interface (Packets for transmit to Ethernet, recieved from MFB) -- ===================================================================== - RX_MFB_CLK : out std_logic := '0'; + RX_MFB_CLK : out std_logic_vector(ETH_PORT_CHAN-1 downto 0) := (others => '0'); RX_MFB_DATA : in slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); RX_MFB_SOF_POS : in slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); RX_MFB_EOF_POS : in slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE*BLOCK_SIZE))-1 downto 0); diff --git a/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_10g4.vhd b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_10g4.vhd new file mode 100644 index 000000000..4da283b30 --- /dev/null +++ b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_10g4.vhd @@ -0,0 +1,239 @@ +-- network_mod_core_10g4.vhd: Core of the Network module with 10G4 XILINX PCSPMA +-- Copyright (C) 2024 CESNET z. s. p. o. +-- Author(s): Vlastimil Kosar +-- +-- SPDX-License-Identifier: BSD-3-Clause + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.math_pack.all; +use work.type_pack.all; +use work.eth_hdr_pack.all; + +architecture TEN_G4 of NETWORK_MOD_CORE is + + -- ========================================================================= + -- CONSTANTS + -- ========================================================================= + + + -- ========================================================================= + -- SIGNALS + -- ========================================================================= + + signal eth_reset_rx_i : std_logic_vector(3 downto 0); + signal eth_reset_tx_i : std_logic_vector(3 downto 0); + signal eth_clk_mii : std_logic_vector(3 downto 0); + signal eth_txd : std_logic_vector(256-1 downto 0); + signal eth_txc : std_logic_vector(32-1 downto 0); + signal eth_rxd : std_logic_vector(256-1 downto 0); + signal eth_rxc : std_logic_vector(32-1 downto 0); + + signal rx_reset : std_logic_vector(3 downto 0); + signal tx_reset : std_logic_vector(3 downto 0); + signal reset_eth_int : std_logic_vector(3 downto 0); + + signal rx_int_mfb_data : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); + signal rx_int_mfb_sof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); + signal rx_int_mfb_eof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE*BLOCK_SIZE))-1 downto 0); + signal rx_int_mfb_sof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal rx_int_mfb_eof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal rx_int_mfb_src_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + signal rx_int_mfb_dst_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + + signal tx_int_mfb_data : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); + signal tx_int_mfb_error : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_sof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); + signal tx_int_mfb_eof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE*BLOCK_SIZE))-1 downto 0); + signal tx_int_mfb_sof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_eof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_src_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + + signal tx_local_fault : std_logic_vector(3 downto 0); + signal tx_local_fault_sync : std_logic_vector(3 downto 0); +begin + + assert (ETH_PORT_CHAN = 4) + report "NETWORK_MOD_CORE: 10G4 Ethernet IP supports only ETH_PORT_CHAN=4!" + severity failure; + assert (ETH_PORT_SPEED = 10) + report "NETWORK_MOD_CORE: 10G4 Ethernet IP supports only ETH_PORT_SPEED=10!" + severity failure; + + -- ========================================================================= + -- 4x10GE version + -- ========================================================================= + ETH_PHY_4x10g_i: entity work.USP_PCS_PMA_WRAPPER + generic map ( + CH0_MAP => 0, + CH1_MAP => 1, + CH2_MAP => 2, + CH3_MAP => 3, + ETH_25G => false, + GTY_TX_EQ => GTY_TX_EQ, + MI_DATA_WIDTH_PHY => MI_DATA_WIDTH_PHY, + MI_ADDR_WIDTH_PHY => MI_ADDR_WIDTH_PHY + ) + port map ( + --! \name Clock and reset signals + RESET => MI_RESET_PHY, + SYSCLK => MI_CLK_PHY, -- Stable clock, 100 MHz + --! \name Transceiver reference clock + REFCLK_P => QSFP_REFCLK_P, + REFCLK_N => QSFP_REFCLK_N, + --! \name Transceivers 0-3 - serial data + TX_P => QSFP_TX_P, + TX_N => QSFP_TX_N, + RX_P => QSFP_RX_P, + RX_N => QSFP_RX_N, + RXPOLARITY => LANE_RX_POLARITY, + TXPOLARITY => LANE_TX_POLARITY, + --! \name XGMII interfaces + TXRESET => tx_reset, + XGCLK => eth_clk_mii, + TX_LOCAL_FAULT => tx_local_fault, + TXD => eth_txd, + TXC => eth_txc, + RXRESET => rx_reset, + RXD => eth_rxd, + RXC => eth_rxc, + -- PMD signal detect + SIGNAL_DETECT => "1111", + -- MI32 interface for management + MI_CLK => MI_CLK_PHY, + MI_DWR => MI_DWR_PHY, + MI_ADDR => MI_ADDR_PHY, + MI_RD => MI_RD_PHY, + MI_WR => MI_WR_PHY, + MI_BE => MI_BE_PHY, + MI_DRD => MI_DRD_PHY, + MI_ARDY => MI_ARDY_PHY, + MI_DRDY => MI_DRDY_PHY + ); + + TX_MFB_CLK <= eth_clk_mii; + RX_MFB_CLK <= eth_clk_mii; + CLK_ETH <= eth_clk_mii(0); + + -- ========================================================================= + -- ADAPTERS + -- ========================================================================= + + gen_umii_decs: for i in 0 to ETH_PORT_CHAN - 1 generate + eth_reset_rx_i(i) <= reset_eth_int(i) or rx_reset(i); + eth_reset_tx_i(i) <= reset_eth_int(i) or tx_reset(i); + + xlgmii2mfb_i: entity work.UMII_DEC + generic map ( + MII_DW => 64, + CNT_ERROR_LENGTH => 5, + XGMII_ALIGN_EN => true + ) + port map ( + CLK => eth_clk_mii(i), + RESET => eth_reset_rx_i(i), + -- ===================================================================== + -- INPUT MII INTERFACE (XGMII, XLGMII, CGMII, CDMII,...) + -- ===================================================================== + MII_RXD => eth_rxd((i+1)*64 - 1 downto i*64), + MII_RXC => eth_rxc((i+1)*8 - 1 downto i*8), + MII_VLD => '1', + -- ===================================================================== + -- OUTPUT MFB LIKE INTERFACE + -- ===================================================================== + TX_DATA => tx_int_mfb_data(i), + TX_SOF_POS => tx_int_mfb_sof_pos(i), + TX_EOF_POS => tx_int_mfb_eof_pos(i), + TX_SOF => tx_int_mfb_sof(i), + TX_EOF => tx_int_mfb_eof(i), + TX_ERR => tx_int_mfb_error(i), + TX_SRC_RDY => tx_int_mfb_src_rdy(i), + -- ===================================================================== + -- OUTPUT LINK STATE INTERFACE + -- ===================================================================== + LINK_UP => RX_LINK_UP(i), + INCOMING_FRAME => open + ); + + mfb2xlgmii_i: entity work.UMII_ENC + generic map ( + MII_DW => 64 + ) + port map ( + -- ===================================================================== + -- CLOCK AND RESET + -- ===================================================================== + CLK => eth_clk_mii(i), + RESET => eth_reset_tx_i(i), + -- ===================================================================== + -- INPUT MFB LIKE INTERFACE + -- ===================================================================== + RX_DATA => rx_int_mfb_data(i), + RX_SOF_POS => rx_int_mfb_sof_pos(i), + RX_EOF_POS => rx_int_mfb_eof_pos(i), + RX_SOF => rx_int_mfb_sof(i), + RX_EOF => rx_int_mfb_eof(i), + RX_SRC_RDY => rx_int_mfb_src_rdy(i), + RX_DST_RDY => rx_int_mfb_dst_rdy(i), + -- ===================================================================== + -- OUTPUT MII INTERFACE (XGMII, XLGMII, CGMII, CDMII,...) + -- ===================================================================== + MII_TXD => eth_txd((i+1)*64 - 1 downto i*64), + MII_TXC => eth_txc((i+1)*8 - 1 downto i*8), + MII_VLD => open, + MII_RDY => '1' + ); + end generate; + + -- ========================================================================= + -- Async crossings + -- ========================================================================= + gen_async_cross: for i in 0 to ETH_PORT_CHAN - 1 generate + -- synchronize TX_LINK_UP + tx_link_up_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => tx_local_fault(i), + BCLK => eth_clk_mii(i), + BRST => '0', + BDATAOUT => tx_local_fault_sync(i) + ); + TX_LINK_UP(i) <= not tx_local_fault_sync(i); + + -- Synchronize reset + eth_reset_sync_i: entity work.ASYNC_RESET + generic map( + TWO_REG => false, + OUT_REG => true, + REPLICAS => 1 + ) + port map( + --! A clock domain + CLK => eth_clk_mii(i), + ASYNC_RST => RESET_ETH, + OUT_RST => reset_eth_int(i downto i) + ); + end generate; + + + TX_MFB_DATA <= tx_int_mfb_data; + TX_MFB_ERROR <= tx_int_mfb_error; + TX_MFB_SOF <= tx_int_mfb_sof; + TX_MFB_EOF <= tx_int_mfb_eof; + TX_MFB_SOF_POS <= tx_int_mfb_sof_pos; + TX_MFB_EOF_POS <= tx_int_mfb_eof_pos; + TX_MFB_SRC_RDY <= tx_int_mfb_src_rdy; + + rx_int_mfb_data <= RX_MFB_DATA; + rx_int_mfb_sof <= RX_MFB_SOF; + rx_int_mfb_eof <= RX_MFB_EOF; + rx_int_mfb_sof_pos <= RX_MFB_SOF_POS; + rx_int_mfb_eof_pos <= RX_MFB_EOF_POS; + rx_int_mfb_src_rdy <= RX_MFB_SRC_RDY; + rx_int_mfb_dst_rdy <= RX_MFB_DST_RDY; +end architecture; diff --git a/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_25g4.vhd b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_25g4.vhd new file mode 100644 index 000000000..1f05af790 --- /dev/null +++ b/core/comp/eth/network_mod/comp/network_mod_core/network_mod_core_usp_25g4.vhd @@ -0,0 +1,288 @@ +-- network_mod_core_25g4.vhd: Core of the Network module with 25G4 XILINX PCSPMA +-- Copyright (C) 2024 CESNET z. s. p. o. +-- Author(s): Vlastimil Kosar +-- +-- SPDX-License-Identifier: BSD-3-Clause + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.math_pack.all; +use work.type_pack.all; +use work.eth_hdr_pack.all; + +architecture XXV_G4 of NETWORK_MOD_CORE is + + -- ========================================================================= + -- CONSTANTS + -- ========================================================================= + + + -- ========================================================================= + -- SIGNALS + -- ========================================================================= + + signal eth_reset_rx_i : std_logic_vector(3 downto 0); + signal eth_reset_tx_i : std_logic_vector(3 downto 0); + signal eth_clk_mii : std_logic_vector(3 downto 0); + signal eth_txd : std_logic_vector(256-1 downto 0); + signal eth_txc : std_logic_vector(32-1 downto 0); + signal eth_rxd : std_logic_vector(256-1 downto 0); + signal eth_rxc : std_logic_vector(32-1 downto 0); + + signal eth_txd_reg0 : std_logic_vector(256-1 downto 0); + signal eth_txc_reg0 : std_logic_vector(32-1 downto 0); + signal eth_rxd_reg0 : std_logic_vector(256-1 downto 0); + signal eth_rxc_reg0 : std_logic_vector(32-1 downto 0); + + signal eth_txd_reg1 : std_logic_vector(256-1 downto 0); + signal eth_txc_reg1 : std_logic_vector(32-1 downto 0); + signal eth_rxd_reg1 : std_logic_vector(256-1 downto 0); + signal eth_rxc_reg1 : std_logic_vector(32-1 downto 0); + + signal rx_reset : std_logic_vector(3 downto 0); + signal tx_reset : std_logic_vector(3 downto 0); + signal reset_eth_int : std_logic_vector(3 downto 0); + + signal rx_int_mfb_data : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); + signal rx_int_mfb_sof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); + signal rx_int_mfb_eof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE*BLOCK_SIZE))-1 downto 0); + signal rx_int_mfb_sof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal rx_int_mfb_eof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal rx_int_mfb_src_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + signal rx_int_mfb_dst_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + + signal tx_int_mfb_data : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); + signal tx_int_mfb_error : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_sof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); + signal tx_int_mfb_eof_pos : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE*BLOCK_SIZE))-1 downto 0); + signal tx_int_mfb_sof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_eof : slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); + signal tx_int_mfb_src_rdy : std_logic_vector(ETH_PORT_CHAN-1 downto 0); + + signal tx_local_fault : std_logic_vector(3 downto 0); + signal tx_local_fault_sync : std_logic_vector(3 downto 0); +begin + + assert (ETH_PORT_CHAN = 4) + report "NETWORK_MOD_CORE: 25G4 Ethernet IP supports only ETH_PORT_CHAN=4!" + severity failure; + assert (ETH_PORT_SPEED = 25) + report "NETWORK_MOD_CORE: 25G4 Ethernet IP supports only ETH_PORT_SPEED=25!" + severity failure; + + -- ========================================================================= + -- 4x10GE version + -- ========================================================================= + ETH_PHY_4x25g_i: entity work.USP_PCS_PMA_WRAPPER + generic map ( + CH0_MAP => 0, + CH1_MAP => 1, + CH2_MAP => 2, + CH3_MAP => 3, + ETH_25G => true, + GTY_TX_EQ => GTY_TX_EQ, + MI_DATA_WIDTH_PHY => MI_DATA_WIDTH_PHY, + MI_ADDR_WIDTH_PHY => MI_ADDR_WIDTH_PHY + ) + port map ( + --! \name Clock and reset signals + RESET => MI_RESET_PHY, + SYSCLK => MI_CLK_PHY, -- Stable clock, 100 MHz + --! \name Transceiver reference clock + REFCLK_P => QSFP_REFCLK_P, + REFCLK_N => QSFP_REFCLK_N, + --! \name Transceivers 0-3 - serial data + TX_P => QSFP_TX_P, + TX_N => QSFP_TX_N, + RX_P => QSFP_RX_P, + RX_N => QSFP_RX_N, + RXPOLARITY => LANE_RX_POLARITY, + TXPOLARITY => LANE_TX_POLARITY, + --! \name XGMII interfaces + TXRESET => tx_reset, + XGCLK => eth_clk_mii, + TX_LOCAL_FAULT => tx_local_fault, + TXD => eth_txd_reg1, + TXC => eth_txc_reg1, + RXRESET => rx_reset, + RXD => eth_rxd, + RXC => eth_rxc, + -- PMD signal detect + SIGNAL_DETECT => "1111", + -- MI32 interface for management + MI_CLK => MI_CLK_PHY, + MI_DWR => MI_DWR_PHY, + MI_ADDR => MI_ADDR_PHY, + MI_RD => MI_RD_PHY, + MI_WR => MI_WR_PHY, + MI_BE => MI_BE_PHY, + MI_DRD => MI_DRD_PHY, + MI_ARDY => MI_ARDY_PHY, + MI_DRDY => MI_DRDY_PHY + ); + + + TX_MFB_CLK <= eth_clk_mii; + RX_MFB_CLK <= eth_clk_mii; + CLK_ETH <= eth_clk_mii(0); + + -- ========================================================================= + -- ADAPTERS + -- ========================================================================= + + gen_umii_decs: for i in 0 to ETH_PORT_CHAN - 1 generate + eth_reset_rx_i(i) <= reset_eth_int(i) or rx_reset(i); + eth_reset_tx_i(i) <= reset_eth_int(i) or tx_reset(i); + + -- XLGMII Pipeline registers to improve timing + rx_xlgmii_pipeline_regs_p: process(eth_clk_mii(i)) + begin + if eth_clk_mii(i)'event and eth_clk_mii(i) = '1' then + if eth_reset_rx_i(i) = '1' then + eth_rxd_reg0((i+1)*64-1 downto i*64) <= X"0100009C0100009C"; + eth_rxc_reg0((i+1)*8-1 downto i*8) <= "00010001"; + + eth_rxd_reg1((i+1)*64-1 downto i*64) <= X"0100009C0100009C"; + eth_rxc_reg1((i+1)*8-1 downto i*8) <= "00010001"; + else + eth_rxd_reg0((i+1)*64-1 downto i*64) <= eth_rxd((i+1)*64-1 downto i*64); + eth_rxc_reg0((i+1)*8-1 downto i*8) <= eth_rxc((i+1)*8-1 downto i*8); + + eth_rxd_reg1((i+1)*64-1 downto i*64) <= eth_rxd_reg0((i+1)*64-1 downto i*64); + eth_rxc_reg1((i+1)*8-1 downto i*8) <= eth_rxc_reg0((i+1)*8-1 downto i*8); + end if; + end if; + end process; + tx_xlgmii_pipeline_regs_p: process(eth_clk_mii(i)) + begin + if eth_clk_mii(i)'event and eth_clk_mii(i) = '1' then + if eth_reset_tx_i(i) = '1' then + eth_txd_reg0((i+1)*64-1 downto i*64) <= X"0707070707070707"; + eth_txc_reg0((i+1)*8-1 downto i*8) <= (others => '1'); + + eth_txd_reg1((i+1)*64-1 downto i*64) <= X"0707070707070707"; + eth_txc_reg1((i+1)*8-1 downto i*8) <= (others => '1'); + else + eth_txd_reg0((i+1)*64-1 downto i*64) <= eth_txd((i+1)*64-1 downto i*64); + eth_txc_reg0((i+1)*8-1 downto i*8) <= eth_txc((i+1)*8-1 downto i*8); + + eth_txd_reg1((i+1)*64-1 downto i*64) <= eth_txd_reg0((i+1)*64-1 downto i*64); + eth_txc_reg1((i+1)*8-1 downto i*8) <= eth_txc_reg0((i+1)*8-1 downto i*8); + end if; + end if; + end process; + + xlgmii2mfb_i: entity work.UMII_DEC + generic map ( + MII_DW => 64, + CNT_ERROR_LENGTH => 5, + XGMII_ALIGN_EN => true + ) + port map ( + CLK => eth_clk_mii(i), + RESET => eth_reset_rx_i(i), + -- ===================================================================== + -- INPUT MII INTERFACE (XGMII, XLGMII, CGMII, CDMII,...) + -- ===================================================================== + MII_RXD => eth_rxd_reg1((i+1)*64 - 1 downto i*64), + MII_RXC => eth_rxc_reg1((i+1)*8 - 1 downto i*8), + MII_VLD => '1', + -- ===================================================================== + -- OUTPUT MFB LIKE INTERFACE + -- ===================================================================== + TX_DATA => tx_int_mfb_data(i), + TX_SOF_POS => tx_int_mfb_sof_pos(i), + TX_EOF_POS => tx_int_mfb_eof_pos(i), + TX_SOF => tx_int_mfb_sof(i), + TX_EOF => tx_int_mfb_eof(i), + TX_ERR => tx_int_mfb_error(i), + TX_SRC_RDY => tx_int_mfb_src_rdy(i), + -- ===================================================================== + -- OUTPUT LINK STATE INTERFACE + -- ===================================================================== + LINK_UP => RX_LINK_UP(i), + INCOMING_FRAME => open + ); + + mfb2xlgmii_i: entity work.UMII_ENC + generic map ( + MII_DW => 64 + ) + port map ( + -- ===================================================================== + -- CLOCK AND RESET + -- ===================================================================== + CLK => eth_clk_mii(i), + RESET => eth_reset_tx_i(i), + -- ===================================================================== + -- INPUT MFB LIKE INTERFACE + -- ===================================================================== + RX_DATA => rx_int_mfb_data(i), + RX_SOF_POS => rx_int_mfb_sof_pos(i), + RX_EOF_POS => rx_int_mfb_eof_pos(i), + RX_SOF => rx_int_mfb_sof(i), + RX_EOF => rx_int_mfb_eof(i), + RX_SRC_RDY => rx_int_mfb_src_rdy(i), + RX_DST_RDY => rx_int_mfb_dst_rdy(i), + -- ===================================================================== + -- OUTPUT MII INTERFACE (XGMII, XLGMII, CGMII, CDMII,...) + -- ===================================================================== + MII_TXD => eth_txd((i+1)*64 - 1 downto i*64), + MII_TXC => eth_txc((i+1)*8 - 1 downto i*8), + MII_VLD => open, + MII_RDY => '1' + ); + end generate; + + -- ========================================================================= + -- Async crossings + -- ========================================================================= + gen_async_cross: for i in 0 to ETH_PORT_CHAN - 1 generate + -- synchronize TX_LINK_UP + tx_link_up_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => tx_local_fault(i), + BCLK => eth_clk_mii(i), + BRST => '0', + BDATAOUT => tx_local_fault_sync(i) + ); + TX_LINK_UP(i) <= not tx_local_fault_sync(i); + + -- Synchronize reset + eth_reset_sync_i: entity work.ASYNC_RESET + generic map( + TWO_REG => false, + OUT_REG => true, + REPLICAS => 1 + ) + port map( + --! A clock domain + CLK => eth_clk_mii(i), + ASYNC_RST => RESET_ETH, + OUT_RST => reset_eth_int(i downto i) + ); + + end generate; + + TX_MFB_DATA <= tx_int_mfb_data; + TX_MFB_ERROR <= tx_int_mfb_error; + TX_MFB_SOF <= tx_int_mfb_sof; + TX_MFB_EOF <= tx_int_mfb_eof; + TX_MFB_SOF_POS <= tx_int_mfb_sof_pos; + TX_MFB_EOF_POS <= tx_int_mfb_eof_pos; + TX_MFB_SRC_RDY <= tx_int_mfb_src_rdy; + + rx_int_mfb_data <= RX_MFB_DATA; + rx_int_mfb_sof <= RX_MFB_SOF; + rx_int_mfb_eof <= RX_MFB_EOF; + rx_int_mfb_sof_pos <= RX_MFB_SOF_POS; + rx_int_mfb_eof_pos <= RX_MFB_EOF_POS; + rx_int_mfb_src_rdy <= RX_MFB_SRC_RDY; + rx_int_mfb_dst_rdy <= RX_MFB_DST_RDY; +end architecture; diff --git a/core/comp/eth/network_mod/comp/network_mod_logic/Modules.tcl b/core/comp/eth/network_mod/comp/network_mod_logic/Modules.tcl index 77a616ddd..d80fd3d57 100644 --- a/core/comp/eth/network_mod/comp/network_mod_logic/Modules.tcl +++ b/core/comp/eth/network_mod/comp/network_mod_logic/Modules.tcl @@ -20,8 +20,8 @@ set PACKAGES "$PACKAGES $OFM_PATH/comp/base/pkg/eth_hdr_pack.vhd" set COMPONENTS [concat $COMPONENTS [list \ [ list "MI_SPLITTER_PLUS_GEN" $MI_SPLITTER_BASE "FULL" ] \ - [ list "TX_MAC_LITE" $TX_MAC_LITE_BASE "NO_CRC" ] \ - [ list "RX_MAC_LITE" $RX_MAC_LITE_BASE "NO_CRC" ] \ + [ list "TX_MAC_LITE" $TX_MAC_LITE_BASE $ARCHGRP ] \ + [ list "RX_MAC_LITE" $RX_MAC_LITE_BASE $ARCHGRP ] \ [ list "MFB_MERGER_GEN" $MFB_MERGER_BASE "FULL" ] \ [ list "MFB_SPLIT_SIMPLE_GEN" $MFB_SPLITTER_BASE "FULL" ] \ ]] diff --git a/core/comp/eth/network_mod/comp/network_mod_logic/network_mod_logic.vhd b/core/comp/eth/network_mod/comp/network_mod_logic/network_mod_logic.vhd index 9854248ed..426e8ef7e 100644 --- a/core/comp/eth/network_mod/comp/network_mod_logic/network_mod_logic.vhd +++ b/core/comp/eth/network_mod/comp/network_mod_logic/network_mod_logic.vhd @@ -59,6 +59,11 @@ generic( -- OTHER configuration: -- ===================================================================== LL_MODE : boolean := false; + -- Use full MAC features: + -- - Generate/Check FCS + -- - Generate IPG + -- - Do not use resize on TX + USE_FULL_MAC : boolean := false; RESET_USER_WIDTH : natural := 8; -- ETH_PORT_CHAN x (TX MAC lite + RX MAC lite) RESET_CORE_WIDTH : natural := ETH_PORT_CHAN * (1 + 1 ); @@ -74,7 +79,7 @@ port( -- CLOCK AND RESET -- ===================================================================== CLK_USER : in std_logic; - TX_CLK_CORE : in std_logic; + TX_CLK_CORE : in std_logic_vector(ETH_PORT_CHAN-1 downto 0); RX_CLK_CORE : in std_logic_vector(ETH_PORT_CHAN-1 downto 0); RESET_USER : in std_logic_vector(RESET_USER_WIDTH-1 downto 0); @@ -359,12 +364,12 @@ begin TX_REGION_SIZE => CORE_REGION_SIZE, TX_BLOCK_SIZE => BLOCK_SIZE , TX_ITEM_WIDTH => ITEM_WIDTH , - RESIZE_ON_TX => True , + RESIZE_ON_TX => not USE_FULL_MAC, PKT_MTU_BYTES => ETH_PORT_TX_MTU , RX_INCLUDE_CRC => false , RX_INCLUDE_IPG => false , - CRC_INSERT_EN => false , - IPG_GENERATE_EN => false , + CRC_INSERT_EN => USE_FULL_MAC , + IPG_GENERATE_EN => USE_FULL_MAC , USE_DSP_CNT => true , LL_MODE => LL_MODE , DEVICE => DEVICE @@ -392,7 +397,7 @@ begin RX_MFB_SRC_RDY => split_mfb_src_rdy(ch), RX_MFB_DST_RDY => split_mfb_dst_rdy(ch), - TX_CLK => TX_CLK_CORE , + TX_CLK => TX_CLK_CORE(ch) , TX_RESET => RESET_CORE(ch*2) , TX_MFB_DATA => TX_CORE_MFB_DATA (ch), TX_MFB_SOF => TX_CORE_MFB_SOF (ch), @@ -449,9 +454,9 @@ begin RESIZE_BUFFER => RESIZE_BUFFER , NETWORK_PORT_ID => ETH_PORT_ID*ETH_PORT_CHAN+ch, -- no support different number of channels for each port PKT_MTU_BYTES => ETH_PORT_RX_MTU , - CRC_IS_RECEIVED => false , - CRC_CHECK_EN => false , - CRC_REMOVE_EN => false , + CRC_IS_RECEIVED => USE_FULL_MAC , + CRC_CHECK_EN => USE_FULL_MAC , + CRC_REMOVE_EN => USE_FULL_MAC , MAC_CHECK_EN => true , MAC_COUNT => 16 , TIMESTAMP_EN => true , diff --git a/core/comp/eth/network_mod/comp/network_mod_logic/uvm/tbench/dut.sv b/core/comp/eth/network_mod/comp/network_mod_logic/uvm/tbench/dut.sv index 51e4585c8..7ec4c02f1 100644 --- a/core/comp/eth/network_mod/comp/network_mod_logic/uvm/tbench/dut.sv +++ b/core/comp/eth/network_mod/comp/network_mod_logic/uvm/tbench/dut.sv @@ -100,7 +100,7 @@ module DUT ( .BOARD (BOARD) ) VHDL_DUT_U ( .CLK_USER (CLK_USER), - .TX_CLK_CORE (CLK_CORE), + .TX_CLK_CORE ({ETH_CHANNELS {CLK_CORE}}), .RX_CLK_CORE ({ETH_CHANNELS {CLK_CORE}}), .RESET_USER (RESET_USER), .RESET_CORE (RESET_CORE), diff --git a/core/comp/eth/network_mod/network_mod.vhd b/core/comp/eth/network_mod/network_mod.vhd index 7354fbf75..654bec0af 100644 --- a/core/comp/eth/network_mod/network_mod.vhd +++ b/core/comp/eth/network_mod/network_mod.vhd @@ -83,8 +83,10 @@ architecture FULL of NETWORK_MOD is constant FPC202_INIT_EN : boolean := (BOARD = "DK-DEV-1SDX-P" or BOARD = "DK-DEV-AGI027RES"); constant RESIZE_BUFFER : boolean := (ETH_CORE_ARCH = "F_TILE" or (ETH_CORE_ARCH = "E_TILE" and ETH_CHANNELS = 4)); + constant IS_USP_10G4_25G4 : boolean := ETH_CORE_ARCH = "10G4" or ETH_CORE_ARCH = "25G4"; + constant TS_TIMEOUT_W : natural := 3; -- last TS is unvalided after 4 cycles - constant TS_REPLICAS : natural := tsel(LL_MODE, ETH_CHANNELS, 1); + constant TS_REPLICAS : natural := tsel(LL_MODE or IS_USP_10G4_25G4, ETH_CHANNELS, 1); -- ========================================================================= -- FUNCTIONS @@ -152,8 +154,8 @@ architecture FULL of NETWORK_MOD is signal rx_usr_mfb_dst_rdy_arr : slv_array_t (ETH_PORTS-1 downto 0)(ETH_PORT_STREAMS-1 downto 0); -- Interior signals, Network Module Logic -> Network Module Core - signal logic_tx_clk : std_logic_vector(ETH_PORTS-1 downto 0); - signal tx_mfb_clk : std_logic_vector(ETH_PORTS-1 downto 0); + signal logic_tx_clk : slv_array_t (ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal tx_mfb_clk : slv_array_t (ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); signal tx_mfb_data_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(MFB_WIDTH_CORE-1 downto 0); signal tx_mfb_sof_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(REGIONS_CORE-1 downto 0); signal tx_mfb_eof_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(REGIONS_CORE-1 downto 0); @@ -168,6 +170,11 @@ architecture FULL of NETWORK_MOD is signal sig_rx_link_up : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); signal sig_tx_link_up : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal sig_activity_rx_sync : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal sig_activity_tx_sync : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal sig_rx_link_up_sync : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal sig_tx_link_up_sync : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + -- MI for MAC lites signal mi_split_dwr : slv_array_t (MI_ADDR_BASES-1 downto 0)(MI_DATA_WIDTH-1 downto 0); signal mi_split_addr : slv_array_t (MI_ADDR_BASES-1 downto 0)(MI_ADDR_WIDTH-1 downto 0); @@ -371,6 +378,7 @@ begin MI_ADDR_WIDTH => MI_ADDR_WIDTH , -- Other LL_MODE => LL_MODE , + USE_FULL_MAC => IS_USP_10G4_25G4, RESET_USER_WIDTH => RESET_WIDTH , RESET_CORE_WIDTH => logic_rst_arr(p)'length, RESIZE_BUFFER => RESIZE_BUFFER , @@ -534,11 +542,11 @@ begin -- ===================================================================== -- MFB clocking based on LL mode generic -- ===================================================================== - mfb_clk_g: if LL_MODE generate + mfb_clk_g: if LL_MODE or IS_USP_10G4_25G4 generate logic_tx_clk(p) <= tx_mfb_clk(p); logic_rx_clk(p) <= rx_mfb_clk(p); else generate - logic_tx_clk(p) <= CLK_ETH(p); + logic_tx_clk(p) <= (others => CLK_ETH(p)); logic_rx_clk(p) <= (others => CLK_ETH(p)); end generate; @@ -627,10 +635,71 @@ begin end generate; end generate; - ACTIVITY_RX <= slv_array_ser(sig_activity_rx); - ACTIVITY_TX <= slv_array_ser(sig_activity_tx); - RX_LINK_UP <= slv_array_ser(sig_rx_link_up); - TX_LINK_UP <= slv_array_ser(sig_tx_link_up); + -- ===================================================================== + -- Synchronize activity and link up signals + -- ===================================================================== + sync_act_link_p_g_en: if LL_MODE or IS_USP_10G4_25G4 generate + sync_act_link_p_g : for p in 0 to ETH_PORTS-1 generate + sync_act_link_g : for ch in 0 to ETH_CHANNELS-1 generate + act_rx_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => sig_activity_rx(p)(ch), + BCLK => CLK_ETH(p), + BRST => '0', + BDATAOUT => sig_activity_rx_sync(p)(ch) + ); + + act_tx_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => sig_activity_tx(p)(ch), + BCLK => CLK_ETH(p), + BRST => '0', + BDATAOUT => sig_activity_tx_sync(p)(ch) + ); + + rx_link_up_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => sig_rx_link_up(p)(ch), + BCLK => CLK_ETH(p), + BRST => '0', + BDATAOUT => sig_rx_link_up_sync(p)(ch) + ); + tx_link_up_sync_i : entity work.ASYNC_OPEN_LOOP + generic map( + IN_REG => false, + TWO_REG => true + ) + port map( + ADATAIN => sig_tx_link_up(p)(ch), + BCLK => CLK_ETH(p), + BRST => '0', + BDATAOUT => sig_tx_link_up_sync(p)(ch) + ); + end generate; + end generate; + else generate + sig_activity_rx_sync <= sig_activity_rx; + sig_activity_tx_sync <= sig_activity_tx; + sig_rx_link_up_sync <= sig_rx_link_up; + sig_tx_link_up_sync <= sig_tx_link_up; + end generate; + + ACTIVITY_RX <= slv_array_ser(sig_activity_rx_sync); + ACTIVITY_TX <= slv_array_ser(sig_activity_tx_sync); + RX_LINK_UP <= slv_array_ser(sig_rx_link_up_sync); + TX_LINK_UP <= slv_array_ser(sig_tx_link_up_sync); -- ===================================================================== -- QSFP control