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 d7f13a3d36a8bbe8dbb0ba7d4c6d5b86f60a3229..c249bdfbf36cd3bfb72c435d906390f3187bf112 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
@@ -211,6 +211,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
   CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDE#;  -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window
 
   CONSTANT c_exp_beamlet_scale   : NATURAL := NATURAL(g_beamlet_scale * REAL(c_sdp_unit_beamlet_scale));  -- c_sdp_unit_beamlet_scale = 2**15;
+  CONSTANT c_exp_beamlet_index   : NATURAL := 0;  -- depends on beamset bset * c_sdp_S_sub_bf
 
   CONSTANT c_exp_sdp_info        : t_sdp_info := (
                                      TO_UVEC(601, 16),   -- station_id
@@ -1213,57 +1214,68 @@ BEGIN
   -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
   -- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop.
 
-  p_exp_sdp_cep_header : PROCESS(exp_dp_bsn)
-  BEGIN
-    -- eth header
-    exp_sdp_cep_header.eth.dst_mac        <= c_cep_eth_dst_mac;
-    exp_sdp_cep_header.eth.src_mac        <= c_cep_eth_src_mac;
-    exp_sdp_cep_header.eth.eth_type       <= x"0800";
-
-    -- ip header
-    exp_sdp_cep_header.ip.version         <= TO_UVEC(                        4, c_network_ip_version_w);
-    exp_sdp_cep_header.ip.header_length   <= TO_UVEC(                        5, c_network_ip_header_length_w);
-    exp_sdp_cep_header.ip.services        <= TO_UVEC(                        0, c_network_ip_services_w);
-    exp_sdp_cep_header.ip.total_length    <=         c_sdp_cep_ip_total_length;  -- 7868, see ICD STAT-CEP
-    exp_sdp_cep_header.ip.identification  <= TO_UVEC(                        0, c_network_ip_identification_w);
-    exp_sdp_cep_header.ip.flags           <= TO_UVEC(                        2, c_network_ip_flags_w);
-    exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC(                        0, c_network_ip_fragment_offset_w);
-    exp_sdp_cep_header.ip.time_to_live    <= TO_UVEC(                      127, c_network_ip_time_to_live_w);
-    exp_sdp_cep_header.ip.protocol        <= TO_UVEC(                       17, c_network_ip_protocol_w);
-    exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w);
-    exp_sdp_cep_header.ip.src_ip_addr     <=                 c_cep_ip_src_addr;  -- c_network_ip_addr_w
-    exp_sdp_cep_header.ip.dst_ip_addr     <=                 c_cep_ip_dst_addr;  -- c_network_ip_addr_w
-
-    -- udp header
-    exp_sdp_cep_header.udp.src_port       <=                 c_cep_udp_src_port;
-    exp_sdp_cep_header.udp.dst_port       <=                 c_cep_udp_dst_port;
-    exp_sdp_cep_header.udp.total_length   <=         c_sdp_cep_udp_total_length;  -- 7848, see ICD STAT-CEP
-    exp_sdp_cep_header.udp.checksum       <= TO_UVEC(                         0, c_network_udp_checksum_w);
-
-    -- app header
-    exp_sdp_cep_header.app.sdp_marker         <= TO_UVEC(c_sdp_marker_beamlets, 8);  -- 98 = x"62" = 'b'
-    exp_sdp_cep_header.app.sdp_version_id     <= TO_UVEC(c_sdp_cep_version_id, 8);  -- 5
-    exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id;
-    exp_sdp_cep_header.app.sdp_station_id     <= c_exp_sdp_info.station_id;
-
-    exp_sdp_cep_header.app.sdp_source_info_antenna_band_id    <= slv(c_exp_sdp_info.antenna_band_index);
-    exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id    <=     c_exp_sdp_info.nyquist_zone_index;
-    exp_sdp_cep_header.app.sdp_source_info_f_adc              <= slv(c_exp_sdp_info.f_adc);
-    exp_sdp_cep_header.app.sdp_source_info_fsub_type          <= slv(c_exp_sdp_info.fsub_type);
-    exp_sdp_cep_header.app.sdp_source_info_payload_error      <= TO_UVEC(0, 1);
-    exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag);
-    exp_sdp_cep_header.app.sdp_source_info_beamlet_width      <= TO_UVEC(c_sdp_W_beamlet, 4);
-    exp_sdp_cep_header.app.sdp_source_info_gn_id              <= TO_UVEC(c_gn_index, 5);
-
-    exp_sdp_cep_header.app.sdp_reserved                       <= TO_UVEC(                               0, 40);
-    exp_sdp_cep_header.app.sdp_beamlet_scale                  <= TO_UVEC(             c_exp_beamlet_scale, 16);
-    exp_sdp_cep_header.app.sdp_beamlet_index                  <= TO_UVEC(                               0, 16);  -- depends on bset
-    exp_sdp_cep_header.app.sdp_nof_blocks_per_packet          <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet,  8);
-    exp_sdp_cep_header.app.sdp_nof_beamlets_per_block         <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16);
-    exp_sdp_cep_header.app.sdp_block_period                   <= c_exp_sdp_info.block_period;
-
-    exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64);   -- depends on bset and time
-  END PROCESS;
+  exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_eth_dst_mac,
+                                                    c_cep_eth_src_mac,
+                                                    c_cep_ip_src_addr,
+                                                    c_cep_ip_dst_addr,
+                                                    c_exp_ip_header_checksum,
+                                                    c_exp_sdp_info,
+                                                    c_gn_index,
+                                                    c_exp_beamlet_scale,
+                                                    c_exp_beamlet_index,
+                                                    exp_dp_bsn);
+
+  --p_exp_sdp_cep_header : PROCESS(exp_dp_bsn)
+  --BEGIN
+  --  -- eth header
+  --  exp_sdp_cep_header.eth.dst_mac        <= c_cep_eth_dst_mac;
+  --  exp_sdp_cep_header.eth.src_mac        <= c_cep_eth_src_mac;
+  --  exp_sdp_cep_header.eth.eth_type       <= x"0800";
+  --
+  --  -- ip header
+  --  exp_sdp_cep_header.ip.version         <= TO_UVEC(                        4, c_network_ip_version_w);
+  --  exp_sdp_cep_header.ip.header_length   <= TO_UVEC(                        5, c_network_ip_header_length_w);
+  --  exp_sdp_cep_header.ip.services        <= TO_UVEC(                        0, c_network_ip_services_w);
+  --  exp_sdp_cep_header.ip.total_length    <=         c_sdp_cep_ip_total_length;  -- 7868, see ICD STAT-CEP
+  --  exp_sdp_cep_header.ip.identification  <= TO_UVEC(                        0, c_network_ip_identification_w);
+  --  exp_sdp_cep_header.ip.flags           <= TO_UVEC(                        2, c_network_ip_flags_w);
+  --  exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC(                        0, c_network_ip_fragment_offset_w);
+  --  exp_sdp_cep_header.ip.time_to_live    <= TO_UVEC(                      127, c_network_ip_time_to_live_w);
+  --  exp_sdp_cep_header.ip.protocol        <= TO_UVEC(                       17, c_network_ip_protocol_w);
+  --  exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w);
+  --  exp_sdp_cep_header.ip.src_ip_addr     <=                 c_cep_ip_src_addr;  -- c_network_ip_addr_w
+  --  exp_sdp_cep_header.ip.dst_ip_addr     <=                 c_cep_ip_dst_addr;  -- c_network_ip_addr_w
+  --
+  --  -- udp header
+  --  exp_sdp_cep_header.udp.src_port       <=                 c_cep_udp_src_port;
+  --  exp_sdp_cep_header.udp.dst_port       <=                 c_cep_udp_dst_port;
+  --  exp_sdp_cep_header.udp.total_length   <=         c_sdp_cep_udp_total_length;  -- 7848, see ICD STAT-CEP
+  --  exp_sdp_cep_header.udp.checksum       <= TO_UVEC(                         0, c_network_udp_checksum_w);
+  --
+  --  -- app header
+  --  exp_sdp_cep_header.app.sdp_marker         <= TO_UVEC(c_sdp_marker_beamlets, 8);  -- 98 = x"62" = 'b'
+  --  exp_sdp_cep_header.app.sdp_version_id     <= TO_UVEC(c_sdp_cep_version_id, 8);  -- 5
+  --  exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id;
+  --  exp_sdp_cep_header.app.sdp_station_id     <= c_exp_sdp_info.station_id;
+  --
+  --  exp_sdp_cep_header.app.sdp_source_info_antenna_band_id    <= slv(c_exp_sdp_info.antenna_band_index);
+  --  exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id    <=     c_exp_sdp_info.nyquist_zone_index;
+  --  exp_sdp_cep_header.app.sdp_source_info_f_adc              <= slv(c_exp_sdp_info.f_adc);
+  --  exp_sdp_cep_header.app.sdp_source_info_fsub_type          <= slv(c_exp_sdp_info.fsub_type);
+  --  exp_sdp_cep_header.app.sdp_source_info_payload_error      <= TO_UVEC(0, 1);
+  --  exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag);
+  --  exp_sdp_cep_header.app.sdp_source_info_beamlet_width      <= TO_UVEC(c_sdp_W_beamlet, 4);
+  --  exp_sdp_cep_header.app.sdp_source_info_gn_id              <= TO_UVEC(c_gn_index, 5);
+  --
+  --  exp_sdp_cep_header.app.sdp_reserved                       <= TO_UVEC(                               0, 40);
+  --  exp_sdp_cep_header.app.sdp_beamlet_scale                  <= TO_UVEC(             c_exp_beamlet_scale, 16);
+  --  exp_sdp_cep_header.app.sdp_beamlet_index                  <= TO_UVEC(                               0, 16);  -- depends on bset
+  --  exp_sdp_cep_header.app.sdp_nof_blocks_per_packet          <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet,  8);
+  --  exp_sdp_cep_header.app.sdp_nof_beamlets_per_block         <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16);
+  --  exp_sdp_cep_header.app.sdp_block_period                   <= c_exp_sdp_info.block_period;
+  --
+  --  exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64);   -- depends on bset and time
+  --END PROCESS;
 
   rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
 
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 5930355ea60378745c482fe374b8f529f4f51448..dd52d4eb206cf007076a9b100f4e9e00400e8d28 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
@@ -75,6 +75,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS
   CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; 
   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_nof_sync            : NATURAL := 1;
 
   -- MM  
   CONSTANT c_mm_file_reg_bsn_source_v2   : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
