diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
index c249bdfbf36cd3bfb72c435d906390f3187bf112..da901213a23fee1782471b330fee9210c8d33a0d 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
@@ -195,7 +195,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
   CONSTANT c_stat_lo_factor      : REAL := 1.0 - c_stat_percentage;  -- lower boundary
   CONSTANT c_stat_hi_factor      : REAL := 1.0 + c_stat_percentage;  -- higher boundary
 
-  CONSTANT c_nof_beamlets_per_data : NATURAL := 2;  -- 2 dual pol beamlets (= XY, XY) per 64b data word
+  CONSTANT c_nof_beamlets_per_data : NATURAL := c_sdp_cep_nof_beamlets_per_longword;  -- = 2 dual pol beamlets per 64b data word
 
   CONSTANT c_beamlet_output_delta : INTEGER := 2;  -- +-delta margin
 
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd
index dd52d4eb206cf007076a9b100f4e9e00400e8d28..270ce27dea1c2cf60728dd488e7e075267b6d1be 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd
@@ -249,8 +249,8 @@ BEGIN
     g_nof_streams         => 1,
     g_data_w              => c_word_w,
     g_hdr_field_arr       => c_sdp_stat_hdr_field_arr,
-    g_remove_crc          => FALSE,
-    g_crc_nof_words       => 0
+    g_remove_crc          => TRUE,
+    g_crc_nof_words       => 1
   )
   PORT MAP (
     mm_rst                => pps_rst,
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub_sst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub_sst_offload.vhd
index 5b14cb9aea233df7b59df0ff7031032d571d7f40..74694c689dfd0849fffcea7de86c61886b268e8e 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub_sst_offload.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub_sst_offload.vhd
@@ -248,8 +248,8 @@ BEGIN
     g_nof_streams         => 1,
     g_data_w              => c_word_w,
     g_hdr_field_arr       => c_sdp_stat_hdr_field_arr,
-    g_remove_crc          => FALSE,
-    g_crc_nof_words       => 0
+    g_remove_crc          => TRUE,
+    g_crc_nof_words       => 1
   )
   PORT MAP (
     mm_rst                => pps_rst,
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd
index a11dac56788bf43d7cbb73d8bfba830f7a65832e..55315adbd57b1bb9dc6bce4e43b2f260c5f35b49 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd
@@ -34,8 +34,21 @@
 -- Usage:
 --   > as 7    # default
 --   > as 12   # for detailed debugging
+--   And add more missing sosi_arr signals or constants via sim tab, entity instance in hierarchy and
+--   then select from objects window, e.g. for:
+--   > add wave -position insertpoint  \
+--     sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/ait_sosi_arr \
+--     sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/pfb_sosi_arr \
+--     sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/fsub_sosi_arr \
+--     sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/bs_sosi
+--   > add wave -position insertpoint  \
+--     sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/c_exp_subband_xst
 --   > run -a  
---   Takes about 10 m
+--   Takes about 50 m
+-- View e.g.:
+--   * rx_sdp_stat_re/im in radix decimal and in format literal or analogue
+--   * rx_sdp_stat_header.app
+--   * new_interval in node_sdp_correlator.vhd
 --
 -------------------------------------------------------------------------------
 LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2c_sdp_station_lib, eth_lib;
@@ -76,13 +89,29 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS
   CONSTANT c_pps_period          : NATURAL := c_nof_clk_per_sync;
   CONSTANT c_wpfb_sim            : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
   CONSTANT c_ctrl_interval_size  : NATURAL := c_nof_clk_per_sync;
+  CONSTANT c_nof_crosslets       : NATURAL := 3;  -- not too large, so that offload still fits in c_nof_block_per_sync
   CONSTANT c_subband_select_arr  : t_natural_arr(0 TO c_sdp_N_crosslets_max-1) := (10, 11, 12, 13, 14, 15, 16);
-  CONSTANT c_subband_step        : NATURAL := 0;
-  CONSTANT c_nof_crosslets       : NATURAL := 3;
-  CONSTANT c_nof_sync            : NATURAL := 2;
+  CONSTANT c_subband_step        : NATURAL := 3;  -- e.g. 0 or c_nof_crosslets
+  CONSTANT c_nof_sync            : NATURAL := 3;
 
-  -- MM  
+  CONSTANT c_max_ratio           : REAL := 0.001;  -- ratio that actual value may differ from expected value
+
+  -- WG
+  CONSTANT c_bsn_start_wg         : NATURAL := 2;
+  CONSTANT c_sp_ampl              : REAL := 0.5;   -- WG normalized amplitude, 1.0 = FS (full scale), use <= 0.5 to avoid XST overflow
+  CONSTANT c_wg_ampl              : NATURAL := NATURAL(c_sp_ampl * REAL(c_sdp_FS_adc));  -- in number of lsb
+  CONSTANT c_wg_subband           : NATURAL := 12;
+
+  -- WPFB
+  CONSTANT c_exp_subband_ampl     : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio;  -- = c_wg_ampl * 0.994817 * 8
+  CONSTANT c_exp_subband_power    : REAL := c_exp_subband_ampl**2.0;  -- complex, so no divide by 2
+  CONSTANT c_exp_subband_sst      : REAL := c_exp_subband_power * REAL(c_nof_block_per_sync);
+  CONSTANT c_exp_subband_xst      : REAL := c_exp_subband_sst;  -- all signal inputs use same WG, and auto correlation XST = SST
+
+  -- MM
   CONSTANT c_mm_file_reg_bsn_source_v2           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
+  CONSTANT c_mm_file_reg_bsn_scheduler_wg        : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
+  CONSTANT c_mm_file_reg_diag_wg                 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
   CONSTANT c_mm_file_reg_crosslets_info          : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_CROSSLETS_INFO";
   CONSTANT c_mm_file_reg_nof_crosslets           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_NOF_CROSSLETS";
   CONSTANT c_mm_file_reg_bsn_sync_scheduler_xsub : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SYNC_SCHEDULER_XSUB";
@@ -113,22 +142,38 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS
   SIGNAL INTA                : STD_LOGIC;
   SIGNAL INTB                : STD_LOGIC;
 
-  SIGNAL eth_clk             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0');
-  SIGNAL eth_txp             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0');
-  SIGNAL eth_rxp             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0');
+  SIGNAL eth_clk             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL eth_txp             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL eth_rxp             : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0');
+
+  -- WG
+  SIGNAL current_bsn_wg      : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
 
   -- Rx packets
   SIGNAL eth_rx_sosi         : t_dp_sosi;
-  SIGNAL eth_rx_data         : STD_LOGIC_VECTOR(c_32-1 downto 0);
+  SIGNAL eth_rx_data         : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
 
   -- Decode packets
   SIGNAL rx_offload_sosi     : t_dp_sosi;
+
+  -- . view payload statistics data
+  SIGNAL rx_word_cnt         : NATURAL := 0;
+  SIGNAL rx_sdp_stat_data    : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
+  SIGNAL rx_sdp_stat_re      : STD_LOGIC_VECTOR(c_64-1 DOWNTO 0);
+  SIGNAL rx_sdp_stat_im      : STD_LOGIC_VECTOR(c_64-1 DOWNTO 0);
+  SIGNAL rx_sdp_stat_re_val  : STD_LOGIC := '0';
+  SIGNAL rx_sdp_stat_im_val  : STD_LOGIC := '0';
+  SIGNAL rx_sdp_stat_index   : NATURAL := 0;
+  SIGNAL rx_a_sp             : NATURAL := 0;
+  SIGNAL rx_b_sp             : NATURAL := 0;
+
+  -- . view header
   SIGNAL rx_hdr_fields_out   : STD_LOGIC_VECTOR(1023 DOWNTO 0);
   SIGNAL rx_hdr_fields_raw   : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0');
   SIGNAL rx_sdp_stat_header  : t_sdp_stat_header;
 
   -- back transceivers
-  SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0);
+  SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 DOWNTO 0);
   SIGNAL JESD204B_REFCLK      : STD_LOGIC := '1';
 
   -- jesd204b syncronization signals
@@ -203,6 +248,7 @@ BEGIN
   tb_clk  <= NOT tb_clk AFTER c_tb_clk_period/2;    -- Testbench MM clock
   
   p_mm_stimuli : PROCESS
+    VARIABLE v_bsn  : NATURAL;
   BEGIN
     -- Wait for DUT power up after reset
     WAIT FOR 1 us;
@@ -219,6 +265,32 @@ BEGIN
     WAIT FOR 1 us;
     pps_rst <= '0';
 
+    ----------------------------------------------------------------------------
+    -- Enable and start WG
+    ----------------------------------------------------------------------------
+    --   0 : mode[7:0]           --> off=0, calc=1, repeat=2, single=3)
+    --       nof_samples[31:16]  --> <= c_ram_wg_size=1024
+    --   1 : phase[15:0]
+    --   2 : freq[30:0]
+    --   3 : ampl[16:0]
+    FOR I IN 0 TO c_sdp_S_pn-1 LOOP
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 0, 1024*2**16 + 1, tb_clk);  -- nof_samples, mode calc
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 1, INTEGER(0.0 * c_diag_wg_phase_unit), tb_clk);  -- phase offset in degrees
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 2, INTEGER(REAL(c_wg_subband) * c_sdp_wg_subband_freq_unit), tb_clk);  -- freq
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk);  -- ampl
+    END LOOP;
+
+    -- Read current BSN
+    mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO  0), tb_clk);
+    mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk);
+    proc_common_wait_some_cycles(tb_clk, 1);
+
+    -- Write scheduler BSN to trigger start of WG at next block
+    v_bsn := TO_UINT(current_bsn_wg) + 2;
+    ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, c_bsn_start_wg, tb_clk);  -- first write low then high part
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1,              0, tb_clk);  -- assume v_bsn < 2**31-1
+
     ----------------------------------------------------------------------------
     -- Setup and enable xsub
     ----------------------------------------------------------------------------
@@ -274,14 +346,14 @@ BEGIN
 
   eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0);
 
-  -- . Verify XST packet header
+  -- . View / verify XST packet header
   u_rx_statistics : ENTITY dp_lib.dp_offload_rx
   GENERIC MAP (
     g_nof_streams         => 1,
     g_data_w              => c_word_w,
     g_hdr_field_arr       => c_sdp_stat_hdr_field_arr,
-    g_remove_crc          => FALSE,
-    g_crc_nof_words       => 0
+    g_remove_crc          => TRUE,
+    g_crc_nof_words       => 1
   )
   PORT MAP (
     mm_rst                => pps_rst,
@@ -300,4 +372,74 @@ BEGIN
 
   rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw);
 
