From 934252332e2d5caa09c381ccb3edd6034ede9f0c Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Fri, 12 Aug 2022 14:09:29 +0200
Subject: [PATCH] updated disturb design files

---
 .../src/vhdl/disturb_beamformer_local.vhd     |   2 +-
 .../src/vhdl/disturb_beamformer_output.vhd    |  42 ++-
 .../vhdl/disturb_crosslets_subband_select.vhd |  52 +++-
 .../disturb/src/vhdl/disturb_pkg.vhd          | 137 +++++-----
 .../disturb/src/vhdl/disturb_station.vhd      | 241 +++++++++---------
 .../src/vhdl/disturb_statistics_offload.vhd   |  91 ++++---
 .../node_disturb_adc_input_and_timing.vhd     |  82 +++---
 .../src/vhdl/node_disturb_beamformer.vhd      |   7 +-
 .../src/vhdl/node_disturb_correlator.vhd      |  41 ++-
 .../src/vhdl/node_disturb_filterbank.vhd      |   9 +-
 .../node_disturb_oversampled_filterbank.vhd   |   9 +-
 .../sdp/src/vhdl/sdp_beamformer_local.vhd     |   2 +-
 12 files changed, 418 insertions(+), 297 deletions(-)

diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_local.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_local.vhd
index 01d56c1392..443b5b0861 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_local.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_local.vhd
@@ -59,7 +59,7 @@ END disturb_beamformer_local;
 ARCHITECTURE str OF disturb_beamformer_local IS
   
   CONSTANT c_complex_adder_latency : NATURAL := ceil_log2(c_disturb_S_pn);
-  CONSTANT c_bf_weights_latency    : NATURAL := 5;
+  CONSTANT c_bf_weights_latency    : NATURAL := 5; -- 3 for complex multiplier + 2 RAM latency
   CONSTANT c_total_latency         : NATURAL := 3 + c_bf_weights_latency + c_complex_adder_latency; 
 
   CONSTANT c_complex_adder_sum_w : NATURAL := c_disturb_W_bf_product + ceil_log2(c_disturb_S_pn); 
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_output.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_output.vhd
index a75cd12734..743d976cf6 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_output.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_beamformer_output.vhd
@@ -78,20 +78,22 @@ ARCHITECTURE str OF disturb_beamformer_output IS
   CONSTANT c_data_w                 : NATURAL := c_nof_complex*c_disturb_W_beamlet; --16b
   CONSTANT c_beamlet_index          : NATURAL := g_beamset_id * c_disturb_S_sub_bf;  -- call beamset 'id' and beamlet 'index'
 
-  -- c_fifo_fill must be the exact size of a packet such that no packet gets stuck in the FIFO or the FIFO gets read out too soon.
+  -- c_fifo_fill must be the exact size of a payload such that no payload gets stuck in the FIFO or the FIFO gets read out too soon.
   -- For packets of variable length, dp_fifo_fill_eop must be used. In this case we can use the standard fill fifo.
-  CONSTANT c_fifo_fill              : NATURAL := c_disturb_cep_nof_blocks_per_packet * c_disturb_cep_nof_beamlets_per_block / 2; -- Size of packet: 2 beamlets (dual pol) fit in 1 64bit longword 
+  CONSTANT c_fifo_fill              : NATURAL := c_disturb_cep_payload_nof_longwords; 
   CONSTANT c_fifo_size              : NATURAL := c_fifo_fill*2; -- Make fifo size large enough for adding header and muxing beamsets.
  
-  SIGNAL snk_in_concat           : t_dp_sosi;
-  SIGNAL dp_packet_merge_src_out : t_dp_sosi;
-  SIGNAL dp_repack_data_src_out  : t_dp_sosi;
-  SIGNAL dp_fifo_sc_src_out      : t_dp_sosi;
-  SIGNAL dp_fifo_sc_src_in       : t_dp_siso;
-  SIGNAL dp_offload_tx_src_out   : t_dp_sosi;
-  SIGNAL dp_offload_tx_src_in    : t_dp_siso;
-  SIGNAL ip_checksum_src_out     : t_dp_sosi;
-  SIGNAL ip_checksum_src_in      : t_dp_siso;
+  SIGNAL snk_in_concat             : t_dp_sosi;
+  SIGNAL dp_packet_merge_src_out   : t_dp_sosi;
+  SIGNAL dp_repack_data_src_out    : t_dp_sosi;
+  SIGNAL dp_fifo_sc_src_out        : t_dp_sosi;
+  SIGNAL dp_fifo_sc_src_in         : t_dp_siso;
+  SIGNAL dp_offload_tx_src_out     : t_dp_sosi;
+  SIGNAL dp_offload_tx_src_in      : t_dp_siso;
+  SIGNAL ip_checksum_src_out       : t_dp_sosi;
+  SIGNAL ip_checksum_src_in        : t_dp_siso;
+  SIGNAL dp_pipeline_ready_src_out : t_dp_sosi;
+  SIGNAL dp_pipeline_ready_src_in  : t_dp_siso;
 
   SIGNAL common_fifo_rd_req : STD_LOGIC;
   SIGNAL payload_err        : STD_LOGIC_VECTOR(0 DOWNTO 0);
@@ -268,6 +270,20 @@ BEGIN
     src_in  => ip_checksum_src_in
   );
 
+  -------------------------------------------------------------------------------
+  -- dp_pipeline_ready to ease timing closure
+  -------------------------------------------------------------------------------
+  u_dp_pipeline_ready : ENTITY dp_lib.dp_pipeline_ready
+  PORT MAP(
+    rst => dp_rst,
+    clk => dp_clk,
+
+    snk_out => ip_checksum_src_in,
+    snk_in  => ip_checksum_src_out,
+    src_in  => dp_pipeline_ready_src_in,
+    src_out => dp_pipeline_ready_src_out
+  );
+
   -------------------------------------------------------------------------------
   -- mms_dp_xonoff
   ------------------------------------------------------------------------------- 
@@ -288,8 +304,8 @@ BEGIN
     dp_clk      => dp_clk, 
 
     -- ST sinks
-    snk_out_arr(0) => ip_checksum_src_in,  
-    snk_in_arr(0)  => ip_checksum_src_out, 
+    snk_out_arr(0) => dp_pipeline_ready_src_in,  
+    snk_in_arr(0)  => dp_pipeline_ready_src_out, 
     -- ST source
     src_in_arr(0)  => src_in, 
     src_out_arr(0) => out_sosi
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_crosslets_subband_select.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_crosslets_subband_select.vhd
index ba5fc6de26..3875533995 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_crosslets_subband_select.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_crosslets_subband_select.vhd
@@ -24,8 +24,18 @@
 -- Purpose: 
 -- Select subbands from incoming blocks
 -- Description:
--- The Crosslet subband select selects N_crosslets from each incoming block. Per 
--- crosslet there are S_pn = 12 subbands, one from each signal input of the PN.
+-- * The Crosslet subband select selects N_crosslets from each incoming block.
+--   Per crosslet there are S_pn = 12 subbands, one from each signal input of
+--   the PN.
+-- * The cur_crosslets_info is valid at the out_sosi.sync and for the entire
+--   sync interval. The cur_crosslets_info identifies the crosslets that are
+--   being calculated during this out_sosi.sync interval.
+--   The prev_crosslets_info identifies the crosslets that were calculated
+--   during the previous out_sosi.sync interval, so the XST for those crosslets
+--   are then pending to be offloaded.
+-- * The new_interval is active before the first out_sosi.sync and inactive
+--   before the next out_sosi.sync, so it can be used to know when a new
+--   sequence of out_sosi.sync intervals starts.
 -- Remark:
 -- . See L5 SDPFW Design Document: Subband Correlator
 --   Link: https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L5+SDPFW+Design+Document%3A+Subband+Correlator
@@ -51,6 +61,8 @@ ENTITY disturb_crosslets_subband_select IS
     in_sosi_arr   : IN  t_dp_sosi_arr(c_disturb_P_pfb-1 DOWNTO 0);
     out_sosi      : OUT t_dp_sosi;
 
+    new_interval  : OUT STD_LOGIC;
+
     mm_rst        : IN  STD_LOGIC;
     mm_clk        : IN  STD_LOGIC;
 
@@ -59,8 +71,9 @@ ENTITY disturb_crosslets_subband_select IS
  
     reg_bsn_sync_scheduler_xsub_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
     reg_bsn_sync_scheduler_xsub_miso : OUT t_mem_miso := c_mem_miso_rst;
-       
-    out_crosslets_info : OUT STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0)
+
+    cur_crosslets_info_rec  : OUT t_disturb_crosslets_info;
+    prev_crosslets_info_rec : OUT t_disturb_crosslets_info
   );
 END disturb_crosslets_subband_select;
 
@@ -91,7 +104,7 @@ ARCHITECTURE str OF disturb_crosslets_subband_select IS
   SIGNAL r     : t_crosslets_control_reg;
   SIGNAL nxt_r : t_crosslets_control_reg;
 
-  SIGNAL start_trigger : STD_LOGIC := '0';
+  SIGNAL start_trigger   : STD_LOGIC := '0';
 
   SIGNAL col_select_mosi : t_mem_mosi := c_mem_mosi_rst;
   SIGNAL col_select_miso : t_mem_miso := c_mem_miso_rst;
@@ -104,13 +117,13 @@ ARCHITECTURE str OF disturb_crosslets_subband_select IS
   SIGNAL crosslets_info_reg    : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL crosslets_info_reg_in : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL active_crosslets_info : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL i_out_crosslets_info  : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL cur_crosslets_info    : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL prev_crosslets_info   : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
 
   -- Map crosslets_info slv to record for easier view in Wave window
   SIGNAL crosslets_info_rec        : t_disturb_crosslets_info;
   SIGNAL crosslets_info_rec_inout  : t_disturb_crosslets_info;
   SIGNAL active_crosslets_info_rec : t_disturb_crosslets_info;
-  SIGNAL out_crosslets_info_rec    : t_disturb_crosslets_info;
 
 BEGIN
 
@@ -135,7 +148,8 @@ BEGIN
     in_sosi_arr  => in_sosi_arr,
     out_sosi_arr => dp_bsn_sync_scheduler_src_out_arr,
 
-    out_start => start_trigger
+    out_start => start_trigger,
+    out_start_interval => new_interval
   );
 
   ---------------------------------------------------------------
@@ -160,10 +174,10 @@ BEGIN
     out_reg  => crosslets_info_reg
   );
 
-  p_set_unused_crosslets : PROCESS(i_out_crosslets_info)
+  p_set_unused_crosslets : PROCESS(cur_crosslets_info)
   BEGIN
     -- MM readback the currently active crosslets info, instead of the initial MM written crosslets_info_reg
-    crosslets_info_reg_in <= i_out_crosslets_info; -- Always use crosslets info 6:0 + step(@ index 15)
+    crosslets_info_reg_in <= cur_crosslets_info; -- Always use crosslets info 6:0 + step(@ index 15)
     -- Set crosslets 14:7 to -1
     FOR I IN g_N_crosslets TO c_disturb_mm_reg_crosslets_info.nof_dat - 2 LOOP
       crosslets_info_reg_in((I+1) * c_disturb_crosslets_index_w - 1 DOWNTO I * c_disturb_crosslets_index_w ) <= TO_SVEC(-1, c_disturb_crosslets_index_w);
@@ -333,7 +347,19 @@ BEGIN
     out_dat => i_out_crosslets_info
   );
 
-  out_crosslets_info <= i_out_crosslets_info;
+  u_common_pipeline_prev : ENTITY common_lib.common_pipeline
+  GENERIC MAP(
+    g_pipeline  => c_crosslets_info_dly,
+    g_in_dat_w  => c_disturb_crosslets_info_reg_w,
+    g_out_dat_w => c_disturb_crosslets_info_reg_w
+  )
+  PORT MAP(
+    rst => dp_rst,
+    clk => dp_clk,
+    in_en => row_sosi.sync,
+    in_dat => cur_crosslets_info,
+    out_dat => prev_crosslets_info
+  );
 
   ---------------------------------------------------------------
   -- Out sosi pipeline
@@ -355,6 +381,8 @@ BEGIN
   crosslets_info_rec        <= func_disturb_map_crosslets_info(crosslets_info_reg);
   crosslets_info_rec_inout  <= func_disturb_map_crosslets_info(crosslets_info_reg_in);
   active_crosslets_info_rec <= func_disturb_map_crosslets_info(active_crosslets_info);
-  out_crosslets_info_rec    <= func_disturb_map_crosslets_info(i_out_crosslets_info);
+
+  cur_crosslets_info_rec    <= func_disturb_map_crosslets_info(cur_crosslets_info);
+  prev_crosslets_info_rec   <= func_disturb_map_crosslets_info(prev_crosslets_info);
 
 END str;
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_pkg.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_pkg.vhd
index a1f39346e5..ca9e7bc573 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_pkg.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_pkg.vhd
@@ -23,12 +23,11 @@
 -- Author: R. van der Walle, E. Kooistra
 -- Purpose: 
 -- . This package contains disturb specific constants.
--- Description:
--- Remark:
--- . See Document: L3 SDP Decision: SDP Parameter definitions.
---   https://support.astron.nl/confluence/display/L2M/L3+SDP+Decision%3A+SDP+Parameter+definitions
+-- Description: See [1]
+-- References:
+-- . [1] https://support.astron.nl/confluence/display/L2M/L3+SDP+Decision%3A+SDP+Parameter+definitions
 -------------------------------------------------------------------------------