@@ -88,12 +89,12 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS
   SIGNAL eth_done            : STD_LOGIC := '0';
 
   -- . 1GbE output
-  CONSTANT c_eth_check_nof_packets        : NATURAL := 1; -- received packets in 1 sync period
+  CONSTANT c_eth_check_nof_packets        : NATURAL := c_nof_sync * 1;
   CONSTANT c_eth_header_size              : NATURAL := 19; -- words
   CONSTANT c_eth_crc_size                 : NATURAL := 1; -- word
   CONSTANT c_eth_packet_size              : NATURAL := c_eth_header_size + c_eth_crc_size + (c_sdp_W_statistic / c_word_w) * c_sdp_S_sub_bf * c_sdp_N_pol; -- 20 + 2 * 488 * 2 = 1972 
   CONSTANT c_eth_check_nof_valid          : NATURAL := c_eth_check_nof_packets * c_eth_packet_size;  
-  CONSTANT c_eth_runtime_timeout          : TIME := 2 * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done at the second sync interval
+  CONSTANT c_eth_runtime_timeout          : TIME := (c_nof_sync + 1) * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done after c_nof_sync intervals
   
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
@@ -109,6 +110,16 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS
   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');
 
+  -- Rx packets
+  SIGNAL eth_rx_sosi         : t_dp_sosi;
+  SIGNAL eth_rx_data         : STD_LOGIC_VECTOR(c_32-1 downto 0);
+
+  -- Decode packets
+  SIGNAL rx_offload_sosi     : t_dp_sosi;
+  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_REFCLK      : STD_LOGIC := '1';
@@ -200,7 +211,7 @@ BEGIN
     ----------------------------------------------------------------------------
     -- Offload enable
     ----------------------------------------------------------------------------
-    mmf_mm_bus_wr(c_mm_file_reg_stat_enable_bst, 0, 1, tb_clk);
+    mmf_mm_bus_wr(c_mm_file_reg_stat_enable_bst, 0, 1, tb_clk);  -- only beamset 0
 
     -- wait for udp offload is done
     proc_common_wait_until_high(ext_clk, eth_done);
@@ -224,9 +235,38 @@ BEGIN
       g_check_nof_valid     => TRUE,
       g_check_nof_valid_ref => c_eth_check_nof_valid
    )
-  PORT MAP (  
+  PORT MAP (
     eth_serial_in => eth_txp(0),
+    eth_src_out   => eth_rx_sosi,
     tb_end        => eth_done
   );
 
+  eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0);
+
+  -- . 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
+  )
+  PORT MAP (
+    mm_rst                => pps_rst,
+    mm_clk                => tb_clk,
+
+    dp_rst                => pps_rst,
+    dp_clk                => eth_clk(0),
+
+    snk_in_arr(0)         => eth_rx_sosi,
+
+    src_out_arr(0)        => rx_offload_sosi,
+
+    hdr_fields_out_arr(0) => rx_hdr_fields_out,
+    hdr_fields_raw_arr(0) => rx_hdr_fields_raw
+  );
+
+  rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw);
+
 END tb;
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 80a3fbf828e332298152bccadb5b6ee33fe80641..5b14cb9aea233df7b59df0ff7031032d571d7f40 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
@@ -74,6 +74,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub_sst_offload IS
   CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; 
   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_nof_sync            : NATURAL := 2;
 
   -- MM  
   CONSTANT c_mm_file_reg_bsn_source_v2    : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
@@ -87,12 +88,12 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub_sst_offload IS
   SIGNAL eth_done            : STD_LOGIC := '0';
 
   -- . 1GbE output
-  CONSTANT c_eth_check_nof_packets        : NATURAL := c_sdp_S_pn; -- received packets in 1 sync period
+  CONSTANT c_eth_check_nof_packets        : NATURAL := c_nof_sync * c_sdp_S_pn;
   CONSTANT c_eth_header_size              : NATURAL := 19; -- words
   CONSTANT c_eth_crc_size                 : NATURAL := 1; -- word
   CONSTANT c_eth_packet_size              : NATURAL := c_eth_header_size + c_eth_crc_size + c_sdp_N_sub * (c_sdp_W_statistic / c_word_w); -- 20 + 512 * 2 = 1044 
   CONSTANT c_eth_check_nof_valid          : NATURAL := c_eth_check_nof_packets * c_eth_packet_size;  
-  CONSTANT c_eth_runtime_timeout          : TIME := 2 * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done at the second sync interval
+  CONSTANT c_eth_runtime_timeout          : TIME := (c_nof_sync + 1) * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done after c_nof_sync intervals
   
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
@@ -108,6 +109,16 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub_sst_offload IS
   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');
 
+  -- Rx packets
+  SIGNAL eth_rx_sosi         : t_dp_sosi;
+  SIGNAL eth_rx_data         : STD_LOGIC_VECTOR(c_32-1 downto 0);
+
+  -- Decode packets
+  SIGNAL rx_offload_sosi     : t_dp_sosi;
+  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_REFCLK      : STD_LOGIC := '1';
@@ -225,7 +236,36 @@ BEGIN
    )
   PORT MAP (  
     eth_serial_in => eth_txp(0),
+    eth_src_out   => eth_rx_sosi,
     tb_end        => eth_done
   );
 
+  eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0);
+
+  -- . 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
+  )
+  PORT MAP (
+    mm_rst                => pps_rst,
+    mm_clk                => tb_clk,
+
+    dp_rst                => pps_rst,
+    dp_clk                => eth_clk(0),
+
+    snk_in_arr(0)         => eth_rx_sosi,
+
+    src_out_arr(0)        => rx_offload_sosi,
+
+    hdr_fields_out_arr(0) => rx_hdr_fields_out,
+    hdr_fields_raw_arr(0) => rx_hdr_fields_raw
+  );
+
+  rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw);
+
 END tb;
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 8219a71f3fe2fbf6a0159224c884afb7a95321b9..a11dac56788bf43d7cbb73d8bfba830f7a65832e 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
@@ -76,11 +76,17 @@ 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_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;
 
   -- 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_stat_enable_xst         : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_STAT_ENABLE_XST";
+  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";
+  CONSTANT c_mm_file_reg_stat_enable_xst         : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_STAT_ENABLE_XST";
 
   -- Tb
   SIGNAL tb_end              : STD_LOGIC := '0';
@@ -90,12 +96,12 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS
   SIGNAL eth_done            : STD_LOGIC := '0';
 
   -- . 1GbE output
-  CONSTANT c_eth_check_nof_packets        : NATURAL := 1; -- received packets in 1 sync period
+  CONSTANT c_eth_check_nof_packets        : NATURAL := c_nof_sync * c_nof_crosslets;
   CONSTANT c_eth_header_size              : NATURAL := 19; -- words
   CONSTANT c_eth_crc_size                 : NATURAL := 1; -- word