+  -- . View / verify XST packet payload
+  p_rx_sdp_view_stat_data : PROCESS(eth_clk(0))
+  BEGIN
+    IF rising_edge(eth_clk(0)) THEN
+      rx_sdp_stat_re_val <= '0';
+      rx_sdp_stat_im_val <= '0';
+      IF rx_offload_sosi.valid = '1' THEN
+        -- Count words 0, 1, 2, 3
+        rx_word_cnt <= 0;
+        IF rx_word_cnt < c_sdp_N_pol * c_nof_complex - 1 THEN
+          rx_word_cnt <= rx_word_cnt + 1;
+        END IF;
+
+        -- Count words for the complex statistics with two 32bits words per 64 bit statistic,
+        -- high word part and real data received first.
+        CASE rx_word_cnt IS
+          WHEN 0 => rx_sdp_stat_data <= rx_offload_sosi.data(c_32-1 DOWNTO 0);
+          WHEN 1 => rx_sdp_stat_re   <= rx_sdp_stat_data & rx_offload_sosi.data(c_32-1 DOWNTO 0);
+                    rx_sdp_stat_re_val <= '1';
+          WHEN 2 => rx_sdp_stat_data <= rx_offload_sosi.data(c_32-1 DOWNTO 0);
+          WHEN 3 => rx_sdp_stat_im   <= rx_sdp_stat_data & rx_offload_sosi.data(c_32-1 DOWNTO 0);
+                    rx_sdp_stat_im_val <= '1';
+          WHEN OTHERS => NULL;
+        END CASE;
+      END IF;
+
+      -- Count the complex statistics
+      IF rx_sdp_stat_im_val = '1' THEN
+        rx_sdp_stat_index <= rx_sdp_stat_index + 1;
+      END IF;
+
+      IF rx_offload_sosi.sop = '1' THEN
+        rx_sdp_stat_index <= 0;  -- restart per Rx packet
+      END IF;
+    END IF;
+  END PROCESS;
+
+  p_rx_sdp_verify_stat_data : PROCESS(eth_clk(0))
+    VARIABLE v_subband_ix : NATURAL;  -- _ix = index
+  BEGIN
+    IF rising_edge(eth_clk(0)) THEN
+      v_subband_ix := TO_UINT(rx_sdp_stat_header.app.sdp_data_id_xst_subband_index);
+      -- real part
+      IF rx_sdp_stat_re_val = '1' THEN
+        IF v_subband_ix = c_wg_subband THEN
+          -- Expect the strong XST value at the WG subband
+          ASSERT almost_equal(TO_SREAL(rx_sdp_stat_re) / c_exp_subband_xst, 1.0, c_max_ratio) REPORT "Wrong XST real value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR;
+        ELSE
+          -- WG is only in one subband, so expect almost zero in the other subbands
+          ASSERT almost_zero(TO_SREAL(rx_sdp_stat_re) / c_exp_subband_xst, c_max_ratio) REPORT "Too large XST real value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR;
+        END IF;
+      END IF;
+      IF rx_sdp_stat_im_val = '1' THEN
+        -- All WG have same phase, so expect zero imaginary part.
+        -- . The imag part is exactly zero for signal inputs a and b that are both connected to the corresponding input of the WPFB.
+        -- . The imag part is  almost zero for signal inputs a and b that are both connected to the opposite inputs of the WPFB, due
+        --   to crosstalk rounding difference from input a to b or from input b to a of the complex FFT.
+        IF (rx_a_sp MOD c_sdp_Q_fft) = (rx_b_sp MOD c_sdp_Q_fft) THEN
+          ASSERT SIGNED(rx_sdp_stat_im) = 0 REPORT "Non zero XST imaginary value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR;
+        ELSE
+          ASSERT almost_zero(TO_SREAL(rx_sdp_stat_im) / c_exp_subband_xst, c_max_ratio) REPORT "Too large XST imaginary value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR;
+        END IF;
+      END IF;
+    END IF;
+  END PROCESS;
+
+  -- rx_sdp_stat_index counts the S_pn * S_pn = X_sq = 12 * 12 = 144 complex statistics
+  rx_a_sp <= rx_sdp_stat_index / c_sdp_S_pn;  -- signal input A
+  rx_b_sp <= rx_sdp_stat_index MOD c_sdp_S_pn;  -- signal input B
+
 END tb;
diff --git a/applications/lofar2/images/images.txt b/applications/lofar2/images/images.txt
index 341a2e0d00c96fd10ee5e2f0f7915fe90bef5451..bad1d5352fff4084b933d82b756a78af8def09bf 100644
--- a/applications/lofar2/images/images.txt
+++ b/applications/lofar2/images/images.txt
@@ -11,7 +11,7 @@ lofar2_unb2b_sdp_station_xsub_one-r087d98be6        | 2021-06-14    | R vd Walle
 unb2b_minimal-rce6b96eed                            | 2021-08-26    | P. Donker            | unb2b_minimal with new mmap, rbf maid with option --unb2_factory
 lofar2_unb2b_sdp_station_full-r9ff51058a            | 2022-01-12    | R vd Walle           | Old Lofar2 SDP station full design for UniBoard2b without ring.
 lofar2_unb2b_sdp_station_full-r2c3958e1f            | 2022-04-29    | R vd Walle           | Lofar2 SDP station full design for UniBoard2b.
-lofar2_unb2b_sdp_station_full_wg-r70b28ffc3         | 2022-06-15    | R vd Walle           | Lofar2 SDP station design without ADC inputs, only WG. Uses dp_clk + dp_pps instead of rx_clk + rx_sysref.
-lofar2_unb2b_sdp_station_full_wg-rf8e898438         | 2022-07-11    | R vd Walle           | Lofar2 SDP station design without ADC inputs, only WG. Uses dp_clk + dp_pps instead of rx_clk + rx_sysref.
-lofar2_unb2c_sdp_station_full-r70484fd08            | 2022-04-29    | R vd Walle           | Lofar2 SDP station full design for UniBoard2c.
-lofar2_unb2c_sdp_station_full-rf8e898438            | 2022-07-11    | R vd Walle           | Lofar2 SDP station full design for UniBoard2c.
+lofar2_unb2b_sdp_station_full_wg-r70b28ffc3         | 2022-06-15    | R vd Walle           | Do not use, has beamlet/subband weight bug, delete when r01205cbe4 is OK.
+lofar2_unb2b_sdp_station_full_wg-r01205cbe4         | 2022-07-14    | R vd Walle           | Lofar2 SDP station design without ADC inputs, only WG. Uses dp_clk + dp_pps instead of rx_clk + rx_sysref.
+lofar2_unb2c_sdp_station_full-r70484fd08            | 2022-04-29    | R vd Walle           | Do not use, has beamlet/subband weight bug, delete when r01205cbe4 is OK.
+lofar2_unb2c_sdp_station_full-r01205cbe4            | 2022-07-14    | R vd Walle           | Lofar2 SDP station full design for UniBoard2c.
diff --git a/applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-rf8e898438.tar.gz b/applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-r01205cbe4.tar.gz
similarity index 66%
rename from applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-rf8e898438.tar.gz
rename to applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-r01205cbe4.tar.gz
index 9920dd7f307b96622cc35684b1d348a2f36be47d..186b0cf9ea654534ab82ddd1ffd7c9e28e0ad5b4 100644
Binary files a/applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-rf8e898438.tar.gz and b/applications/lofar2/images/lofar2_unb2b_sdp_station_full_wg-r01205cbe4.tar.gz differ
diff --git a/applications/lofar2/images/lofar2_unb2c_sdp_station_full-rf8e898438.tar.gz b/applications/lofar2/images/lofar2_unb2c_sdp_station_full-r01205cbe4.tar.gz
similarity index 67%
rename from applications/lofar2/images/lofar2_unb2c_sdp_station_full-rf8e898438.tar.gz
rename to applications/lofar2/images/lofar2_unb2c_sdp_station_full-r01205cbe4.tar.gz
index 308eb264cbb7a46b94a3ba6db271e4b0e222d27a..5fcf627d167aeb69ff14debbc11ae0d4e394a6ea 100644
Binary files a/applications/lofar2/images/lofar2_unb2c_sdp_station_full-rf8e898438.tar.gz and b/applications/lofar2/images/lofar2_unb2c_sdp_station_full-r01205cbe4.tar.gz differ
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd
index 3053b5f21d4b25e3851a0c57cd02ddec09accbac..b1972f74aa3ad94953a3dcdb1587725903982b5c 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd
@@ -310,7 +310,8 @@ BEGIN
     g_nof_stat      => c_sdp_S_sub_bf*c_sdp_N_pol_bf,
     g_in_data_w     => c_sdp_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_sdp_N_pol_bf
   )
   PORT MAP (
     mm_rst          => mm_rst,
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
index 43c17b7a7734a746960722a9ccb37fe0a608027f..d7467674f8b7a78d568da9ea681077fe0a62cde1 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
@@ -22,11 +22,13 @@
 --
 -- Author: R. van der Walle
 -- Purpose: 
--- . Implements the functionality of the Subband Correlator in the 
+-- . Implements the functionality of the Subband Correlator (F_sub) in the
 --   LOFAR2 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;
@@ -118,6 +120,8 @@ ARCHITECTURE str OF node_sdp_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_sdp_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_sdp_crosslets_info_reg_w-1 DOWNTO 0);
+  SIGNAL prev_crosslets_info_rec       : t_sdp_crosslets_info;
   SIGNAL nof_crosslets_reg             : STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0);
   SIGNAL nof_crosslets                 : STD_LOGIC_VECTOR(c_sdp_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
@@ -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_sdp_nof_crosslets_reg_w) WHEN TO_UINT(nof_crosslets_reg) < 1 ELSE 
                    nof_crosslets_reg WHEN TO_UINT(nof_crosslets_reg) <= c_sdp_N_crosslets_max ELSE 
@@ -434,6 +442,7 @@ BEGIN
   -- XST UDP offload 
   ---------------------------------------------------------------
   xst_udp_sosi <= mon_xst_udp_sosi_arr(0);
+
   u_sdp_xst_udp_offload: ENTITY work.sdp_statistics_offload
   GENERIC MAP (
     g_statistics_type          => "XST",
@@ -461,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,9 +483,10 @@ BEGIN
     gn_index       => TO_UINT(gn_id),
     ring_info      => ring_info,
     sdp_info       => sdp_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
+    weighted_subbands_flag => '1',  -- because XSub uses in_sosi_arr = fsub_sosi_arr, so weighted subbands
+
+    nof_crosslets      => nof_crosslets,
+    crosslets_info_rec => prev_crosslets_info_rec
   );
 
 END str;
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
index e7796662df1ae18012395c10cfcc5897f5c49abf..5c11d1481a6dbf3c7ea9edb10ebb7dbdb7031fa8 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
@@ -262,7 +262,8 @@ BEGIN
         g_nof_stat      => c_sdp_N_sub*c_sdp_Q_fft,
         g_in_data_w     => c_sdp_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_sdp_Q_fft
       )
       PORT MAP (
         mm_rst          => mm_rst,
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
index 2a7d53aedc234b28cc2e2a929add7cd0bfbf6a5c..b7638e6df68a210231533e47e986a953a95eba7d 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
@@ -78,9 +78,9 @@ ARCHITECTURE str OF sdp_beamformer_output IS
   CONSTANT c_data_w                 : NATURAL := c_nof_complex*c_sdp_W_beamlet; --16b
   CONSTANT c_beamlet_index          : NATURAL := g_beamset_id * c_sdp_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_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / 2; -- Size of packet: 2 beamlets (dual pol) fit in 1 64bit longword 
+  CONSTANT c_fifo_fill              : NATURAL := c_sdp_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;
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
index 3dec6eb52968ae1f86598a42c32e9e7771852cf2..a32d05170126eac25662f7df361b93231825fd97 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
@@ -120,7 +120,10 @@ BEGIN
     g_gain_w          => c_sdp_W_bf_weight,
     g_in_dat_w        => c_sdp_W_subband,
     g_out_dat_w       => c_gain_out_dat_w,
-    g_gains_file_name => g_gains_file_name
+    g_gains_file_name => g_gains_file_name,
+    -- extra input latency to ease timing.
+    g_pipeline_real_mult_input    => 2, 
+    g_pipeline_complex_mult_input => 2 
   )
   PORT MAP (
     -- System
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd
index 2cc902a393ad0a179fe76657d4931681ca520549..2e9acfb004d6e586a1e032f21cabccc6994b5646 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_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
@@ -45,14 +55,16 @@ ENTITY sdp_crosslets_subband_select IS
     g_ctrl_interval_size_min : NATURAL := c_sdp_xst_nof_clk_per_sync_min
   );
   PORT (
-    dp_clk        : IN  STD_LOGIC;
-    dp_rst        : IN  STD_LOGIC;
+    dp_clk         : IN  STD_LOGIC;
+    dp_rst         : IN  STD_LOGIC;
 
-    in_sosi_arr   : IN  t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);
-    out_sosi      : OUT t_dp_sosi;
+    in_sosi_arr    : IN  t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);
+    out_sosi       : OUT t_dp_sosi;
 
-    mm_rst        : IN  STD_LOGIC;
-    mm_clk        : IN  STD_LOGIC;
+    new_interval   : OUT STD_LOGIC;
+
+    mm_rst         : IN  STD_LOGIC;
+    mm_clk         : IN  STD_LOGIC;
 
     reg_crosslets_info_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
     reg_crosslets_info_miso : OUT t_mem_miso := c_mem_miso_rst;
@@ -60,13 +72,13 @@ ENTITY sdp_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_sdp_crosslets_info_reg_w-1 DOWNTO 0)
+    cur_crosslets_info_rec  : OUT t_sdp_crosslets_info;
+    prev_crosslets_info_rec : OUT t_sdp_crosslets_info
   );
 END sdp_crosslets_subband_select;
 
 ARCHITECTURE str OF sdp_crosslets_subband_select IS
 
-
   CONSTANT c_crosslets_info_dly  : NATURAL := 1;
   CONSTANT c_col_select_addr_w   : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_N_sub);
   CONSTANT c_row_select_slv_w    : NATURAL := ceil_log2(c_sdp_P_pfb);