-LIBRARY IEEE, common_lib, rTwoSDF_lib, fft_lib, filter_lib, wpfb_lib, diag_lib;
+LIBRARY IEEE, common_lib, rTwoSDF_lib, fft_lib, filter_lib, wpfb_lib, diag_lib, tech_jesd204b_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.math_real.ALL;
 USE common_lib.common_pkg.ALL;
@@ -40,6 +39,7 @@ USE rTwoSDF_lib.rTwoSDFPkg.ALL;
 USE fft_lib.fft_pkg.ALL; 
 USE filter_lib.fil_pkg.ALL; 
 USE wpfb_lib.wpfb_pkg.ALL;
+USE tech_jesd204b_lib.tech_jesd204b_pkg.ALL;
 
 PACKAGE disturb_pkg is
   -------------------------------------------------
@@ -116,26 +116,31 @@ PACKAGE disturb_pkg is
   CONSTANT c_disturb_N_ring_nof_mac10g         : NATURAL := 3; -- for disturb_station_xsub_ring design.
 
   -- Derived constants
-  CONSTANT c_disturb_FS_adc             : NATURAL := 2**(c_disturb_W_adc - 1); -- full scale FS corresponds to amplitude 1.0
-  CONSTANT c_disturb_wg_ampl_lsb          : REAL := c_diag_wg_ampl_unit / REAL(c_disturb_FS_adc);  -- WG amplitude in number of LSbit resolution steps
-  CONSTANT c_disturb_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/REAL(c_disturb_N_fft);  -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus
-  CONSTANT c_disturb_N_clk_per_sync     : NATURAL := c_disturb_f_adc_MHz*10**6;  -- Default 200M clock cycles per second
-  CONSTANT c_disturb_N_clk_sync_timeout : NATURAL := c_disturb_f_adc_MHz*10**6 + c_disturb_f_adc_MHz*10**5;  -- 10% margin.
-  CONSTANT c_disturb_N_sync_jesd        : NATURAL := c_disturb_S_pn * c_disturb_N_sync_rcu / c_disturb_S_rcu; -- = 4, nof JESD IP sync outputs per PN
-  CONSTANT c_disturb_A_pn               : NATURAL := c_disturb_S_pn / c_disturb_N_pol;  -- = 6 dual pol antenna per PN, is 6 signal input pairs
-  CONSTANT c_disturb_P_pfb              : NATURAL := c_disturb_S_pn / c_disturb_Q_fft;  -- = 6 PFB units, for 6 signal input pairs
-  CONSTANT c_disturb_T_adc              : TIME    := (10**6 / c_disturb_f_adc_MHz) * 1 ps;  -- = 5 ns @ 200MHz
-  CONSTANT c_disturb_T_sub              : TIME    := c_disturb_N_fft * c_disturb_T_adc;  -- = 5.12 us @ 200MHz
-  CONSTANT c_disturb_W_bf_product       : NATURAL := c_disturb_W_subband + c_disturb_W_bf_weight -1;
-  CONSTANT c_disturb_X_sq               : NATURAL := c_disturb_S_pn * c_disturb_S_pn;  -- = 144
-  CONSTANT c_disturb_block_period       : NATURAL := c_disturb_N_fft * 1000 / c_disturb_f_adc_MHz;  -- = 5120 [ns]
-  CONSTANT c_disturb_N_beamlets_disturb     : NATURAL := c_disturb_N_beamsets * c_disturb_S_sub_bf;  -- = 976
-  CONSTANT c_disturb_unit_sub_weight    : NATURAL := 2**c_disturb_W_sub_weight_fraction;  -- 2**13, so range +-4.0 for 16 bit signed weight
-  CONSTANT c_disturb_unit_bf_weight     : NATURAL := 2**c_disturb_W_bf_weight_fraction;  -- 2**14, so range +-2.0 for 16 bit signed weight
-  CONSTANT c_disturb_unit_beamlet_scale : NATURAL := 2**c_disturb_W_beamlet_scale_fraction;  -- 2**15, so range +-1.0 for 16 bit signed weight
-
-  -- Default / tb values
-  CONSTANT c_disturb_beamlet_scale_default   : NATURAL := 2**15;
+  CONSTANT c_disturb_FS_adc                  : NATURAL := 2**(c_disturb_W_adc - 1); -- full scale FS corresponds to amplitude 1.0
+  CONSTANT c_disturb_wg_ampl_lsb             : REAL := c_diag_wg_ampl_unit / REAL(c_disturb_FS_adc);  -- WG amplitude in number of LSbit resolution steps
+  CONSTANT c_disturb_wg_subband_freq_unit    : REAL := c_diag_wg_freq_unit/REAL(c_disturb_N_fft);  -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus
+  CONSTANT c_disturb_N_clk_per_sync          : NATURAL := c_disturb_f_adc_MHz*10**6;  -- Default 200M clock cycles per second
+  CONSTANT c_disturb_N_clk_sync_timeout      : NATURAL := c_disturb_f_adc_MHz*10**6 + c_disturb_f_adc_MHz*10**5;  -- 10% margin.
+  CONSTANT c_disturb_N_clk_sync_timeout_xsub : NATURAL := 2147483647;  -- = 2**31 - 1 = largest value for NATURAL for 10.7 seconds. Do not use 2*31 to avoid Modelsim NATURAL overflow warning.
+  CONSTANT c_disturb_N_sync_jesd             : NATURAL := c_disturb_S_pn * c_disturb_N_sync_rcu / c_disturb_S_rcu; -- = 4, nof JESD IP sync outputs per PN
+  CONSTANT c_disturb_f_sub_Hz                : REAL := REAL(c_disturb_f_adc_MHz * 10**6) / REAL(c_sdp_N_fft);  -- = 195312.5
+  CONSTANT c_disturb_N_int                   : NATURAL := c_disturb_f_adc_MHz * 10**6;  -- nof ADC sample periods per 1 s integration interval
+  CONSTANT c_disturb_N_int_sub               : REAL := c_disturb_f_sub_Hz;  -- nof subband sample periods per 1 s integration interval
+  CONSTANT c_disturb_N_int_sub_lo            : NATURAL := NATURAL(FLOOR(c_disturb_N_int_sub));  -- = 195312
+  CONSTANT c_disturb_N_int_sub_hi            : NATURAL := NATURAL(CEIL(c_disturb_N_int_sub));  -- = 195313
+  CONSTANT c_disturb_A_pn                    : NATURAL := c_disturb_S_pn / c_disturb_N_pol;  -- = 6 dual pol antenna per PN, is 6 signal input pairs
+  CONSTANT c_disturb_P_pfb                   : NATURAL := c_disturb_S_pn / c_disturb_Q_fft;  -- = 6 PFB units, for 6 signal input pairs
+  CONSTANT c_disturb_T_adc                   : TIME    := (10**6 / c_disturb_f_adc_MHz) * 1 ps;  -- = 5 ns @ 200MHz
+  CONSTANT c_disturb_T_sub                   : TIME    := c_disturb_N_fft * c_disturb_T_adc;  -- = 5.12 us @ 200MHz
+  CONSTANT c_disturb_W_bf_product            : NATURAL := c_disturb_W_subband + c_disturb_W_bf_weight -1;
+  CONSTANT c_disturb_X_sq                    : NATURAL := c_disturb_S_pn * c_disturb_S_pn;  -- = 144
+  CONSTANT c_disturb_block_period            : NATURAL := c_disturb_N_fft * 1000 / c_disturb_f_adc_MHz;  -- = 5120 [ns]
+  CONSTANT c_disturb_N_beamlets_disturb      : NATURAL := c_disturb_N_beamsets * c_disturb_S_sub_bf;  -- = 976
+
+  -- . unit weights
+  CONSTANT c_disturb_unit_sub_weight         : NATURAL := 2**c_disturb_W_sub_weight_fraction;  -- 2**13, so range +-4.0 for 16 bit signed weight
+  CONSTANT c_disturb_unit_bf_weight          : NATURAL := 2**c_disturb_W_bf_weight_fraction;  -- 2**14, so range +-2.0 for 16 bit signed weight
+  CONSTANT c_disturb_unit_beamlet_scale      : NATURAL := 2**c_disturb_W_beamlet_scale_fraction;  -- 2**15, so range +-1.0 for 16 bit signed weight
 
   -----------------------------------------------------------------------------
   -- PFB
@@ -321,6 +326,7 @@ PACKAGE disturb_pkg is
   -----------------------------------------------------------------------------
   -- Beamlet output via 10GbE to CEP (= central processor)
   -----------------------------------------------------------------------------
+  CONSTANT c_disturb_cep_version_id  : NATURAL := 5;
   CONSTANT c_disturb_marker_beamlets : NATURAL := 98;  -- = x"62" = 'b'
 
   CONSTANT c_disturb_cep_eth_dst_mac       : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"00074306C700"; -- 00074306C700 = DOP36-eth0
@@ -329,41 +335,44 @@ PACKAGE disturb_pkg is
   CONSTANT c_disturb_cep_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"C0A8";      -- 31:16, 15:8 = backplane, 7:0 = node + 1 = 192.168.xx.yy
   CONSTANT c_disturb_cep_ip_total_length   : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7868, 16);  -- see ICD STAT-CEP
   CONSTANT c_disturb_cep_udp_total_length  : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7848, 16);  -- see ICD STAT-CEP
-  CONSTANT c_disturb_cep_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5000, 16);
+  CONSTANT c_disturb_cep_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5000, 16);  -- 0x1380 = 5000
   CONSTANT c_disturb_cep_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D0";        -- 15:8, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0])
 
-  CONSTANT c_disturb_cep_app_header_len    : NATURAL := 32;
+  CONSTANT c_disturb_cep_app_header_len    : NATURAL := 32;  -- octets, see ICD STAT-CEP
+  CONSTANT c_disturb_cep_header_len        : NATURAL := 14 + 20 + 8 + c_disturb_cep_app_header_len;  -- = eth + ip + udp + app = 74 octets, see ICD STAT-CEP
 