-  CONSTANT c_eth_packet_size              : NATURAL := c_eth_header_size + c_eth_crc_size + (c_sdp_W_statistic / c_word_w) * c_sdp_S_pn * c_sdp_S_pn * c_nof_complex; -- 20 + 2 * 12 * 12 * 2 = 596 
+  CONSTANT c_eth_packet_size              : NATURAL := c_eth_header_size + c_eth_crc_size + (c_sdp_W_statistic / c_word_w) * c_sdp_S_pn * c_sdp_S_pn * c_nof_complex; -- 20 + 2 * 12 * 12 * 2 = 596
   CONSTANT c_eth_check_nof_valid          : NATURAL := c_eth_check_nof_packets * c_eth_packet_size;  
-  CONSTANT c_eth_runtime_timeout          : TIME := 3 * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done at the third sync interval
+  CONSTANT c_eth_runtime_timeout          : TIME := (c_nof_sync + 2) * c_nof_clk_per_sync * c_ext_clk_period;  -- eth statistics should be done after c_nof_sync
   
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
@@ -111,6 +117,16 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS
   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');
 
+  -- Rx packets
+  SIGNAL eth_rx_sosi         : t_dp_sosi;
+  SIGNAL eth_rx_data         : STD_LOGIC_VECTOR(c_32-1 downto 0);
+
+  -- Decode packets
+  SIGNAL rx_offload_sosi     : t_dp_sosi;
+  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_REFCLK      : STD_LOGIC := '1';
@@ -204,15 +220,26 @@ BEGIN
     pps_rst <= '0';
 
     ----------------------------------------------------------------------------
-    -- Enable xsub
+    -- Setup and enable xsub
     ----------------------------------------------------------------------------
+
+    -- Crosslets info
+    FOR I IN 0 TO c_sdp_N_crosslets_max-1 LOOP
+      mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, I, c_subband_select_arr(I), tb_clk);  -- offsets
+    END LOOP;
+    mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, 15, c_subband_step, tb_clk);  -- step size
+
+    -- Number of crosslets
+    mmf_mm_bus_wr(c_mm_file_reg_nof_crosslets, 0, c_nof_crosslets, tb_clk);
+
+    -- Integration interval and enable
     mmf_mm_bus_wr(c_mm_file_reg_bsn_sync_scheduler_xsub, 1, c_ctrl_interval_size, tb_clk);  -- Interval size
     mmf_mm_bus_wr(c_mm_file_reg_bsn_sync_scheduler_xsub, 2, c_nof_block_per_sync, tb_clk);  -- first write bsn low then bsn high part
     mmf_mm_bus_wr(c_mm_file_reg_bsn_sync_scheduler_xsub, 3,                    0, tb_clk);  -- bsn high, assume v_bsn < 2**31-1
     mmf_mm_bus_wr(c_mm_file_reg_bsn_sync_scheduler_xsub, 0,                    1, tb_clk);  -- enable
 
     ----------------------------------------------------------------------------
-    -- Offload enable
+    -- XST offload enable
     ----------------------------------------------------------------------------
     mmf_mm_bus_wr(c_mm_file_reg_stat_enable_xst, 0, 1, tb_clk);
 
@@ -229,8 +256,9 @@ BEGIN
   END PROCESS;
 
   -------------------------------------------------------------------------
-  -- Verify proper DUT 1GbE offload output using Ethernet packet statistics 
+  -- Verify proper DUT 1GbE offload output
   -------------------------------------------------------------------------
+  -- . Verify Ethernet packet statistics
   u_eth_statistics : ENTITY eth_lib.eth_statistics
     GENERIC MAP (
       g_runtime_nof_packets => c_eth_check_nof_packets,
@@ -240,7 +268,36 @@ BEGIN
    )
   PORT MAP (  
     eth_serial_in => eth_txp(0),
+    eth_src_out   => eth_rx_sosi,
     tb_end        => eth_done
   );
 
+  eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0);
+
+  -- . 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
+  )
+  PORT MAP (
+    mm_rst                => pps_rst,
+    mm_clk                => tb_clk,
+
+    dp_rst                => pps_rst,
+    dp_clk                => eth_clk(0),
+
+    snk_in_arr(0)         => eth_rx_sosi,
+
+    src_out_arr(0)        => rx_offload_sosi,
+
+    hdr_fields_out_arr(0) => rx_hdr_fields_out,
+    hdr_fields_raw_arr(0) => rx_hdr_fields_raw
+  );
+
+  rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw);
+
 END tb;
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
index 376b64247fa6e8bef2e5f4d903a4b97d95a2b225..30bec41ee81f0b7e11370b8723aa3e9a65d7b190 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
@@ -198,7 +198,7 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_stat_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608";  -- 00:22:86:08:pp:qq
   CONSTANT c_sdp_stat_ip_dst_addr       : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"0A6300FE";  -- 0A6300FE = '10.99.0.254' = DOP36-enp2s0
   CONSTANT c_sdp_stat_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63";    -- 10.99.xx.yy
-  CONSTANT c_sdp_stat_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5001, 16);
+  CONSTANT c_sdp_stat_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5001, 16);  -- 0x1389 = 5001
   CONSTANT c_sdp_sst_udp_src_port_15_8  : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D0";  -- TBC, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0])
   CONSTANT c_sdp_bst_udp_src_port_15_8  : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D1";  -- TBC
   CONSTANT c_sdp_xst_udp_src_port_15_8  : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D2";  -- TBC
@@ -318,7 +318,7 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_cep_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"C0A8";      -- 31:16, 15:8 = backplane, 7:0 = node + 1 = 192.168.xx.yy
   CONSTANT c_sdp_cep_ip_total_length   : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7868, 16);  -- see ICD STAT-CEP
   CONSTANT c_sdp_cep_udp_total_length  : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7848, 16);  -- see ICD STAT-CEP
-  CONSTANT c_sdp_cep_udp_dst_port      : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5000, 16);
+  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;
@@ -566,6 +566,7 @@ PACKAGE sdp_pkg is
   FUNCTION func_sdp_get_stat_app_total_length(g_statistics_type : STRING) RETURN NATURAL;
   FUNCTION func_sdp_get_stat_udp_total_length(g_statistics_type : STRING) RETURN NATURAL;
   FUNCTION func_sdp_get_stat_ip_total_length(g_statistics_type : STRING) RETURN NATURAL;
+  FUNCTION func_sdp_get_stat_udp_src_port(g_statistics_type : STRING; gn_index : NATURAL) RETURN STD_LOGIC_VECTOR;
   FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL;
   FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING) RETURN NATURAL;  -- use c_sdp_S_pn, c_sdp_P_sq, c_sdp_N_crosslets_max
 
@@ -701,6 +702,14 @@ PACKAGE BODY sdp_pkg IS
     RETURN c_sdp_udp_total_length + c_network_ip_header_len;
   END func_sdp_get_stat_ip_total_length;
 