@@ -91,7 +103,7 @@ ARCHITECTURE str OF sdp_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 +116,13 @@ ARCHITECTURE str OF sdp_crosslets_subband_select IS
   SIGNAL crosslets_info_reg    : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL crosslets_info_reg_in : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL active_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL i_out_crosslets_info  : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL cur_crosslets_info    : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL prev_crosslets_info   : STD_LOGIC_VECTOR(c_sdp_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_sdp_crosslets_info;
   SIGNAL crosslets_info_rec_inout  : t_sdp_crosslets_info;
   SIGNAL active_crosslets_info_rec : t_sdp_crosslets_info;
-  SIGNAL out_crosslets_info_rec    : t_sdp_crosslets_info;
 
 BEGIN
 
@@ -135,7 +147,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 +173,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_sdp_mm_reg_crosslets_info.nof_dat - 2 LOOP
       crosslets_info_reg_in((I+1) * c_sdp_crosslets_index_w - 1 DOWNTO I * c_sdp_crosslets_index_w ) <= TO_SVEC(-1, c_sdp_crosslets_index_w);
@@ -319,7 +332,7 @@ BEGIN
   END GENERATE;
 
   -- pipeline for alignment with sync
-  u_common_pipeline : ENTITY common_lib.common_pipeline
+  u_common_pipeline_cur : ENTITY common_lib.common_pipeline
   GENERIC MAP(
     g_pipeline  => c_crosslets_info_dly,
     g_in_dat_w  => c_sdp_crosslets_info_reg_w,
@@ -330,10 +343,22 @@ BEGIN
     clk => dp_clk,
     in_en => row_sosi.sync,
     in_dat => active_crosslets_info,
-    out_dat => i_out_crosslets_info
+    out_dat => cur_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_sdp_crosslets_info_reg_w,
+    g_out_dat_w => c_sdp_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 +380,8 @@ BEGIN
   crosslets_info_rec        <= func_sdp_map_crosslets_info(crosslets_info_reg);
   crosslets_info_rec_inout  <= func_sdp_map_crosslets_info(crosslets_info_reg_in);
   active_crosslets_info_rec <= func_sdp_map_crosslets_info(active_crosslets_info);
-  out_crosslets_info_rec    <= func_sdp_map_crosslets_info(i_out_crosslets_info);
+
+  cur_crosslets_info_rec    <= func_sdp_map_crosslets_info(cur_crosslets_info);
+  prev_crosslets_info_rec   <= func_sdp_map_crosslets_info(prev_crosslets_info);
 
 END str;
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
index ff1b1565b89a30808872ffaf4392ce4ca297bac8..1f392030b12ec07086cbf4db03e3f304d44545a5 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
@@ -114,11 +114,13 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_wg_subband_freq_unit    : REAL := c_diag_wg_freq_unit/REAL(c_sdp_N_fft);  -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus
   CONSTANT c_sdp_N_clk_per_sync          : NATURAL := c_sdp_f_adc_MHz*10**6;  -- Default 200M clock cycles per second
   CONSTANT c_sdp_N_clk_sync_timeout      : NATURAL := c_sdp_f_adc_MHz*10**6 + c_sdp_f_adc_MHz*10**5;  -- 10% margin.
-  CONSTANT c_sdp_N_clk_sync_timeout_xsub : NATURAL := 2**31 - 1;  -- 10.7 seconds = largest value for NATURAL.
+  CONSTANT c_sdp_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_sdp_N_sync_jesd             : NATURAL := c_sdp_S_pn * c_sdp_N_sync_rcu / c_sdp_S_rcu; -- = 4, nof JESD IP sync outputs per PN
-  CONSTANT c_sdp_f_sub_Hz                : REAL := REAL(c_sdp_f_adc_MHz * 10**6) / REAL(c_sdp_N_fft);
+  CONSTANT c_sdp_f_sub_Hz                : REAL := REAL(c_sdp_f_adc_MHz * 10**6) / REAL(c_sdp_N_fft);  -- = 195312.5
   CONSTANT c_sdp_N_int                   : NATURAL := c_sdp_f_adc_MHz * 10**6;  -- nof ADC sample periods per 1 s integration interval
   CONSTANT c_sdp_N_int_sub               : REAL := c_sdp_f_sub_Hz;  -- nof subband sample periods per 1 s integration interval
+  CONSTANT c_sdp_N_int_sub_lo            : NATURAL := NATURAL(FLOOR(c_sdp_N_int_sub));  -- = 195312
+  CONSTANT c_sdp_N_int_sub_hi            : NATURAL := NATURAL(CEIL(c_sdp_N_int_sub));  -- = 195313
   CONSTANT c_sdp_A_pn                    : NATURAL := c_sdp_S_pn / c_sdp_N_pol;  -- = 6 dual pol antenna per PN, is 6 signal input pairs
   CONSTANT c_sdp_P_pfb                   : NATURAL := c_sdp_S_pn / c_sdp_Q_fft;  -- = 6 PFB units, for 6 signal input pairs
   CONSTANT c_sdp_T_adc                   : TIME    := (10**6 / c_sdp_f_adc_MHz) * 1 ps;  -- = 5 ns @ 200MHz
@@ -309,9 +311,10 @@ PACKAGE sdp_pkg is
   END RECORD;
 
   -----------------------------------------------------------------------------
-  -- Beamlet output via 10GbE to CEP (= central processor)
+  -- Beamlet output via 10GbE to CEP (= central processor, see ICD STAT-CEP)
   -----------------------------------------------------------------------------
-  CONSTANT c_sdp_marker_beamlets : NATURAL := 98;  -- = x"62" = 'b'
+  CONSTANT c_sdp_cep_version_id        : NATURAL := 5;
+  CONSTANT c_sdp_marker_beamlets       : NATURAL := 98;  -- = x"62" = 'b'
 
   CONSTANT c_sdp_cep_eth_dst_mac       : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"00074306C700"; -- 00074306C700 = DOP36-eth0
   CONSTANT c_sdp_cep_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608";  -- 47:16, 15:8 = backplane, 7:0 = node
@@ -322,13 +325,16 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_cep_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5000, 16);  -- 0x1380 = 5000
   CONSTANT c_sdp_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_sdp_cep_app_header_len    : NATURAL := 32;
+  CONSTANT c_sdp_cep_app_header_len    : NATURAL := 32;  -- octets, see ICD STAT-CEP
+  CONSTANT c_sdp_cep_header_len        : NATURAL := 14 + 20 + 8 + c_sdp_cep_app_header_len;  -- = eth + ip + udp + app = 74 octets, see ICD STAT-CEP
 
-  CONSTANT c_sdp_cep_version_id             : NATURAL := 5;
-  CONSTANT c_sdp_cep_nof_blocks_per_packet  : NATURAL := 4;
-  CONSTANT c_sdp_cep_nof_beamlets_per_block : NATURAL := c_sdp_S_sub_bf; -- number of dual pol beamlets (c_sdp_N_pol_bf = 2)
+  CONSTANT c_sdp_cep_nof_blocks_per_packet     : NATURAL := 4;  -- number of time blocks of beamlets per output packet
+  CONSTANT c_sdp_cep_nof_beamlets_per_block    : NATURAL := c_sdp_S_sub_bf; -- number of dual pol beamlets (c_sdp_N_pol_bf = 2)
+  CONSTANT c_sdp_cep_nof_beamlets_per_longword : NATURAL := 2;  -- 2 dual pol, complex, 8bit beamlets fit in 1 64bit longword
+  CONSTANT c_sdp_cep_payload_nof_longwords     : NATURAL := c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / c_sdp_cep_nof_beamlets_per_longword;  -- = 976
+  CONSTANT c_sdp_cep_packet_nof_longwords      : NATURAL := ceil_div(c_sdp_cep_header_len, c_longword_sz) + c_sdp_cep_payload_nof_longwords; -- without tail CRC, the CRC is applied by 10GbE MAC
 
-  CONSTANT c_sdp_cep_nof_hdr_fields : NATURAL := 3+12+4+18+1; -- 592b; 9.25 64b words
+  CONSTANT c_sdp_cep_nof_hdr_fields : NATURAL := 3+12+4+18+1;  -- c_sdp_cep_header_len / c_longword_sz = 74 / 8 = 9.25 64b words = 592b
   CONSTANT c_sdp_cep_hdr_field_sel  : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111001"&"0111"&"1100"&"00000010"&"000110"&"0";  -- 0=data path, 1=MM controlled TODO
 --CONSTANT c_sdp_cep_hdr_field_sel  : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "100"&"000000010001"&"0100"&"0100"&"00000000"&"101000"&"0";  -- 0=data path, 1=MM controlled TODO
 
@@ -494,6 +500,8 @@ PACKAGE sdp_pkg is
     step       : NATURAL;
   END RECORD;
 
+  CONSTANT c_sdp_crosslets_info_rst : t_sdp_crosslets_info := (offset_arr => (OTHERS => 0), step => 0);
+
   CONSTANT c_sdp_mm_reg_nof_crosslets  : t_c_mem := (latency  => 1,
                                                      adr_w    => 1,
                                                      dat_w    => ceil_log2(c_sdp_N_crosslets_max+1),  
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
index 7396bd3d3a6133dab982e8af25078f0f2114b1a7..7455fcaf62c5127110fd4ff974b0c1d6a6187b3d 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
@@ -26,7 +26,7 @@
 --   Combines sdp nodes. Contains the UniBoard2 HW version independent LOFAR2 SDP application code.
 -------------------------------------------------------------------------------
 
-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;
+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;
@@ -88,15 +88,6 @@ ENTITY sdp_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 
     ----------------------------------------------
@@ -170,6 +161,7 @@ ENTITY sdp_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 
     ----------------------------------------------
@@ -265,6 +257,18 @@ ENTITY sdp_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 
     ----------------------------------------------
@@ -321,35 +325,38 @@ ENTITY sdp_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');
 
@@ -363,14 +370,17 @@ END sdp_station;
 
 ARCHITECTURE str OF sdp_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_sdp_N_pol * c_sdp_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_sdp_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_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); 
   CONSTANT c_addr_w_ram_bf_weights                 : NATURAL := ceil_log2(c_sdp_N_pol * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); 
@@ -386,27 +396,37 @@ ARCHITECTURE str OF sdp_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_sdp_N_crosslets_max * c_sdp_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_sdp_S_sub_bf * c_sdp_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_lane_payload_nof_longwords_xst : NATURAL := c_sdp_N_crosslets_max * c_sdp_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_sdp_S_sub_bf * c_sdp_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_sdp_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;
+  CONSTANT c_sync_timeout              : NATURAL := sel_a_b(g_sim, g_sim_sync_timeout, c_sdp_N_clk_sync_timeout);
+
+  -- 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 sdp_info                   : t_sdp_info := c_sdp_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 
   ----------------------------------------------
@@ -505,26 +525,29 @@ ARCHITECTURE str OF sdp_station IS
   SIGNAL bf_udp_siso_arr                   : t_dp_siso_arr(c_sdp_N_beamsets-1 DOWNTO 0);    
   SIGNAL bf_10GbE_hdr_fields_out_arr       : t_slv_1024_arr(c_sdp_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);
@@ -534,10 +557,6 @@ ARCHITECTURE str OF sdp_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 sdp_info                          : t_sdp_info := c_sdp_info_rst;
-  SIGNAL ring_info                         : t_ring_info;
-
-
 BEGIN
 
   -----------------------------------------------------------------------------
@@ -993,7 +1012,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
@@ -1014,21 +1033,21 @@ BEGIN
       snk_in_arr  => bf_udp_sosi_arr,
       snk_out_arr => bf_udp_siso_arr,
     
-      src_out => nw_10gbe_snk_in_arr(0),
-      src_in  => nw_10gbe_snk_out_arr(0)
+      src_out => nw_10gbe_beamlet_output_snk_in_arr(0),
+      src_in  => nw_10gbe_beamlet_output_snk_out_arr(0)
     );
 
     ---------------
-    -- 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_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_sdp_cep_hdr_field_arr
   
     )
@@ -1054,15 +1073,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 
     );
@@ -1074,8 +1093,8 @@ 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_use_dp_layer              => c_use_dp_layer,
+        g_lane_packet_length        => c_lane_payload_nof_longwords_xst,
+        g_use_dp_layer              => TRUE,
         g_nof_rx_monitors           => c_sdp_N_pn_max,
         g_nof_tx_monitors           => c_sdp_N_pn_max,
         g_err_bi                    => c_err_bi,
@@ -1123,8 +1142,8 @@ 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_use_dp_layer              => c_use_dp_layer,
+          g_lane_packet_length        => c_lane_payload_nof_longwords_bf,
+          g_use_dp_layer              => TRUE,
           g_nof_rx_monitors           => 1,
           g_nof_tx_monitors           => 1,
           g_err_bi                    => c_err_bi,