-  CONSTANT c_disturb_cep_version_id             : NATURAL := 5;
-  CONSTANT c_disturb_cep_nof_blocks_per_packet  : NATURAL := 4;
-  CONSTANT c_disturb_cep_nof_beamlets_per_block : NATURAL := c_disturb_S_sub_bf; -- number of dual pol beamlets (c_disturb_N_pol_bf = 2)
+  CONSTANT c_disturb_cep_nof_blocks_per_packet     : NATURAL := 4;
+  CONSTANT c_disturb_cep_nof_beamlets_per_block    : NATURAL := c_disturb_S_sub_bf; -- number of dual pol beamlets (c_disturb_N_pol_bf = 2)
+  CONSTANT c_disturb_cep_nof_beamlets_per_longword : NATURAL := 2;  -- 2 dual pol, complex, 8bit beamlets fit in 1 64bit longword
+  CONSTANT c_disturb_cep_payload_nof_longwords     : NATURAL := c_disturb_cep_nof_blocks_per_packet * c_disturb_cep_nof_beamlets_per_block / c_disturb_cep_nof_beamlets_per_longword;  -- = 976
+  CONSTANT c_disturb_cep_packet_nof_longwords      : NATURAL := ceil_div(c_disturb_cep_header_len, c_longword_sz) + c_disturb_cep_payload_nof_longwords; -- without tail CRC, the CRC is applied by 10GbE MAC
 
   CONSTANT c_disturb_cep_nof_hdr_fields : NATURAL := 3+12+4+18+1; -- 592b; 9.25 64b words
   CONSTANT c_disturb_cep_hdr_field_sel  : STD_LOGIC_VECTOR(c_disturb_cep_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111011"&"0111"&"1100"&"00000010"&"000110"&"0";  -- 0=data path, 1=MM controlled TODO
 --CONSTANT c_disturb_cep_hdr_field_sel  : STD_LOGIC_VECTOR(c_disturb_cep_nof_hdr_fields-1 DOWNTO 0) := "100"&"000000010001"&"0100"&"0100"&"00000000"&"101000"&"0";  -- 0=data path, 1=MM controlled TODO
 
   CONSTANT c_disturb_cep_hdr_field_arr : t_common_field_arr(c_disturb_cep_nof_hdr_fields-1 DOWNTO 0) := ( 
-      ( field_name_pad("eth_dst_mac"                        ), "RW", 48, field_default(c_disturb_cep_eth_dst_mac) ),
-      ( field_name_pad("eth_src_mac"                        ), "RW", 48, field_default(0) ),
-      ( field_name_pad("eth_type"                           ), "RW", 16, field_default(x"0800") ),
-
-      ( field_name_pad("ip_version"                         ), "RW",  4, field_default(4) ),
-      ( field_name_pad("ip_header_length"                   ), "RW",  4, field_default(5) ),
-      ( field_name_pad("ip_services"                        ), "RW",  8, field_default(0) ),
-      ( field_name_pad("ip_total_length"                    ), "RW", 16, field_default(c_disturb_cep_ip_total_length) ),
-      ( field_name_pad("ip_identification"                  ), "RW", 16, field_default(0) ),
-      ( field_name_pad("ip_flags"                           ), "RW",  3, field_default(2) ),
-      ( field_name_pad("ip_fragment_offset"                 ), "RW", 13, field_default(0) ),
-      ( field_name_pad("ip_time_to_live"                    ), "RW",  8, field_default(127) ),
-      ( field_name_pad("ip_protocol"                        ), "RW",  8, field_default(17) ),
-      ( field_name_pad("ip_header_checksum"                 ), "RW", 16, field_default(0) ),
-      ( field_name_pad("ip_src_addr"                        ), "RW", 32, field_default(c_disturb_cep_ip_src_addr_31_16 & x"0203") ), -- Default src IP = 192.168.2.3
-      ( field_name_pad("ip_dst_addr"                        ), "RW", 32, field_default(c_disturb_cep_ip_dst_addr) ),
-
-      ( field_name_pad("udp_src_port"                       ), "RW", 16, field_default(0) ), 
-      ( field_name_pad("udp_dst_port"                       ), "RW", 16, field_default(c_disturb_cep_udp_dst_port) ),
-      ( field_name_pad("udp_total_length"                   ), "RW", 16, field_default(c_disturb_cep_udp_total_length) ),
-      ( field_name_pad("udp_checksum"                       ), "RW", 16, field_default(0) ),
+      ( field_name_pad("eth_dst_mac"                            ), "RW", 48, field_default(c_disturb_cep_eth_dst_mac) ),
+      ( field_name_pad("eth_src_mac"                            ), "RW", 48, field_default(0) ),
+      ( field_name_pad("eth_type"                               ), "RW", 16, field_default(x"0800") ),
+
+      ( field_name_pad("ip_version"                             ), "RW",  4, field_default(4) ),
+      ( field_name_pad("ip_header_length"                       ), "RW",  4, field_default(5) ),
+      ( field_name_pad("ip_services"                            ), "RW",  8, field_default(0) ),
+      ( field_name_pad("ip_total_length"                        ), "RW", 16, field_default(c_disturb_cep_ip_total_length) ),
+      ( field_name_pad("ip_identification"                      ), "RW", 16, field_default(0) ),
+      ( field_name_pad("ip_flags"                               ), "RW",  3, field_default(2) ),
+      ( field_name_pad("ip_fragment_offset"                     ), "RW", 13, field_default(0) ),
+      ( field_name_pad("ip_time_to_live"                        ), "RW",  8, field_default(127) ),
+      ( field_name_pad("ip_protocol"                            ), "RW",  8, field_default(17) ),
+      ( field_name_pad("ip_header_checksum"                     ), "RW", 16, field_default(0) ),
+      ( field_name_pad("ip_src_addr"                            ), "RW", 32, field_default(0) ),
+      ( field_name_pad("ip_dst_addr"                            ), "RW", 32, field_default(c_disturb_cep_ip_dst_addr) ),
+
+      ( field_name_pad("udp_src_port"                           ), "RW", 16, field_default(0) ), 
+      ( field_name_pad("udp_dst_port"                           ), "RW", 16, field_default(c_disturb_cep_udp_dst_port) ),
+      ( field_name_pad("udp_total_length"                       ), "RW", 16, field_default(c_disturb_cep_udp_total_length) ),
+      ( field_name_pad("udp_checksum"                           ), "RW", 16, field_default(0) ),
 
       ( field_name_pad("disturb_marker"                         ), "RW",  8, field_default(c_disturb_marker_beamlets) ),
       ( field_name_pad("disturb_version_id"                     ), "RW",  8, field_default(c_disturb_cep_version_id) ),
@@ -380,13 +389,13 @@ PACKAGE disturb_pkg is
       ( field_name_pad("disturb_source_info_gn_id"              ), "RW",  5, field_default(0) ),
 
       ( field_name_pad("disturb_reserved"                       ), "RW", 40, field_default(0) ),
-      ( field_name_pad("disturb_beamlet_scale"                  ), "RW", 16, field_default(c_disturb_beamlet_scale_default) ),
+      ( field_name_pad("disturb_beamlet_scale"                  ), "RW", 16, field_default(c_disturb_unit_beamlet_scale) ),
       ( field_name_pad("disturb_beamlet_index"                  ), "RW", 16, field_default(0) ),
       ( field_name_pad("disturb_nof_blocks_per_packet"          ), "RW",  8, field_default(c_disturb_cep_nof_blocks_per_packet) ),
       ( field_name_pad("disturb_nof_beamlets_per_block"         ), "RW", 16, field_default(c_disturb_cep_nof_beamlets_per_block) ),
       ( field_name_pad("disturb_block_period"                   ), "RW", 16, field_default(c_disturb_block_period) ),
 
-      ( field_name_pad("dp_bsn"                             ), "RW", 64, field_default(0) ) 
+      ( field_name_pad("dp_bsn"                                 ), "RW", 64, field_default(0) ) 
   );
   CONSTANT c_disturb_reg_cep_hdr_dat_addr_w : NATURAL := ceil_log2(field_nof_words(c_disturb_cep_hdr_field_arr, c_word_w));
 
@@ -435,16 +444,18 @@ PACKAGE disturb_pkg is
   CONSTANT c_disturb_reg_nw_10GbE_eth10g_addr_w : NATURAL := 1;
 
   -- JESD204
-  CONSTANT c_disturb_jesd204b_freq             : STRING := "200MHz";
-  CONSTANT c_disturb_jesd204b_mm_jesd_ctrl_reg : t_c_mem := (latency  => 1,
+  CONSTANT c_disturb_jesd204b_freq    : STRING := "200MHz";
+  CONSTANT c_disturb_mm_jesd_ctrl_reg : t_c_mem := (latency  => 1,
                                                          adr_w    => 1,
                                                          dat_w    => c_word_w,
                                                          nof_dat  => 1,
-                                                         init_sl  => '0');
+                                                         init_sl  => '0');  -- PIO_JESD_CTRL
 
   -- AIT MM address widths
   CONSTANT c_disturb_jesd204b_addr_w               : NATURAL := ceil_log2(c_disturb_S_pn) + 8; 
   CONSTANT c_disturb_jesd_ctrl_addr_w              : NATURAL := 1; 
+  CONSTANT c_disturb_jesd_ctrl_reset_bi            : NATURAL := 31;
+  CONSTANT c_disturb_jesd_ctrl_enable_w            : NATURAL := 31;
   CONSTANT c_disturb_reg_bsn_monitor_input_addr_w  : NATURAL := 8;
   CONSTANT c_disturb_reg_wg_addr_w                 : NATURAL := ceil_log2(c_disturb_S_pn) + 2; 
   CONSTANT c_disturb_ram_wg_addr_w                 : NATURAL := ceil_log2(c_disturb_S_pn) + 10; 
@@ -502,6 +513,8 @@ PACKAGE disturb_pkg is
     step       : NATURAL;
   END RECORD;
 
+  CONSTANT c_disturb_crosslets_info_rst : t_sdp_crosslets_info := (offset_arr => (OTHERS => 0), step => 0);
+
   CONSTANT c_disturb_mm_reg_nof_crosslets  : t_c_mem := (latency  => 1,
                                                      adr_w    => 1,
                                                      dat_w    => ceil_log2(c_disturb_N_crosslets_max+1),  
@@ -575,6 +588,7 @@ PACKAGE disturb_pkg is
   FUNCTION func_disturb_get_stat_app_total_length(g_statistics_type : STRING) RETURN NATURAL;
   FUNCTION func_disturb_get_stat_udp_total_length(g_statistics_type : STRING) RETURN NATURAL;
   FUNCTION func_disturb_get_stat_ip_total_length(g_statistics_type : STRING) RETURN NATURAL;
+  FUNCTION func_disturb_get_stat_udp_src_port(g_statistics_type : STRING; gn_index : NATURAL) RETURN STD_LOGIC_VECTOR;
   FUNCTION func_disturb_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL;
   FUNCTION func_disturb_get_stat_nof_packets(g_statistics_type : STRING) RETURN NATURAL;  -- use c_disturb_S_pn, c_disturb_P_sq, c_disturb_N_crosslets_max
 
@@ -600,8 +614,7 @@ PACKAGE BODY disturb_pkg IS
     --   pn_index = gn_index MOD c_disturb_N_pn_max
     --
     -- The c_disturb_N_pn_max = 16 fits the LB and HB of LOFAR2:
-    -- . The LB starts at GN index = 0 and has c_disturb_N_pn_lb = c_disturb_N_pn_max
-    --   = 16 nodes.
+    -- . The LB starts at GN index = 0 and has c_disturb_N_pn_max = 16 nodes.
     -- . The HB starts at GN index = c_disturb_N_pn_max, and has 8 or 16 nodes
     --   dependent on the type of station.
     --
@@ -711,6 +724,14 @@ PACKAGE BODY disturb_pkg IS
     RETURN c_disturb_udp_total_length + c_network_ip_header_len;
   END func_disturb_get_stat_ip_total_length;
 
+  FUNCTION func_disturb_get_stat_udp_src_port(g_statistics_type : STRING; gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
+    CONSTANT c_gn_index : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(gn_index, 8);
+  BEGIN
+    RETURN sel_a_b(g_statistics_type="BST", c_disturb_bst_udp_src_port_15_8 & c_gn_index,    -- BST = 0xD0 & gn_index
+           sel_a_b(g_statistics_type="XST", c_disturb_xst_udp_src_port_15_8 & c_gn_index,    -- XST = 0xD1 & gn_index
+                                            c_disturb_sst_udp_src_port_15_8 & c_gn_index));  -- SST = 0xD2 & gn_index
+  END func_disturb_get_stat_udp_src_port;
+
   FUNCTION func_disturb_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL IS
   BEGIN
     RETURN sel_a_b(g_statistics_type="BST", 1,
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_station.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_station.vhd
index 1a631e7ac9..69654503bc 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_station.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_station.vhd
@@ -26,14 +26,13 @@
 --   Combines disturb nodes. Contains the UniBoard2 HW version independent LOFAR2 SDP application code.
 -------------------------------------------------------------------------------
 
-LIBRARY IEEE, common_lib, technology_lib, diag_lib, dp_lib, tech_jesd204b_lib, wpfb_lib, tech_pll_lib, tr_10gbe_lib, nw_10gbe_lib, eth_lib, ring_lib;
+LIBRARY IEEE, common_lib, diag_lib, dp_lib, tech_jesd204b_lib, wpfb_lib, tech_pll_lib, tr_10GbE_lib, nw_10GbE_lib, eth_lib, ring_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
 USE IEEE.NUMERIC_STD.ALL;
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE common_lib.common_network_layers_pkg.ALL;
 USE common_lib.common_field_pkg.ALL;
-USE technology_lib.technology_pkg.ALL;
 USE diag_lib.diag_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
 USE wpfb_lib.wpfb_pkg.ALL;
@@ -43,7 +42,6 @@ USE ring_lib.ring_pkg.ALL;
 
 ENTITY disturb_station IS
   GENERIC (
-    g_technology             : NATURAL := c_tech_arria10_e1sg;
     g_sim                    : BOOLEAN := FALSE; -- Overridden by TB
     g_sim_disturb                : t_disturb_sim := c_disturb_sim;  -- Used when g_sim = TRUE, otherwise use HW defaults
     g_sim_sync_timeout       : NATURAL := 1024;
@@ -91,15 +89,6 @@ ENTITY disturb_station IS
     udp_tx_sosi_arr            : OUT t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
     udp_tx_siso_arr            : IN  t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);  
 
-    ----------------------------------------------
-    -- 10 GbE 
-    ----------------------------------------------
-    reg_nw_10GbE_mac_copi      : IN  t_mem_copi := c_mem_copi_rst;
-    reg_nw_10GbE_mac_cipo      : OUT t_mem_cipo := c_mem_cipo_rst;
-
-    reg_nw_10GbE_eth10g_copi   : IN  t_mem_copi := c_mem_copi_rst;
-    reg_nw_10GbE_eth10g_cipo   : OUT t_mem_cipo := c_mem_cipo_rst;
-
     ----------------------------------------------
     -- AIT 
     ----------------------------------------------
@@ -173,6 +162,7 @@ ENTITY disturb_station IS
     -- SST UDP offload bsn monitor
     reg_bsn_monitor_v2_sst_offload_copi : IN  t_mem_copi := c_mem_copi_rst;
     reg_bsn_monitor_v2_sst_offload_cipo : OUT t_mem_cipo := c_mem_cipo_rst;
+
     ----------------------------------------------
     -- SDP Info 
     ----------------------------------------------
@@ -268,6 +258,18 @@ ENTITY disturb_station IS
     -- BF ring bsn at sync 
     reg_dp_block_validate_bsn_at_sync_bf_copi  : IN  t_mem_copi := c_mem_copi_rst;
     reg_dp_block_validate_bsn_at_sync_bf_cipo  : OUT t_mem_cipo := c_mem_cipo_rst;
+
+    ----------------------------------------------
+    -- BST
+    ----------------------------------------------
+    -- Statistics Enable
+    reg_stat_enable_bst_copi      : IN  t_mem_copi := c_mem_copi_rst;
+    reg_stat_enable_bst_cipo      : OUT t_mem_cipo := c_mem_cipo_rst;
+
+    -- Statistics header info
+    reg_stat_hdr_dat_bst_copi     : IN  t_mem_copi := c_mem_copi_rst;
+    reg_stat_hdr_dat_bst_cipo     : OUT t_mem_cipo := c_mem_cipo_rst;
+
     ----------------------------------------------
     -- SST 
     ----------------------------------------------
@@ -324,35 +326,38 @@ ENTITY disturb_station IS
     reg_dp_block_validate_bsn_at_sync_xst_copi  : IN  t_mem_copi := c_mem_copi_rst;
     reg_dp_block_validate_bsn_at_sync_xst_cipo  : OUT t_mem_cipo := c_mem_cipo_rst;
 
-    -- XST ring MAC 
+    ----------------------------------------------
+    -- tr 10 GbE for ring
+    ----------------------------------------------
+
     reg_tr_10GbE_mac_copi                       : IN  t_mem_copi := c_mem_copi_rst;
     reg_tr_10GbE_mac_cipo                       : OUT t_mem_cipo := c_mem_cipo_rst;
                              
-    -- XST ring ETH 
     reg_tr_10GbE_eth10g_copi                    : IN  t_mem_copi := c_mem_copi_rst;
     reg_tr_10GbE_eth10g_cipo                    : OUT t_mem_cipo := c_mem_cipo_rst;
 
+    -- RING_0 serial
+    RING_0_TX: OUT STD_LOGIC_VECTOR(c_quad - 1 DOWNTO 0) := (OTHERS => '0');
+    RING_0_RX: IN  STD_LOGIC_VECTOR(c_quad - 1 DOWNTO 0) := (OTHERS => '0');
+
+    -- RING_1 serial
+    RING_1_TX : OUT STD_LOGIC_VECTOR(c_quad - 1 DOWNTO 0) := (OTHERS => '0');
+    RING_1_RX : IN  STD_LOGIC_VECTOR(c_quad - 1 DOWNTO 0) := (OTHERS => '0');
 
     ----------------------------------------------
-    -- BST 
+    -- nw 10 GbE for beamlet output
     ----------------------------------------------
-    -- Statistics Enable
-    reg_stat_enable_bst_copi      : IN  t_mem_copi := c_mem_copi_rst;
-    reg_stat_enable_bst_cipo      : OUT t_mem_cipo := c_mem_cipo_rst;
-    
-    -- Statistics header info 
-    reg_stat_hdr_dat_bst_copi     : IN  t_mem_copi := c_mem_copi_rst;
-    reg_stat_hdr_dat_bst_cipo     : OUT t_mem_cipo := c_mem_cipo_rst;
+    reg_nw_10GbE_mac_copi      : IN  t_mem_copi := c_mem_copi_rst;
+    reg_nw_10GbE_mac_cipo      : OUT t_mem_cipo := c_mem_cipo_rst;
 
-    -- RING_0 serial
-    RING_0_TX: OUT STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
-    RING_0_RX: IN  STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
+    reg_nw_10GbE_eth10g_copi   : IN  t_mem_copi := c_mem_copi_rst;
+    reg_nw_10GbE_eth10g_cipo   : OUT t_mem_cipo := c_mem_cipo_rst;
 
-    -- RING_1 serial
-    RING_1_TX : OUT STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
-    RING_1_RX : IN  STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
+    ----------------------------------------------
+    -- QSFP for beamlet output and for ring cable
+    ----------------------------------------------
 
-    -- QSFP serial
+    -- QSFP serial (6 QSFP ports per FPGA)
     unb2_board_front_io_serial_tx_arr : OUT STD_LOGIC_VECTOR(6 * c_quad-1 DOWNTO 0) := (OTHERS => '0');
     unb2_board_front_io_serial_rx_arr : IN  STD_LOGIC_VECTOR(6 * c_quad-1 DOWNTO 0) := (OTHERS => '0');
 
@@ -366,14 +371,17 @@ END disturb_station;
 
 ARCHITECTURE str OF disturb_station IS
 
-  -- 10 GbE Interface
-  CONSTANT c_nof_10GbE_offload_streams     : NATURAL := 1;
-  CONSTANT c_nof_blocks_per_packet         : NATURAL := 4;
-  CONSTANT c_nof_beamlets_per_block        : NATURAL := c_disturb_N_pol * c_disturb_S_sub_bf; 
-  CONSTANT c_10GbE_block_size              : NATURAL := c_nof_blocks_per_packet * c_nof_beamlets_per_block / 4; -- 4 beamlets fit in 1 64bit longword 
-  CONSTANT c_fifo_tx_fill                  : NATURAL := c_10GbE_block_size; 
-  CONSTANT c_fifo_tx_size                  : NATURAL := c_fifo_tx_fill + 11; -- Make fifo size large enough for adding header.
- 
+  -- Make Tx FIFOs at least c_fifo_tx_fill_margin larger than needed to fit the largest Tx packet
+  CONSTANT c_fifo_tx_fill_margin           : NATURAL := 10;  -- >= c_fifo_fill_margin = 6 that is used in dp_fifo_fill_eop
+
+  -- 10 GbE Interface for beamlet output
+  CONSTANT c_nof_10GbE_beamlet_output      : NATURAL := 1;
+
+  -- The nw_10GbE/tr_10GbE uses dp_fifo_fill_eop, so rely on releasing packets (beamlets, arp and ping) at eop instead
+  -- of at fill level. Make fifo size large enough to fit one packet and the c_fifo_tx_fill_margin.
+  CONSTANT c_fifo_tx_size_beamlet_output   : NATURAL := true_log_pow2(c_disturb_cep_packet_nof_longwords + c_fifo_tx_fill_margin);  -- = 976 + 6 --> 1024
+  CONSTANT c_fifo_tx_fill_beamlet_output   : NATURAL := c_fifo_tx_size_beamlet_output - c_fifo_tx_fill_margin;  -- = maximum fill level, so rely on eop
+
   -- Address widths of a single MM instance
   CONSTANT c_addr_w_ram_ss_ss_wide                 : NATURAL := ceil_log2(c_disturb_P_pfb * c_disturb_S_sub_bf * c_disturb_Q_fft); 
   CONSTANT c_addr_w_ram_bf_weights                 : NATURAL := ceil_log2(c_disturb_N_pol * c_disturb_P_pfb * c_disturb_S_sub_bf * c_disturb_Q_fft); 
@@ -391,27 +399,38 @@ ARCHITECTURE str OF disturb_station IS
   CONSTANT c_f_adc     : STD_LOGIC := '1'; -- '0' => 160M, '1' => 200M
   CONSTANT c_fsub_type : STD_LOGIC := '0'; -- '0' => critical sampled PFB, '1' => oversampled PFB
  
-  CONSTANT c_use_dp_layer              : BOOLEAN := TRUE; 
-  CONSTANT c_lane_packet_length_xst    : NATURAL := c_disturb_N_crosslets_max * c_disturb_S_pn / 2; -- = crosslet subband select block size devided by 2 as it is repacked from 32b to 64b. = 42 words
-  CONSTANT c_lane_packet_length_bf     : NATURAL := (c_disturb_S_sub_bf * c_disturb_N_pol_bf * 9) / 16; -- = beamlet block size repacked from 36b to 64b (9/16 = 36/64). = 549 words
-  CONSTANT c_err_bi                    : NATURAL := 0; 
+  CONSTANT c_use_dp_layer              : BOOLEAN := TRUE;  
+  CONSTANT c_lane_payload_nof_longwords_xst : NATURAL := c_disturb_N_crosslets_max * c_disturb_S_pn / 2; -- = crosslet subband select block size divided by 2 as it is repacked from 32b to 64b. = 42 longwords
+  CONSTANT c_lane_payload_nof_longwords_bf  : NATURAL := (c_disturb_S_sub_bf * c_disturb_N_pol_bf * 9) / 16; -- = beamlet block size repacked from 36b to 64b (9/16 = 36/64). = 549 longwords
+  CONSTANT c_lane_payload_nof_longwords_max : NATURAL := largest(c_lane_payload_nof_longwords_xst, c_lane_payload_nof_longwords_bf);
+  CONSTANT c_lane_packet_nof_longwords_max  : NATURAL := c_lane_payload_nof_longwords_max + c_ring_dp_hdr_field_size;  -- = 549 + 3 = 552
+
+  CONSTANT c_err_bi                    : NATURAL := 0;
   CONSTANT c_nof_err_counts            : NATURAL := 8; 
   CONSTANT c_bsn_at_sync_check_channel : NATURAL := 1; 
   CONSTANT c_validate_channel          : BOOLEAN := TRUE; 
   CONSTANT c_validate_channel_mode     : STRING  := "=";
   CONSTANT c_sync_timeout              : NATURAL := sel_a_b(g_sim, g_sim_sync_timeout, c_disturb_N_clk_sync_timeout );
-  CONSTANT c_xsub_fifo_tx_fill         : NATURAL := c_lane_packet_length_bf + sel_a_b(c_use_dp_layer, c_ring_dp_hdr_field_size, c_ring_eth_hdr_field_size); --total max packet length (bf has largest packets)
-  CONSTANT c_xsub_fifo_tx_size         : NATURAL := 2 * c_lane_packet_length_bf;
+
+  -- Use same Tx FIFO size for all lanes in the ring to ease the code, no need to optimize Tx FIFO RAM usage per lane.
+  -- The tr_10GbE uses dp_fifo_fill_eop, so rely on releasing packets (beamlets, crosslets) at eop instead
+  -- of at fill level. Make fifo size large enough to fit one packet and the c_fifo_tx_fill_margin.
+  CONSTANT c_fifo_tx_size_ring         : NATURAL := true_log_pow2(c_lane_packet_nof_longwords_max + c_fifo_tx_fill_margin);  -- = 552 + 6 --> 1024
+  CONSTANT c_fifo_tx_fill_ring         : NATURAL := c_fifo_tx_size_ring - c_fifo_tx_fill_margin;  -- = maximum fill level, so rely on eop
 
   CONSTANT c_nof_lane                  : NATURAL := 3; -- 0 = XST, 1 = BF_0, 2 = BF_1.
   CONSTANT c_nof_if                    : NATURAL := 3; -- 3 different interfaces, QSFP, RING_0 and RING_1
   CONSTANT c_qsfp_if_offset            : NATURAL := 0; -- QSFP signals are indexed at c_nof_if * I.
   CONSTANT c_ring_0_if_offset          : NATURAL := 1; -- RING_0 signals are indexed at c_nof_if * I + 1. 
   CONSTANT c_ring_1_if_offset          : NATURAL := 2; -- RING_1 signals are indexed at c_nof_if * I + 2.
-  CONSTANT c_nof_mac                   : NATURAL := 12; -- Using 9 out of 12 (this is NOT optimized away during synthesis), must match one of the MAC IP variations, e.g. 1, 3, 4, 12, 24, 48
+  CONSTANT c_ring_nof_mac              : NATURAL := 12; -- Using 9 out of 12 (this is NOT optimized away during synthesis), must match one of the MAC IP variations, e.g. 1, 3, 4, 12, 24, 48
+
+  SIGNAL gn_index                   : NATURAL := 0;
+  SIGNAL this_rn                    : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0);
+
+  SIGNAL disturb_info               : t_disturb_info := c_disturb_info_rst;
+  SIGNAL ring_info                  : t_ring_info;
 
-  SIGNAL gn_index : NATURAL := 0;
-  SIGNAL this_rn  : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0);  
   ----------------------------------------------
   -- BF 
   ----------------------------------------------
@@ -510,26 +529,29 @@ ARCHITECTURE str OF disturb_station IS
   SIGNAL bf_udp_siso_arr                   : t_dp_siso_arr(c_disturb_N_beamsets-1 DOWNTO 0);    
   SIGNAL bf_10GbE_hdr_fields_out_arr       : t_slv_1024_arr(c_disturb_N_beamsets-1 DOWNTO 0);
 
-  -- 10GbE
+  -- 10GbE clock
   SIGNAL tr_ref_clk_312                    : STD_LOGIC;
   SIGNAL tr_ref_clk_156                    : STD_LOGIC;
   SIGNAL tr_ref_rst_156                    : STD_LOGIC;
 
-  SIGNAL tr_10gbe_serial_tx_arr            : STD_LOGIC_VECTOR(c_nof_mac-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL tr_10gbe_serial_rx_arr            : STD_LOGIC_VECTOR(c_nof_mac-1 DOWNTO 0) := (OTHERS => '0');
+  -- 10GbE ring
+  SIGNAL tr_10gbe_ring_serial_tx_arr       : STD_LOGIC_VECTOR(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL tr_10gbe_ring_serial_rx_arr       : STD_LOGIC_VECTOR(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => '0');
 
-  SIGNAL nw_10gbe_snk_in_arr               : t_dp_sosi_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
-  SIGNAL nw_10gbe_snk_out_arr              : t_dp_siso_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
-  SIGNAL nw_10gbe_src_out_arr              : t_dp_sosi_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
-  SIGNAL nw_10gbe_src_in_arr               : t_dp_siso_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
+  SIGNAL tr_10gbe_ring_snk_in_arr          : t_dp_sosi_arr(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL tr_10gbe_ring_snk_out_arr         : t_dp_siso_arr(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
+  SIGNAL tr_10gbe_ring_src_out_arr         : t_dp_sosi_arr(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL tr_10gbe_ring_src_in_arr          : t_dp_siso_arr(c_ring_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
 
-  SIGNAL nw_10GbE_hdr_fields_in_arr        : t_slv_1024_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0);
-          
-  SIGNAL tr_10gbe_src_out_arr              : t_dp_sosi_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);         
-  SIGNAL tr_10gbe_snk_in_arr               : t_dp_sosi_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);      
-  SIGNAL tr_10gbe_src_in_arr               : t_dp_siso_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);   
-  SIGNAL tr_10gbe_snk_out_arr              : t_dp_siso_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);  
+  -- 10GbE beamlet output
+  SIGNAL nw_10gbe_beamlet_output_snk_in_arr  : t_dp_sosi_arr(c_nof_10GbE_beamlet_output-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL nw_10gbe_beamlet_output_snk_out_arr : t_dp_siso_arr(c_nof_10GbE_beamlet_output-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
+  SIGNAL nw_10gbe_beamlet_output_src_out_arr : t_dp_sosi_arr(c_nof_10GbE_beamlet_output-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL nw_10gbe_beamlet_output_src_in_arr  : t_dp_siso_arr(c_nof_10GbE_beamlet_output-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
 
+  SIGNAL nw_10GbE_hdr_fields_in_arr        : t_slv_1024_arr(c_nof_10GbE_beamlet_output-1 DOWNTO 0);
+
+  -- Network mac, ip, udp
   SIGNAL cep_eth_src_mac                   : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
   SIGNAL cep_ip_src_addr                   : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0);
   SIGNAL cep_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
@@ -539,10 +561,6 @@ ARCHITECTURE str OF disturb_station IS
   SIGNAL bst_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
   SIGNAL xst_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
 
-  SIGNAL disturb_info                          : t_disturb_info := c_disturb_info_rst;
-  SIGNAL ring_info                         : t_ring_info;
-
-
 BEGIN
 
   -----------------------------------------------------------------------------
@@ -606,7 +624,6 @@ BEGIN
   -----------------------------------------------------------------------------
   u_ait: ENTITY work.node_disturb_adc_input_and_timing
   GENERIC MAP(
-    g_technology                => g_technology,
     g_sim                       => g_sim,
     g_no_jesd                   => g_no_jesd,
     g_bsn_nof_clk_per_sync      => g_bsn_nof_clk_per_sync                
@@ -1000,7 +1017,7 @@ BEGIN
     );
 
     -----------------------------------------------------------------------------
-    -- DP MUX
+    -- DP MUX to multiplex the c_sdp_N_beamsets via one beamlet output 10GbE link
     -----------------------------------------------------------------------------
     -- Assign hdr_fields to nw_10GbE for ARP/PING functionality. Only the fields: 
     -- eth_src_mac, ip_src_addr and ip_dst_addr are used. Which are identical for
@@ -1026,17 +1043,16 @@ BEGIN
     );
 
     ---------------
-    -- nw_10GbE
+    -- nw_10GbE beamlet output
     ---------------
-    u_nw_10GbE: ENTITY nw_10GbE_lib.nw_10GbE
+    u_nw_10GbE_beamlet_output: ENTITY nw_10GbE_lib.nw_10GbE
     GENERIC MAP (
-      g_technology    => g_technology,
       g_sim           => g_sim,
       g_sim_level     => 1,
-      g_nof_macs      => c_nof_10GbE_offload_streams,
+      g_nof_macs      => c_nof_10GbE_beamlet_output,
       g_direction     => "TX_RX",
-      g_tx_fifo_fill  => c_fifo_tx_fill,
-      g_tx_fifo_size  => c_fifo_tx_size,
+      g_tx_fifo_fill  => c_fifo_tx_fill_beamlet_output,
+      g_tx_fifo_size  => c_fifo_tx_size_beamlet_output,
       g_ip_hdr_field_arr => c_disturb_cep_hdr_field_arr
   
     )
@@ -1062,15 +1078,15 @@ BEGIN
       dp_clk                => dp_clk,
       dp_pps                => dp_pps,
   
-      src_out_arr           => nw_10gbe_src_out_arr,
-      src_in_arr            => nw_10gbe_src_in_arr,
-  
-      snk_out_arr           => nw_10gbe_snk_out_arr,
-      snk_in_arr            => nw_10gbe_snk_in_arr,
+      snk_out_arr           => nw_10gbe_beamlet_output_snk_out_arr,
+      snk_in_arr            => nw_10gbe_beamlet_output_snk_in_arr,
   
+      src_out_arr           => nw_10gbe_beamlet_output_src_out_arr,
+      src_in_arr            => nw_10gbe_beamlet_output_src_in_arr,
+
       -- Serial IO
-      serial_tx_arr         => unb2_board_front_io_serial_tx_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad), 
-      serial_rx_arr         => unb2_board_front_io_serial_rx_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad),
+      serial_tx_arr         => unb2_board_front_io_serial_tx_arr(c_nof_10GbE_beamlet_output+c_quad-1 DOWNTO c_quad),
+      serial_rx_arr         => unb2_board_front_io_serial_rx_arr(c_nof_10GbE_beamlet_output+c_quad-1 DOWNTO c_quad),
   
       hdr_fields_in_arr     => nw_10GbE_hdr_fields_in_arr 
     );
@@ -1082,7 +1098,7 @@ BEGIN
       GENERIC MAP (
         g_lane_direction            => 1, -- transport in positive direction.
         g_lane_data_w               => c_longword_w,
-        g_lane_packet_length        => c_lane_packet_length_xst,
+        g_lane_packet_length        => c_lane_payload_nof_longwords_xst,
         g_use_dp_layer              => c_use_dp_layer,
         g_nof_rx_monitors           => c_disturb_N_pn_max,
         g_nof_tx_monitors           => c_disturb_N_pn_max,
@@ -1131,7 +1147,7 @@ BEGIN
         GENERIC MAP (
           g_lane_direction            => 1, -- transport in positive direction.
           g_lane_data_w               => c_longword_w,
-          g_lane_packet_length        => c_lane_packet_length_bf,
+          g_lane_packet_length        => c_lane_payload_nof_longwords_bf,
           g_use_dp_layer              => c_use_dp_layer,
           g_nof_rx_monitors           => c_disturb_N_pn_max,
           g_nof_tx_monitors           => c_disturb_N_pn_max,
@@ -1239,30 +1255,30 @@ BEGIN
     -- Combine seperate signals into array for tr_10GbE
     -----------------------------------------------------------------------------  
     gen_lane_wires : FOR I IN 0 TO c_nof_lane-1 GENERATE 
-    -- QSFP_RX
-    lane_rx_cable_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_qsfp_if_offset) WHEN ring_info.use_cable_to_previous_rn = '1' ELSE c_dp_sosi_rst; -- use_cable_to_previous_rn=1 -> even lanes receive from cable
+      -- QSFP_RX, use_cable_to_previous_rn=1 -> even lanes receive from cable
+      lane_rx_cable_sosi_arr(I) <= tr_10gbe_ring_src_out_arr(c_nof_if * I + c_qsfp_if_offset) WHEN ring_info.use_cable_to_previous_rn = '1' ELSE c_dp_sosi_rst;
 
-    -- QSFP_TX
-    tr_10gbe_snk_in_arr(c_nof_if * I + c_qsfp_if_offset) <= lane_tx_cable_sosi_arr(I) WHEN ring_info.use_cable_to_next_rn = '1'      ELSE c_dp_sosi_rst; -- use_cable_to_next_rn=1 -> even lanes transmit to cable
+      -- QSFP_TX, use_cable_to_next_rn=1 -> even lanes transmit to cable
+      tr_10gbe_ring_snk_in_arr(c_nof_if * I + c_qsfp_if_offset) <= lane_tx_cable_sosi_arr(I) WHEN ring_info.use_cable_to_next_rn = '1'      ELSE c_dp_sosi_rst;
   
-    -- RING_0_RX even lanes receive from RING_0 (from the left)
-    lane_rx_board_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_ring_0_if_offset);
+      -- RING_0_RX even lanes receive from RING_0 (from the left)
+      lane_rx_board_sosi_arr(I) <= tr_10gbe_ring_src_out_arr(c_nof_if * I + c_ring_0_if_offset);
   
-    -- RING_1_TX even lanes transmit to RING_1 (to the right)
-    tr_10gbe_snk_in_arr(c_nof_if * I + c_ring_1_if_offset) <= lane_tx_board_sosi_arr(I); 
+      -- RING_1_TX even lanes transmit to RING_1 (to the right)
+      tr_10gbe_ring_snk_in_arr(c_nof_if * I + c_ring_1_if_offset) <= lane_tx_board_sosi_arr(I);
     END GENERATE;
 
     -----------------------------------------------------------------------------
-    -- tr_10GbE
+    -- tr_10GbE ring
     -----------------------------------------------------------------------------
-    u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE
+    u_tr_10GbE_ring: ENTITY tr_10GbE_lib.tr_10GbE
     GENERIC MAP (
       g_sim           => g_sim,
       g_sim_level     => 1,
-      g_nof_macs      => c_nof_mac,
+      g_nof_macs      => c_ring_nof_mac,
       g_direction     => "TX_RX",
-      g_tx_fifo_fill  => c_xsub_fifo_tx_fill,
-      g_tx_fifo_size  => c_xsub_fifo_tx_size
+      g_tx_fifo_fill  => c_fifo_tx_fill_ring,
+      g_tx_fifo_size  => c_fifo_tx_size_ring
     )
     PORT MAP (
       -- Transceiver PLL reference clock
@@ -1285,15 +1301,15 @@ BEGIN
       dp_rst                => dp_rst,
       dp_clk                => dp_clk,
 
-      src_out_arr           => tr_10gbe_src_out_arr,
-      src_in_arr            => tr_10gbe_src_in_arr,
+      src_out_arr           => tr_10gbe_ring_src_out_arr,
+      src_in_arr            => tr_10gbe_ring_src_in_arr,
 
-      snk_out_arr           => tr_10gbe_snk_out_arr,
-      snk_in_arr            => tr_10gbe_snk_in_arr,
+      snk_out_arr           => tr_10gbe_ring_snk_out_arr,
+      snk_in_arr            => tr_10gbe_ring_snk_in_arr,
 
       -- Serial IO
-      serial_tx_arr         => tr_10gbe_serial_tx_arr, 
-      serial_rx_arr         => tr_10gbe_serial_rx_arr
+      serial_tx_arr         => tr_10gbe_ring_serial_tx_arr,
+      serial_rx_arr         => tr_10gbe_ring_serial_rx_arr
     );
 
     -----------------------------------------------------------------------------
@@ -1303,19 +1319,19 @@ BEGIN
     -- QSFP port, RING_0 port and RING_1 port.
     gen_serial_wires : FOR I IN 0 TO c_nof_lane-1 GENERATE 
       -- QSFP_TX
-      unb2_board_front_io_serial_tx_arr(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_qsfp_if_offset); 
+      unb2_board_front_io_serial_tx_arr(I) <= tr_10gbe_ring_serial_tx_arr(c_nof_if * I + c_qsfp_if_offset);
       -- QSFP_RX
-      tr_10gbe_serial_rx_arr(c_nof_if * I + c_qsfp_if_offset) <= unb2_board_front_io_serial_rx_arr(I); 
+      tr_10gbe_ring_serial_rx_arr(c_nof_if * I + c_qsfp_if_offset) <= unb2_board_front_io_serial_rx_arr(I);
     
       -- RING_0_TX 
-      RING_0_TX(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_ring_0_if_offset);
+      RING_0_TX(I) <= tr_10gbe_ring_serial_tx_arr(c_nof_if * I + c_ring_0_if_offset);
       -- RING_0_RX
-      tr_10gbe_serial_rx_arr(c_nof_if * I + c_ring_0_if_offset) <= RING_0_RX(I); 
+      tr_10gbe_ring_serial_rx_arr(c_nof_if * I + c_ring_0_if_offset) <= RING_0_RX(I);
     
       -- RING_1_TX
-      RING_1_TX(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_ring_1_if_offset);
+      RING_1_TX(I) <= tr_10gbe_ring_serial_tx_arr(c_nof_if * I + c_ring_1_if_offset);
       -- RING_1_RX
-      tr_10gbe_serial_rx_arr(c_nof_if * I + c_ring_1_if_offset) <= RING_1_RX(I); 
+      tr_10gbe_ring_serial_rx_arr(c_nof_if * I + c_ring_1_if_offset) <= RING_1_RX(I);
     END GENERATE;
   END GENERATE;
 
@@ -1323,9 +1339,6 @@ BEGIN
   -- PLL
   ---------
   u_tech_pll_xgmii_mac_clocks : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks
-  GENERIC MAP (
-    g_technology => g_technology
-  )
   PORT MAP (
     refclk_644 => SA_CLK,
     rst_in     => mm_rst,
@@ -1339,12 +1352,12 @@ BEGIN
   -- LEDs
   ------------
   -- QSFP 1 - Beamlets 
-  unb2_board_qsfp_leds_tx_siso_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_snk_out_arr;
-  unb2_board_qsfp_leds_tx_sosi_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_snk_in_arr;
-  unb2_board_qsfp_leds_rx_sosi_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_src_out_arr;
+  unb2_board_qsfp_leds_tx_siso_arr(c_nof_10GbE_beamlet_output+c_quad-1 DOWNTO c_quad) <= nw_10gbe_beamlet_output_snk_out_arr;
+  unb2_board_qsfp_leds_tx_sosi_arr(c_nof_10GbE_beamlet_output+c_quad-1 DOWNTO c_quad) <= nw_10gbe_beamlet_output_snk_in_arr;
+  unb2_board_qsfp_leds_rx_sosi_arr(c_nof_10GbE_beamlet_output+c_quad-1 DOWNTO c_quad) <= nw_10gbe_beamlet_output_src_out_arr;
 
   -- QSFP 0 - Ring
-  unb2_board_qsfp_leds_tx_siso_arr(0 DOWNTO 0) <= tr_10gbe_snk_out_arr(0 DOWNTO 0);
-  unb2_board_qsfp_leds_tx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_snk_in_arr(0 DOWNTO 0);
-  unb2_board_qsfp_leds_rx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_src_out_arr(0 DOWNTO 0);
+  unb2_board_qsfp_leds_tx_siso_arr(0 DOWNTO 0) <= tr_10gbe_ring_snk_out_arr(0 DOWNTO 0);
+  unb2_board_qsfp_leds_tx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_ring_snk_in_arr(0 DOWNTO 0);
+  unb2_board_qsfp_leds_rx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_ring_src_out_arr(0 DOWNTO 0);
 END str;
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/disturb_statistics_offload.vhd b/applications/disturb2/libraries/disturb/src/vhdl/disturb_statistics_offload.vhd
index e74ec7acf7..9975c01c18 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/disturb_statistics_offload.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/disturb_statistics_offload.vhd
@@ -109,12 +109,13 @@ USE work.disturb_pkg.ALL;
 
 ENTITY disturb_statistics_offload IS
   GENERIC (
-    g_statistics_type     : STRING  := "SST";
-    g_offload_time        : NATURAL := c_disturb_offload_time;
-    g_beamset_id          : NATURAL := 0;
-    g_P_sq                : NATURAL := c_disturb_P_sq;  -- number of available correlator cells,
-    g_crosslets_direction : NATURAL := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction
-    g_reverse_word_order  : BOOLEAN := TRUE  -- default word order is MSB after LSB, we need to stream LSB after MSB.
+    g_statistics_type          : STRING  := "SST";
+    g_offload_time             : NATURAL := c_disturb_offload_time;
+    g_beamset_id               : NATURAL := 0;
+    g_P_sq                     : NATURAL := c_disturb_P_sq;  -- number of available correlator cells,
+    g_crosslets_direction      : NATURAL := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction
+    g_reverse_word_order       : BOOLEAN := TRUE;  -- default word order is MSB after LSB, we need to stream LSB after MSB.
+    g_bsn_monitor_sync_timeout : NATURAL := c_disturb_N_clk_sync_timeout
   );
   PORT (
     -- Clocks and reset
@@ -141,7 +142,8 @@ ENTITY disturb_statistics_offload IS
 
     -- Input timing regarding the integration interval of the statistics
     in_sosi          : IN t_dp_sosi;
-    
+    new_interval     : IN STD_LOGIC := '0';
+
     -- Streaming output of offloaded statistics packets
     out_sosi         : OUT t_dp_sosi;
     out_siso         : IN t_dp_siso;
@@ -153,10 +155,11 @@ ENTITY disturb_statistics_offload IS
 
     gn_index                : IN NATURAL;
     ring_info               : IN t_ring_info := c_ring_info_rst;  -- only needed for XST
-    disturb_info                : IN t_disturb_info;
+    disturb_info            : IN t_disturb_info;
     weighted_subbands_flag  : IN STD_LOGIC := '0';
+
     nof_crosslets           : IN STD_LOGIC_VECTOR(c_disturb_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-    crosslets_info          : IN STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0')
+    crosslets_info_rec      : IN t_disturb_crosslets_info := c_disturb_crosslets_info_rst
   );
 END disturb_statistics_offload;
 
@@ -187,7 +190,7 @@ ARCHITECTURE str OF disturb_statistics_offload IS
     packet_count         : NATURAL RANGE 0 TO c_nof_packets_max;
     start_address        : NATURAL RANGE 0 TO c_mm_ram_size;
     start_pulse          : STD_LOGIC;
-    sync                 : STD_LOGIC;
+    start_sync           : STD_LOGIC;
     dp_header_info       : STD_LOGIC_VECTOR(1023 DOWNTO 0);
     payload_err          : STD_LOGIC;
     in_sop_cnt           : NATURAL;
@@ -201,8 +204,7 @@ ARCHITECTURE str OF disturb_statistics_offload IS
     crosslets_info_rec   : t_disturb_crosslets_info;
   END RECORD;
 
-  CONSTANT c_crosslets_info_rst : t_disturb_crosslets_info := (offset_arr => (OTHERS => 0), step => 0);
-  CONSTANT c_reg_rst            : t_reg := (0, 0, '0', '0', (OTHERS => '0'), '0', 0, 0, 0, 0, 0, 0, 0, 0, c_crosslets_info_rst);
+  CONSTANT c_reg_rst            : t_reg := (0, 0, '0', '0', (OTHERS => '0'), '0', 0, 0, 0, 0, 0, 0, 0, 0, c_disturb_crosslets_info_rst);
 
   SIGNAL r     : t_reg;
   SIGNAL nxt_r : t_reg;
@@ -224,8 +226,10 @@ ARCHITECTURE str OF disturb_statistics_offload IS
   SIGNAL data_id_rec              : t_disturb_stat_data_id;
   SIGNAL data_id_slv              : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
 
+  SIGNAL in_trigger               : STD_LOGIC;
   SIGNAL trigger_en               : STD_LOGIC := '0';
   SIGNAL trigger_offload          : STD_LOGIC := '0';
+  SIGNAL mm_done                  : STD_LOGIC := '0';
   SIGNAL dp_sop                   : STD_LOGIC := '0';
   SIGNAL dp_block_from_mm_src_out : t_dp_sosi;
   SIGNAL dp_block_from_mm_src_in  : t_dp_siso;
@@ -237,6 +241,8 @@ ARCHITECTURE str OF disturb_statistics_offload IS
 
   SIGNAL bsn_at_sync              : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL dp_header_info           : STD_LOGIC_VECTOR(1023 DOWNTO 0):= (OTHERS => '0');
+  SIGNAL r_dp_header_sop          : STD_LOGIC;
+  SIGNAL r_dp_header_rec          : t_disturb_stat_header;
 
   -- Debug signals for view in Wave window
   SIGNAL dbg_c_marker                    : NATURAL := c_marker;
@@ -336,7 +342,7 @@ BEGIN
   END PROCESS;
 
   -- Assign application header data_id for different statistic types, use
-  -- GENERATE to keep unused fields at 0.
+  -- GENERATE to keep unused fields at 0 (all fields are NATURAL, so default to 0).
   gen_data_id_sst : IF g_statistics_type = "SST" GENERATE
     data_id_rec.sst_signal_input_index <= r.packet_count + c_disturb_V_oversample * local_si_offset;
   END GENERATE;
@@ -357,7 +363,7 @@ BEGIN
   BEGIN
     v := r;
     v.start_pulse := '0';
-    v.sync := '0';
+    v.start_sync := '0';
     
     -- Count number of sop in a sync interval and get payload errors and keep them till next sync.
     IF in_sosi.sync = '1' THEN
@@ -375,10 +381,10 @@ BEGIN
     END IF;
 
 
-    -- For XST offload capture nof_crosslets and crosslets_info at in_sosi.sync,
+    -- For XST offload capture nof_crosslets and crosslets_info_rec at in_sosi.sync,
     -- to make sure they do not change during packets offload.
     -- . The disturb_crosslets_subband_select.vhd takes in [2] takes care that
-    --   nof_crosslets and crosslets_info are valid at the xsel_sosi.sync. The
+    --   nof_crosslets and crosslets_info_rec are valid at the xsel_sosi.sync. The
     --   mmp_dp_bsn_align_v2 in [2] then aligns the local xsel_sosi with the
     --   remote data and passes on the sync. After some latency the sync
     --   arrives at the disturb_statistics_offload. This latency is very short
@@ -386,7 +392,7 @@ BEGIN
     --   are still valid at the in_sosi.sync.
     IF in_sosi.sync = '1' THEN
       v.nof_crosslets      := TO_UINT(nof_crosslets);
-      v.crosslets_info_rec := func_disturb_map_crosslets_info(crosslets_info);
+      v.crosslets_info_rec := crosslets_info_rec;
     END IF;
 
     -- The trigger_offload occurs nof_cycles_dly after the in_sosi.sync and the
@@ -402,7 +408,7 @@ BEGIN
       -- Use trigger_offload to start first packet offload, all
       -- g_statistics_type start from start address 0
       v.start_pulse        := '1';
-      v.sync               := '1';
+      v.start_sync         := '1';
       v.start_address      := 0;
       v.packet_count       := 0;
       v.interleave_count   := 0;  -- only used for SST
@@ -413,9 +419,7 @@ BEGIN
 
     -- The dp_sop = '1' when the packet has been read from statistics memory
     -- and is about to get out of the dp_fifo_fill_eop in
-    -- u_dp_block_from_mm_dc. The difference between dp_sop and the mm_done
-    -- output of u_dp_block_from_mm_dc, is that dp_sop also includes any
-    -- dp_fifo_fill_eop latency. This ensures that the dp_sop identifies the
+    -- u_dp_block_from_mm_dc. This ensures that the dp_sop identifies the
     -- sop of the offload packet. At the dp_sop:
     -- . the dp_header_info per packet offload can be released
     -- . the next packet offload can be prepared
@@ -445,7 +449,7 @@ BEGIN
 
         ELSIF g_statistics_type = "XST" THEN
           -- start_address:
-          --   nof_crosslets:     0,     1,     2,     3,     4,     5,     6
+          --   nof_crosslets:     1,     2,     3,     4,     5,     6,     7
           --   X_sq instance:
           --           0          0,   576,  1152,  1728,  2304,  2880,  3456
           --           1       4096,  4672,  5248,  5824,  6400,  6976,  7552
@@ -476,6 +480,14 @@ BEGIN
     nxt_r <= v;
   END PROCESS;
 
+  -- The in_trigger can skip the first in_sosi.sync. This is necessary if the
+  -- in_sosi input can be restarted, because then at every restart there is
+  -- no valid previous in_sosi.sync interval yet. This is used for XST offload,
+  -- because then the in_sync interval is MM programmable. For SST and BST the
+  -- new_interval = '0' is not used, because then the in_sosi typically
+  -- remains on after it was started.
+  in_trigger <= in_sosi.sync AND NOT new_interval;
+
   u_mms_common_variable_delay : ENTITY common_lib.mms_common_variable_delay
   PORT MAP (
     mm_rst => mm_rst,
@@ -488,7 +500,7 @@ BEGIN
     reg_enable_miso => reg_enable_miso,
 
     delay           => nof_cycles_dly,
-    trigger         => in_sosi.sync,
+    trigger         => in_trigger,
     trigger_en      => trigger_en,
     trigger_dly     => trigger_offload
   );
@@ -501,7 +513,8 @@ BEGIN
     g_nof_data           => c_mm_nof_data,
     g_word_w             => c_word_w,
     g_reverse_word_order => g_reverse_word_order,
-    g_bsn_w              => c_dp_stream_bsn_w
+    g_bsn_w              => c_dp_stream_bsn_w,
+    g_bsn_incr_enable    => FALSE  -- all offload block have same bsn_at_sync
   ) 
   PORT MAP(
     dp_rst        => dp_rst,
@@ -509,25 +522,23 @@ BEGIN
     mm_rst        => mm_rst,
     mm_clk        => mm_clk,
     start_pulse   => r.start_pulse,
-    sync_in       => r.sync,
-    bsn_at_sync   => bsn_at_sync, 
+    sync_in       => r.start_sync,
+    bsn_at_sync   => bsn_at_sync,
     start_address => r.start_address,
     mm_mosi       => master_mosi,
     mm_miso       => master_miso,
+    out_sop       => dp_sop,  -- = dp_block_from_mm_src_out.sop
     out_sosi      => dp_block_from_mm_src_out,
     out_siso      => dp_block_from_mm_src_in
   );
 
-  -- Use dp_block_from_mm_src_out.sop as dp_sop, to include the
-  -- dp_fifo_fill_eop that is in dp_block_from_mm_dc. The dp_sop thus is the
-  -- sop of the packet that is about to be offloaded by u_dp_offload_tx_v3.
-  -- The r.dp_header_info must be available at the dp_offload_snk_in.sop.
-  -- This is guaranteed because:
+  -- The dp_sop is the sop of the packet that is about to be offloaded by
+  -- u_dp_offload_tx_v3. The r.dp_header_info must be available at the
+  -- dp_offload_snk_in.sop. This is guaranteed because:
   -- . r.dp_header_info is available one clock cycle after dp_sop in
   --   p_control_packet_offload.
   -- . The dp_offload_snk_in is delayed also by at least one clock cycle by
   --   u_dp_pipeline_ready.
-  dp_sop <= dp_block_from_mm_src_out.sop;
 
   u_dp_pipeline_ready : ENTITY dp_lib.dp_pipeline_ready
   PORT MAP(
@@ -541,6 +552,13 @@ BEGIN
     src_out      => dp_offload_snk_in
   );
 
+  -- The bsn_at_sync is passed on via r.dp_header_info so that
+  -- u_dp_offload_tx_v3 can put it in the udp_sosi header.
+  -- The dp_offload_snk_in.bsn that is passed on by u_dp_block_from_mm_dc is
+  -- in fact not used, but useful to see in udp_sosi.bsn in the Wave Window.
+  -- Similar dp_offload_snk_in.sync that is passed on by u_dp_block_from_mm_dc
+  -- is in fact not used, but useful to have in udp_sosi.sync (e.g. for the
+  -- tb).
   u_dp_offload_tx_v3: ENTITY dp_lib.dp_offload_tx_v3
   GENERIC MAP (
     g_nof_streams    => c_nof_streams,
@@ -564,13 +582,17 @@ BEGIN
     hdr_fields_in_arr(0) => r.dp_header_info
   );
 
+  -- Debug signal, r_dp_header_rec must be available at the r_dp_header_sop
+  r_dp_header_sop <= dp_offload_snk_in.sop;
+  r_dp_header_rec <= func_sdp_map_stat_header(r.dp_header_info);
+
   out_sosi <= udp_sosi;
 
   u_bsn_mon_udp : ENTITY dp_lib.mms_dp_bsn_monitor_v2
   GENERIC MAP (
     g_nof_streams        => 1,  
     g_cross_clock_domain => TRUE,
-    g_sync_timeout       => c_disturb_N_clk_sync_timeout,
+    g_sync_timeout       => g_bsn_monitor_sync_timeout,
     g_bsn_w              => c_dp_stream_bsn_w,
     g_error_bi           => 0,
     g_cnt_sop_w          => c_word_w,
@@ -592,7 +614,4 @@ BEGIN
     in_sosi_arr(0) => udp_sosi
   );
 
-
-
-
 END str;
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_adc_input_and_timing.vhd b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_adc_input_and_timing.vhd
index 8a00a000b1..0178f116ae 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_adc_input_and_timing.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_adc_input_and_timing.vhd
@@ -26,20 +26,17 @@
 --   Contains all the signal processing blocks to receive and time the ADC input data
 --   See https://support.astron.nl/confluence/display/STAT/L5+SDPFW+DD%3A+ADC+data+input+and+timestamp
 
-LIBRARY IEEE, common_lib, technology_lib, diag_lib, aduh_lib, dp_lib, tech_jesd204b_lib, st_lib;
+LIBRARY IEEE, common_lib, diag_lib, aduh_lib, dp_lib, tech_jesd204b_lib, st_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
 USE IEEE.NUMERIC_STD.ALL;
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
-USE technology_lib.technology_pkg.ALL;
-USE technology_lib.technology_select_pkg.ALL;
 USE diag_lib.diag_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
 USE work.disturb_pkg.ALL;
 
 ENTITY node_disturb_adc_input_and_timing IS
   GENERIC (
-    g_technology              : NATURAL := c_tech_select_default;
     g_no_jesd                 : BOOLEAN := FALSE;
     g_buf_nof_data            : NATURAL := c_disturb_V_si_db;
     g_bsn_nof_clk_per_sync    : NATURAL := c_disturb_N_clk_per_sync;  -- Default 200M, overide for short simulation
@@ -143,9 +140,11 @@ ARCHITECTURE str OF node_disturb_adc_input_and_timing IS
   SIGNAL nxt_mux_sosi_arr           : t_dp_sosi_arr(c_disturb_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL st_sosi_arr                : t_dp_sosi_arr(c_disturb_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);    
 
-  SIGNAL mm_rst_internal            : STD_LOGIC; 
-  SIGNAL mm_jesd_ctrl_reg           : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
-  SIGNAL jesd204b_disable_arr       : STD_LOGIC_VECTOR(c_disturb_S_pn-1 DOWNTO 0);
+  SIGNAL mm_rst_jesd                : STD_LOGIC;
+  SIGNAL mm_jesd_ctrl_reg_wr        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL mm_jesd_ctrl_reg_rd        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL jesd204b_disable_arr       : STD_LOGIC_VECTOR(c_sdp_S_pn-1 DOWNTO 0);
+  SIGNAL jesd204b_reset_request     : STD_LOGIC := '0';
 
 BEGIN
 
@@ -155,18 +154,30 @@ BEGIN
     rx_sysref <= dp_pps;
   END GENERATE;
 
-  -- The node AIT is reset at power up by mm_rst and under software control by jesd204b_disable_arr.
-  -- The mm_rst internal will cause a reset on the rx_rst by the reset sequencer in the u_jesd204b.
-  -- The MM jesd204b_disable_arr is intended for node AIT resynchronisation tests of the u_jesd204b.
-  -- The MM jesd204b_disable_arr should not be applied in an SDP application, because this will cause
+  -- The node AIT is reset at power up by mm_rst and under software control by mm_rst_jesd.
+  -- The mm_rst_jesd will cause a reset on the rx_rst by the reset sequencer in the u_jesd204b.
+  -- The mm_rst_jesd is intended for node AIT resynchronisation tests of the u_jesd204b.
+  -- The mm_rst_jesd should not be applied in an active SDP application, because this will cause
   -- a disturbance in the block timing of the out_sosi_arr(i).sync,bsn,sop,eop. The other logic
   -- in an SDP application assumes that the block timing of the out_sosi_arr(i) only contains
-  -- complete blocks, so from sop to eop.
+  -- complete blocks, so from sop to eop. Therefore, first mms_dp_bsn_source_v2 should be
+  -- disabled to stop and flush the block processing, before applying mm_rst_jesd.
 
-  mm_rst_internal <= mm_rst OR mm_jesd_ctrl_reg(31);
-  gen_jesd_disable : FOR I IN 0 TO c_disturb_S_pn-1 GENERATE
-    jesd204b_disable_arr(i) <= mm_jesd_ctrl_reg(i);
-  END GENERATE;
+  -- Only accept JESD204B IP reset when the processing is disabled (indicated by bs_sosi.valid
+  -- = '0'), to avoid corrupt bs_sosi blocks entering the subsequent processing due to that a
+  -- JESD204B IP reset causes that the rx_clk stops.
+  mm_rst_jesd <= mm_rst OR jesd204b_reset_request;
+
+  jesd204b_disable_arr <= mm_jesd_ctrl_reg_wr(c_sdp_S_pn-1 DOWNTO 0);
+  jesd204b_reset_request <= mm_jesd_ctrl_reg_wr(c_sdp_jesd_ctrl_reset_bi) AND NOT bs_sosi.valid;
+
+  p_mm_jesd_ctrl_reg_rd : PROCESS(mm_jesd_ctrl_reg_wr, jesd204b_reset_request)
+  BEGIN
+    -- default readback what was written
+    mm_jesd_ctrl_reg_rd <= mm_jesd_ctrl_reg_wr;
+    -- report actual JESD204B reset status
+    mm_jesd_ctrl_reg_rd(c_sdp_jesd_ctrl_reset_bi) <= jesd204b_reset_request;
+  END PROCESS;
 
   gen_jesd : IF g_no_jesd = FALSE GENERATE
     -----------------------------------------------------------------------------
@@ -175,7 +186,7 @@ BEGIN
     
     u_jesd204b: ENTITY tech_jesd204b_lib.tech_jesd204b 
     GENERIC MAP(
-      g_sim                => g_sim,               
+      g_sim                => FALSE, -- do not use g_sim, because JESD204B IP does support mm_clk in sim
       g_nof_streams        => c_disturb_S_pn,
       g_nof_sync_n         => c_disturb_N_sync_jesd,
       g_jesd_freq          => c_disturb_jesd204b_freq
@@ -194,7 +205,7 @@ BEGIN
     
       -- MM
       mm_clk               => mm_clk,           
-      mm_rst               => mm_rst_internal,           
+      mm_rst               => mm_rst_jesd,
     
       jesd204b_mosi        => jesd204b_mosi,         
       jesd204b_miso        => jesd204b_miso,         
@@ -203,8 +214,7 @@ BEGIN
       serial_tx_arr        => open,
       serial_rx_arr        => JESD204B_SERIAL_DATA(c_disturb_S_pn-1 downto 0)
     );
-  
-  
+
     -----------------------------------------------------------------------------
     -- Time delay: dp_shiftram
     -- . copied from unb1_bn_capture_input (apertif)
@@ -223,7 +233,6 @@ BEGIN
       END LOOP;
     END PROCESS;
   
-  
     u_dp_shiftram : ENTITY dp_lib.dp_shiftram
     GENERIC MAP (
       g_nof_streams => c_disturb_S_pn, 
@@ -235,7 +244,7 @@ BEGIN
       dp_rst   => rx_rst,
       dp_clk   => rx_clk,
   
-      mm_rst   => mm_rst_internal,
+      mm_rst   => mm_rst,
       mm_clk   => mm_clk,
   
       sync_in  => bs_sosi.sync,
@@ -261,7 +270,7 @@ BEGIN
   )
   PORT MAP (
     -- Clocks and reset
-    mm_rst            => mm_rst_internal,
+    mm_rst            => mm_rst,
     mm_clk            => mm_clk,
     dp_rst            => rx_rst,
     dp_clk            => rx_clk,
@@ -284,7 +293,7 @@ BEGIN
   )
   PORT MAP (
     -- Memory-mapped clock domain
-    mm_rst      => mm_rst_internal,
+    mm_rst      => mm_rst,
     mm_clk      => mm_clk,
 
     reg_mosi    => reg_bsn_scheduler_wg_mosi,
@@ -321,7 +330,7 @@ BEGIN
   )
   PORT MAP (
     -- Memory-mapped clock domain
-    mm_rst              => mm_rst_internal,
+    mm_rst              => mm_rst,
     mm_clk              => mm_clk,
 
     reg_mosi            => reg_wg_mosi,
@@ -390,7 +399,7 @@ BEGIN
   )
   PORT MAP (
     -- Memory-mapped clock domain
-    mm_rst      => mm_rst_internal,
+    mm_rst      => mm_rst,
     mm_clk      => mm_clk,
     reg_mosi    => reg_bsn_monitor_input_mosi,
     reg_miso    => reg_bsn_monitor_input_miso,
@@ -415,7 +424,7 @@ BEGIN
   )
   PORT MAP (
     -- Memory-mapped clock domain
-    mm_rst         => mm_rst_internal,
+    mm_rst         => mm_rst,
     mm_clk         => mm_clk,
 
     reg_mosi       => reg_aduh_monitor_mosi, -- read only access to the signal path data mean sum and power sum registers
@@ -437,14 +446,13 @@ BEGIN
 
   u_diag_data_buffer_bsn : ENTITY diag_lib.mms_diag_data_buffer
   GENERIC MAP (
-    g_technology   => g_technology,
     g_nof_streams  => c_disturb_S_pn,
     g_data_w       => c_disturb_W_adc,
     g_buf_nof_data => g_buf_nof_data,
     g_buf_use_sync => TRUE -- when TRUE start filling the buffer at the in_sync, else after the last word was read
   )
   PORT MAP (
-    mm_rst            => mm_rst_internal,
+    mm_rst            => mm_rst,
     mm_clk            => mm_clk,
     dp_rst            => rx_rst,
     dp_clk            => rx_clk,
@@ -470,7 +478,7 @@ BEGIN
     g_nof_data_per_sync_diff => c_disturb_N_fft/2 
   )
   PORT MAP (
-    mm_rst            => mm_rst_internal,
+    mm_rst            => mm_rst,
     mm_clk            => mm_clk,
     dp_rst            => rx_rst,
     dp_clk            => rx_clk,
@@ -516,7 +524,7 @@ BEGIN
   -----------------------------------------------------------------------------
   u_mm_jesd_ctrl_reg : ENTITY common_lib.common_reg_r_w
   GENERIC MAP (
-    g_reg       => c_disturb_jesd204b_mm_jesd_ctrl_reg,
+    g_reg       => c_disturb_mm_jesd_ctrl_reg,
     g_init_reg  => (OTHERS => '0')
   )
   PORT MAP (
@@ -524,15 +532,15 @@ BEGIN
     clk       => mm_clk,
     -- control side
     wr_en     => jesd_ctrl_mosi.wr,
-    wr_adr    => jesd_ctrl_mosi.address(c_disturb_jesd204b_mm_jesd_ctrl_reg.adr_w-1 DOWNTO 0),
-    wr_dat    => jesd_ctrl_mosi.wrdata(c_disturb_jesd204b_mm_jesd_ctrl_reg.dat_w-1 DOWNTO 0),
+    wr_adr    => jesd_ctrl_mosi.address(c_disturb_mm_jesd_ctrl_reg.adr_w-1 DOWNTO 0),
+    wr_dat    => jesd_ctrl_mosi.wrdata(c_disturb_mm_jesd_ctrl_reg.dat_w-1 DOWNTO 0),
     rd_en     => jesd_ctrl_mosi.rd,
-    rd_adr    => jesd_ctrl_mosi.address(c_disturb_jesd204b_mm_jesd_ctrl_reg.adr_w-1 DOWNTO 0),
-    rd_dat    => jesd_ctrl_miso.rddata(c_disturb_jesd204b_mm_jesd_ctrl_reg.dat_w-1 DOWNTO 0),
+    rd_adr    => jesd_ctrl_mosi.address(c_disturb_mm_jesd_ctrl_reg.adr_w-1 DOWNTO 0),
+    rd_dat    => jesd_ctrl_miso.rddata(c_disturb_mm_jesd_ctrl_reg.dat_w-1 DOWNTO 0),
     rd_val    => OPEN,
     -- data side
-    out_reg   => mm_jesd_ctrl_reg,
-    in_reg    => mm_jesd_ctrl_reg
+    out_reg   => mm_jesd_ctrl_reg_wr,
+    in_reg    => mm_jesd_ctrl_reg_rd
   );
 
 END str;
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_beamformer.vhd b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_beamformer.vhd
index b2c21e4b5c..adadc0a5d4 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_beamformer.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_beamformer.vhd
@@ -41,7 +41,7 @@ USE work.disturb_pkg.ALL;
 ENTITY node_disturb_beamformer IS
   GENERIC (
     g_sim                    : BOOLEAN := FALSE;
-    g_sim_disturb                : t_disturb_sim := c_disturb_sim;
+    g_sim_disturb            : t_disturb_sim := c_disturb_sim;
     g_beamset_id             : NATURAL := 0;
     g_scope_selected_beamlet : NATURAL := 0
   );
@@ -310,7 +310,8 @@ BEGIN
     g_nof_stat      => c_disturb_S_sub_bf*c_disturb_N_pol_bf,
     g_in_data_w     => c_disturb_W_beamlet_sum,
     g_stat_data_w   => c_longword_w,
-    g_stat_data_sz  => c_longword_sz/c_word_sz
+    g_stat_data_sz  => c_longword_sz/c_word_sz,
+    g_stat_multiplex=> c_disturb_N_pol_bf
   )
   PORT MAP (
     mm_rst          => mm_rst,
@@ -383,7 +384,7 @@ BEGIN
 
     gn_index     => TO_UINT(gn_id),
     ring_info    => ring_info,
-    disturb_info     => disturb_info,
+    disturb_info => disturb_info,
     weighted_subbands_flag => '1'  -- because BF uses in_sosi_arr = fsub_sosi_arr, so weighted subbands
   );
 
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_correlator.vhd b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_correlator.vhd
index d8869dd499..2efd538c19 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_correlator.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_correlator.vhd
@@ -23,10 +23,12 @@
 -- Author: R. van der Walle
 -- Purpose: 
 -- . Implements the functionality of the Subband Correlator in the 
---   LOFAR2 SDPFW design.
+--   DISTURB2 SDPFW design.
 -- Description:
 -- Remark:
--- .
+-- . Use new_interval to avoid offloading undefined XST data for the first
+--   sync interval after an F_sub restart, because then there is no previous
+--   sync interval with valid XST data yet.
 -------------------------------------------------------------------------------
 
 LIBRARY IEEE, common_lib, dp_lib, reorder_lib, st_lib, mm_lib, ring_lib;
@@ -41,7 +43,7 @@ USE work.disturb_pkg.ALL;
 ENTITY node_disturb_correlator IS
   GENERIC (
     g_sim            : BOOLEAN := FALSE;
-    g_sim_disturb        : t_disturb_sim := c_disturb_sim;
+    g_sim_disturb    : t_disturb_sim := c_disturb_sim;
     g_P_sq           : NATURAL := c_disturb_P_sq
   );
   PORT (
@@ -78,7 +80,7 @@ ENTITY node_disturb_correlator IS
     reg_bsn_monitor_v2_xst_offload_copi      : IN  t_mem_copi := c_mem_copi_rst;
     reg_bsn_monitor_v2_xst_offload_cipo      : OUT t_mem_cipo;
 
-    disturb_info          : IN t_disturb_info;
+    disturb_info      : IN t_disturb_info;
     ring_info         : IN t_ring_info;
     gn_id             : IN STD_LOGIC_VECTOR(c_disturb_W_gn_id-1 DOWNTO 0);
     stat_eth_src_mac  : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
@@ -118,6 +120,8 @@ ARCHITECTURE str OF node_disturb_correlator IS
   SIGNAL xsel_data_sosi                : t_dp_sosi := c_dp_sosi_rst;
   SIGNAL local_sosi                    : t_dp_sosi := c_dp_sosi_rst;
 
+  SIGNAL new_interval                  : STD_LOGIC;
+
   SIGNAL ring_mux_sosi                 : t_dp_sosi := c_dp_sosi_rst;
   SIGNAL ring_mux_siso                 : t_dp_siso := c_dp_siso_rdy;
   SIGNAL dp_fifo_fill_sosi             : t_dp_sosi := c_dp_sosi_rst;
@@ -131,7 +135,7 @@ ARCHITECTURE str OF node_disturb_correlator IS
   SIGNAL crosslets_cipo_arr            : t_mem_cipo_arr(g_P_sq-1 DOWNTO 0) := (OTHERS => c_mem_cipo_rst); 
   SIGNAL mon_xst_udp_sosi_arr          : t_dp_sosi_arr(0 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
 
-  SIGNAL crosslets_info                : STD_LOGIC_VECTOR(c_disturb_crosslets_info_reg_w-1 DOWNTO 0);
+  SIGNAL prev_crosslets_info_rec       : t_disturb_crosslets_info;
   SIGNAL nof_crosslets_reg             : STD_LOGIC_VECTOR(c_disturb_nof_crosslets_reg_w-1 DOWNTO 0);
   SIGNAL nof_crosslets                 : STD_LOGIC_VECTOR(c_disturb_nof_crosslets_reg_w-1 DOWNTO 0);
 BEGIN
@@ -175,6 +179,8 @@ BEGIN
     in_sosi_arr    => quant_sosi_arr,
     out_sosi       => xsel_sosi,
 
+    new_interval   => new_interval,
+
     mm_rst         => mm_rst,
     mm_clk         => mm_clk,
 
@@ -184,7 +190,8 @@ BEGIN
     reg_bsn_sync_scheduler_xsub_mosi => reg_bsn_sync_scheduler_xsub_copi,
     reg_bsn_sync_scheduler_xsub_miso => reg_bsn_sync_scheduler_xsub_cipo,
                             
-    out_crosslets_info => crosslets_info
+    cur_crosslets_info_rec => OPEN,
+    prev_crosslets_info_rec => prev_crosslets_info_rec
   );
  
   -- Use xsel_sosi as local bsn and sync reference since the sync
@@ -325,7 +332,7 @@ BEGIN
     g_use_mm_output           => TRUE,   
     g_rd_latency              => 1, -- Required for st_xst 
     -- for mms_dp_bsn_monitor_v2
-    g_nof_clk_per_sync        => c_disturb_N_clk_sync_timeout, -- Using c_disturb_N_clk_sync_timeout as g_nof_clk_per_sync is used for BSN monitor timeout.
+    g_nof_clk_per_sync        => c_disturb_N_clk_sync_timeout_xsub, -- Using c_disturb_N_clk_sync_timeout_xsub as g_nof_clk_per_sync is used for BSN monitor timeout.
     g_nof_input_bsn_monitors  => g_P_sq,  
     g_use_bsn_output_monitor  => TRUE  
     )
@@ -425,6 +432,7 @@ BEGIN
     in_reg   => nof_crosslets,
     out_reg  => nof_crosslets_reg
   );
+
   -- Force nof crosslets to max nof crosslets if a higher value is written or to 1 if a lower value is written via MM.
   nof_crosslets <= TO_UVEC(1, c_disturb_nof_crosslets_reg_w) WHEN TO_UINT(nof_crosslets_reg) < 1 ELSE 
                    nof_crosslets_reg WHEN TO_UINT(nof_crosslets_reg) <= c_disturb_N_crosslets_max ELSE 
@@ -434,12 +442,14 @@ BEGIN
   -- XST UDP offload 
   ---------------------------------------------------------------
   xst_udp_sosi <= mon_xst_udp_sosi_arr(0);
+
   u_disturb_xst_udp_offload: ENTITY work.disturb_statistics_offload
   GENERIC MAP (
-    g_statistics_type     => "XST",
-    g_offload_time        => sel_a_b(g_sim, g_sim_disturb.offload_time, c_disturb_offload_time),
-    g_P_sq                => g_P_sq,
-    g_crosslets_direction => 1  -- = lane direction
+    g_statistics_type          => "XST",
+    g_offload_time             => sel_a_b(g_sim, g_sim_disturb.offload_time, c_disturb_offload_time),
+    g_P_sq                     => g_P_sq,
+    g_crosslets_direction      => 1,  -- = lane direction
+    g_bsn_monitor_sync_timeout => c_disturb_N_clk_sync_timeout_xsub
   )
   PORT MAP (
     mm_clk    => mm_clk,
@@ -460,7 +470,9 @@ BEGIN
     reg_bsn_monitor_v2_offload_copi => reg_bsn_monitor_v2_xst_offload_copi,
     reg_bsn_monitor_v2_offload_cipo => reg_bsn_monitor_v2_xst_offload_cipo,
 
-    in_sosi   => crosslets_sosi,
+    in_sosi      => crosslets_sosi,
+    new_interval => new_interval,
+
     out_sosi  => mon_xst_udp_sosi_arr(0),
     out_siso  => xst_udp_siso,
 
@@ -472,8 +484,9 @@ BEGIN
     ring_info      => ring_info,
     disturb_info       => disturb_info,
     weighted_subbands_flag  => '1',  -- because XSub uses in_sosi_arr = fsub_sosi_arr, so weighted subbands
-    nof_crosslets  => nof_crosslets,
-    crosslets_info => crosslets_info
+
+    nof_crosslets      => nof_crosslets,
+    crosslets_info_rec => prev_crosslets_info_rec
   );
 
 END str;
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_filterbank.vhd b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_filterbank.vhd
index a8d96b9a2d..6cd1ffb837 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_filterbank.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_filterbank.vhd
@@ -49,7 +49,7 @@ USE work.disturb_pkg.ALL;
 ENTITY node_disturb_filterbank IS
   GENERIC (
     g_sim                    : BOOLEAN := FALSE;
-    g_sim_disturb                : t_disturb_sim := c_disturb_sim;
+    g_sim_disturb            : t_disturb_sim := c_disturb_sim;
     g_wpfb                   : t_wpfb := c_disturb_wpfb_subbands;
     g_scope_selected_subband : NATURAL := 0
   );
@@ -86,7 +86,7 @@ ENTITY node_disturb_filterbank IS
     reg_bsn_monitor_v2_sst_offload_cipo : OUT t_mem_cipo;
 
     disturb_info : IN t_disturb_info;
-    gn_id    : IN STD_LOGIC_VECTOR(c_disturb_W_gn_id-1 DOWNTO 0);
+    gn_id        : IN STD_LOGIC_VECTOR(c_disturb_W_gn_id-1 DOWNTO 0);
 
     eth_src_mac  : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
     ip_src_addr  : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0);
@@ -262,7 +262,8 @@ BEGIN
         g_nof_stat      => c_disturb_N_sub*c_disturb_Q_fft,
         g_in_data_w     => c_disturb_W_subband,
         g_stat_data_w   => g_wpfb.stat_data_w,
-        g_stat_data_sz  => g_wpfb.stat_data_sz
+        g_stat_data_sz  => g_wpfb.stat_data_sz,
+        g_stat_multiplex=> c_disturb_Q_fft
       )
       PORT MAP (
         mm_rst          => mm_rst,
@@ -368,7 +369,7 @@ BEGIN
     ip_src_addr  => ip_src_addr,
 
     gn_index                => TO_UINT(gn_id),
-    disturb_info                => disturb_info,
+    disturb_info            => disturb_info,
     weighted_subbands_flag  => weighted_subbands_flag
   );
 
diff --git a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_oversampled_filterbank.vhd b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_oversampled_filterbank.vhd
index ca30271d07..291879ee74 100644
--- a/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_oversampled_filterbank.vhd
+++ b/applications/disturb2/libraries/disturb/src/vhdl/node_disturb_oversampled_filterbank.vhd
@@ -569,10 +569,11 @@ BEGIN
   gen_stats_streams: FOR I IN 0 TO c_disturb_V_oversample * c_disturb_P_pfb-1 GENERATE
     u_subband_stats : ENTITY st_lib.st_sst
       GENERIC MAP(
-        g_nof_stat      => c_disturb_N_sub*c_disturb_Q_fft,
-        g_in_data_w     => c_disturb_W_subband,
-        g_stat_data_w   => g_wpfb.stat_data_w,
-        g_stat_data_sz  => g_wpfb.stat_data_sz
+        g_nof_stat       => c_disturb_N_sub*c_disturb_Q_fft,
+        g_in_data_w      => c_disturb_W_subband,
+        g_stat_data_w    => g_wpfb.stat_data_w,
+        g_stat_data_sz   => g_wpfb.stat_data_sz, 
+        g_stat_multiplex => c_disturb_Q_fft
       )
       PORT MAP (
         mm_rst          => mm_rst,
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
index c7d6f7fc46..52c400be4b 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
@@ -59,7 +59,7 @@ END sdp_beamformer_local;
 ARCHITECTURE str OF sdp_beamformer_local IS
   
   CONSTANT c_complex_adder_latency : NATURAL := ceil_log2(c_sdp_S_pn);
-  CONSTANT c_bf_weights_latency    : NATURAL := 5;
+  CONSTANT c_bf_weights_latency    : NATURAL := 5; -- 3 for complex multiplier + 2 RAM latency
   CONSTANT c_total_latency         : NATURAL := 3 + c_bf_weights_latency + c_complex_adder_latency; 
 
   CONSTANT c_complex_adder_sum_w : NATURAL := c_sdp_W_bf_product + ceil_log2(c_sdp_S_pn); 
-- 
GitLab