+  FUNCTION func_sdp_get_stat_udp_src_port(g_statistics_type : STRING; gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
+    CONSTANT c_gn_index : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(gn_index, 8);
+  BEGIN
+    RETURN sel_a_b(g_statistics_type="BST", c_sdp_bst_udp_src_port_15_8 & c_gn_index,    -- BST = 0xD0 & gn_index
+           sel_a_b(g_statistics_type="XST", c_sdp_xst_udp_src_port_15_8 & c_gn_index,    -- XST = 0xD1 & gn_index
+                                            c_sdp_sst_udp_src_port_15_8 & c_gn_index));  -- SST = 0xD2 & gn_index
+  END func_sdp_get_stat_udp_src_port;
+
   FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL IS
   BEGIN
     RETURN sel_a_b(g_statistics_type="BST", 1,
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
index 934dbb94caddf710fb87cdda18238fa359dc3b2b..efb23c8a92d1e738b96ed7cbdbb2263ed7ed2b92 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
@@ -187,7 +187,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS
     packet_count         : NATURAL RANGE 0 TO c_nof_packets_max;
     start_address        : NATURAL RANGE 0 TO c_mm_ram_size;
     start_pulse          : STD_LOGIC;
-    sync                 : STD_LOGIC;
+    start_sync           : STD_LOGIC;
     dp_header_info       : STD_LOGIC_VECTOR(1023 DOWNTO 0);
     payload_err          : STD_LOGIC;
     in_sop_cnt           : NATURAL;
@@ -337,7 +337,7 @@ BEGIN
   END PROCESS;
 
   -- Assign application header data_id for different statistic types, use
-  -- GENERATE to keep unused fields at 0.
+  -- GENERATE to keep unused fields at 0 (all fields are NATURAL, so default to 0).
   gen_data_id_sst : IF g_statistics_type = "SST" GENERATE
     data_id_rec.sst_signal_input_index <= r.packet_count + local_si_offset;
   END GENERATE;
@@ -358,7 +358,7 @@ BEGIN
   BEGIN
     v := r;
     v.start_pulse := '0';
-    v.sync := '0';
+    v.start_sync := '0';
     
     -- Count number of sop in a sync interval and get payload errors and keep them till next sync.
     IF in_sosi.sync = '1' THEN
@@ -378,7 +378,7 @@ BEGIN
 
     -- For XST offload capture nof_crosslets and crosslets_info at in_sosi.sync,
     -- to make sure they do not change during packets offload.
-    -- . The sdp_crosslets_subband_select.vhd takes in [2] takes care that
+    -- . The sdp_crosslets_subband_select.vhd in [2] takes care that
     --   nof_crosslets and crosslets_info 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
@@ -403,7 +403,7 @@ BEGIN
       -- Use trigger_offload to start first packet offload, all
       -- g_statistics_type start from start address 0
       v.start_pulse        := '1';
-      v.sync               := '1';
+      v.start_sync         := '1';
       v.start_address      := 0;
       v.packet_count       := 0;
       v.interleave_count   := 0;  -- only used for SST
@@ -414,9 +414,7 @@ BEGIN
 
     -- The dp_sop = '1' when the packet has been read from statistics memory
     -- and is about to get out of the dp_fifo_fill_eop in
-    -- u_dp_block_from_mm_dc. The difference between dp_sop and the mm_done
-    -- output of u_dp_block_from_mm_dc, is that dp_sop also includes any
-    -- dp_fifo_fill_eop latency. This ensures that the dp_sop identifies the
+    -- u_dp_block_from_mm_dc. This ensures that the dp_sop identifies the
     -- sop of the offload packet. At the dp_sop:
     -- . the dp_header_info per packet offload can be released
     -- . the next packet offload can be prepared
@@ -446,7 +444,7 @@ BEGIN
 
         ELSIF g_statistics_type = "XST" THEN
           -- start_address:
-          --   nof_crosslets:     0,     1,     2,     3,     4,     5,     6
+          --   nof_crosslets:     1,     2,     3,     4,     5,     6,     7
           --   X_sq instance:
           --           0          0,   576,  1152,  1728,  2304,  2880,  3456
           --           1       4096,  4672,  5248,  5824,  6400,  6976,  7552
@@ -502,7 +500,8 @@ BEGIN
     g_nof_data           => c_mm_nof_data,
     g_word_w             => c_word_w,
     g_reverse_word_order => g_reverse_word_order,
-    g_bsn_w              => c_dp_stream_bsn_w
+    g_bsn_w              => c_dp_stream_bsn_w,
+    g_bsn_incr_enable    => FALSE  -- all offload block have same bsn_at_sync
   ) 
   PORT MAP(
     dp_rst        => dp_rst,
@@ -510,26 +509,23 @@ BEGIN
     mm_rst        => mm_rst,
     mm_clk        => mm_clk,
     start_pulse   => r.start_pulse,
-    sync_in       => r.sync,
-    bsn_at_sync   => bsn_at_sync, 
+    sync_in       => r.start_sync,
+    bsn_at_sync   => bsn_at_sync,
     start_address => r.start_address,
-    done          => mm_done,  -- not used, use dp_sop instead
     mm_mosi       => master_mosi,
     mm_miso       => master_miso,
+    out_sop       => dp_sop,  -- = dp_block_from_mm_src_out.sop
     out_sosi      => dp_block_from_mm_src_out,
     out_siso      => dp_block_from_mm_src_in
   );
 
-  -- Use dp_block_from_mm_src_out.sop as dp_sop, to include the
-  -- dp_fifo_fill_eop that is in dp_block_from_mm_dc. The dp_sop thus is the
-  -- sop of the packet that is about to be offloaded by u_dp_offload_tx_v3.
-  -- The r.dp_header_info must be available at the dp_offload_snk_in.sop.
-  -- This is guaranteed because:
+  -- The dp_sop is the sop of the packet that is about to be offloaded by
+  -- u_dp_offload_tx_v3. The r.dp_header_info must be available at the
+  -- dp_offload_snk_in.sop. This is guaranteed because:
   -- . r.dp_header_info is available one clock cycle after dp_sop in
   --   p_control_packet_offload.
   -- . The dp_offload_snk_in is delayed also by at least one clock cycle by
   --   u_dp_pipeline_ready.
-  dp_sop <= dp_block_from_mm_src_out.sop;
 
   u_dp_pipeline_ready : ENTITY dp_lib.dp_pipeline_ready
   PORT MAP(
@@ -543,6 +539,13 @@ BEGIN
     src_out      => dp_offload_snk_in
   );
 
+  -- The bsn_at_sync is passed on via r.dp_header_info so that
+  -- u_dp_offload_tx_v3 can put it in the udp_sosi header.
+  -- The dp_offload_snk_in.bsn that is passed on by u_dp_block_from_mm_dc is
+  -- in fact not used, but useful to see in udp_sosi.bsn in the Wave Window.
+  -- Similar dp_offload_snk_in.sync that is passed on by u_dp_block_from_mm_dc
+  -- is in fact not used, but useful to have in udp_sosi.sync (e.g. for the
+  -- tb).
   u_dp_offload_tx_v3: ENTITY dp_lib.dp_offload_tx_v3
   GENERIC MAP (
     g_nof_streams    => c_nof_streams,
@@ -594,7 +597,4 @@ BEGIN
     in_sosi_arr(0) => udp_sosi
   );
 
-
-
-
 END str;
diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
index 7c2e39c5f1af617d757ee4fe815428bedac881ce..529ca373069abab0a5067ea4975abb1fab15ab13 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
@@ -28,17 +28,45 @@
 LIBRARY IEEE, common_lib;
 USE IEEE.std_logic_1164.ALL;
 USE common_lib.common_pkg.ALL;
+USE common_lib.common_network_layers_pkg.ALL;
 USE work.sdp_pkg.ALL;
 
 PACKAGE tb_sdp_pkg is
   -----------------------------------------------------------------------------
   -- Statistics offload
   -----------------------------------------------------------------------------
+  FUNCTION func_sdp_compose_stat_header(eth_dst_mac            : STD_LOGIC_VECTOR(47 DOWNTO 0);  -- eth header
+                                        eth_src_mac            : STD_LOGIC_VECTOR(47 DOWNTO 0);
+                                        ip_src_addr            : STD_LOGIC_VECTOR(31 DOWNTO 0);  -- ip header
+                                        ip_dst_addr            : STD_LOGIC_VECTOR(31 DOWNTO 0);
+                                        sdp_info               : t_sdp_info;  -- app header
+                                        g_statistics_type      : STRING;
+                                        weighted_subbands_flag : STD_LOGIC;
+                                        gn_index               : NATURAL;
+                                        nof_block_per_sync     : NATURAL;
+                                        sst_signal_input       : NATURAL;
+                                        beamlet_index          : NATURAL;
+                                        subband_index          : NATURAL;
+                                        xst_signal_input_A     : NATURAL;
+                                        xst_signal_input_B     : NATURAL;
+                                        dp_bsn                 : NATURAL) RETURN t_sdp_stat_header;
+
   FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header) RETURN BOOLEAN;
 
   -----------------------------------------------------------------------------
   -- Beamlet output via 10GbE to CEP (= central processor)
   -----------------------------------------------------------------------------
+  FUNCTION func_sdp_compose_cep_header(eth_dst_mac        : STD_LOGIC_VECTOR(47 DOWNTO 0);  -- eth header
+                                       eth_src_mac        : STD_LOGIC_VECTOR(47 DOWNTO 0);
+                                       ip_src_addr        : STD_LOGIC_VECTOR(31 DOWNTO 0);  -- ip header
+                                       ip_dst_addr        : STD_LOGIC_VECTOR(31 DOWNTO 0);
+                                       ip_header_checksum : NATURAL;
+                                       sdp_info           : t_sdp_info;  -- app header
+                                       gn_index           : NATURAL;
+                                       beamlet_scale      : NATURAL;
+                                       beamlet_index      : NATURAL;
+                                       dp_bsn             : NATURAL) RETURN t_sdp_cep_header;
+
   FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN;
 
 
@@ -46,6 +74,99 @@ END PACKAGE tb_sdp_pkg;
 
 PACKAGE BODY tb_sdp_pkg IS
 