@@ -1231,30 +1250,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
@@ -1277,15 +1296,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
     );
 
     -----------------------------------------------------------------------------
@@ -1295,19 +1314,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;
 
@@ -1328,12 +1347,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/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
index 1338fe6d15b0c5bec083dd968b12817a003e259c..b9815e98407b87317b19f63ed24da1f6c0b7fc98 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
@@ -142,7 +142,8 @@ ENTITY sdp_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;
@@ -156,8 +157,9 @@ ENTITY sdp_statistics_offload IS
     ring_info               : IN t_ring_info := c_ring_info_rst;  -- only needed for XST
     sdp_info                : IN t_sdp_info;
     weighted_subbands_flag  : IN STD_LOGIC := '0';
+
     nof_crosslets           : IN STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-    crosslets_info          : IN STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0')
+    crosslets_info_rec      : IN t_sdp_crosslets_info := c_sdp_crosslets_info_rst
   );
 END sdp_statistics_offload;
 
@@ -202,8 +204,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS
     crosslets_info_rec   : t_sdp_crosslets_info;
   END RECORD;
 
-  CONSTANT c_crosslets_info_rst : t_sdp_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_sdp_crosslets_info_rst);
 
   SIGNAL r     : t_reg;
   SIGNAL nxt_r : t_reg;
@@ -225,6 +226,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS
   SIGNAL data_id_rec              : t_sdp_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';
@@ -239,6 +241,8 @@ ARCHITECTURE str OF sdp_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_sdp_stat_header;
 
   -- Debug signals for view in Wave window
   SIGNAL dbg_c_marker                    : NATURAL := c_marker;
@@ -353,7 +357,7 @@ BEGIN
 
   data_id_slv <= func_sdp_map_stat_data_id(g_statistics_type, data_id_rec);
 
-  p_control_packet_offload : PROCESS(r, in_sosi, local_si_offset, trigger_offload, nof_crosslets, crosslets_info, nof_packets, dp_sop, dp_header_info)
+  p_control_packet_offload : PROCESS(r, in_sosi, nof_crosslets, crosslets_info_rec, trigger_offload, dp_sop, dp_header_info, nof_packets)  -- in order of appearance
     VARIABLE v       : t_reg;
     VARIABLE v_index : NATURAL;
   BEGIN
@@ -376,19 +380,18 @@ BEGIN
       END IF;
     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 sdp_crosslets_subband_select.vhd 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 sdp_statistics_offload. This latency is very short
-    --   compared to the sync period, so the nof_crosslets and crosslet_info
+    --   compared to the sync period, so the nof_crosslets and crosslets_info_rec
     --   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_sdp_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
@@ -476,6 +479,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 +499,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
   );
@@ -570,6 +581,10 @@ 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
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
index 05d222f417f158351779bbee469fc7b5543f3124..e5e7d4f12cc299106f3fa6856cf5b01cd87d068a 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
@@ -120,7 +120,10 @@ BEGIN
     g_gain_w          => c_sdp_W_sub_weight,
     g_in_dat_w        => c_sdp_W_subband,
     g_out_dat_w       => c_gain_out_dat_w,
-    g_gains_file_name => g_gains_file_name
+    g_gains_file_name => g_gains_file_name,
+    -- extra input latency to ease timing.
+    g_pipeline_real_mult_input    => 2, 
+    g_pipeline_complex_mult_input => 2 
   )
   PORT MAP (
     -- System
diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_crosslets_subband_select.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_crosslets_subband_select.vhd
index d58cd1b58e1de6fbc64612736e5f3bad2ce48e72..800b255c457e678d9da3d4d7f8771321b5033873 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_crosslets_subband_select.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_crosslets_subband_select.vhd
@@ -30,7 +30,7 @@
 -- Description: The tb starts the dut by writing a scheduled bsn to the bsn_scheduler
 -- via MM. The offsets and step are configured using MM. The dut makes the subband 
 -- selection based on the MM configuration and N_crosslets. The TB then verifies out_sosi 
--- and out_crosslets_info of the dut by comparing it to the expected output.
+-- and cur_crosslets_info of the dut by comparing it to the expected output.
 
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
@@ -84,20 +84,19 @@ ARCHITECTURE tb OF tb_sdp_crosslets_subband_select IS
   SIGNAL mm_trigger_miso    : t_mem_miso;
 
   SIGNAL st_en              : STD_LOGIC := '1';
+  SIGNAL st_bsn             : NATURAL := c_scheduled_bsn - c_nof_block_dly;
   SIGNAL st_siso_arr        : t_dp_siso_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
   SIGNAL st_sosi_arr        : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL exp_sosi           : t_dp_sosi := c_dp_sosi_rst;
   
-  SIGNAL bsn                : NATURAL := c_scheduled_bsn - c_nof_block_dly;
-  
   SIGNAL in_sosi_arr        : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   
   SIGNAL out_sosi           : t_dp_sosi;
 
-  SIGNAL exp_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL out_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL exp_crosslets_info_rec : t_sdp_crosslets_info;
-  SIGNAL out_crosslets_info_rec : t_sdp_crosslets_info;
+  SIGNAL exp_cur_crosslets_info_rec   : t_sdp_crosslets_info;
+  SIGNAL cur_crosslets_info_rec       : t_sdp_crosslets_info;
+  SIGNAL exp_prev_crosslets_info_rec  : t_sdp_crosslets_info;
+  SIGNAL prev_crosslets_info_rec      : t_sdp_crosslets_info;
 
 BEGIN
 
@@ -106,7 +105,7 @@ BEGIN
   rst <= '1', '0' AFTER c_clk_period*7;           
   
   p_mm_stimuli : PROCESS
-  VARIABLE k : NATURAL;
+    VARIABLE k : NATURAL;
   BEGIN
     proc_common_wait_until_low(mm_clk, rst);
     proc_common_wait_some_cycles(mm_clk, 50); -- Give dut some time to start
@@ -141,7 +140,7 @@ BEGIN
     END LOOP;
     ASSERT rd_crosslet_step = 0 REPORT "Wrong crosslet step after rst." SEVERITY ERROR;
 
-    -- b) Read crosslet_info in every sync interval
+    -- b) Read crosslets_info in every sync interval
     WHILE TRUE LOOP
       proc_common_wait_until_hi_lo(clk, out_sosi.sync);
       proc_common_wait_cross_clock_domain_latency(c_clk_period, c_mm_clk_period);
@@ -157,9 +156,9 @@ BEGIN
       proc_common_wait_some_cycles(mm_clk, 1);
       -- Verify that readback crosslet info is active crosslets_info
       FOR I IN 0 TO c_N_crosslets-1 LOOP
-        ASSERT rd_crosslet_offsets(I) = exp_crosslets_info_rec.offset_arr(I) REPORT "Wrong active crosslet offset in output sync interval." SEVERITY ERROR;
+        ASSERT rd_crosslet_offsets(I) = exp_cur_crosslets_info_rec.offset_arr(I) REPORT "Wrong active crosslet offset in output sync interval." SEVERITY ERROR;
       END LOOP;
-      ASSERT rd_crosslet_step = exp_crosslets_info_rec.step REPORT "Wrong active crosslet step in output sync interval." SEVERITY ERROR;
+      ASSERT rd_crosslet_step = exp_cur_crosslets_info_rec.step REPORT "Wrong active crosslet step in output sync interval." SEVERITY ERROR;
     END LOOP;
 
     WAIT;
@@ -198,14 +197,14 @@ BEGIN
   END GENERATE;
   
   -- Time stimuli  
-  bsn <= bsn + 1 WHEN rising_edge(clk) AND (st_sosi_arr(0).eop='1'); 
+  st_bsn <= st_bsn + 1 WHEN rising_edge(clk) AND (st_sosi_arr(0).eop='1');
 
   -- Add BSN to the ST data
-  p_in_sosi : PROCESS(st_sosi_arr, bsn)
+  p_in_sosi : PROCESS(st_sosi_arr, st_bsn)
   BEGIN    
+    in_sosi_arr <= st_sosi_arr;
     FOR I IN 0 TO c_sdp_P_pfb-1 LOOP
-      in_sosi_arr(I)     <= st_sosi_arr(I);
-      in_sosi_arr(I).bsn <= TO_DP_BSN(bsn);
+      in_sosi_arr(I).bsn <= TO_DP_BSN(st_bsn);
     END LOOP;
   END PROCESS;
 
@@ -216,19 +215,28 @@ BEGIN
     VARIABLE v_col : NATURAL := 0;
     VARIABLE v_row : NATURAL := 0;
     VARIABLE v_offset : NATURAL := 0; 
-    VARIABLE v_sync_ix : NATURAL := 0;
+    VARIABLE v_sync_ix : NATURAL := 0;  -- ix = index
     VARIABLE v_k : NATURAL := 0;
   BEGIN
     FOR I IN 0 TO c_nof_sync*c_nof_block_per_sync-1 LOOP
       v_sync_ix := I / c_nof_block_per_sync;
       exp_sosi <= c_dp_sosi_rst;
+
+      -- In a tb it is ok and it can be handy to use rising_edge() on a combinatorial signal
       WAIT UNTIL rising_edge(out_sosi.sop);
 
-      exp_crosslets_info_slv(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) <= TO_UVEC(c_crosslet_step, c_sdp_crosslets_index_w);
+      -- Current sync interval crosslets_info
+      exp_cur_crosslets_info_rec.step <= c_crosslet_step;
       FOR C IN 0 TO c_nof_ch_sel_col-1 LOOP
-        exp_crosslets_info_slv((C+1)*c_sdp_crosslets_index_w-1 DOWNTO C*c_sdp_crosslets_index_w) <= TO_UVEC(c_crosslet_offsets(C) + v_sync_ix * c_crosslet_step, c_sdp_crosslets_index_w);
+        exp_cur_crosslets_info_rec.offset_arr(C) <= c_crosslet_offsets(C) + v_sync_ix * c_crosslet_step;
       END LOOP;
 
+      -- Previous sync interval crosslets_info
+      IF out_sosi.sync = '1' THEN
+        exp_prev_crosslets_info_rec <= exp_cur_crosslets_info_rec;
+      END IF;
+
+      -- Crosslet data
       FOR J IN 0 TO c_nof_ch_sel-1 LOOP
         v_offset := J / (c_nof_ch_sel_col*c_nof_ch_sel_row);
         v_col := J MOD c_nof_ch_sel_col;
@@ -241,7 +249,6 @@ BEGIN
           exp_sosi.sop <= '1';
           IF I MOD c_nof_block_per_sync = 0 THEN
             exp_sosi.sync <= '1';
-
           END IF;
         ELSIF j = c_nof_ch_sel-1 THEN 
           exp_sosi.eop <= '1';
