From b9500f611fa5a51e6f9d865c39b7396509dd57a5 Mon Sep 17 00:00:00 2001 From: Stepan Friedl Date: Tue, 12 Nov 2024 15:18:17 +0100 Subject: [PATCH 1/5] feat(tx_mac_lite): low latency mode option with PFIFO disabled --- comp/nic/mac_lite/tx_mac_lite/tx_mac_lite.vhd | 84 +++++++++++-------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/comp/nic/mac_lite/tx_mac_lite/tx_mac_lite.vhd b/comp/nic/mac_lite/tx_mac_lite/tx_mac_lite.vhd index e0859434b..9998696ee 100644 --- a/comp/nic/mac_lite/tx_mac_lite/tx_mac_lite.vhd +++ b/comp/nic/mac_lite/tx_mac_lite/tx_mac_lite.vhd @@ -69,6 +69,8 @@ entity TX_MAC_LITE is -- Maximum number of Transactions waiting for space insertion -- Ignored when IPG_GENERATE_EN==false TRANS_FIFO_SIZE : natural := 128; + -- Low-latency mode: do not discard errornous frames + LL_MODE : boolean := false; -- FPGA device name. DEVICE : string := "STRATIX10"; -- Targeted version of Ethernet standart @@ -616,42 +618,52 @@ begin TX_MFB_DST_RDY => sp_mfb_dst_rdy ); else generate - buffer_i : entity work.MFB_PD_ASFIFO - generic map( - ITEMS => DFIFO_ITEMS, - -- More time is needed to calculate CRC. - -- Lack of time is reported as error: "TX_MAC_LITE_CRC_INSERT: CRC32 out of sync!". - WR_PTR_ADD_LATENCY => 16, - REGIONS => MD_REGIONS, - REGION_SIZE => MD_REGION_SIZE, - BLOCK_SIZE => MD_BLOCK_SIZE, - ITEM_WIDTH => MD_ITEM_WIDTH, - DEVICE => DEVICE - ) - port map( - RX_CLK => RX_CLK, - RX_RESET => RX_RESET, - RX_DATA => fd_mfb_data, - RX_SOF_POS => fd_mfb_sof_pos, - RX_EOF_POS => fd_mfb_eof_pos, - RX_SOF => fd_mfb_sof, - RX_EOF => fd_mfb_eof, - RX_SRC_RDY => fd_mfb_src_rdy, - RX_DST_RDY => fd_mfb_dst_rdy, - RX_DISCARD => fd_mfb_discard, - RX_FORCE_DISCARD => '0', - STATUS => open, - - TX_CLK => TX_CLK, - TX_RESET => TX_RESET, - TX_DATA => sp_mfb_data, - TX_SOF_POS => sp_mfb_sof_pos, - TX_EOF_POS => sp_mfb_eof_pos, - TX_SOF => sp_mfb_sof, - TX_EOF => sp_mfb_eof, - TX_SRC_RDY => sp_mfb_src_rdy, - TX_DST_RDY => sp_mfb_dst_rdy - ); + pdfifo_buff_g: if not LL_MODE generate + buffer_i : entity work.MFB_PD_ASFIFO + generic map( + ITEMS => DFIFO_ITEMS, + -- More time is needed to calculate CRC. + -- Lack of time is reported as error: "TX_MAC_LITE_CRC_INSERT: CRC32 out of sync!". + WR_PTR_ADD_LATENCY => 16, + REGIONS => MD_REGIONS, + REGION_SIZE => MD_REGION_SIZE, + BLOCK_SIZE => MD_BLOCK_SIZE, + ITEM_WIDTH => MD_ITEM_WIDTH, + DEVICE => DEVICE + ) + port map( + RX_CLK => RX_CLK, + RX_RESET => RX_RESET, + RX_DATA => fd_mfb_data, + RX_SOF_POS => fd_mfb_sof_pos, + RX_EOF_POS => fd_mfb_eof_pos, + RX_SOF => fd_mfb_sof, + RX_EOF => fd_mfb_eof, + RX_SRC_RDY => fd_mfb_src_rdy, + RX_DST_RDY => fd_mfb_dst_rdy, + RX_DISCARD => fd_mfb_discard, + RX_FORCE_DISCARD => '0', + STATUS => open, + + TX_CLK => TX_CLK, + TX_RESET => TX_RESET, + TX_DATA => sp_mfb_data, + TX_SOF_POS => sp_mfb_sof_pos, + TX_EOF_POS => sp_mfb_eof_pos, + TX_SOF => sp_mfb_sof, + TX_EOF => sp_mfb_eof, + TX_SRC_RDY => sp_mfb_src_rdy, + TX_DST_RDY => sp_mfb_dst_rdy + ); + else generate + sp_mfb_data <= fd_mfb_data; + sp_mfb_sof_pos <= fd_mfb_sof_pos; + sp_mfb_eof_pos <= fd_mfb_eof_pos; + sp_mfb_sof <= fd_mfb_sof; + sp_mfb_eof <= fd_mfb_eof; + fd_mfb_dst_rdy <= sp_mfb_dst_rdy; + sp_mfb_src_rdy <= fd_mfb_src_rdy; + end generate; end generate; -- ========================================================================= From 7273af23873453d1bdf546b5116b8fa0b005286c Mon Sep 17 00:00:00 2001 From: Stepan Friedl Date: Wed, 13 Nov 2024 08:35:31 +0100 Subject: [PATCH 2/5] feat(network_mod_core): separate RX and TX MFB clocks and Eth TX clock sharing --- .../comp/network_mod_core/network_mod_core_ent.vhd | 7 +++++++ 1 file changed, 7 insertions(+) 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 bbbd462fd..8e06c596b 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 @@ -57,6 +57,9 @@ generic( -- ===================================================================== -- Other configuration: -- ===================================================================== + -- Enable sharing of Ethernet TX clock. When true, the CLK_ETH_IN port is used + -- as clock source for all Eth channels + CLK_ETH_IN_ENABLE : boolean := false; TS_DEMO_EN : boolean := false; TX_DMA_CHANNELS : natural := 8; -- GTY TX equalization bits: 59:40 - precursor, @@ -79,6 +82,8 @@ port( -- CLOCK AND RESET -- ===================================================================== CLK_ETH : out std_logic; + CLK_ETH_IN : in std_logic := '0'; + CLK_STABLE : out std_logic_vector(ETH_PORT_CHAN-1 downto 0) := (others => '1'); RESET_ETH : in std_logic; -- ===================================================================== @@ -102,6 +107,7 @@ port( -- ===================================================================== -- RX interface (Packets for transmit to Ethernet, recieved from MFB) -- ===================================================================== + RX_MFB_CLK : out std_logic := '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); @@ -122,6 +128,7 @@ port( -- ===================================================================== -- TX interface (Packets received from Ethernet, for transmit to MFB) -- ===================================================================== + TX_MFB_CLK : out std_logic_vector(ETH_PORT_CHAN-1 downto 0) := (others => '0'); TX_MFB_DATA : out slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*REGION_SIZE*BLOCK_SIZE*ITEM_WIDTH-1 downto 0); TX_MFB_ERROR : out slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS-1 downto 0); TX_MFB_SOF_POS : out slv_array_t (ETH_PORT_CHAN-1 downto 0)(REGIONS*max(1,log2(REGION_SIZE))-1 downto 0); From 1d2c80418083ae64588802cdf342f465f7db017e Mon Sep 17 00:00:00 2001 From: Stepan Friedl Date: Wed, 13 Nov 2024 08:43:29 +0100 Subject: [PATCH 3/5] feat(network_mod): low latency optimalizations Add LL_MODE generic to enable the optimalizations Separate RX and TX MFB clocking between core and logic Add LL_MODE port to enable the low latency mode, which uses separate RX and TX MFB clocking. --- .../network_mod_logic/network_mod_logic.vhd | 13 +++-- .../comp/network_mod_logic/uvm/tbench/dut.sv | 3 +- core/comp/eth/network_mod/network_mod.vhd | 47 +++++++++++++++++-- core/comp/eth/network_mod/network_mod_ent.vhd | 2 + 4 files changed, 55 insertions(+), 10 deletions(-) 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 a75af577a..97c2c73fd 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 @@ -58,6 +58,7 @@ generic( -- ===================================================================== -- OTHER configuration: -- ===================================================================== + LL_MODE : 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 ); @@ -73,7 +74,8 @@ port( -- CLOCK AND RESET -- ===================================================================== CLK_USER : in std_logic; - CLK_CORE : in std_logic; + TX_CLK_CORE : in std_logic; + 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); RESET_CORE : in std_logic_vector(RESET_CORE_WIDTH-1 downto 0); @@ -364,6 +366,7 @@ begin CRC_INSERT_EN => false , IPG_GENERATE_EN => false , USE_DSP_CNT => true , + LL_MODE => LL_MODE , DEVICE => DEVICE ) port map( @@ -389,7 +392,7 @@ begin RX_MFB_SRC_RDY => split_mfb_src_rdy(ch), RX_MFB_DST_RDY => split_mfb_dst_rdy(ch), - TX_CLK => CLK_CORE , + TX_CLK => TX_CLK_CORE , TX_RESET => RESET_CORE(ch*2) , TX_MFB_DATA => TX_CORE_MFB_DATA (ch), TX_MFB_SOF => TX_CORE_MFB_SOF (ch), @@ -455,7 +458,7 @@ begin DEVICE => DEVICE ) port map( - RX_CLK => CLK_CORE , + RX_CLK => RX_CLK_CORE(ch) , RX_RESET => RESET_CORE(ch*2+1), -- todo TX_CLK => CLK_USER , TX_RESET => RESET_USER(0), @@ -531,8 +534,8 @@ begin MFB_ITEM_WIDTH => ITEM_WIDTH , INPUT_FIFO_SIZE => 8 , RX_PAYLOAD_EN => (others => true), - IN_PIPE_EN => true , - OUT_PIPE_EN => true , + IN_PIPE_EN => not LL_MODE , + OUT_PIPE_EN => not LL_MODE , DEVICE => DEVICE ) port map( 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 7fc24debc..51e4585c8 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,8 @@ module DUT ( .BOARD (BOARD) ) VHDL_DUT_U ( .CLK_USER (CLK_USER), - .CLK_CORE (CLK_CORE), + .TX_CLK_CORE (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 2c391ecad..c3c70ad6f 100644 --- a/core/comp/eth/network_mod/network_mod.vhd +++ b/core/comp/eth/network_mod/network_mod.vhd @@ -110,9 +110,13 @@ architecture FULL of NETWORK_MOD is -- ========================================================================= -- SIGNALS -- ========================================================================= - signal repl_rst_arr : slv_array_t(ETH_PORTS-1 downto 0)(RESET_REPLICAS-1 downto 0); + signal repl_rst_arr : slv_array_t(ETH_PORTS-1 downto 0)(RESET_REPLICAS-1 downto 0); + signal logic_rst_arr : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS*2-1 downto 0); + signal clk_eth_stable : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); -- Interior signals, Network Module Core -> Network Module Logic + signal logic_rx_clk : slv_array_t (ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal rx_mfb_clk : slv_array_t (ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); signal rx_mfb_data_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(MFB_WIDTH_CORE-1 downto 0); signal rx_mfb_sof_pos_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(MFB_SOFP_WIDTH_CORE-1 downto 0); signal rx_mfb_eof_pos_i : slv_array_2d_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(MFB_EOFP_WIDTH_CORE-1 downto 0); @@ -147,6 +151,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 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); @@ -218,6 +224,20 @@ begin ASYNC_RST => RESET_ETH (p), OUT_RST => repl_rst_arr(p) ); + + chan_reset_g: for ch in ETH_CHANNELS-1 downto 0 generate + network_mod_logic_reset_i : entity work.ASYNC_RESET + generic map ( + TWO_REG => false, + OUT_REG => true , + REPLICAS => 2 + ) + port map ( + CLK => logic_rx_clk(p)(ch), + ASYNC_RST => RESET_ETH (p) or (not clk_eth_stable(p)(ch)), + OUT_RST => logic_rst_arr(p)(ch*2+1 downto ch*2) + ); + end generate; end generate; -- ========================================================================= @@ -353,17 +373,19 @@ begin MI_DATA_WIDTH => MI_DATA_WIDTH , MI_ADDR_WIDTH => MI_ADDR_WIDTH , -- Other + LL_MODE => LL_MODE , RESET_USER_WIDTH => RESET_WIDTH , - RESET_CORE_WIDTH => RESET_REPLICAS-2, + RESET_CORE_WIDTH => logic_rst_arr(p)'length, RESIZE_BUFFER => RESIZE_BUFFER , DEVICE => DEVICE , BOARD => BOARD ) port map( CLK_USER => CLK_USER, - CLK_CORE => CLK_ETH(p), + TX_CLK_CORE => logic_tx_clk(p), + RX_CLK_CORE => logic_rx_clk(p), RESET_USER => RESET_USER, - RESET_CORE => repl_rst_arr(p)(RESET_REPLICAS-1 downto 2), + RESET_CORE => logic_rst_arr(p), -- Control/status interface ACTIVITY_RX => sig_activity_rx(p), @@ -441,6 +463,7 @@ begin ITEM_WIDTH => ITEM_WIDTH , MI_DATA_WIDTH_PHY => MI_DATA_WIDTH_PHY, MI_ADDR_WIDTH_PHY => MI_ADDR_WIDTH_PHY, + CLK_ETH_IN_ENABLE => LL_MODE , TS_DEMO_EN => TS_DEMO_EN , TX_DMA_CHANNELS => TX_DMA_CHANNELS , LANE_RX_POLARITY => LANE_RX_POLARITY(p*LANES+LANES-1 downto p*LANES), @@ -452,6 +475,8 @@ begin port map ( -- clock and reset CLK_ETH => CLK_ETH(p), + CLK_ETH_IN => CLK_ETH(0), + CLK_STABLE => clk_eth_stable(p), RESET_ETH => repl_rst_arr(p)(0), -- ETH serial interface QSFP_REFCLK_P => ETH_REFCLK_P(p), @@ -461,6 +486,7 @@ begin QSFP_TX_P => ETH_TX_P(p*LANES+LANES-1 downto p*LANES), QSFP_TX_N => ETH_TX_N(p*LANES+LANES-1 downto p*LANES), -- RX interface (packets for transmit to Ethernet, recieved from TX MAC lite) + RX_MFB_CLK => tx_mfb_clk (p), RX_MFB_DATA => tx_mfb_data_i (p), RX_MFB_SOF_POS => tx_mfb_sof_pos_i(p), RX_MFB_EOF_POS => tx_mfb_eof_pos_i(p), @@ -477,6 +503,7 @@ begin TSU_TS_DV => synced_ts_dv(p), -- TX interface (packets received from Ethernet, transmit to RX MAC lite) + TX_MFB_CLK => rx_mfb_clk (p), TX_MFB_DATA => rx_mfb_data_i (p), TX_MFB_SOF_POS => rx_mfb_sof_pos_i(p), TX_MFB_EOF_POS => rx_mfb_eof_pos_i(p), @@ -507,9 +534,21 @@ begin MISC_NET2TOP => MISC_NET2TOP(p) ); + -- ===================================================================== + -- MFB clocking based on LL mode generic + -- ===================================================================== + mfb_clk_g: if LL_MODE 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_rx_clk(p) <= (others => CLK_ETH(p)); + end generate; + -- ===================================================================== -- TIMESTAMP ASFIFOX -- ===================================================================== + -- TBD: in LL_MODE, synchronize timestamps per channel / logic_rx_clk ts_asfifox_i : entity work.ASFIFOX generic map( DATA_WIDTH => 64 , diff --git a/core/comp/eth/network_mod/network_mod_ent.vhd b/core/comp/eth/network_mod/network_mod_ent.vhd index 888e52862..d59a34dc7 100644 --- a/core/comp/eth/network_mod/network_mod_ent.vhd +++ b/core/comp/eth/network_mod/network_mod_ent.vhd @@ -81,6 +81,8 @@ generic( -- WARNING: works only for a single-channel (and single-Region) designs with E-Tile (Intel)! TS_DEMO_EN : boolean := false; TX_DMA_CHANNELS : natural := 16; + -- Enable low latency optimalization + LL_MODE : boolean := false; -- Ethernet lanes polarity LANE_RX_POLARITY : std_logic_vector(ETH_PORTS*LANES-1 downto 0) := (others => '0'); LANE_TX_POLARITY : std_logic_vector(ETH_PORTS*LANES-1 downto 0) := (others => '0'); From 9427b6792f92eb28a483e6518577557a327d66fc Mon Sep 17 00:00:00 2001 From: Stepan Friedl Date: Wed, 13 Nov 2024 14:26:02 +0100 Subject: [PATCH 4/5] feat(network_mod): per channel timestamps synchronization for LL mode and TS logic cleanup Add TS_SYNC component to make the code cleaner --- core/comp/eth/network_mod/Modules.tcl | 1 + .../network_mod_logic/network_mod_logic.vhd | 8 +- core/comp/eth/network_mod/network_mod.vhd | 108 +++++------------- core/comp/eth/network_mod/ts_sync.vhd | 107 +++++++++++++++++ 4 files changed, 142 insertions(+), 82 deletions(-) create mode 100644 core/comp/eth/network_mod/ts_sync.vhd diff --git a/core/comp/eth/network_mod/Modules.tcl b/core/comp/eth/network_mod/Modules.tcl index 8a0832857..109676206 100644 --- a/core/comp/eth/network_mod/Modules.tcl +++ b/core/comp/eth/network_mod/Modules.tcl @@ -38,6 +38,7 @@ if {$ARCHGRP == "EMPTY"} { # Source files for implemented component lappend MOD "$ENTITY_BASE/qsfp_ctrl.vhd" + lappend MOD "$ENTITY_BASE/ts_sync.vhd" lappend MOD "$ENTITY_BASE/network_mod.vhd" lappend MOD "$ENTITY_BASE/DevTree.tcl" } 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 97c2c73fd..9854248ed 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 @@ -151,8 +151,8 @@ port( -- ===================================================================== -- TSU interface -- ===================================================================== - TSU_TS_NS : in std_logic_vector(64-1 downto 0); - TSU_TS_DV : in std_logic + TSU_TS_NS : in slv_array_t(ETH_PORT_CHAN-1 downto 0)(64-1 downto 0); + TSU_TS_DV : in std_logic_vector(ETH_PORT_CHAN-1 downto 0) ); end entity; @@ -473,8 +473,8 @@ begin ADAPTER_LINK_UP => RX_LINK_UP(ch), - TSU_TS_NS => TSU_TS_NS, - TSU_TS_DV => TSU_TS_DV, + TSU_TS_NS => TSU_TS_NS(ch), + TSU_TS_DV => TSU_TS_DV(ch), TX_MFB_DATA => merg_mfb_data (ch), TX_MFB_SOF => merg_mfb_sof (ch), diff --git a/core/comp/eth/network_mod/network_mod.vhd b/core/comp/eth/network_mod/network_mod.vhd index c3c70ad6f..7354fbf75 100644 --- a/core/comp/eth/network_mod/network_mod.vhd +++ b/core/comp/eth/network_mod/network_mod.vhd @@ -84,6 +84,7 @@ architecture FULL of NETWORK_MOD is constant RESIZE_BUFFER : boolean := (ETH_CORE_ARCH = "F_TILE" or (ETH_CORE_ARCH = "E_TILE" and ETH_CHANNELS = 4)); constant TS_TIMEOUT_W : natural := 3; -- last TS is unvalided after 4 cycles + constant TS_REPLICAS : natural := tsel(LL_MODE, ETH_CHANNELS, 1); -- ========================================================================= -- FUNCTIONS @@ -188,12 +189,8 @@ architecture FULL of NETWORK_MOD is signal mi_split_drdy_phy : std_logic_vector(MI_ADDR_BASES_PHY-1 downto 0); -- TS signals - signal asfifox_ts_dv_n : std_logic_vector(ETH_PORTS-1 downto 0); - signal asfifox_ts_ns : slv_array_t (ETH_PORTS-1 downto 0)(64-1 downto 0); - signal asfifox_ts_timeout : u_array_t(ETH_PORTS-1 downto 0)(TS_TIMEOUT_W-1 downto 0); - signal asfifox_ts_last_vld : std_logic_vector(ETH_PORTS-1 downto 0); - signal synced_ts_dv : std_logic_vector(ETH_PORTS-1 downto 0); - signal synced_ts_ns : slv_array_t (ETH_PORTS-1 downto 0)(64-1 downto 0); + signal synced_ts_dv : slv_array_t(ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0); + signal synced_ts_ns : slv_array_2d_t (ETH_PORTS-1 downto 0)(ETH_CHANNELS-1 downto 0)(64-1 downto 0); -- Demo signals signal eth_tx_mvb_channel_arr : slv_array_t (ETH_PORTS-1 downto 0)(REGIONS*max(1,log2(TX_DMA_CHANNELS))-1 downto 0); @@ -499,8 +496,8 @@ begin RX_MVB_TIMESTAMP => mvb_ts (p), RX_MVB_VLD => mvb_vld(p), - TSU_TS_NS => synced_ts_ns(p), - TSU_TS_DV => synced_ts_dv(p), + TSU_TS_NS => synced_ts_ns(p)(0), + TSU_TS_DV => synced_ts_dv(p)(0), -- TX interface (packets received from Ethernet, transmit to RX MAC lite) TX_MFB_CLK => rx_mfb_clk (p), @@ -546,78 +543,33 @@ begin end generate; -- ===================================================================== - -- TIMESTAMP ASFIFOX + -- TIMESTAMP synchronization -- ===================================================================== - -- TBD: in LL_MODE, synchronize timestamps per channel / logic_rx_clk - ts_asfifox_i : entity work.ASFIFOX - generic map( - DATA_WIDTH => 64 , - ITEMS => 32 , - RAM_TYPE => "LUT" , - FWFT_MODE => true , - OUTPUT_REG => true , - DEVICE => DEVICE - ) - port map ( - WR_CLK => CLK_ETH (0) , - WR_RST => repl_rst_arr(0)(1), - WR_DATA => TSU_TS_NS , - WR_EN => TSU_TS_DV , - WR_FULL => open , - WR_AFULL => open , - WR_STATUS => open , - - RD_CLK => CLK_ETH (p) , - RD_RST => repl_rst_arr (p)(1), - RD_DATA => asfifox_ts_ns (p) , - RD_EN => '1' , - RD_EMPTY => asfifox_ts_dv_n(p) , - RD_AEMPTY => open , - RD_STATUS => open - ); + ts_chan_sync_g: for ch in 0 to TS_REPLICAS-1 generate + + ts_sync_i: entity work.TS_SYNC + generic map ( + DEVICE => DEVICE, + TS_TIMEOUT_W => TS_TIMEOUT_W + ) + port map ( + TSU_RST => repl_rst_arr(0)(1), + TSU_CLK => CLK_ETH (0) , + TSU_TS_NS => TSU_TS_NS , + TSU_TS_DV => TSU_TS_DV , + -- + SYNC_RST => logic_rst_arr(p)(ch*2), + SYNC_CLK => logic_rx_clk(p)(ch) , + SYNCED_TS_NS => synced_ts_ns(p)(ch) , + SYNCED_TS_DV => synced_ts_dv(p)(ch) + ); + end generate; - process(CLK_ETH) - begin - if (rising_edge(CLK_ETH(p))) then - if (asfifox_ts_dv_n(p) = '1' and asfifox_ts_timeout(p)(TS_TIMEOUT_W-1) = '0') then - asfifox_ts_timeout(p) <= asfifox_ts_timeout(p) + 1; - end if; - if (repl_rst_arr(p)(1) = '1' or asfifox_ts_dv_n(p) = '0') then - asfifox_ts_timeout(p) <= (others => '0'); - end if; - end if; - end process; - - process(CLK_ETH) - begin - if (rising_edge(CLK_ETH(p))) then - if (asfifox_ts_dv_n(p) = '0') then - asfifox_ts_last_vld(p) <= '1'; - end if; - if (repl_rst_arr(p)(1) = '1') then - asfifox_ts_last_vld(p) <= '0'; - end if; - end if; - end process; - - -- Synced TS is valid if the value is current or if the value is a few - -- clock cycles old. This provides filtering for occasional flushing of - -- the asynchronous FIFO. - process(CLK_ETH) - begin - if (rising_edge(CLK_ETH(p))) then - if (asfifox_ts_dv_n(p) = '0') then - synced_ts_ns(p) <= asfifox_ts_ns(p); - end if; - - synced_ts_dv(p) <= (not asfifox_ts_dv_n(p)) or - (asfifox_ts_last_vld(p) and not asfifox_ts_timeout(p)(TS_TIMEOUT_W-1)); - - if (repl_rst_arr(p)(1) = '1') then - synced_ts_dv(p) <= '0'; - end if; - end if; - end process; + -- When the single TS_SYNC is generated, replicate channel 0 timestaps to all other channels + ts_repl_g: for ch in TS_REPLICAS+1 to ETH_CHANNELS generate + synced_ts_ns(p)(ch-1) <= synced_ts_ns(p)(0); + synced_ts_dv(p)(ch-1) <= synced_ts_dv(p)(0); + end generate; -- ETH clock is used as TSU main clock TSU_CLK <= CLK_ETH (0) ; diff --git a/core/comp/eth/network_mod/ts_sync.vhd b/core/comp/eth/network_mod/ts_sync.vhd new file mode 100644 index 000000000..4c44ecae4 --- /dev/null +++ b/core/comp/eth/network_mod/ts_sync.vhd @@ -0,0 +1,107 @@ +-- ts_sync.vhd: Timestamps synchronizer for the Network_mod +-- Copyright (C) 2024 CESNET z. s. p. o. +-- Author(s): Stepan Friedl +-- SPDX-License-Identifier: BSD-3-Clause + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity TS_SYNC is +generic ( + DEVICE : string := "STRATIX10"; -- AGILEX, STRATIX10, ULTRASCALE + TS_TIMEOUT_W : natural := 3 +); +port ( + TSU_RST : in std_logic; + TSU_CLK : in std_logic; + TSU_TS_NS : in std_logic_vector(63 downto 0); + TSU_TS_DV : in std_logic; + -- + SYNC_RST : in std_logic; + SYNC_CLK : in std_logic; + SYNCED_TS_NS : out std_logic_vector(63 downto 0); + SYNCED_TS_DV : out std_logic + ); +end entity; + +architecture behavioral of TS_SYNC is + + signal asfifox_ts_ns : std_logic_vector(63 downto 0); + signal asfifox_ts_dv_n : std_logic; + signal asfifox_ts_timeout : unsigned(TS_TIMEOUT_W-1 downto 0); + signal asfifox_ts_last_vld : std_logic; + +begin + + ts_asfifox_i : entity work.ASFIFOX + generic map( + DATA_WIDTH => 64 , + ITEMS => 32 , + RAM_TYPE => "LUT" , + FWFT_MODE => true , + OUTPUT_REG => true , + DEVICE => DEVICE + ) + port map ( + WR_CLK => TSU_CLK , + WR_RST => TSU_RST , + WR_DATA => TSU_TS_NS , + WR_EN => TSU_TS_DV , + WR_FULL => open , + WR_AFULL => open , + WR_STATUS => open , + + RD_CLK => SYNC_CLK , + RD_RST => SYNC_RST , + RD_DATA => asfifox_ts_ns , + RD_EN => '1' , + RD_EMPTY => asfifox_ts_dv_n, + RD_AEMPTY => open , + RD_STATUS => open + ); + + process(SYNC_CLK) + begin + if (rising_edge(SYNC_CLK)) then + if (asfifox_ts_dv_n = '1' and asfifox_ts_timeout(TS_TIMEOUT_W-1) = '0') then + asfifox_ts_timeout <= asfifox_ts_timeout + 1; + end if; + if (SYNC_RST = '1' or asfifox_ts_dv_n = '0') then + asfifox_ts_timeout <= (others => '0'); + end if; + end if; + end process; + + process(SYNC_CLK) + begin + if (rising_edge(SYNC_CLK)) then + if (asfifox_ts_dv_n = '0') then + asfifox_ts_last_vld <= '1'; + end if; + if (SYNC_RST = '1') then + asfifox_ts_last_vld <= '0'; + end if; + end if; + end process; + + -- Synced TS is valid if the value is current or if the value is a few + -- clock cycles old. This provides filtering for occasional flushing of + -- the asynchronous FIFO. + process(SYNC_CLK) + begin + if (rising_edge(SYNC_CLK)) then + if (asfifox_ts_dv_n = '0') then + SYNCED_TS_NS <= asfifox_ts_ns; + end if; + + SYNCED_TS_DV <= (not asfifox_ts_dv_n) or + (asfifox_ts_last_vld and not asfifox_ts_timeout(TS_TIMEOUT_W-1)); + + if (SYNC_RST = '1') then + SYNCED_TS_DV <= '0'; + end if; + end if; + end process; + +end architecture; From e51600215bdf73e4b8a602a3f67b7ccc220c73f5 Mon Sep 17 00:00:00 2001 From: Stepan Friedl Date: Wed, 13 Nov 2024 14:40:16 +0100 Subject: [PATCH 5/5] feat: add LL_MODE constant into netcope_const.vhd --- core/config/core_conf.tcl | 3 +++ core/config/core_const.tcl | 2 ++ core/top/fpga_common.vhd | 1 + 3 files changed, 6 insertions(+) diff --git a/core/config/core_conf.tcl b/core/config/core_conf.tcl index 964f81088..c422d4f9e 100644 --- a/core/config/core_conf.tcl +++ b/core/config/core_conf.tcl @@ -151,3 +151,6 @@ set PCIE_CTRL_DEBUG_ENABLE false # Enables Timstamp limit demo/testing logic set TS_DEMO_EN false + +# Enable Low-latency optimalizations +set LL_MODE false diff --git a/core/config/core_const.tcl b/core/config/core_const.tcl index 1bbfcb597..b196afd47 100755 --- a/core/config/core_const.tcl +++ b/core/config/core_const.tcl @@ -185,3 +185,5 @@ VhdlPkgBool PCIE_CORE_DEBUG_ENABLE $PCIE_CORE_DEBUG_ENABLE VhdlPkgBool PCIE_CTRL_DEBUG_ENABLE $PCIE_CTRL_DEBUG_ENABLE VhdlPkgBool TS_DEMO_EN $TS_DEMO_EN +VhdlPkgBool LL_MODE $LL_MODE + diff --git a/core/top/fpga_common.vhd b/core/top/fpga_common.vhd index 5b188d058..13e745c94 100644 --- a/core/top/fpga_common.vhd +++ b/core/top/fpga_common.vhd @@ -1539,6 +1539,7 @@ begin MI_DATA_WIDTH_PHY => 32 , MI_ADDR_WIDTH_PHY => 32 , + LL_MODE => LL_MODE , TS_DEMO_EN => TS_DEMO_EN , TX_DMA_CHANNELS => DMA_TX_CHANNELS,