+  FUNCTION func_sdp_compose_stat_header(eth_dst_mac            : STD_LOGIC_VECTOR(47 DOWNTO 0);  -- eth header
+                                        eth_src_mac            : STD_LOGIC_VECTOR(47 DOWNTO 0);
+                                        ip_src_addr            : STD_LOGIC_VECTOR(31 DOWNTO 0);  -- ip header
+                                        ip_dst_addr            : STD_LOGIC_VECTOR(31 DOWNTO 0);
+                                        sdp_info               : t_sdp_info;  -- app header
+                                        g_statistics_type      : STRING;
+                                        weighted_subbands_flag : STD_LOGIC;
+                                        gn_index               : NATURAL;
+                                        nof_block_per_sync     : NATURAL;
+                                        sst_signal_input       : NATURAL;
+                                        beamlet_index          : NATURAL;
+                                        subband_index          : NATURAL;
+                                        xst_signal_input_A     : NATURAL;
+                                        xst_signal_input_B     : NATURAL;
+                                        dp_bsn                 : NATURAL) RETURN t_sdp_stat_header IS
+    CONSTANT c_nof_statistics_per_packet : NATURAL := func_sdp_get_stat_nof_statistics_per_packet(g_statistics_type);
+    CONSTANT c_udp_total_length          : NATURAL := func_sdp_get_stat_udp_total_length(g_statistics_type);
+    CONSTANT c_ip_total_length           : NATURAL := func_sdp_get_stat_ip_total_length(g_statistics_type);
+    CONSTANT c_marker                    : NATURAL := func_sdp_get_stat_marker(g_statistics_type);
+    CONSTANT c_nof_signal_inputs         : NATURAL := func_sdp_get_stat_nof_signal_inputs(g_statistics_type);
+
+    VARIABLE v_hdr : t_sdp_stat_header;
+  BEGIN
+    -- eth header
+    v_hdr.eth.dst_mac        := eth_dst_mac;
+    v_hdr.eth.src_mac        := eth_src_mac;
+    v_hdr.eth.eth_type       := x"0800";
+
+    -- ip header
+    v_hdr.ip.version         := TO_UVEC(                4, c_network_ip_version_w);
+    v_hdr.ip.header_length   := TO_UVEC(                5, c_network_ip_header_length_w);
+    v_hdr.ip.services        := TO_UVEC(                0, c_network_ip_services_w);
+    v_hdr.ip.total_length    := TO_UVEC(c_ip_total_length, c_network_ip_total_length_w);
+    v_hdr.ip.identification  := TO_UVEC(                0, c_network_ip_identification_w);
+    v_hdr.ip.flags           := TO_UVEC(                2, c_network_ip_flags_w);
+    v_hdr.ip.fragment_offset := TO_UVEC(                0, c_network_ip_fragment_offset_w);
+    v_hdr.ip.time_to_live    := TO_UVEC(              127, c_network_ip_time_to_live_w);
+    v_hdr.ip.protocol        := TO_UVEC(               17, c_network_ip_protocol_w);
+    v_hdr.ip.header_checksum := TO_UVEC(                0, c_network_ip_header_checksum_w);
+    v_hdr.ip.src_ip_addr     :=               ip_src_addr;  -- c_network_ip_addr_w
+    v_hdr.ip.dst_ip_addr     :=               ip_dst_addr;  -- c_network_ip_addr_w
+
+    -- udp header
+    IF g_statistics_type = "SST" THEN
+      v_hdr.udp.src_port := c_sdp_sst_udp_src_port_15_8 & TO_UVEC(gn_index, 8);
+    ELSIF g_statistics_type = "BST" THEN
+      v_hdr.udp.src_port := c_sdp_bst_udp_src_port_15_8 & TO_UVEC(gn_index, 8);
+    ELSIF g_statistics_type = "XST" THEN
+      v_hdr.udp.src_port := c_sdp_xst_udp_src_port_15_8 & TO_UVEC(gn_index, 8);
+    END IF;
+    v_hdr.udp.dst_port       :=   c_sdp_stat_udp_dst_port;
+    v_hdr.udp.total_length   := TO_UVEC(c_udp_total_length, c_network_udp_port_w);
+    v_hdr.udp.checksum       := TO_UVEC(                 0, c_network_udp_checksum_w);
+
+    -- app header
+    v_hdr.app.sdp_marker                              := TO_UVEC(c_marker, 8);
+    v_hdr.app.sdp_version_id                          := TO_UVEC(c_sdp_stat_version_id, 8);
+    v_hdr.app.sdp_observation_id                      := sdp_info.observation_id;
+    v_hdr.app.sdp_station_id                          := sdp_info.station_id;
+
+    v_hdr.app.sdp_source_info_antenna_band_id         := slv(sdp_info.antenna_band_index);
+    v_hdr.app.sdp_source_info_nyquist_zone_id         :=     sdp_info.nyquist_zone_index;
+    v_hdr.app.sdp_source_info_f_adc                   := slv(sdp_info.f_adc);
+    v_hdr.app.sdp_source_info_fsub_type               := slv(sdp_info.fsub_type);
+    v_hdr.app.sdp_source_info_payload_error           := TO_UVEC(0, 1);
+    v_hdr.app.sdp_source_info_beam_repositioning_flag := slv(sdp_info.beam_repositioning_flag);
+    v_hdr.app.sdp_source_info_weighted_subbands_flag  := slv(weighted_subbands_flag);
+    v_hdr.app.sdp_source_info_reserved                := TO_UVEC(0, 3);
+    v_hdr.app.sdp_source_info_gn_id                   := TO_UVEC(gn_index, 5);
+
+    v_hdr.app.sdp_reserved                            := TO_UVEC(                 0,  8);
+    v_hdr.app.sdp_integration_interval                := TO_UVEC(nof_block_per_sync, 24);
+    IF g_statistics_type = "SST" THEN
+      v_hdr.app.sdp_data_id                           := TO_UVEC(sst_signal_input, 32);
+      v_hdr.app.sdp_data_id_sst_signal_input_index    := TO_UVEC(sst_signal_input,  8);
+    ELSIF g_statistics_type = "BST" THEN
+      v_hdr.app.sdp_data_id                           := TO_UVEC(beamlet_index, 32);
+      v_hdr.app.sdp_data_id_bst_beamlet_index         := TO_UVEC(beamlet_index, 16);
+    ELSIF g_statistics_type = "XST" THEN
+      v_hdr.app.sdp_data_id                           := TO_UVEC(0, 7) & TO_UVEC(subband_index, 9) & TO_UVEC(xst_signal_input_A, 8) & TO_UVEC(xst_signal_input_B, 8);
+      v_hdr.app.sdp_data_id_xst_subband_index         := TO_UVEC(subband_index, 9);
+      v_hdr.app.sdp_data_id_xst_signal_input_A_index  := TO_UVEC(xst_signal_input_A, 8);
+      v_hdr.app.sdp_data_id_xst_signal_input_B_index  := TO_UVEC(xst_signal_input_B, 8);
+    END IF;
+    v_hdr.app.sdp_nof_signal_inputs                   := TO_UVEC(          c_nof_signal_inputs,  8);
+    v_hdr.app.sdp_nof_bytes_per_statistic             := TO_UVEC(c_sdp_nof_bytes_per_statistic,  8);
+    v_hdr.app.sdp_nof_statistics_per_packet           := TO_UVEC(  c_nof_statistics_per_packet, 16);
+    v_hdr.app.sdp_block_period                        := sdp_info.block_period;
+
+    v_hdr.app.dp_bsn := TO_UVEC(dp_bsn, 64);
+    RETURN v_hdr;
+  END func_sdp_compose_stat_header;
+
   FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header) RETURN BOOLEAN IS
   BEGIN
     -- eth header
@@ -116,6 +237,69 @@ PACKAGE BODY tb_sdp_pkg IS
   END func_sdp_verify_stat_header;
 
 