@@ -250,8 +257,8 @@ BEGIN
         exp_sosi.re <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA(   (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_crosslet_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
         exp_sosi.im <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA(1+ (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_crosslet_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
         proc_common_wait_some_cycles(clk, 1);
-
       END LOOP;
+
       exp_sosi <= c_dp_sosi_rst;
     END LOOP;
     WAIT;
@@ -260,14 +267,17 @@ BEGIN
   p_verify_out_data : PROCESS(clk)
   BEGIN
     IF rising_edge(clk) THEN
-      ASSERT out_sosi.valid = exp_sosi.valid      REPORT "Wrong out_sosi.valid"      SEVERITY ERROR;
-      ASSERT out_sosi.sop   = exp_sosi.sop        REPORT "Wrong out_sosi.sop"        SEVERITY ERROR;
-      ASSERT out_sosi.eop   = exp_sosi.eop        REPORT "Wrong out_sosi.eop"        SEVERITY ERROR;
-      ASSERT out_sosi.sync  = exp_sosi.sync       REPORT "Wrong out_sosi.sync"       SEVERITY ERROR;
-      ASSERT out_crosslets_info_slv = exp_crosslets_info_slv  REPORT "Wrong out_crosslets_info_slv"  SEVERITY ERROR;
+      ASSERT out_sosi.valid = exp_sosi.valid REPORT "Wrong out_sosi.valid" SEVERITY ERROR;
+      ASSERT out_sosi.sop   = exp_sosi.sop   REPORT "Wrong out_sosi.sop"   SEVERITY ERROR;
+      ASSERT out_sosi.eop   = exp_sosi.eop   REPORT "Wrong out_sosi.eop"   SEVERITY ERROR;
+      ASSERT out_sosi.sync  = exp_sosi.sync  REPORT "Wrong out_sosi.sync"  SEVERITY ERROR;
+
+      ASSERT cur_crosslets_info_rec  = exp_cur_crosslets_info_rec  REPORT "Wrong cur_crosslets_info"  SEVERITY ERROR;
+      ASSERT prev_crosslets_info_rec = exp_prev_crosslets_info_rec REPORT "Wrong prev_crosslets_info" SEVERITY ERROR;
+
       IF exp_sosi.valid = '1' THEN
-        ASSERT out_sosi.re  = exp_sosi.re    REPORT "Wrong out_sosi.re"    SEVERITY ERROR;
-        ASSERT out_sosi.im  = exp_sosi.im    REPORT "Wrong out_sosi.im"    SEVERITY ERROR;
+        ASSERT out_sosi.re  = exp_sosi.re REPORT "Wrong out_sosi.re" SEVERITY ERROR;
+        ASSERT out_sosi.im  = exp_sosi.im REPORT "Wrong out_sosi.im" SEVERITY ERROR;
       END IF;
     END IF;
   END PROCESS;
@@ -294,11 +304,8 @@ BEGIN
     in_sosi_arr => in_sosi_arr,
     out_sosi    => out_sosi,
 
-    out_crosslets_info => out_crosslets_info_slv
+    cur_crosslets_info_rec  => cur_crosslets_info_rec,
+    prev_crosslets_info_rec => prev_crosslets_info_rec
   );
  
-  -- Map crosslets_info slv to record for easier view in Wave window
-  exp_crosslets_info_rec <= func_sdp_map_crosslets_info(exp_crosslets_info_slv);
-  out_crosslets_info_rec <= func_sdp_map_crosslets_info(out_crosslets_info_slv);
-
 END tb;
diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
index 1193efc51d1626ac76565c476870d39bcff62236..5298580a65d5c2f3be3ffb750a21a60821eb7e3f 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
@@ -172,9 +172,9 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   SIGNAL offload_rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
   SIGNAL offload_rx_hdr_dat_miso : t_mem_miso;
 
+  SIGNAL new_interval            : STD_LOGIC := '0';
   SIGNAL in_sosi                 : t_dp_sosi := c_dp_sosi_rst;
   SIGNAL in_crosslets_info_rec   : t_sdp_crosslets_info;
-  SIGNAL in_crosslets_info_slv   : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0);
 
   SIGNAL sdp_offload_data        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);  -- 32 bit
   SIGNAL sdp_offload_sosi        : t_dp_sosi;
@@ -242,6 +242,9 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   SIGNAL dbg_c_ram_size                  : NATURAL := c_ram_size;
   SIGNAL dbg_c_crosslets_info_rec        : t_sdp_crosslets_info := c_crosslets_info_rec;
   SIGNAL dbg_c_crosslets_info_slv        : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := c_crosslets_info_slv;
+  SIGNAL dbg_c_nof_block_per_sync        : NATURAL := c_nof_block_per_sync;
+  SIGNAL dbg_c_nof_clk_per_block         : NATURAL := c_nof_clk_per_block;
+  SIGNAL dbg_c_nof_clk_per_sync          : NATURAL := c_nof_clk_per_sync ;
 
 BEGIN
 
@@ -282,7 +285,9 @@ BEGIN
     in_sosi.bsn <= TO_DP_BSN(c_bsn_init);
     in_sosi.valid <= '1';
     in_crosslets_info_rec <= c_crosslets_info_rec;
+    new_interval <= '1';  -- mark first in_sosi.sync interval
     WHILE TRUE LOOP
+      -- One in_sosi.sync interval
       FOR i IN 0 TO c_nof_block_per_sync-1 LOOP
         FOR j IN 0 TO c_nof_clk_per_block-1 LOOP
           in_sosi.sync  <= '0';
@@ -305,17 +310,15 @@ BEGIN
           proc_common_wait_some_cycles(dp_clk, 1);
         END LOOP;
       END LOOP;
+      new_interval <= '0';
     END LOOP;
     WAIT;
   END PROCESS;
 
-  in_crosslets_info_slv <= func_sdp_map_crosslets_info(in_crosslets_info_rec);
-
   -- Enable the statistics offload when input is running
   p_enable_trigger : PROCESS
   BEGIN
-    -- Wait at least one sync interval, so that DUT can have measured the integration_interval
-    proc_common_wait_until_hi_lo(dp_clk, in_sosi.sync);
+    proc_common_wait_until_low(dp_clk, mm_rst);
     proc_common_wait_some_cycles(mm_clk, 10);
     -- Enable common variable delay.
     proc_mem_mm_bus_wr(c_reg_enable_mm_addr_enable, 1, mm_clk, enable_miso, enable_mosi);
@@ -648,6 +651,8 @@ BEGIN
 
     -- ST
     in_sosi          => in_sosi,
+    new_interval     => new_interval,
+
     out_sosi         => sdp_offload_sosi,
     out_siso         => sdp_offload_siso,
 
@@ -660,11 +665,12 @@ BEGIN
     ring_info               => c_exp_ring_info,
     sdp_info                => c_exp_sdp_info,
     weighted_subbands_flag  => weighted_subbands_flag,
+
     nof_crosslets           => c_mm_nof_crosslets,
-    crosslets_info          => in_crosslets_info_slv
+    crosslets_info_rec      => in_crosslets_info_rec
   );
 
-  -- Check crosslet_info functions
+  -- Verify crosslets_info functions
   ASSERT c_crosslets_info_rec = func_sdp_map_crosslets_info(c_crosslets_info_slv) REPORT "Error in func_sdp_map_crosslets_info()" SEVERITY FAILURE;
 
   -- To view the 32 bit 1GbE offload data more easily in the Wave window
diff --git a/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd b/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd
index 22099bf168a065ce4064308f9e30c4a84b12f1e0..62e5956eca69267ecf4434ab5fc0570419f82d3a 100644
--- a/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd
+++ b/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd
@@ -63,6 +63,9 @@
 -- * out_start:
 --   Pulse at out_sosi.sync with out_sosi.bsn = ctrl_start_bsn. The first
 --   out_sosi.sync interval will have nof_blk_max blocks.
+-- * out_start_interval:
+--   Active from out_start until next out_sosi.sync, so active during the
+--   first out_sosi.sync interval of a new out_sosi sequence.
 -- * out_enable:
 --   Goes high at first out_sosi.sync. In case of a restart when ctrl_enable
 --   was already '1', then the out_enable will go low and high to ensure that
@@ -135,6 +138,7 @@ ENTITY dp_bsn_sync_scheduler IS
     in_sosi                  : IN t_dp_sosi;
     out_sosi                 : OUT t_dp_sosi;
     out_start                : OUT STD_LOGIC;  -- pulse at out_sosi.sync at ctrl_start_bsn
+    out_start_interval       : OUT STD_LOGIC;  -- active during first out_sosi.sync interval
     out_enable               : OUT STD_LOGIC   -- for tb verification purposes
   );
 END dp_bsn_sync_scheduler;
@@ -166,9 +170,13 @@ ARCHITECTURE rtl OF dp_bsn_sync_scheduler IS
   SIGNAL r            : t_reg;
   SIGNAL nxt_r        : t_reg;
 
-  SIGNAL output_start : STD_LOGIC;
-  SIGNAL output_sync  : STD_LOGIC;
-  SIGNAL output_sosi  : t_dp_sosi;
+  SIGNAL output_enable             : STD_LOGIC;
+  SIGNAL output_next               : STD_LOGIC;  -- active at next output_sync's
+  SIGNAL output_start              : STD_LOGIC;  -- active at first output_sync
+  SIGNAL output_start_interval     : STD_LOGIC;  -- active during first output_sync interval
+  SIGNAL output_start_interval_reg : STD_LOGIC := '0';
+  SIGNAL output_sync               : STD_LOGIC;
+  SIGNAL output_sosi               : t_dp_sosi;
 
 BEGIN
 
@@ -371,14 +379,16 @@ BEGIN
     nxt_r <= v;
   END PROCESS;
 
+  output_enable <= nxt_r.output_enable;
+
   -----------------------------------------------------------------------------
   -- Output in_sosi with programmed sync interval or disable the output
   -----------------------------------------------------------------------------
   -- . note this is part of p_comb, but using a separate process is fine too.
-  p_output_sosi : PROCESS(in_sosi, nxt_r, output_sync)
+  p_output_sosi : PROCESS(in_sosi, output_enable, output_sync)
   BEGIN
     output_sosi <= in_sosi;
-    IF nxt_r.output_enable = '1' THEN
+    IF output_enable = '1' THEN
       output_sosi.sync <= output_sync;
     ELSE
       output_sosi.sync  <= '0';
@@ -389,7 +399,30 @@ BEGIN
   END PROCESS;
 
   -----------------------------------------------------------------------------
-  -- Pipeline output to avoid timing closure problems due to use of nxt_r.output_enable
+  -- Determine output_start_interval
+  -----------------------------------------------------------------------------
+  output_next <= output_sync AND NOT output_start;
+
+  p_output_start_interval : PROCESS(output_start_interval_reg, output_start, output_next, output_enable)
+  BEGIN
+    -- Hold output_start until next sync interval
+    output_start_interval <= output_start_interval_reg;
+    IF output_start = '1' THEN
+      output_start_interval <= '1';
+    ELSIF output_next = '1' THEN
+      output_start_interval <= '0';
+    END IF;
+    -- provided that output_enable is still active
+    IF output_enable = '0' THEN
+      output_start_interval <= '0';
+    END IF;
+  END PROCESS;
+
+  output_start_interval_reg <= output_start_interval WHEN rising_edge(clk);
+
+
+  -----------------------------------------------------------------------------
+  -- Pipeline output to avoid timing closure problems due to use of output_enable
   -----------------------------------------------------------------------------
   u_out_sosi : ENTITY work.dp_pipeline
   GENERIC MAP (
@@ -406,11 +439,13 @@ BEGIN
 
   gen_pipe_out_start : IF g_pipeline = 1 GENERATE
     out_start <= output_start WHEN rising_edge(clk);
+    out_start_interval <= output_start_interval_reg;
     out_enable <= r.output_enable;
   END GENERATE;
   no_pipe_out_start : IF g_pipeline = 0 GENERATE
     out_start <= output_start;
-    out_enable <= nxt_r.output_enable;
+    out_start_interval <= output_start_interval;
+    out_enable <= output_enable;
   END GENERATE;
 
 END rtl;
diff --git a/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd b/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd
index 21063d1e94390343e93984f694530cb543810f59..381cd124bba1ff193c3423fc76e24d20af32a686 100644
--- a/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd
+++ b/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd
@@ -19,7 +19,7 @@
 -------------------------------------------------------------------------------
 
 -------------------------------------------------------------------------------
--- Author: R. van der Walle
+-- Author: R. van der Walle, E. Kooistra
 
 -- Purpose:
 --   The FIFO starts outputting data when the output is ready and it has been
@@ -32,6 +32,22 @@
 --   after the fifo has been filled sufficiently, a frame is also available when
 --   the in_eop has been received earlier than the specified g_fifo_fill. For
 --   more details, please consult the description of dp_fill_fifo_core.
+-- Usage:
+-- * Typically rely only on eop to release any block from the FIFO. This can
+--   be achieved by choosing:
+--   . g_fifo_size >= largest block size + c_fifo_fill_margin.
+--   . g_fifo_fill = largest block size, or equivalently choose:
+--     g_fifo_fill = g_fifo_size - c_fifo_fill_margin
+--   It is not adviced to choose g_fifo_fill = g_fifo_size, because then
+--   internally the FIFO becomes c_fifo_fill_margin bigger and may then use
+--   more RAM. Default c_fifo_fill_margin = 4 + 2 = 6 words.
+-- * Often it is possible to make full use of a block RAM by using a FIFO size
+--   that is a power of 2, so g_fifo_size = true_log_pow2(largest block size +
+--   c_fifo_tx_fill_margin).
+-- Remark:
+-- * The dp_fifo_fill_eop cannot handle continues stream of blocks without a
+--   gap between blocks it needs 1 cycle to process a block.
+--
 -------------------------------------------------------------------------------
 
 LIBRARY IEEE, common_lib, technology_lib;
diff --git a/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd
index 9cfe48f8dba79806999f160015e2e625b4753190..513fc0e7efb6600ab29ea46932670cd0340b7508 100644
--- a/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd
+++ b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd
@@ -79,10 +79,11 @@ ENTITY mmp_dp_bsn_sync_scheduler IS
     reg_miso        : OUT t_mem_miso;
 
     -- Streaming
-    in_sosi         : IN t_dp_sosi;
-    out_sosi        : OUT t_dp_sosi;
-    out_start       : OUT STD_LOGIC;
-    out_enable      : OUT STD_LOGIC
+    in_sosi            : IN t_dp_sosi;
+    out_sosi           : OUT t_dp_sosi;
+    out_start          : OUT STD_LOGIC;
+    out_start_interval : OUT STD_LOGIC;
+    out_enable         : OUT STD_LOGIC
   );
 END mmp_dp_bsn_sync_scheduler;
 
