Skip to content

Commit

Permalink
Merge branch 'xkosar02-usp-10g-25g-mergefest' into 'devel'
Browse files Browse the repository at this point in the history
Add support for 10G/25G MAC for ULTRASCALE+ FPGA

See merge request ndk/ndk-fpga!122
  • Loading branch information
jakubcabal committed Dec 11, 2024
2 parents 1ca1296 + 4ee1aaf commit d441da9
Show file tree
Hide file tree
Showing 10 changed files with 680 additions and 30 deletions.
16 changes: 14 additions & 2 deletions apps/minimal/build/fb2cghh/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
18 changes: 11 additions & 7 deletions core/comp/eth/network_mod/Modules.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand Down
33 changes: 33 additions & 0 deletions core/comp/eth/network_mod/comp/network_mod_core/Modules.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
--
-- 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;
Loading

0 comments on commit d441da9

Please sign in to comment.