+  FUNCTION func_sdp_compose_cep_header(eth_dst_mac        : STD_LOGIC_VECTOR(47 DOWNTO 0);  -- eth header
+                                       eth_src_mac        : STD_LOGIC_VECTOR(47 DOWNTO 0);
+                                       ip_src_addr        : STD_LOGIC_VECTOR(31 DOWNTO 0);  -- ip header
+                                       ip_dst_addr        : STD_LOGIC_VECTOR(31 DOWNTO 0);
+                                       ip_header_checksum : NATURAL;
+                                       sdp_info           : t_sdp_info;  -- app header
+                                       gn_index           : NATURAL;
+                                       beamlet_scale      : NATURAL;
+                                       beamlet_index      : NATURAL;
+                                       dp_bsn             : NATURAL) RETURN t_sdp_cep_header IS
+    VARIABLE v_hdr : t_sdp_cep_header;
+  BEGIN
+    -- eth header
+    v_hdr.eth.dst_mac        := eth_dst_mac;
+    v_hdr.eth.src_mac        := eth_src_mac;
+    v_hdr.eth.eth_type       := x"0800";
+
+    -- ip header
+    v_hdr.ip.version         := TO_UVEC(                        4, c_network_ip_version_w);
+    v_hdr.ip.header_length   := TO_UVEC(                        5, c_network_ip_header_length_w);
+    v_hdr.ip.services        := TO_UVEC(                        0, c_network_ip_services_w);
+    v_hdr.ip.total_length    :=         c_sdp_cep_ip_total_length;
+    v_hdr.ip.identification  := TO_UVEC(                        0, c_network_ip_identification_w);
+    v_hdr.ip.flags           := TO_UVEC(                        2, c_network_ip_flags_w);
+    v_hdr.ip.fragment_offset := TO_UVEC(                        0, c_network_ip_fragment_offset_w);
+    v_hdr.ip.time_to_live    := TO_UVEC(                      127, c_network_ip_time_to_live_w);
+    v_hdr.ip.protocol        := TO_UVEC(                       17, c_network_ip_protocol_w);
+    v_hdr.ip.header_checksum := TO_UVEC(       ip_header_checksum, c_network_ip_header_checksum_w);
+    v_hdr.ip.src_ip_addr     :=                       ip_src_addr;  -- c_network_ip_addr_w
+    v_hdr.ip.dst_ip_addr     :=                       ip_dst_addr;  -- c_network_ip_addr_w
+
+    -- udp header
+    v_hdr.udp.src_port       := c_sdp_cep_udp_src_port_15_8 & TO_UVEC(gn_index, 8);
+    v_hdr.udp.dst_port       := c_sdp_cep_udp_dst_port;
+    v_hdr.udp.total_length   := c_sdp_cep_udp_total_length;
+    v_hdr.udp.checksum       := TO_UVEC(0, c_network_udp_checksum_w);
+
+    -- app header
+    v_hdr.app.sdp_marker                              := TO_UVEC(c_sdp_marker_beamlets, 8);
+    v_hdr.app.sdp_version_id                          := TO_UVEC(c_sdp_cep_version_id, 8);
+    v_hdr.app.sdp_observation_id                      := sdp_info.observation_id;
+    v_hdr.app.sdp_station_id                          := sdp_info.station_id;
+
+    v_hdr.app.sdp_source_info_antenna_band_id         := slv(sdp_info.antenna_band_index);
+    v_hdr.app.sdp_source_info_nyquist_zone_id         :=     sdp_info.nyquist_zone_index;
+    v_hdr.app.sdp_source_info_f_adc                   := slv(sdp_info.f_adc);
+    v_hdr.app.sdp_source_info_fsub_type               := slv(sdp_info.fsub_type);
+    v_hdr.app.sdp_source_info_payload_error           := TO_UVEC(0, 1);
+    v_hdr.app.sdp_source_info_repositioning_flag      := slv(sdp_info.beam_repositioning_flag);
+    v_hdr.app.sdp_source_info_beamlet_width           := TO_UVEC(c_sdp_W_beamlet, 4);
+    v_hdr.app.sdp_source_info_gn_id                   := TO_UVEC(gn_index, 5);
+
+    v_hdr.app.sdp_reserved                            := TO_UVEC(0, 40);
+    v_hdr.app.sdp_beamlet_scale                       := TO_UVEC(beamlet_scale, 16);
+    v_hdr.app.sdp_beamlet_index                       := TO_UVEC(beamlet_index, 16);
+    v_hdr.app.sdp_nof_blocks_per_packet               := TO_UVEC(c_sdp_cep_nof_blocks_per_packet, 8);
+    v_hdr.app.sdp_nof_beamlets_per_block              := TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16);
+    v_hdr.app.sdp_block_period                        := sdp_info.block_period;
+
+    v_hdr.app.dp_bsn := TO_UVEC(dp_bsn, 64);
+    RETURN v_hdr;
+  END func_sdp_compose_cep_header;
+
   FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN IS
     VARIABLE v_beamlet_index : NATURAL;
   BEGIN
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 99ebd6f839aef1583d421cee33c40dfcca70927a..1193efc51d1626ac76565c476870d39bcff62236 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
@@ -85,7 +85,7 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   -- In this tb simply use fixed network src addresses
   CONSTANT c_eth_src_mac  : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := x"123456789ABC";
   CONSTANT c_ip_src_addr  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0) := x"0A090807";
-  CONSTANT c_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := x"D001";
+  CONSTANT c_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := func_sdp_get_stat_udp_src_port(g_statistics_type, g_gn_index);
 
   -- Used mm_adresses on mm bus "enable_mosi/miso".
   CONSTANT c_reg_enable_mm_addr_enable : NATURAL := 0;
@@ -191,7 +191,7 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   SIGNAL rx_sdp_stat_header      : t_sdp_stat_header;
   SIGNAL exp_sdp_stat_header     : t_sdp_stat_header;
 
-  SIGNAL exp_dp_bsn              : STD_LOGIC_VECTOR(63 DOWNTO 0);
+  SIGNAL exp_dp_bsn              : NATURAL;
   SIGNAL exp_sst_signal_input    : NATURAL;
   SIGNAL exp_bst_beamlet_index   : NATURAL;
   SIGNAL cur_X_sq_cell           : NATURAL;
@@ -354,7 +354,7 @@ BEGIN
   -- verify it at rx_offload_sosi.eop.
 
   -- For all statistics
-  exp_dp_bsn <= TO_SVEC(c_bsn_init + 1 + rx_sync_cnt * c_nof_block_per_sync, 64);
+  exp_dp_bsn <= c_bsn_init + 1 + rx_sync_cnt * c_nof_block_per_sync;
   -- SST
   exp_sst_signal_input <= rx_packet_cnt + c_sdp_S_pn * gn_index;
   -- BST
@@ -369,70 +369,21 @@ BEGIN
   -- . prepare expected XST signal_input_B index, assume crosslet transport in positive direction
   exp_xst_signal_input_B <= (source_gn MOD c_sdp_N_pn_max) * c_sdp_S_pn;
 