@@ -215,6 +216,7 @@ BEGIN
     in_sosi                  => in_sosi,
     out_sosi                 => out_sosi,
     out_start                => out_start,
+    out_start_interval       => out_start_interval,
     out_enable               => out_enable
   );
 
diff --git a/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler_arr.vhd b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler_arr.vhd
index 38a473d061ab50d2a974dc5bc071b5a8d8f9225f..708f83cc5b3fbd31e88817a699f0866910d0b294 100644
--- a/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler_arr.vhd
+++ b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler_arr.vhd
@@ -50,10 +50,11 @@ ENTITY mmp_dp_bsn_sync_scheduler_arr IS
     reg_miso        : OUT t_mem_miso;
 
     -- Streaming
-    in_sosi_arr     : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-    out_sosi_arr    : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-    out_start       : OUT STD_LOGIC;
-    out_enable      : OUT STD_LOGIC
+    in_sosi_arr        : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    out_sosi_arr       : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    out_start          : OUT STD_LOGIC;
+    out_start_interval : OUT STD_LOGIC;
+    out_enable         : OUT STD_LOGIC
   );
 END mmp_dp_bsn_sync_scheduler_arr;
 
@@ -84,8 +85,9 @@ BEGIN
     in_sosi  => in_sosi_arr(0),
     out_sosi => single_src_out,
 
-    out_start  => out_start,
-    out_enable => out_enable
+    out_start          => out_start,
+    out_start_interval => out_start_interval,
+    out_enable         => out_enable
   );
 
   -- Pipeline in_sosi_arr to compensate for the latency in mmp_dp_bsn_sync_scheduler
diff --git a/libraries/base/dp/src/vhdl/mms_dp_gain_serial_arr.vhd b/libraries/base/dp/src/vhdl/mms_dp_gain_serial_arr.vhd
index 25551f29f88ba7b36582739de336065b9bcd1c6a..7e8174fa8f8f52c878ebf7f3f6af51087179eab3 100644
--- a/libraries/base/dp/src/vhdl/mms_dp_gain_serial_arr.vhd
+++ b/libraries/base/dp/src/vhdl/mms_dp_gain_serial_arr.vhd
@@ -100,7 +100,7 @@ ARCHITECTURE str OF mms_dp_gain_serial_arr IS
   --   dat_w     : NATURAL;
   --   nof_dat   : NATURAL;    -- optional, nof dat words <= 2**adr_w
   --   init_sl   : STD_LOGIC;  -- optional, init all dat words to std_logic '0', '1' or 'X'
-  CONSTANT c_mm_ram : t_c_mem := (latency  => 2, -- set latency to 2 to ease timing
+  CONSTANT c_mm_ram : t_c_mem := (latency  => 1, 
                                   adr_w    => ceil_log2(g_nof_gains),
                                   dat_w    => sel_a_b(g_complex_gain, c_nof_complex, 1) * g_gain_w,
                                   nof_dat  => g_nof_gains,
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd
index 67939303a128f1791853c3c7ea1314f5296d2f48..930588f18e0c8b0114dd064c864f1449a19ea81a 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd
@@ -34,7 +34,7 @@
 -- > as 4
 -- > run -all
 --   View in Wave window u_dut: r, nxt_r, and tb: in_sosi, out_sosi,
---   out_sync, out_start
+--   out_sync, out_start, out_start_interval
 --
 -- Development steps:
 --  . Step    1 ~1 day work (idea started earlier, so requirements were clear),
@@ -76,13 +76,14 @@ USE dp_lib.tb_dp_pkg.ALL;
 ENTITY tb_dp_bsn_sync_scheduler IS
   GENERIC (
     -- Input sync period and sosi ctrl
-    g_nof_input_sync               : NATURAL := 10;
+    g_nof_input_sync               : NATURAL := 10;  -- Use c_nof_input_sync > g_block_size, see tb_tb_dp_bsn_sync_scheduler
     g_nof_block_per_input_sync     : NATURAL := 17;
     g_block_size                   : NATURAL := 2;
     g_input_gap_size               : NATURAL := 0;
 
     -- Output sync period
-    g_nof_samples_per_output_sync  : NATURAL := 45  -- 45 / g_block_size = 4.5
+    g_nof_samples_per_output_sync  : NATURAL := 45;  -- 45 / g_block_size = 4.5
+    g_pipeline                     : NATURAL := 0   -- 0 or 1
   );
 END tb_dp_bsn_sync_scheduler;
 
@@ -108,6 +109,8 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS
   CONSTANT c_output_nof_blocks_min        : NATURAL := g_nof_samples_per_output_sync / g_block_size;
   CONSTANT c_enable_init_nof_bsn          : NATURAL := ceil_value(c_output_nof_blocks_min / g_block_size + 10, g_nof_block_per_input_sync);
 
+  CONSTANT c_out_enable_margin            : NATURAL := g_block_size;
+
   SIGNAL clk                   : STD_LOGIC := '1';
   SIGNAL rst                   : STD_LOGIC := '1';
   SIGNAL cnt                   : INTEGER := 0;
@@ -145,28 +148,36 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS
   -- Output
   SIGNAL out_sync              : STD_LOGIC;  -- declared next to in_sync, out_start and out_sosi for easier comparison in Wave window
   SIGNAL out_start             : STD_LOGIC;
+  SIGNAL out_start_interval    : STD_LOGIC;
+  SIGNAL exp_start_interval    : STD_LOGIC := '0';
+  SIGNAL first_interval        : STD_LOGIC := '0';
   SIGNAL out_enable            : STD_LOGIC;
+  SIGNAL expected_out_enable   : STD_LOGIC := '0';
   SIGNAL out_sosi              : t_dp_sosi := c_dp_sosi_init;
 
   -- Verify
+  SIGNAL in_sosi_integer_comb  : t_dp_sosi_integer;
+  SIGNAL in_sosi_integer_pipe  : t_dp_sosi_integer;
   SIGNAL in_sosi_integer       : t_dp_sosi_integer;
   SIGNAL out_sosi_integer      : t_dp_sosi_integer;
 
-  SIGNAL verify_sosi_equal     : STD_LOGIC := '0';
-  SIGNAL verify_sync           : STD_LOGIC := '1';
-  SIGNAL recover_from_in_lost  : STD_LOGIC := '0';
+  SIGNAL verify_sosi_equal          : STD_LOGIC := '0';
+  SIGNAL verify_sosi_equal_at_sop   : STD_LOGIC := '0';
+  SIGNAL verify_sosi_equal_at_valid : STD_LOGIC := '0';
+  SIGNAL verify_sync                : STD_LOGIC := '1';
+  SIGNAL recover_from_in_lost       : STD_LOGIC := '0';
 
-  SIGNAL verifying_sync_equal  : STD_LOGIC := '0';
+  SIGNAL verifying_sync_equal     : STD_LOGIC := '0';
 
-  SIGNAL prev_out_enable       : STD_LOGIC := '0';
-  SIGNAL pending_out_disable   : STD_LOGIC := '0';
-  SIGNAL expected_out_enable   : STD_LOGIC := '0';
-  SIGNAL expected_out_enable1  : STD_LOGIC := '0';
-  SIGNAL expected_out_enable2  : STD_LOGIC := '0';
-  SIGNAL expecting_out_start   : STD_LOGIC := '0';
-  SIGNAL hold_out_eop          : STD_LOGIC := '0';
-  SIGNAL hold_out_sop          : STD_LOGIC := '0';
-  SIGNAL out_sop_cnt           : NATURAL := 0;
+  SIGNAL prev_ctrl_enable         : STD_LOGIC := '0';
+  SIGNAL prev_out_enable          : STD_LOGIC := '0';
+  SIGNAL out_enable_cnt           : NATURAL := 0;
+  SIGNAL nxt_out_enable_cnt       : NATURAL := 0;
+  SIGNAL expected_out_enable_comb : STD_LOGIC := '0';
+  SIGNAL expected_out_enable_pipe : STD_LOGIC := '0';
+  SIGNAL expecting_out_start      : STD_LOGIC := '0';
+  SIGNAL hold_out_sop             : STD_LOGIC := '0';
+  SIGNAL out_sop_cnt              : NATURAL := 0;
 
   SIGNAL dbg_out_sosi_sync     : STD_LOGIC;
   SIGNAL dbg_out_sosi_sop      : STD_LOGIC;
@@ -346,75 +357,53 @@ BEGIN
   -----------------------------------------------------------------------------
   -- . Verify out_enable
   -----------------------------------------------------------------------------
-  p_hold_out_eop : PROCESS(clk)
+  -- The expected out_enable is difficult to determine cycle exact, because
+  -- it depends on g_block_size = 2 or > 2 and on g_pipeline. Therfore use
+  -- expected_out_enable_comb = '-' to define dont care.
+  -- * For g_block_size = 2 the use of r.enable (instead of v.enable) in
+  --   dp_bsn_sync_scheduler.vhd causes that the output can stay enabled 2
+  --   cycles longer, which is ok. Using v.enable does avoid these extra
+  --   cycles, but for timing closure it is preferred to use r.enable.
+
+  -- Verify out_enable
+  p_expected_out_enable : PROCESS(ctrl_enable, in_sosi, ctrl_start_bsn, ctrl_enable_evt, out_enable_cnt, ctrl_enable, in_sosi, ctrl_start_bsn)
   BEGIN
-    IF rising_edge(clk) THEN
-      IF out_sosi.eop = '1' THEN
-        hold_out_eop <= '1';
-      ELSIF out_sosi.sop = '1' THEN
-        hold_out_eop <= '0';
-      END IF;
-    END IF;
-  END PROCESS;
+    -- Default
+    expected_out_enable_comb <= '0';
 
-  -- Determine expected out_enable
-  p_expected_out_enable : PROCESS(ctrl_enable, ctrl_enable_evt, in_sosi, ctrl_start_bsn, out_enable, pending_out_disable, hold_out_eop)
-  BEGIN
-    -- Expect output disable after ctrl_enable_evt
-    IF ctrl_enable_evt = '1' THEN
-       IF out_enable = '0' THEN
-         -- Output is already disabled
-         expected_out_enable <= '0';
-       ELSE
-         -- Output is enabled, so this is a re-enable event.
-         IF hold_out_eop = '1' THEN
-           expected_out_enable <= '0';  -- end of block, so output can disable immediately
-         ELSE
-           pending_out_disable <= '1';  -- plan output disable before re-enable
-         END IF;
-       END IF;
-    END IF;
-
-    IF pending_out_disable <= '1' THEN
-      IF hold_out_eop = '1' THEN
-        expected_out_enable <= '0';  -- end of block, so output can disable
-        pending_out_disable <= '0';
-      END IF;
-    END IF;
-
-    -- Expect output enable at start BSN
+    -- Expect output enable '1' when ctrl_enable is active, but after ctrl_start_bsn
     IF ctrl_enable = '1' THEN
       IF UNSIGNED(in_sosi.bsn) >= UNSIGNED(ctrl_start_bsn) THEN
-        expected_out_enable <= '1';
+        expected_out_enable_comb <= '1';
       END IF;
     END IF;
+
+    -- Introduce some dont care margin in case of ctrl_enable_evt when ctrl_enable was active and may change.
+    -- The ctrl_enable may go inactive (= stop) or remain active (= restart).
+    IF ctrl_enable_evt = '1' AND prev_ctrl_enable = '1' THEN
+      nxt_out_enable_cnt <= 0;
+      expected_out_enable_comb <= '-';
+    ELSIF out_enable_cnt < c_out_enable_margin THEN
+      nxt_out_enable_cnt <= out_enable_cnt + 1;
+      expected_out_enable_comb <= '-';
+    END IF;
   END PROCESS;
 
-  expected_out_enable1 <= expected_out_enable  WHEN rising_edge(clk);
-  expected_out_enable2 <= expected_out_enable1 WHEN rising_edge(clk);
+  prev_ctrl_enable <= ctrl_enable WHEN rising_edge(clk);
+
+  out_enable_cnt <= nxt_out_enable_cnt WHEN rising_edge(clk);
+
+  expected_out_enable_pipe <= expected_out_enable_comb WHEN rising_edge(clk);
+
+  expected_out_enable <= expected_out_enable_comb WHEN g_pipeline = 0 ELSE expected_out_enable_pipe;
 
   p_verify_out_enable : PROCESS(clk)
   BEGIN
-    -- Use registered values to compare, to avoid combinatorial differences
-    -- that can occur during a simulation delta cycle. These combinatorial
-    -- differences are not relevant, because they get resolved after a few
-    -- delta cycles.
     IF rising_edge(clk) THEN
-      IF out_enable /= expected_out_enable THEN
-        IF out_enable = '1' THEN
-          IF g_block_size > 2 THEN
-            REPORT "Unexpected enabled out_enable" SEVERITY ERROR;
-          ELSIF out_enable /= expected_out_enable2 THEN
-            -- For g_block_size = 2 the use of r.enable (instead of v.enable)
-            -- in dp_bsn_sync_scheduler.vhd causes that the output can stay
-            -- enabled 2 cycles longer, which is ok. Using v.enable does
-            -- avoid this need to use expected_out_enable2, but for timing
-            -- closure it is preferred to use r.enable.
-            REPORT "Unexpected enabled out_enable2" SEVERITY ERROR;
-          END IF;
-        ELSE
-          REPORT "Unexpected disabled out_enable" SEVERITY ERROR;
-        END IF;
+      IF expected_out_enable = '1' THEN
+        ASSERT out_enable = '1' REPORT "Wrong out_enable, should be active" SEVERITY ERROR;
+      ELSIF expected_out_enable = '0' THEN
+        ASSERT out_enable = '0' REPORT "Wrong out_enable, should be inactive" SEVERITY ERROR;
       END IF;
     END IF;
   END PROCESS;
@@ -471,6 +460,23 @@ BEGIN
     END IF;
   END PROCESS;
 
+  exp_start_interval <= out_start OR (first_interval AND NOT out_sync) WHEN rst = '0' ELSE '0';
+
+  p_verify_out_start_interval : PROCESS(clk)
+  BEGIN
+    IF rising_edge(clk) THEN
+      -- Create first_interval for exp_start_interval
+      IF out_start = '1' THEN
+        first_interval <= '1';
+      ELSIF out_sync = '1' THEN
+        first_interval <= '0';
+      END IF;
+
+      -- Verify exp_start_interval
+      ASSERT exp_start_interval = out_start_interval REPORT "Wrong out_start_interval" SEVERITY ERROR;
+    END IF;
+  END PROCESS;
+
   -----------------------------------------------------------------------------
   -- . Verify out_sosi = in_sosi, for all fields except out_sosi.sync
   -----------------------------------------------------------------------------
@@ -480,14 +486,19 @@ BEGIN
   -- declaration is not sufficient.
 
   verify_sosi_equal <= out_enable WHEN rising_edge(clk);
-  in_sosi_integer   <= func_dp_stream_slv_to_integer(in_sosi, c_natural_w) WHEN rising_edge(clk);
-  out_sosi_integer  <= func_dp_stream_slv_to_integer(out_sosi, c_natural_w) WHEN rising_edge(clk);
+  verify_sosi_equal_at_sop <= verify_sosi_equal AND in_sosi_integer.sop;
+  verify_sosi_equal_at_valid <= verify_sosi_equal AND in_sosi_integer.valid;
+
+  in_sosi_integer_comb <= func_dp_stream_slv_to_integer(in_sosi, c_natural_w) WHEN rising_edge(clk);
+  in_sosi_integer_pipe <= in_sosi_integer_comb WHEN rising_edge(clk);
+  in_sosi_integer <= in_sosi_integer_comb WHEN g_pipeline = 0 ELSE in_sosi_integer_pipe;
+  out_sosi_integer <= func_dp_stream_slv_to_integer(out_sosi, c_natural_w) WHEN rising_edge(clk);
 
-  proc_dp_verify_sosi_equal(  "bsn", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
+  proc_dp_verify_sosi_equal(  "bsn", clk, verify_sosi_equal_at_sop, out_sosi_integer, in_sosi_integer);
   proc_dp_verify_sosi_equal(  "sop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
   proc_dp_verify_sosi_equal(  "eop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
   proc_dp_verify_sosi_equal("valid", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
-  proc_dp_verify_sosi_equal( "data", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
+  proc_dp_verify_sosi_equal( "data", clk, verify_sosi_equal_at_valid, out_sosi_integer, in_sosi_integer);
 
   -- Verify that out_sosi blocks have sop and eop
   proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_out_sop);
@@ -558,7 +569,7 @@ BEGIN
   GENERIC MAP (
     g_bsn_w           => c_bsn_w,
     g_block_size      => g_block_size,
-    g_pipeline        => 0
+    g_pipeline        => g_pipeline
   )
   PORT MAP (
     rst                   => rst,
@@ -578,6 +589,7 @@ BEGIN
     in_sosi               => in_sosi,
     out_sosi              => out_sosi,
     out_start             => out_start,
+    out_start_interval    => out_start_interval,
     out_enable            => out_enable
   );
 
diff --git a/libraries/base/dp/tb/vhdl/tb_mms_dp_gain_serial_arr.vhd b/libraries/base/dp/tb/vhdl/tb_mms_dp_gain_serial_arr.vhd
index 43da667fd785be1a580b1607b5eb35a361d1a3ce..23bc0cbdaaeeefce44a4b31ee61c3b660d9428f2 100644
--- a/libraries/base/dp/tb/vhdl/tb_mms_dp_gain_serial_arr.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_mms_dp_gain_serial_arr.vhd
@@ -57,7 +57,7 @@ ARCHITECTURE tb OF tb_mms_dp_gain_serial_arr IS
   CONSTANT c_mm_clk_period              : TIME := 20 ns;
   CONSTANT c_dp_clk_period              : TIME := 10 ns;
   CONSTANT c_cross_clock_domain_latency : NATURAL := 20;
-  CONSTANT c_dut_latency                : NATURAL := 5;    -- = 3 for the real or complex multiplier + 2 for the RAM read latency
+  CONSTANT c_dut_latency                : NATURAL := 4;    -- = 3 for the real or complex multiplier + 1 for the RAM read latency
   
   CONSTANT c_real_multiply              : BOOLEAN := g_complex_data=FALSE AND g_complex_gain=FALSE;
   CONSTANT c_nof_gains_w                : NATURAL := ceil_log2(g_nof_gains);
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
index aea05a239d8776863bee18a2457fe397579c8727..03f0254a6fc66f4851572fcf8438cdfe00e763f6 100644
--- a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
@@ -42,6 +42,7 @@ ARCHITECTURE tb OF tb_tb_dp_bsn_sync_scheduler IS
   -- repeat period of the sync pattern is visible by nxt_r.accumulate in
   -- dp_bsn_scheduler.vhd.
   CONSTANT c_nof_input_sync : NATURAL := 25;
+  CONSTANT c_pipeline       : NATURAL := 1;
 
 BEGIN
   -- from tb_dp_bsn_scheduler.vhd
@@ -54,27 +55,30 @@ BEGIN
   --
   -- -- Output sync period
   -- g_nof_samples_per_output_sync  : NATURAL := 45;  -- = g_block_size * 9 / 2
+  -- g_pipeline                     : NATURAL := 0
 
-  u_output_is_input             : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 170);  -- 170/10 = 17    block/out_sync, = in_sosi
-  u_output_is_input_no_gaps     : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17,  5, 0,  85);  --  85/5  = 17    block/out_sync, = in_sosi
+  gen_tb : FOR P IN 0 TO c_pipeline GENERATE
+    u_output_is_input             : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 170, P);  -- 170/10 = 17    block/out_sync, = in_sosi
+    u_output_is_input_no_gaps     : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17,  5, 0,  85, P);  --  85/5  = 17    block/out_sync, = in_sosi
 
-  u_sync_interval_0_5x          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  85);  --  85/10 =  8.5  block/out_sync, factor  85/170 = 0.5,
-  u_sync_interval_1_5x          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 255);  -- 255/10 = 25.5  block/out_sync, factor 255/170 = 1.5,
-  u_sync_interval_prime_251     : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 251);  -- 251/10 = 25.1  block/out_sync, 251 is a prime
+    u_sync_interval_0_5x          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  85, P);  --  85/10 =  8.5  block/out_sync, factor  85/170 = 0.5,
+    u_sync_interval_1_5x          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 255, P);  -- 255/10 = 25.5  block/out_sync, factor 255/170 = 1.5,
+    u_sync_interval_prime_251     : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3, 251, P);  -- 251/10 = 25.1  block/out_sync, 251 is a prime
 
