Skip to content

Commit

Permalink
feat(network_mod): per channel timestamps synchronization for LL mode…
Browse files Browse the repository at this point in the history
… and TS logic cleanup

Add TS_SYNC component to make the code cleaner
  • Loading branch information
Stepan Friedl committed Nov 14, 2024
1 parent 1d2c804 commit 9427b67
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 82 deletions.
1 change: 1 addition & 0 deletions core/comp/eth/network_mod/Modules.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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),
Expand Down
108 changes: 30 additions & 78 deletions core/comp/eth/network_mod/network_mod.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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) ;
Expand Down
107 changes: 107 additions & 0 deletions core/comp/eth/network_mod/ts_sync.vhd
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
-- 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;

0 comments on commit 9427b67

Please sign in to comment.