-  p_exp_sdp_stat_header : PROCESS(weighted_subbands_flag, gn_index, exp_dp_bsn, exp_sst_signal_input, exp_subband_index, exp_xst_signal_input_A, exp_xst_signal_input_B)
-  BEGIN
-    -- eth header
-    exp_sdp_stat_header.eth.dst_mac        <= c_sdp_stat_eth_dst_mac;
-    exp_sdp_stat_header.eth.src_mac        <= c_eth_src_mac;
-    exp_sdp_stat_header.eth.eth_type       <= x"0800";
-
-    -- ip header
-    exp_sdp_stat_header.ip.version         <= TO_UVEC(                4, c_network_ip_version_w);
-    exp_sdp_stat_header.ip.header_length   <= TO_UVEC(                5, c_network_ip_header_length_w);
-    exp_sdp_stat_header.ip.services        <= TO_UVEC(                0, c_network_ip_services_w);
-    exp_sdp_stat_header.ip.total_length    <= TO_UVEC(c_ip_total_length, c_network_ip_total_length_w);
-    exp_sdp_stat_header.ip.identification  <= TO_UVEC(                0, c_network_ip_identification_w);
-    exp_sdp_stat_header.ip.flags           <= TO_UVEC(                2, c_network_ip_flags_w);
-    exp_sdp_stat_header.ip.fragment_offset <= TO_UVEC(                0, c_network_ip_fragment_offset_w);
-    exp_sdp_stat_header.ip.time_to_live    <= TO_UVEC(              127, c_network_ip_time_to_live_w);
-    exp_sdp_stat_header.ip.protocol        <= TO_UVEC(               17, c_network_ip_protocol_w);
-    exp_sdp_stat_header.ip.header_checksum <= TO_UVEC(                0, c_network_ip_header_checksum_w);
-    exp_sdp_stat_header.ip.src_ip_addr     <=             c_ip_src_addr;  -- c_network_ip_addr_w
-    exp_sdp_stat_header.ip.dst_ip_addr     <=    c_sdp_stat_ip_dst_addr;  -- c_network_ip_addr_w
-
-    -- udp header
-    exp_sdp_stat_header.udp.src_port       <=             c_udp_src_port;
-    exp_sdp_stat_header.udp.dst_port       <= TO_UVEC(              5001, c_network_udp_port_w);
-    exp_sdp_stat_header.udp.total_length   <= TO_UVEC(c_udp_total_length, c_network_udp_port_w);
-    exp_sdp_stat_header.udp.checksum       <= TO_UVEC(                 0, c_network_udp_checksum_w);
-
-    -- app header
-    exp_sdp_stat_header.app.sdp_marker                              <= TO_UVEC(c_marker, 8);
-    exp_sdp_stat_header.app.sdp_version_id                          <= TO_UVEC(c_sdp_stat_version_id, 8);
-    exp_sdp_stat_header.app.sdp_observation_id                      <= c_exp_sdp_info.observation_id;
-    exp_sdp_stat_header.app.sdp_station_id                          <= c_exp_sdp_info.station_id;
-
-    exp_sdp_stat_header.app.sdp_source_info_antenna_band_id         <= slv(c_exp_sdp_info.antenna_band_index);
-    exp_sdp_stat_header.app.sdp_source_info_nyquist_zone_id         <=     c_exp_sdp_info.nyquist_zone_index;
-    exp_sdp_stat_header.app.sdp_source_info_f_adc                   <= slv(c_exp_sdp_info.f_adc);
-    exp_sdp_stat_header.app.sdp_source_info_fsub_type               <= slv(c_exp_sdp_info.fsub_type);
-    exp_sdp_stat_header.app.sdp_source_info_payload_error           <= TO_UVEC(0, 1);
-    exp_sdp_stat_header.app.sdp_source_info_beam_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag);
-    exp_sdp_stat_header.app.sdp_source_info_weighted_subbands_flag  <= slv(weighted_subbands_flag);
-    exp_sdp_stat_header.app.sdp_source_info_reserved                <= TO_UVEC(0, 3);
-    exp_sdp_stat_header.app.sdp_source_info_gn_id                   <= TO_UVEC(gn_index, 5);
-
-    exp_sdp_stat_header.app.sdp_reserved                            <= TO_UVEC(                   0,  8);
-    exp_sdp_stat_header.app.sdp_integration_interval                <= TO_UVEC(c_nof_block_per_sync, 24);
-    IF g_statistics_type = "SST" THEN
-      exp_sdp_stat_header.app.sdp_data_id                           <= TO_UVEC(exp_sst_signal_input, 32);
-      exp_sdp_stat_header.app.sdp_data_id_sst_signal_input_index    <= TO_UVEC(exp_sst_signal_input,  8);
-    ELSIF g_statistics_type = "BST" THEN
-      exp_sdp_stat_header.app.sdp_data_id                           <= TO_UVEC(c_beamlet_index, 32);
-      exp_sdp_stat_header.app.sdp_data_id_bst_beamlet_index         <= TO_UVEC(c_beamlet_index, 16);
-    ELSIF g_statistics_type = "XST" THEN
-      exp_sdp_stat_header.app.sdp_data_id                           <= TO_UVEC(0, 7) & TO_UVEC(exp_subband_index, 9) & TO_UVEC(exp_xst_signal_input_A, 8) & TO_UVEC(exp_xst_signal_input_B, 8);
-      exp_sdp_stat_header.app.sdp_data_id_xst_subband_index         <= TO_UVEC(exp_subband_index, 9);
-      exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_A_index  <= TO_UVEC(exp_xst_signal_input_A, 8);
-      exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_B_index  <= TO_UVEC(exp_xst_signal_input_B, 8);
-    END IF;
-    exp_sdp_stat_header.app.sdp_nof_signal_inputs                   <= TO_UVEC(          c_nof_signal_inputs,  8);
-    exp_sdp_stat_header.app.sdp_nof_bytes_per_statistic             <= TO_UVEC(c_sdp_nof_bytes_per_statistic,  8);
-    exp_sdp_stat_header.app.sdp_nof_statistics_per_packet           <= TO_UVEC(  c_nof_statistics_per_packet, 16);
-    exp_sdp_stat_header.app.sdp_block_period                        <= c_exp_sdp_info.block_period;
-
-    exp_sdp_stat_header.app.dp_bsn <= exp_dp_bsn;
-  END PROCESS;
+  exp_sdp_stat_header <= func_sdp_compose_stat_header(c_sdp_stat_eth_dst_mac,
+                                                      c_eth_src_mac,
+                                                      c_ip_src_addr,
+                                                      c_sdp_stat_ip_dst_addr,
+                                                      c_exp_sdp_info,
+                                                      g_statistics_type,
+                                                      weighted_subbands_flag,
+                                                      gn_index,
+                                                      c_nof_block_per_sync,
+                                                      exp_sst_signal_input,
+                                                      c_beamlet_index,
+                                                      exp_subband_index,
+                                                      exp_xst_signal_input_A,
+                                                      exp_xst_signal_input_B,
+                                                      exp_dp_bsn);
 
   rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw);
 
diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
index 839b6eee681665af5afb5b3a144169868fc309c5..fb32a58e02b98a023a4ddce8a75dfae4068bf0d0 100644
--- a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
+++ b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
@@ -58,8 +58,9 @@
 --   sync_in is not equal to start_pulse as start pulse indicates the start
 --   of a packet and not the start of a sync period.
 -- . For generating a bsn at out_sosi, the bsn_at_sync should contain the 
---   desired bsn at sync_in pulse. The bsn is increased in this component at
---   every start_pulse.
+--   desired bsn at sync_in pulse. If g_bsn_incr_enable then out_sosi.bsn is
+--   incremented in this component at every start_pulse, else out_sosi.bsn
+--   is kept at bsn_at_sync.
 -- --------------------------------------------------------------------------
 
 LIBRARY IEEE,common_lib;
@@ -78,16 +79,17 @@ ENTITY dp_block_from_mm IS
     g_word_w             : NATURAL := c_word_w;
     g_mm_rd_latency      : NATURAL := 1;  -- default 1 from rd_en to rd_val, use 2 to ease timing closure
     g_reverse_word_order : BOOLEAN := FALSE;
-    g_bsn_w              : NATURAL := 1
-  ); 
+    g_bsn_w              : NATURAL := 1;
+    g_bsn_incr_enable    : BOOLEAN := TRUE
+  );
   PORT (
     rst           : IN  STD_LOGIC;
     clk           : IN  STD_LOGIC;
     start_pulse   : IN  STD_LOGIC;
-    sync_in       : IN  STD_LOGIC := '0'; -- Must be syncronous with start_pulse.
+    sync_in       : IN  STD_LOGIC := '0';  -- Must be syncronous with start_pulse.
     bsn_at_sync   : IN  STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); 
     start_address : IN  NATURAL;
-    mm_done       : OUT STD_LOGIC;
+    mm_done       : OUT STD_LOGIC;  -- = out_sosi.eop
     mm_mosi       : OUT t_mem_mosi;
     mm_miso       : IN  t_mem_miso;
     out_sosi      : OUT t_dp_sosi;
@@ -158,7 +160,7 @@ BEGIN
     out_sosi.bsn   <= RESIZE_DP_BSN(out_bsn);  -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.bsn can be used for output bsn
   END PROCESS;
 
-  mm_done <= r.eop;
+  mm_done <= out_eop;
 
   p_reg : PROCESS(rst, clk)
   BEGIN
@@ -219,7 +221,7 @@ BEGIN
           IF v.sync_in_detected = '1' THEN
             v.sync := '1';
             v.sync_in_detected := '0';
-          ELSE
+          ELSIF g_bsn_incr_enable = TRUE THEN
             v.bsn := INCR_UVEC(r.bsn, 1);
           END IF;
         END IF;
diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd
index 86189e162cc1f7c9ccc80c94795eac7f32d9a7f4..b355ca2e1d552d078a634042fabe958c1372826c 100644
--- a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd
+++ b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd
@@ -21,10 +21,22 @@
 -- . Pieter Donker
 -- Purpose:
 -- . Read a block of data from memory mapped (MM) location and stream it as a block of data,
---   this is a dual-clock wrapper around dp_block_from_mm.vhd 
+--   this is a dual-clock wrapper around dp_block_from_mm.vhd.
 -- Description:
 -- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank
 -- . see dp_block_from_mm.vhd
+-- . read block - output block synchronisation:
+--   The start_pulse causes dp_block_from_mm to read a block from memory. The
+--   mm_done = mm_fifo_sosi.eop signals that the last word was read from
+--   memory and is about to enter the u_dp_fifo_fill_eop. The
+--   u_dp_fifo_fill_eop can only output a new packet when it has got the eop,
+--   so then the out_sop = dp_out_sosi.sop will appear some cycles later at the
+--   u_dp_fifo_fill_eop output, due to the mm_clk - dp_clk domain crossing.
+--   The out_sop thus indicates that the complete block available in the
+--   u_dp_fifo_fill_eop and is being output. Now a new start_pulse can be
+--   accepted by dp_block_from_mm_dc to read a next block. Thanks to this
+--   handshake the start_pulse and out_sop always follow in pairs.
+--
 -- --------------------------------------------------------------------------
 
 LIBRARY IEEE,common_lib;