-  u_short_block_4_3_15          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  4,  3, 3,  15);  --  15/3  =  5    block/out_sync,
-  u_short_block_5_3_16          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  5,  3, 3,  16);  --  16/3  =  5.33 block/out_sync,
-  u_short_block_6_3_17          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  6,  3, 3,  17);  --  17/3  =  5.66 block/out_sync,
+    u_short_block_4_3_15          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  4,  3, 3,  15, P);  --  15/3  =  5    block/out_sync,
+    u_short_block_5_3_16          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  5,  3, 3,  16, P);  --  16/3  =  5.33 block/out_sync,
+    u_short_block_6_3_17          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  6,  3, 3,  17, P);  --  17/3  =  5.66 block/out_sync,
 
-  u_short_block_no_gaps_4_3_15  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  4,  3, 0,  15);  --  15/3  =  5    block/out_sync,
-  u_short_block_no_gaps_5_3_16  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  5,  3, 0,  16);  --  16/3  =  5.33 block/out_sync,
-  u_short_block_no_gaps_6_3_17  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  6,  3, 0,  17);  --  17/3  =  5.66 block/out_sync,
+    u_short_block_no_gaps_4_3_15  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  4,  3, 0,  15, P);  --  15/3  =  5    block/out_sync,
+    u_short_block_no_gaps_5_3_16  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  5,  3, 0,  16, P);  --  16/3  =  5.33 block/out_sync,
+    u_short_block_no_gaps_6_3_17  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  6,  3, 0,  17, P);  --  17/3  =  5.66 block/out_sync,
 
-  u_short_block_size_2          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  7,  2, 3,  16);  --  16/2  =  8    block/out_sync,
-  u_short_block_size_2_no_gaps  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  7,  2, 0,  16);  --  16/2  =  8    block/out_sync,
+    u_short_block_size_2          : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  7,  2, 3,  16, P);  --  16/2  =  8    block/out_sync,
+    u_short_block_size_2_no_gaps  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync,  7,  2, 0,  16, P);  --  16/2  =  8    block/out_sync,
 
-  u_fraction_half               : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  45);  --  45/10 =  4.5  block/out_sync
-  u_fraction_0                  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  50);  --  50/10 =  5    block/out_sync
+    u_fraction_half               : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  45, P);  --  45/10 =  4.5  block/out_sync
+    u_fraction_0                  : ENTITY work.tb_dp_bsn_sync_scheduler GENERIC MAP (c_nof_input_sync, 17, 10, 3,  50, P);  --  50/10 =  5    block/out_sync
+  END GENERATE;
 
 END tb;
   
diff --git a/libraries/base/ring/src/vhdl/ring_pkg.vhd b/libraries/base/ring/src/vhdl/ring_pkg.vhd
index 41ecf785cedd835bc29d1b7270f45c6499d52560..da55bc2268dc5badf90243a91ae79e45123ceb61 100644
--- a/libraries/base/ring/src/vhdl/ring_pkg.vhd
+++ b/libraries/base/ring/src/vhdl/ring_pkg.vhd
@@ -78,8 +78,7 @@ PACKAGE ring_pkg is
       ( field_name_pad("eth_src_mac"  ), "RW", 48, field_default(c_ring_eth_src_mac) ),
       ( field_name_pad("eth_type"     ), "RW", 16, field_default(0) )
   );
-  CONSTANT c_ring_eth_hdr_field_size : NATURAL := ceil_div(field_slv_len(c_ring_eth_hdr_field_arr), c_longword_w);
-
+  CONSTANT c_ring_eth_hdr_field_size : NATURAL := ceil_div(field_slv_len(c_ring_eth_hdr_field_arr), c_longword_w);  -- = 14/8 = 2 longwords
 
   CONSTANT c_ring_dp_nof_hdr_fields : NATURAL := 6;
   CONSTANT c_ring_dp_hdr_field_sel  : STD_LOGIC_VECTOR(c_ring_dp_nof_hdr_fields-1 DOWNTO 0) := "000"&"000";
@@ -91,7 +90,7 @@ PACKAGE ring_pkg is
       ( field_name_pad("dp_sync"      ), "RW",  1, field_default(0) ),
       ( field_name_pad("dp_bsn"       ), "RW", 63, field_default(0) )
   );
-  CONSTANT c_ring_dp_hdr_field_size : NATURAL := ceil_div(field_slv_len(c_ring_dp_hdr_field_arr), c_longword_w);
+  CONSTANT c_ring_dp_hdr_field_size : NATURAL := ceil_div(field_slv_len(c_ring_dp_hdr_field_arr), c_longword_w);  -- = 24/8 = 3 longwords
 
   FUNCTION func_ring_nof_hops_to_source_rn(hops, this_rn, N_rn, lane_dir : NATURAL) RETURN NATURAL;
   FUNCTION func_ring_nof_hops_to_source_rn(hops, this_rn, N_rn : STD_LOGIC_VECTOR; lane_dir : NATURAL) RETURN STD_LOGIC_VECTOR; -- return vector length is same as hops vector length
diff --git a/libraries/dsp/st/src/vhdl/st_sst.vhd b/libraries/dsp/st/src/vhdl/st_sst.vhd
index b21195656a2cec221c3a4afdb74bf46efc740349..a0092862dae0d6ab6f159514e81f27f8f3f7459a 100644
--- a/libraries/dsp/st/src/vhdl/st_sst.vhd
+++ b/libraries/dsp/st/src/vhdl/st_sst.vhd
@@ -21,6 +21,7 @@
 
 LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
+USE IEEE.math_real.ALL;  -- for sim only
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE common_lib.common_field_pkg.ALL;
@@ -43,6 +44,10 @@ USE technology_lib.technology_select_pkg.ALL;
 --   of the previous sync interval. The length of the sync interval determines
 --   the nof accumlations per statistic, hence the integration time. See st_calc
 --   for more details.
+--
+--   View wrdata_power and stat_bin in Wave window to see the stat power
+--   values series.
+--
 -- Remarks:
 -- . The in_sync is assumed to be a pulse an interpreted directly.
 -- . The MM register is single page RAM to save memory resources. Therefore
@@ -56,12 +61,13 @@ USE technology_lib.technology_select_pkg.ALL;
 ENTITY st_sst IS
   GENERIC (
     g_technology    : NATURAL := c_tech_select_default;
-    g_nof_stat      : NATURAL := 512;   -- nof accumulators
+    g_nof_stat      : NATURAL := 512;   -- total nof accumulators
     g_xst_enable    : BOOLEAN := FALSE; -- when set to true, an extra memory is instantiated to hold the imaginary part of the cross-correlation results
     g_in_data_w     : NATURAL := 18;    -- width o dth edata to be accumulated
     g_stat_data_w   : NATURAL := 54;    -- statistics accumulator width
-    g_stat_data_sz  : NATURAL := 2      -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
-  );                
+    g_stat_data_sz  : NATURAL := 2;     -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
+    g_stat_multiplex: NATURAL := 2      -- number of accumulators per stat_bin, for debug purposes with view in Wave window
+  );
   PORT (            
     mm_rst          : IN  STD_LOGIC;
     mm_clk          : IN  STD_LOGIC;
@@ -103,7 +109,7 @@ ARCHITECTURE str OF st_sst IS
   CONSTANT c_field_arr : t_common_field_arr(0 DOWNTO 0) := (0=> ( field_name_pad("treshold"), "RW", c_nof_stat_w, field_default(0) ));
 
   SIGNAL mm_fields_out : STD_LOGIC_VECTOR(field_slv_out_len(c_field_arr)-1 DOWNTO 0);
-  SIGNAL treshold      : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);  
+  SIGNAL treshold      : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
   
   TYPE reg_type IS RECORD
     in_sosi_reg : t_dp_sosi;  
@@ -113,14 +119,20 @@ ARCHITECTURE str OF st_sst IS
   
   SIGNAL r, rin       : reg_type;
   SIGNAL in_sync      : STD_LOGIC;  
-  SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);  
+
+  SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);
   SIGNAL stat_data_im : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);  
   
   SIGNAL wrdata_re    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
   SIGNAL wrdata_im    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
-  
-  SIGNAL stat_mosi    : t_mem_mosi;
-  SIGNAL count        : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
+
+  -- Sim only signals for observing wrdata_power with indices in Wave window
+  SIGNAL wrdata_power : REAL;
+  SIGNAL stat_bin     : NATURAL;
+
+  SIGNAL stat_mosi    : t_mem_mosi := c_mem_mosi_rst;
+
+  SIGNAL treshold_count : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
 
   SIGNAL ram_st_sst_mosi_arr : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
   SIGNAL ram_st_sst_miso_arr : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
@@ -153,24 +165,23 @@ BEGIN
   ------------------------------------------------------------------------------
   -- Input registers and preparation of the input data for the multiplier. 
   ------------------------------------------------------------------------------
-  comb : PROCESS(r, dp_rst, in_complex, count, treshold)
+  comb : PROCESS(r, dp_rst, in_complex, treshold_count, treshold)
     VARIABLE v : reg_type;
   BEGIN
     v               := r;
     v.in_sosi_reg   := in_complex; 
     
-    IF(count = zeros OR treshold = zeros) THEN 
+    IF treshold_count = zeros OR treshold = zeros THEN
       v.in_a_re  := in_complex.re(g_in_data_w-1 DOWNTO 0);
       v.in_a_im  := in_complex.im(g_in_data_w-1 DOWNTO 0);
     END IF;
    
-    IF(dp_rst = '1') THEN
+    IF dp_rst = '1' THEN
       v.in_a_re := (OTHERS => '0');
       v.in_a_im := (OTHERS => '0');
     END IF;
       
-    rin             <= v;  
-    
+    rin <= v;
   END PROCESS comb;
   
   regs : PROCESS(dp_clk)
@@ -181,7 +192,7 @@ BEGIN
   END PROCESS;  
 
   ------------------------------------------------------------------------------
-  -- Counter used to detect when treshold is reached in order to load new 
+  -- Counter used to detect when treshold is reached in order to load new
   -- input vlaues for the multiplier. 
   ------------------------------------------------------------------------------
   treshold_cnt : ENTITY common_lib.common_counter
@@ -197,13 +208,13 @@ BEGIN
     clk     => dp_clk,           
     cnt_clr => in_complex.eop,   
     cnt_en  => in_complex.valid, 
-    cnt_max => treshold,       
-    count   => count             
+    cnt_max => treshold,
+    count   => treshold_count
   );
 
   in_sync <= in_complex.sync;
   
-  st_calc : ENTITY work.st_calc 
+  st_calc : ENTITY work.st_calc
   GENERIC MAP (
     g_technology   => g_technology,
     g_nof_mux      => 1,
@@ -228,10 +239,19 @@ BEGIN
     out_val        => stat_mosi.wr,
     out_val_m      => OPEN
   );
-  
-  wrdata_re <= RESIZE_MEM_UDATA(stat_data_re);
-  wrdata_im <= RESIZE_MEM_UDATA(stat_data_im);
-  
+
+  -- Auto correlations are unsigned value, cross correlations are signed values
+  wrdata_re <= RESIZE_MEM_UDATA(stat_data_re) WHEN g_xst_enable=FALSE ELSE RESIZE_MEM_SDATA(stat_data_re);
+  wrdata_im <= RESIZE_MEM_UDATA(stat_data_im) WHEN g_xst_enable=FALSE ELSE RESIZE_MEM_SDATA(stat_data_im);
+
+  -- synthesis translate_off
+  -- View SST or XST power values in wave window (stat_data_im = 0 for SST)
+  wrdata_power <= COMPLEX_RADIUS(TO_SREAL(stat_data_re), TO_SREAL(stat_data_im)) ** 2.0;
+
+  stat_bin <= TO_UINT(stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0)) / g_stat_multiplex;
+  -- synthesis translate_on
+
+  -- For SST or for real part of XST
   stat_reg_re : ENTITY common_lib.common_ram_crw_crw_ratio
   GENERIC MAP (
     g_technology => g_technology,
@@ -261,12 +281,12 @@ BEGIN
     rd_val_b  => OPEN
   );                                   
  
-  gen_re: IF g_xst_enable=FALSE GENERATE
+  gen_sst: IF g_xst_enable=FALSE GENERATE
     ram_st_sst_mosi_arr(0) <= ram_st_sst_mosi;
     ram_st_sst_miso        <= ram_st_sst_miso_arr(0);
   END GENERATE;
   
-  gen_im: IF g_xst_enable=TRUE GENERATE
+  gen_xst: IF g_xst_enable=TRUE GENERATE
     ---------------------------------------------------------------
     -- COMBINE MEMORY MAPPED INTERFACES
     ---------------------------------------------------------------
@@ -284,6 +304,7 @@ BEGIN
       miso_arr => ram_st_sst_miso_arr
     );
   
+    -- For imaginary part of XST
     stat_reg_im : ENTITY common_lib.common_ram_crw_crw_ratio
     GENERIC MAP (
       g_technology => g_technology,
@@ -311,8 +332,7 @@ BEGIN
       rd_en_b   => '0',
       rd_dat_b  => OPEN,
       rd_val_b  => OPEN
-    );     
-    
+    );
   END GENERATE;
   
-END str;
\ No newline at end of file
+END str;
diff --git a/libraries/dsp/st/src/vhdl/st_xsq.vhd b/libraries/dsp/st/src/vhdl/st_xsq.vhd
index 4378a4c7507b12ec38b0467b1f2ac923b9c2f998..89bcd301e434019512d0cd44d4ffe9c57d56ac07 100644
--- a/libraries/dsp/st/src/vhdl/st_xsq.vhd
+++ b/libraries/dsp/st/src/vhdl/st_xsq.vhd
@@ -27,6 +27,10 @@
 --   of the previous sync interval. The length of the sync interval determines
 --   the nof accumlations per statistic, hence the integration time. See st_calc
 --   for more details.
+--
+--   View wrdata_power and a_sp, b_sp and crosslet_index in Wave window to see
+--   the stat power values series.
+--
 -- Remarks:
 -- . The in_sync is assumed to be a pulse an interpreted directly.
 -- . The MM register is single page RAM to save memory resources. Therefore
@@ -42,11 +46,13 @@
 
 LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
+USE IEEE.math_real.ALL;  -- for sim only
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE common_lib.common_field_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
 USE technology_lib.technology_select_pkg.ALL;
+
 ENTITY st_xsq IS
   GENERIC (
     g_nof_signal_inputs : NATURAL := 2;
@@ -100,7 +106,14 @@ ARCHITECTURE str OF st_xsq IS
   
   SIGNAL wrdata_re    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
   SIGNAL wrdata_im    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
-  
+
+  -- Sim only signals for observing wrdata_power with indices in Wave window
+  SIGNAL wrdata_power   : REAL;
+  SIGNAL stat_index     : NATURAL;
+  SIGNAL a_sp           : NATURAL;
+  SIGNAL b_sp           : NATURAL;
+  SIGNAL crosslet_index : NATURAL;
+
   SIGNAL stat_mosi    : t_mem_mosi := c_mem_mosi_rst;
 
   SIGNAL ram_st_xsq_mosi_arr      : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
@@ -165,9 +178,20 @@ BEGIN
     out_val_m      => OPEN
   );
   
-  wrdata_re <= RESIZE_MEM_UDATA(stat_data_re);
-  wrdata_im <= RESIZE_MEM_UDATA(stat_data_im);
+  -- Cross correlations are signed values
+  wrdata_re <= RESIZE_MEM_SDATA(stat_data_re);
+  wrdata_im <= RESIZE_MEM_SDATA(stat_data_im);
   
+  -- synthesis translate_off
+  wrdata_power <= COMPLEX_RADIUS(TO_SREAL(stat_data_re), TO_SREAL(stat_data_im)) ** 2.0;
+
+  -- Indices for statistics [crosslets][in A][in B]
+  stat_index <= TO_UINT(stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0));
+  a_sp <= (stat_index / g_nof_signal_inputs) MOD g_nof_signal_inputs;
+  b_sp <= stat_index MOD g_nof_signal_inputs;
+  crosslet_index <= stat_index / c_xsq;
+  -- synthesis translate_on
+
   ---------------------------------------------------------------
   -- COMBINE MEMORY MAPPED INTERFACES
   ---------------------------------------------------------------