@@ -42,8 +54,9 @@ ENTITY dp_block_from_mm_dc IS
     g_nof_data           : NATURAL;
     g_word_w             : NATURAL := c_word_w;
     g_reverse_word_order : BOOLEAN := FALSE;
-    g_bsn_w              : NATURAL := 1
-  ); 
+    g_bsn_w              : NATURAL := 1;
+    g_bsn_incr_enable    : BOOLEAN := TRUE
+  );
   PORT (
     -- mm_clk domain
     mm_rst        : IN  STD_LOGIC;
@@ -54,10 +67,10 @@ ENTITY dp_block_from_mm_dc IS
     dp_rst        : IN  STD_LOGIC;
     dp_clk        : IN  STD_LOGIC;
     start_pulse   : IN  STD_LOGIC;
-    sync_in       : IN  STD_LOGIC := '0'; -- Must be syncronous with start_pulse.
+    sync_in       : IN  STD_LOGIC := '0';  -- Must be syncronous with start_pulse.
     bsn_at_sync   : IN  STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); 
     start_address : IN  NATURAL;
-    done          : OUT STD_LOGIC;
+    out_sop       : OUT STD_LOGIC;  -- = out_sosi.sop
     out_sosi      : OUT t_dp_sosi;
     out_siso      : IN  t_dp_siso
   );
@@ -69,61 +82,80 @@ ARCHITECTURE str OF dp_block_from_mm_dc IS
 
   -- Fit one packet in FIFO, and less than two, to avoid filling the FIFO with
   -- multiple packets in case writing FIFO (mm_clk) is faster than reading
-  -- FIFO (dp_clk).
+  -- FIFO (dp_clk). It also works if the FIFO can fit multiple packets,
+  -- because the handshake between out_sop and start_pulse takes care that a
+  -- new packet will only be input when the previous packet is being output.
   CONSTANT c_fifo_fill    : NATURAL := c_packet_size;
   CONSTANT c_fifo_size    : NATURAL := c_packet_size + c_packet_size/2;
   CONSTANT c_start_addr_w : NATURAL := c_natural_w;
   CONSTANT c_delay_len    : NATURAL := c_meta_delay_len;
 
+  SIGNAL dp_out_sosi          : t_dp_sosi := c_dp_sosi_rst;
+  SIGNAL dp_out_siso          : t_dp_siso;
   SIGNAL mm_fifo_sosi         : t_dp_sosi := c_dp_sosi_rst;
   SIGNAL mm_fifo_siso         : t_dp_siso;
-  SIGNAL start_pulse_dly      : STD_LOGIC_VECTOR(0 TO c_delay_len) := (OTHERS => '0');
-  SIGNAL sync_dly             : STD_LOGIC_VECTOR(0 TO c_delay_len) := (OTHERS => '0');
   SIGNAL mm_start_pulse       : STD_LOGIC := '0';
+  SIGNAL mm_sync_hi           : STD_LOGIC := '0';
+  SIGNAL mm_sync_level        : STD_LOGIC := '0';
   SIGNAL mm_sync              : STD_LOGIC := '0';
-  SIGNAL mm_done              : STD_LOGIC := '0';
+  SIGNAL mm_done              : STD_LOGIC := '0';  -- not used, instead use out_sop
   SIGNAL mm_bsn_at_sync       : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0)        := (OTHERS => '0');
   SIGNAL start_address_slv    : STD_LOGIC_VECTOR(c_start_addr_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL mm_start_address_slv : STD_LOGIC_VECTOR(c_start_addr_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL mm_start_address     : NATURAL := 0;
 
 BEGIN
-  -- Use sync/start_pulse_dly to make sure mm_start_address_slv is stable before
-  -- mm_start_pulse, also when mm_clk is faster than dp_clk (e.g. in sim).
-  start_pulse_dly(0) <= start_pulse;
-  start_pulse_dly(1 TO c_delay_len) <= start_pulse_dly(0 TO c_delay_len-1) WHEN rising_edge(dp_clk);
-  sync_dly(0) <= sync_in;
-  sync_dly(1 TO c_delay_len) <= sync_dly(0 TO c_delay_len-1) WHEN rising_edge(dp_clk);
 
+  -- Use g_delay_len = c_meta_delay_len + 4 for start_pulse and g_delay_len =
+  -- c_meta_delay_len for the other signals. The + 4 ensures that the other
+  -- signals are already stable in the mm_clk domain, when the mm_start_pulse
+  -- occurs in the mm_clk domain. Use + 4 to still have 2 clock cycles margin
+  -- if mm_start_pulse arrive one clock cycle early and mm_sync_hi arrives one
+  -- clock cycle late.
   u_common_spulse_start_pulse : ENTITY common_lib.common_spulse
+  GENERIC MAP (
+    g_delay_len => c_meta_delay_len + 4
+  )
   PORT MAP (
     in_rst      => dp_rst,
     in_clk      => dp_clk,
-    in_pulse    => start_pulse_dly(c_delay_len),
+    in_pulse    => start_pulse,
     out_rst     => mm_rst,
     out_clk     => mm_clk,
     out_pulse   => mm_start_pulse
   );
 
+  -- The synchronous start_pulse and sync_in in the dp_clk domain cannot be
+  -- passed on via two separate common_spulse instances, because then they may
+  -- appear at different clock cycles in the mm_clk domain, due to that the
+  -- dp_clk and mm_clk are asynchronous on HW. Therefore use mm_sync_level to
+  -- pass on sync_in.
   u_common_spulse_sync : ENTITY common_lib.common_spulse
+  GENERIC MAP (
+    g_delay_len => c_meta_delay_len
+  )
   PORT MAP (
     in_rst      => dp_rst,
     in_clk      => dp_clk,
-    in_pulse    => sync_dly(c_delay_len),
+    in_pulse    => sync_in,
     out_rst     => mm_rst,
     out_clk     => mm_clk,
-    out_pulse   => mm_sync
+    out_pulse   => mm_sync_hi
   );
 
-  u_common_spulse_mm_done : ENTITY common_lib.common_spulse
-  PORT MAP (
-    in_rst      => mm_rst,
-    in_clk      => mm_clk,
-    in_pulse    => mm_done,
-    out_rst     => dp_rst,
-    out_clk     => dp_clk,
-    out_pulse   => done
-  );
+  p_mm_sync : PROCESS(mm_clk)
+  BEGIN
+    IF rising_edge(mm_clk) THEN
+      IF mm_sync_hi = '1' THEN
+        mm_sync_level <= '1';
+      END IF;
+      IF mm_start_pulse = '1' THEN
+        mm_sync_level <= '0';
+      END IF;
+    END IF;
+  END PROCESS;
+
+  mm_sync <= mm_sync_level AND mm_start_pulse;  -- synchronous with mm_start_pulse
 
   start_address_slv <= TO_UVEC(start_address, c_start_addr_w);
   mm_start_address <= TO_UINT(mm_start_address_slv);
@@ -169,8 +201,8 @@ BEGIN
     snk_in      => mm_fifo_sosi,
     snk_out     => mm_fifo_siso,
     -- ST source
-    src_out     => out_sosi,
-    src_in      => out_siso
+    src_out     => dp_out_sosi,
+    src_in      => dp_out_siso
   );
 
   u_dp_block_from_mm : ENTITY work.dp_block_from_mm
@@ -181,7 +213,8 @@ BEGIN
     g_nof_data           => g_nof_data,
     g_word_w             => g_word_w,
     g_reverse_word_order => g_reverse_word_order,
-    g_bsn_w              => g_bsn_w 
+    g_bsn_w              => g_bsn_w,
+    g_bsn_incr_enable    => g_bsn_incr_enable
   )
   PORT MAP (
     clk         => mm_clk,
@@ -191,11 +224,18 @@ BEGIN
     sync_in       => mm_sync,
     bsn_at_sync   => mm_bsn_at_sync,
     start_address => mm_start_address,
-    mm_done       => mm_done,
+    mm_done       => mm_done,  -- = mm_fifo_sosi.eop
     mm_mosi       => mm_mosi,
     mm_miso       => mm_miso,
     out_sosi      => mm_fifo_sosi,
     out_siso      => mm_fifo_siso
   );
+
+  -- Wire output
+  out_sop <= dp_out_sosi.sop;
+
+  out_sosi <= dp_out_sosi;
+  dp_out_siso <= out_siso;
+
       
 END str;