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 6deb4c7bdecfa6063d88f32be59c54745d97c0a1..a925ba49ae0e65c0cc75b49b91ea20e17f00e487 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
@@ -111,6 +111,9 @@
 --   are default 0, but in sim the BF weights in node_sdp_beamformer.vhd
 --   are default unit weights. Therefore also write the BF weight for default
 --   beamlet 102 to define it value, in case g_beamlet /= 102.
+-- * A simulation only section in sdp_beamformer_output.vhd disturbs the BSN,
+--   to cause a merged payload error, so that sdp_source_info_payload_error
+--   can be verified here.
 --
 -- Usage:
 --   > as 7    # default
@@ -436,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is
   signal rx_sdp_cep_header   : t_sdp_cep_header;
   signal exp_sdp_cep_header  : t_sdp_cep_header;
   signal exp_dp_bsn          : natural;
+  signal exp_payload_error   : std_logic := '0';
 
   -- Beamlets packets data
   signal rx_beamlet_data     : std_logic_vector(c_longword_w - 1 downto 0);  -- 64 bit
@@ -1245,10 +1249,10 @@ begin
 
   -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
   -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop.
-
   exp_sdp_cep_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum,
                                                     c_exp_sdp_info,
                                                     c_gn_index,
+                                                    exp_payload_error,
                                                     c_exp_beamlet_scale,
                                                     c_exp_beamlet_index,
                                                     exp_dp_bsn);
@@ -1256,15 +1260,39 @@ begin
   rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
 
   p_verify_cep_header : process
-    variable v_bool : boolean;
+    variable v_pkt_cnt : natural;
+    variable v_new_pkt : boolean;
+    variable v_error   : std_logic := '0';
+    variable v_bsn     : natural := 0;
+    variable v_bool    : boolean;
   begin
     wait until rising_edge(ext_clk);
+    -- Count packets per beamset
+    v_pkt_cnt := rx_beamlet_sop_cnt / c_sdp_N_beamsets;
+    v_new_pkt := rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0;
 
     -- Prepare exp_sdp_cep_header at sop, so that it can be verified at eop
     if rx_beamlet_sosi.sop = '1' then
-      -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet
-      if rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0 then
-        exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
+      -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet,
+      -- both beamsets are outputting packets.
+      if v_new_pkt then
+        -- Default expected
+        v_error := '0';
+        v_bsn := c_init_bsn + v_pkt_cnt * c_sdp_cep_nof_blocks_per_packet;
+
+        -- Expected due to bsn and payload_error stimuli in sdp_beamformer_output.vhd.
+        if v_pkt_cnt = 1 then
+          v_error := '1';
+        elsif v_pkt_cnt = 2 or v_pkt_cnt = 3 then
+          v_bsn := v_bsn + 1;
+        elsif v_pkt_cnt = 4 then
+          v_bsn := v_bsn + 1;
+          v_error := '1';
+        end if;
+
+        -- Apply expected values
+        exp_payload_error <= v_error;
+        exp_dp_bsn <= v_bsn;
       end if;
     end if;
 
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
index bf565dbc2ebb961fa6152afc6a1956c31f0008c0..879bc4cfe166f7920a74ea04833ea2cf9a8b4005 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
@@ -105,6 +105,9 @@
 -- * The c_wg_phase_offset and c_subband_phase_offset are used to tune the WG
 --   phase reference to 0.0 degrees at the start (sop)
 -- * Use g_beamlet_scale = 2**10, for full scale WG and N_ant = 1, see [1]
+-- * A simulation only section in sdp_beamformer_output.vhd disturbs the BSN,
+--   to cause a merged payload error, so that sdp_source_info_payload_error
+--   can be verified here.
 --
 -- Usage:
 --   > as 7    # default
@@ -439,6 +442,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is
   signal rx_sdp_cep_header   : t_sdp_cep_header;
   signal exp_sdp_cep_header  : t_sdp_cep_header;
   signal exp_dp_bsn          : natural;
+  signal exp_payload_error   : std_logic := '0';
 
   -- Beamlets packets data
   signal rx_beamlet_data     : std_logic_vector(c_longword_w - 1 downto 0);  -- 64 bit
@@ -577,7 +581,6 @@ begin
   i_QSFP_0_RX(0)         <= i_QSFP_0_TX(c_last_rn);
   i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0);
 
-
   ------------------------------------------------------------------------------
   -- CEP model
   ------------------------------------------------------------------------------
@@ -721,7 +724,6 @@ begin
     --     END RECORD;
     -- . Write
 
-
     for RN in 0 to c_last_rn loop
       v_gn := g_first_gn + RN;
       mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn mod c_quad) & "REG_SDP_INFO",  8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk);
@@ -1361,11 +1363,11 @@ begin
 
   -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
   -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop.
-
   exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_ip_src_addr,
                                                     c_exp_ip_header_checksum,
                                                     c_exp_sdp_info,
                                                     c_last_gn,
+                                                    exp_payload_error,
                                                     c_exp_beamlet_scale,
                                                     c_exp_beamlet_index,
                                                     exp_dp_bsn);
@@ -1373,15 +1375,39 @@ begin
   rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
 
   p_verify_cep_header : process
-    variable v_bool : boolean;
+    variable v_pkt_cnt : natural;
+    variable v_new_pkt : boolean;
+    variable v_error   : std_logic := '0';
+    variable v_bsn     : natural := 0;
+    variable v_bool    : boolean;
   begin
     wait until rising_edge(ext_clk);
+    -- Count packets per beamset
+    v_pkt_cnt := rx_beamlet_sop_cnt / c_sdp_N_beamsets;
+    v_new_pkt := rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0;
 
     -- Prepare exp_sdp_cep_header at sop, so that it can be verified at eop
     if rx_beamlet_sosi.sop = '1' then
-      -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet
-      if rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0 then
-        exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
+      -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet,
+      -- both beamsets are outputting packets.
+      if v_new_pkt then
+        -- Default expected
+        v_error := '0';
+        v_bsn := c_init_bsn + v_pkt_cnt * c_sdp_cep_nof_blocks_per_packet;
+
+        -- Expected due to bsn and payload_error stimuli in sdp_beamformer_output.vhd.
+        if v_pkt_cnt = 1 then
+          v_error := '1';
+        elsif v_pkt_cnt = 2 or v_pkt_cnt = 3 then
+          v_bsn := v_bsn + 1;
+        elsif v_pkt_cnt = 4 then
+          v_bsn := v_bsn + 1;
+          v_error := '1';
+        end if;
+
+        -- Apply expected values
+        exp_payload_error <= v_error;
+        exp_dp_bsn <= v_bsn;
       end if;
     end if;
 
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 890947c5915a3a28e0ab023f71f4e85f83984e6a..2ba6c2fb7accfbb26a6c290d0e8a277db0ca400c 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
@@ -20,10 +20,12 @@
 
 -------------------------------------------------------------------------------
 --
--- Author: R. van der Walle
+-- Author: R. van der Walle, E. Kooistra (payload error support)
 -- Purpose:
 -- The beamformer output (BDO) packetizes the beamlet data into UDP/IP packets.
 -- Description:
+-- * https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Beamformer
+-- * https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations
 -- Remark:
 --
 -------------------------------------------------------------------------------
@@ -73,22 +75,27 @@ entity sdp_beamformer_output is
   );
 end sdp_beamformer_output;
 
-
 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'
+  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 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_payload_nof_longwords;
-  constant c_fifo_size              : natural := c_fifo_fill * 2;  -- Make fifo size large enough for adding header and muxing beamsets.
+  -- Use c_fifo_fill = c_fifo_size - margin so that FIFO does not get read out too soon.
+  -- The dp_fifo_fill_eop takes care that the FIFO gets read out whenever there is an
+  -- eop in the FIFO, so that no payload gets stuck in the FIFO. Thanks to the use of eop
+  -- it possible to pass on blocks of variable length.
+  -- Make fifo size large enough for adding header, muxing c_sdp_N_beamsets beamsets and
+  -- delaying output to be able to realign snk_in.err field from snk_in.eop to src_out.sop.
+  constant c_fifo_fill      : natural := c_sdp_cep_payload_nof_longwords;  -- 976
+  constant c_fifo_size      : natural := true_log_pow2(c_sdp_cep_payload_nof_longwords) * c_sdp_N_beamsets;  -- 2048
 
   signal snk_in_concat             : t_dp_sosi;
-  signal dp_packet_merge_src_out   : t_dp_sosi;
   signal dp_repack_data_src_out    : t_dp_sosi;
-  signal dp_fifo_sc_src_out        : t_dp_sosi;
-  signal dp_fifo_sc_src_in         : t_dp_siso;
+  signal dp_packet_merge_src_out   : t_dp_sosi;
+  signal dp_fifo_merge_src_out     : t_dp_sosi;
+  signal dp_fifo_merge_src_in      : t_dp_siso;
+  signal dp_pipeline_src_out       : t_dp_sosi;
+  signal dp_pipeline_src_in        : t_dp_siso;
   signal dp_offload_tx_src_out     : t_dp_sosi;
   signal dp_offload_tx_src_in      : t_dp_siso;
   signal ip_checksum_src_out       : t_dp_sosi;
@@ -96,12 +103,13 @@ architecture str of sdp_beamformer_output is
   signal dp_pipeline_ready_src_out : t_dp_sosi;
   signal dp_pipeline_ready_src_in  : t_dp_siso;
 
-  signal common_fifo_rd_req : std_logic;
+  signal dbg_bsn_offset        : std_logic;
   signal payload_err        : std_logic_vector(0 downto 0);
   signal station_info       : std_logic_vector(15 downto 0) := (others => '0');
 
   -- Default set all data path driven header fields to 0
   signal dp_offload_tx_hdr_fields : std_logic_vector(1023 downto 0) := (others => '0');
+  signal dp_offload_tx_header     : t_sdp_cep_header;  -- to view dp_offload_tx_hdr_fields in Wave window
 
 begin
 
@@ -111,15 +119,45 @@ begin
   -- . send beamlet data big endian with X.re part first, then X.im, Y.re, Y.im
   -------------------------------------------------------------------------------
   p_snk_in_arr : process(in_sosi)
+    variable v_ref_time : time := 0 ns;
   begin
     snk_in_concat <= in_sosi;
     snk_in_concat.data(c_data_w - 1 downto 0) <= in_sosi.re(c_sdp_W_beamlet - 1 downto 0) & in_sosi.im(c_sdp_W_beamlet - 1 downto 0);
+
+    -- synthesis translate_off
+    -- Force BSN error in simulation to verify payload error in tb_lofar2_unb2c_sdp_station_bf.vhd,
+    -- this will cause two times payload errors, one when BSN goes wrong and one when BSN goes ok again.
+    dbg_bsn_offset <= '0';
+    if v_ref_time = 0 ns then
+      if in_sosi.sop = '1' then
+        -- Use start of input as reference time, rather than e.g. fixed 50 us, to be
+        -- independent of how long it takes for the tb to deliver the first block.
+        v_ref_time := NOW;
+        -- Offset the v_ref_time to the second block of the c_sdp_cep_nof_blocks_per_packet
+        -- = 4 blocks that will be merged.
+        v_ref_time := v_ref_time + c_sdp_block_period * 1 ns;
+      end if;
+    elsif NOW > v_ref_time + 1 * c_sdp_cep_nof_blocks_per_packet * c_sdp_block_period * 1 ns and
+          NOW < v_ref_time + 4 * c_sdp_cep_nof_blocks_per_packet * c_sdp_block_period * 1 ns then
+      -- Disturb BSN to cause merged payload error. Expected results for the merged blocks:
+      -- . index 0 : First merged block bsn ok and payload_error = '0'.
+      -- . index 1 : bsn still ok, but payload error = '1', due to bsn++ after first block
+      -- . index 2,3 : bsn wrong due to bsn++, but payload error = '0', because all 4
+      --               merged blocks have incrementing bsn
+      -- . index 4 : bsn still wrong due to bsn++, and payload error = '1', because the bsn
+      --             is restored after first block, so the merged blocks do not have
+      --             incrementing bsn
+      -- . index >= 5 : bsn ok and payload_error = '0'.
+      dbg_bsn_offset <= '1';
+      snk_in_concat.bsn <= INCR_UVEC(in_sosi.bsn, 1);
+    end if;
+    -- synthesis translate_on
   end process;
 
   -------------------------------------------------------------------------------
   -- dp_repack_data
   -- . 16b -> 64b
-  -- . We don't need to flow control the source beacause we're going from 16b->64b
+  -- . We don't need to flow control the source because we're going from 16b->64b
   -------------------------------------------------------------------------------
   u_dp_repack_data : entity dp_lib.dp_repack_data
   generic map (
@@ -144,7 +182,8 @@ begin
   -------------------------------------------------------------------------------
   u_dp_packet_merge : entity dp_lib.dp_packet_merge
   generic map(
-    g_nof_pkt       => c_sdp_cep_nof_blocks_per_packet
+    g_nof_pkt       => c_sdp_cep_nof_blocks_per_packet,
+    g_bsn_increment => 1
   )
   port map(
     rst     => dp_rst,
@@ -159,16 +198,9 @@ begin
 
   -------------------------------------------------------------------------------
   -- FIFO
-  -- . We're inserting headers, so dp_offload_tx needs a flow controllable
-  --   source.
-  -- . Also, we need a fill FIFO here because 16b->64b will introduce gaps in our
-  --   TX stream (not allowed by 10G TX MAC).
-  -- . The fill fifo waits until c_fifo_fill words are received before enabling the
-  --   output. The total number of words in the fifo is determined by the
-  --   backpressure.
   -------------------------------------------------------------------------------
-  u_dp_fifo_fill_sc : entity dp_lib.dp_fifo_fill_sc
-  generic map (
+  u_dp_fifo_fill_eop_sc : entity dp_lib.dp_fifo_fill_eop_sc
+  generic map (  -- pass on dp_packet_merge_src_out.err via u_common_fifo_sc_err
     g_data_w         => c_longword_w,
     g_empty_w        => c_byte_w,
     g_use_empty      => true,
@@ -182,28 +214,44 @@ begin
   port map (
     clk     => dp_clk,
     rst     => dp_rst,
-
     snk_in  => dp_packet_merge_src_out,
-
-    src_out => dp_fifo_sc_src_out,
-    src_in  => dp_fifo_sc_src_in
+    src_out => dp_fifo_merge_src_out,
+    src_in  => dp_fifo_merge_src_in
   );
 
-  -- Simple fifo to store the payload error at eop of FIFO input to be used at sop of FIFO output.
-  -- It can then be used in the packet header.
-  common_fifo_rd_req <= dp_fifo_sc_src_out.sop;
-  u_common_fifo_sc : entity common_lib.common_fifo_sc
+  -- Simple fifo to store the payload error bit at eop of FIFO input to be used at sop of FIFO
+  -- output, so that payload_err can then be used in the packet header.
+  -- Typically the u_dp_fifo_fill_eop will store between 0 and c_sdp_N_beamsets = 2 packets.
+  -- Choose g_nof_words > c_sdp_N_beamsets to have some margin compared to c_fifo_size of the
+  -- data FIFO.
+  u_common_fifo_sc_err : entity common_lib.common_fifo_sc
   generic map (
     g_dat_w => 1,
-    g_nof_words => 2
+    g_nof_words => c_sdp_N_beamsets + 2
   )
   port map (
-    rst => dp_rst,
-    clk => dp_clk,
+    rst    => dp_rst,
+    clk    => dp_clk,
     wr_dat => dp_packet_merge_src_out.err(0 downto 0),
     wr_req => dp_packet_merge_src_out.eop,
     rd_dat => payload_err,
-    rd_req => common_fifo_rd_req
+    rd_req => dp_fifo_merge_src_out.sop
+  );
+
+  -- Pipeline FIFO output to align payload_err at dp_pipeline_src_out.sop
+  u_pipeline : entity dp_lib.dp_pipeline
+  generic map (
+    g_pipeline => 1
+  )
+  port map  (
+    rst        => dp_rst,
+    clk        => dp_clk,
+    -- ST sink
+    snk_out    => dp_fifo_merge_src_in,
+    snk_in     => dp_fifo_merge_src_out,
+    -- ST source
+    src_in     => dp_pipeline_src_in,
+    src_out    => dp_pipeline_src_out
   );
 
   -------------------------------------------------------------------------------
@@ -287,8 +335,10 @@ begin
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" ) downto field_lo(c_sdp_cep_hdr_field_arr,  "sdp_beamlet_index" )) <= TO_UVEC(c_beamlet_index, c_halfword_w);
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period"  ) downto field_lo(c_sdp_cep_hdr_field_arr,  "sdp_block_period"  )) <= sdp_info.block_period;
 
-  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn" ) downto field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn" )) <= dp_fifo_sc_src_out.bsn(63 downto 0);
+  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn" ) downto field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn" )) <= dp_pipeline_src_out.bsn(63 downto 0);
 
+  -- For viewing the header fields in wave window
+  dp_offload_tx_header <= func_sdp_map_cep_header(dp_offload_tx_hdr_fields);
 
   -------------------------------------------------------------------------------
   -- dp_offload_tx_v3
@@ -312,8 +362,8 @@ begin
     reg_hdr_dat_mosi      => reg_hdr_dat_mosi,
     reg_hdr_dat_miso      => reg_hdr_dat_miso,
 
-    snk_in_arr(0)         => dp_fifo_sc_src_out,
-    snk_out_arr(0)        => dp_fifo_sc_src_in,
+    snk_in_arr(0)         => dp_pipeline_src_out,
+    snk_out_arr(0)        => dp_pipeline_src_in,
 
     src_out_arr(0)        => dp_offload_tx_src_out,
     src_in_arr(0)         => dp_offload_tx_src_in,
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 b8866c2a7c796cf94b70c8e66f1d54bd97a0700e..d84f73d36b3aa9e40ad46423df5a9c748285ea2d 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
@@ -64,6 +64,7 @@ package tb_sdp_pkg is
                                        ip_header_checksum : natural;
                                        sdp_info           : t_sdp_info;  -- app header
                                        gn_index           : natural;
+                                       payload_error      : std_logic;
                                        beamlet_scale      : natural;
                                        beamlet_index      : natural;
                                        dp_bsn             : natural) return t_sdp_cep_header;
@@ -71,6 +72,7 @@ package tb_sdp_pkg is
   function func_sdp_compose_cep_header(ip_header_checksum : natural;
                                        sdp_info           : t_sdp_info;  -- app header
                                        gn_index           : natural;
+                                       payload_error      : std_logic;
                                        beamlet_scale      : natural;
                                        beamlet_index      : natural;
                                        dp_bsn             : natural) return t_sdp_cep_header;
@@ -283,6 +285,7 @@ package body tb_sdp_pkg is
                                        ip_header_checksum : natural;
                                        sdp_info           : t_sdp_info;  -- app header
                                        gn_index           : natural;
+                                       payload_error      : std_logic;
                                        beamlet_scale      : natural;
                                        beamlet_index      : natural;
                                        dp_bsn             : natural) return t_sdp_cep_header is
@@ -326,7 +329,7 @@ package body tb_sdp_pkg is
     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_payload_error           := slv(payload_error);
     v_hdr.app.sdp_source_info_beam_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, 8);
@@ -345,6 +348,7 @@ package body tb_sdp_pkg is
   function func_sdp_compose_cep_header(ip_header_checksum : natural;
                                        sdp_info           : t_sdp_info;  -- app header
                                        gn_index           : natural;
+                                       payload_error      : std_logic;
                                        beamlet_scale      : natural;
                                        beamlet_index      : natural;
                                        dp_bsn             : natural) return t_sdp_cep_header is
@@ -356,6 +360,7 @@ package body tb_sdp_pkg is
                                        ip_header_checksum,
                                        sdp_info,
                                        gn_index,
+                                       payload_error,
                                        beamlet_scale,
                                        beamlet_index,
                                        dp_bsn);
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 f40db1a79d224bb1622681dedc480ab2684fe5b7..3f2abfd71def8826205ce01c75174837bd53f458 100644
--- a/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd
+++ b/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd
@@ -45,8 +45,10 @@
 --   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.
+-- * The dp_fifo_fill_eop can handle continues stream of blocks without a
+--   gap between blocks, as shown by tb_dp_fifo_fill_eop.vhd, because
+--   snk_out.ready remains active and the FIFO does not run full. This was
+--   fixed by Reinier in Nov 2021 as part of L2SDP-505.
 --
 -------------------------------------------------------------------------------
 
diff --git a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
index 5e4b1d58d90d7f9cd1608a7a3d935eb1ce099290..551460047fcdcb08626100979c5788b8a1b0ff11 100644
--- a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
+++ b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
@@ -20,11 +20,22 @@
 --------------------------------------------------------------------------------
 
 -- Purpose:
--- . Merge g_nof_pkt input packets into one output packet
+-- . Merge nof_pkt input packets into one output packet.
 -- Description:
+-- . Merge nof_pkt snk_in blocks per src_out block. If nof_pkt = 0 then there
+--   is no output. If nof_pkt = 1 then the output is the same as the input.
 -- . The output is the same as the registered input, except for the SOP and EOP
---   signal; these are overridden to create output packets as long as multiple (g_nof_pkt)
---   input packets.
+--   signal; these are overridden to create output packets as long as multiple
+--   (g_nof_pkt) input packets.
+-- . Uses bsn of first snk_in block as bsn for merged output src_out block.
+-- . The snk_in.err fields of the input blocks are OR-ed to reflect combined
+--   error status of the merged blocks in src_out.err of the output block.
+-- . When g_bsn_increment = 0 then the snk_in.bsn is not checked.
+-- . When g_bsn_increment > 0 then the src_out.err[g_bsn_err_bi] = '1', if
+--   the snk_in.bsn did not increment by g_bsn_increment for the merged snk_in
+--   blocks in the src_out block. If the bsn increment for the merged blocks is
+--   correct, then src_out.err[g_bsn_err_bi] = '0' to indicate that the
+--   merged blocks are consecutive, so no input block got lost for this merge.
 --
 -- Remarks:
 -- . g_nof_pkt statically sets the number of packets to merge into one in absence of
@@ -165,7 +176,6 @@
 -- . The advantage of this scheme it that it allows designing the function without flow
 --   control according to scheme A). Then make nxt_r available instead of r and lead nxt_r
 --   through dp_pipeline to register it and to add the flow control.
---
 
 library IEEE,common_lib;
 use IEEE.std_logic_1164.all;
@@ -176,7 +186,9 @@ use work.dp_stream_pkg.all;
 entity dp_packet_merge is
   generic (
     g_nof_pkt       : natural;
-    g_align_at_sync : boolean := false
+    g_align_at_sync : boolean := false;
+    g_bsn_increment : natural := 0;
+    g_bsn_err_bi    : natural := 0  -- bit index (bi) in scr_out.err for snk_in.bsn error
   );
   port (
     rst         : in  std_logic;
@@ -202,6 +214,8 @@ architecture rtl of dp_packet_merge is
     align_cnt   : natural range 0 to g_nof_pkt + 1;
     busy        : std_logic;
     sync        : std_logic;
+    next_bsn    : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
+    bsn_err     : std_logic;
     src_out     : t_dp_sosi;
   end record;
 
@@ -224,7 +238,6 @@ begin
     src_out <= r.src_out;
 
     -- can put dp_hold_input here --
-
   end generate;
 
   gen_dp_latency_adapter : if c_use_dp_latency_adapter = true generate
@@ -332,18 +345,27 @@ begin
         if snk_in.sync = '1' then
           v.src_out.sync  := '1';  -- set out sync to '1' if this first block contains the sync.
         end if;
+        v.next_bsn        := INCR_UVEC(snk_in.bsn, g_bsn_increment);  -- expected bsn for next snk_in block
+        v.bsn_err         := '0';  -- bsn of first block is correct by default
       else
         if snk_in.sync = '1' then
           v.sync := '1';  -- Capture sync if it occurs on a pkt_cnt /= 0 so we can use it in the next merged packet
         end if;
+        v.next_bsn        := INCR_UVEC(r.next_bsn, g_bsn_increment);  -- expected bsn for next snk_in block
+        if unsigned(snk_in.bsn) /= unsigned(r.next_bsn) then
+          v.bsn_err       := '1';
+        end if;
       end if;
     end if;
 
     if snk_in.eop = '1' then
       if r.pkt_cnt = 0 then
-        v.src_out.err     := snk_in.err;
+        v.src_out.err := snk_in.err;
       else
-        v.src_out.err     := r.src_out.err or snk_in.err;  -- OR the err fields of the packets to reflect combined error status.
+        v.src_out.err := r.src_out.err or snk_in.err;  -- OR the err fields of the packets to reflect combined error status.
+      end if;
+      if g_bsn_increment > 0 then
+        v.src_out.err(g_bsn_err_bi) := r.bsn_err;  -- report bsn error bit in case of missing snk_in block
       end if;
 
       if r.pkt_cnt = r.nof_pkt - 1 then
@@ -369,6 +391,8 @@ begin
       v.align_cnt   := 0;
       v.busy        := '0';
       v.sync        := '0';
+      v.next_bsn    := (others => '0');
+      v.bsn_err     := '0';
       v.src_out     := c_dp_sosi_rst;
     end if;
 
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_fifo_fill_eop.vhd b/libraries/base/dp/tb/vhdl/tb_dp_fifo_fill_eop.vhd
index 5898e43f38a16626271d535e210c8fb030b967f1..b2ce169ff9463cac24202c5c6cb4f4b5c6385302 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_fifo_fill_eop.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_fifo_fill_eop.vhd
@@ -47,7 +47,7 @@ use work.tb_dp_pkg.all;
 entity tb_dp_fifo_fill_eop is
   generic (
     -- Try FIFO settings
-    g_dut_use_dual_clock  : boolean := true;
+    g_dut_use_dual_clock  : boolean := false;
     g_dut_use_bsn         : boolean := false;
     g_dut_use_empty       : boolean := false;
     g_dut_use_channel     : boolean := false;
@@ -55,9 +55,10 @@ entity tb_dp_fifo_fill_eop is
     g_dut_fifo_rl         : natural := 1;  -- internal RL,  use 0 for look ahead FIFO, default 1 for normal FIFO
     g_dut_fifo_size       : natural := 128;
     g_dut_fifo_fill       : natural := 100;  -- selectable >= 0 for dp_fifo_fill
+    g_block_size          : natural := 14;  -- to verify g_block_size > or < g_dut_fifo_fill
     g_dut_use_rd_fill_32b : boolean := false;
-    g_dut_use_gap         : boolean := true;
-    g_dut_use_random_ctrl : boolean := true
+    g_dut_use_gap         : boolean := false;
+    g_dut_use_random_ctrl : boolean := false
   );
 end tb_dp_fifo_fill_eop;
 
@@ -75,7 +76,7 @@ architecture tb of tb_dp_fifo_fill_eop is
   constant c_tx_latency     : natural := c_dut_in_latency;  -- TX ready latency of TB
   constant c_tx_void        : natural := sel_a_b(c_tx_latency, 1, 0);  -- used to avoid empty range VHDL warnings when c_tx_latency=0
   constant c_tx_offset_sop  : natural := 3;
-  constant c_tx_period_sop  : natural := 14;  -- sop in data valid cycle 3,  17,  31, ...
+  constant c_tx_period_sop  : natural := g_block_size;  -- sop in data valid cycle 3,  17,  31, ...
   constant c_tx_offset_eop  : natural := sel_a_b(g_dut_use_gap, 12, 16);  -- eop in data valid cycle 12,  26,  40, ...
   constant c_tx_period_eop  : natural := c_tx_period_sop;
   constant c_tx_offset_sync : natural := 3;  -- sync in data valid cycle 3, 20, 37, ...
@@ -115,6 +116,7 @@ architecture tb of tb_dp_fifo_fill_eop is
   signal in_val         : std_logic;
   signal in_sop         : std_logic;
   signal in_eop         : std_logic;
+  signal in_en          : std_logic := '0';
 
   signal wr_ful         : std_logic;
   signal rd_usedw       : std_logic_vector(ceil_log2(largest(g_dut_fifo_size, g_dut_fifo_fill + c_dut_fifo_af_margin + 2)) - 1 downto 0);
@@ -148,8 +150,6 @@ architecture tb of tb_dp_fifo_fill_eop is
 
 begin
 
-
-
   clk <= not clk or tb_end after clk_period / 2;
   rst <= '1', '0' after clk_period * 7;
 
@@ -159,7 +159,6 @@ begin
   -- Input data
   cnt_val <= in_ready and cnt_en and not gap_en when g_dut_use_random_ctrl else in_ready and not gap_en;
 
-
   proc_dp_cnt_dat(rst, clk, cnt_val, cnt_dat);
   proc_dp_tx_data(c_tx_latency, rst, clk, cnt_val, cnt_dat, tx_data, tx_val, in_data, in_val);
   proc_dp_tx_ctrl(c_tx_offset_sync, c_tx_period_sync, in_data, in_val, in_sync);
@@ -169,6 +168,23 @@ begin
     proc_dp_tx_ctrl(c_tx_offset_gap, c_tx_period_gap, in_data, in_val, gap_en);
   end generate;
 
+  -- Use in_en to ensure that in_sosi starts with in_sop, so no spurious
+  -- in_eop or in_val without an in_sop. The FIFO will ignore these
+  -- spurious in_eop or in_val, but for testing the fill_eop mechanism
+  -- it is more clear to test with only complete input blocks. The
+  -- general assumption is that only complete blocks are allowed to enter
+  -- the application code, so incomplete blocks are already avoided at the
+  -- external interface code of the FPGA and by making sure that FIFOs
+  -- will stop accepting new blocks before they would overflow.
+  p_in_en : process
+  begin
+    wait until in_sop = '1';
+    wait until in_eop = '1';
+    wait until in_sop = '1';
+    in_en <= '1';
+    wait;
+  end process;
+
   in_bsn     <= INCR_UVEC(in_data, c_bsn_offset);
   in_empty   <= INCR_UVEC(in_data, c_empty_offset);
   in_channel <= INCR_UVEC(in_data, c_channel_offset);
@@ -236,10 +252,10 @@ begin
   in_sosi.bsn(c_dp_bsn_w - 1 downto 0)   <= in_bsn(c_dp_bsn_w - 1 downto 0);
   in_sosi.empty                        <= in_empty(c_dp_empty_w - 1 downto 0);
   in_sosi.channel                      <= in_channel(c_dp_channel_w - 1 downto 0);
-  in_sosi.sync                         <= in_sync;
-  in_sosi.valid                        <= (in_val and not gap_en);
-  in_sosi.sop                          <= in_sop;
-  in_sosi.eop                          <= in_eop;
+  in_sosi.sync                         <= in_en and in_sync;
+  in_sosi.valid                        <= in_en and (in_val and not gap_en);
+  in_sosi.sop                          <= in_en and in_sop;
+  in_sosi.eop                          <= in_en and in_eop;
 
   out_siso.ready <= out_ready;  -- SISO
   out_siso.xon   <= '1';
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd
index 61c520974c5017dd9eb8d6a653c1d58ccffbe9b7..2c60d0f34f4d88165c32aac96f975f7629ff2d74 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd
@@ -66,6 +66,9 @@ entity tb_dp_packet_merge is
     g_pkt_len                : natural := 10;
     g_pkt_gap                : natural := 0;
     g_align_at_sync          : boolean := false;
+    g_verify_bsn_err         : boolean := false;
+    g_bsn_increment          : natural := 2;
+    g_bsn_err_at_pkt_index   : natural := 6;  -- force wrong snk_in.bsn for packet with this index, in range(g_nof_repeat)
     g_use_dp_packet_unmerge  : boolean := false
   );
 end tb_dp_packet_merge;
@@ -84,13 +87,17 @@ architecture tb of tb_dp_packet_merge is
   constant c_data_max                 : unsigned(g_data_w - 1 downto 0) := (others => '1');
   constant c_data_init                : integer := -1;
   constant c_bsn_init                 : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := X"0000000000000000";  -- X"0877665544332211"
+  constant c_bsn_error                : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := (others => '1');  -- use -1 as bsn error value
   constant c_err_init                 : natural := 247;
+  constant c_bsn_err_bi               : natural := 31;  -- use sufficiently high bsn error bit index, that is outside counter range of c_err_init
   constant c_channel_init             : integer := 5;  -- fixed
 
   constant c_nof_pkt_not_zero         : natural := sel_a_b(g_nof_pkt = 0, 1, g_nof_pkt);
   constant c_nof_merged_sop           : natural := sel_a_b(g_nof_pkt = 0, 0, ceil_div(g_nof_repeat, c_nof_pkt_not_zero));
   constant c_verify_at_least          : natural := largest(1,c_nof_merged_sop / 2);  -- verify that at least some packets have been merged, not exact to allow variation by p_stimuli_mm
   constant c_verify_data_gap          : natural := g_nof_pkt;
+  constant c_verify_bsn_gap           : natural := g_nof_pkt * g_bsn_increment;
+  constant c_exp_err_at_pkt_index     : natural := g_bsn_err_at_pkt_index / sel_a_b(g_nof_pkt = 0, 1, g_nof_pkt);
 
   signal tb_end                     : std_logic := '0';
   signal clk                        : std_logic := '1';
@@ -123,6 +130,8 @@ architecture tb of tb_dp_packet_merge is
   signal verify_snk_in              : t_dp_sosi;
   signal verify_data                : std_logic_vector(g_data_w - 1 downto 0);
   signal prev_verify_snk_in         : t_dp_sosi;
+  signal merged_pkt_cnt             : natural := 0;
+  signal merged_pkt_err             : std_logic;
 
   signal verify_hold_sop            : std_logic := '0';
   signal verify_en_valid            : std_logic := '0';
@@ -164,9 +173,10 @@ begin
   -- Generate data path input data
   p_stimuli_st : process
     variable v_sosi : t_dp_sosi := c_dp_sosi_rst;
+    variable v_bsn  : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
   begin
     -- Adjust initial sosi field values by -1 to compensate for auto increment
-    v_sosi.bsn     := INCR_UVEC(c_bsn_init,                    -1);
+    v_bsn          := INCR_UVEC(c_bsn_init,                    -1);
     v_sosi.channel := INCR_UVEC(TO_DP_CHANNEL(c_channel_init), -1);
     v_sosi.data    := INCR_UVEC(TO_DP_DATA(c_data_init),       -1);
     v_sosi.err     := INCR_UVEC(TO_DP_ERROR(c_err_init),       -1);
@@ -178,13 +188,21 @@ begin
     -- Generate c_nof_repeat packets
     for I in 0 to g_nof_repeat - 1 loop
       -- Auto increment v_sosi field values for this packet
-      v_sosi.bsn     := INCR_UVEC(v_sosi.bsn, 1);
+      v_bsn          := INCR_UVEC(v_bsn, g_bsn_increment);
+      v_sosi.bsn     := v_bsn;
       v_sosi.sync    := sel_a_b((unsigned(v_sosi.bsn) mod c_sync_period) = c_sync_offset, '1', '0');  -- insert sync starting at BSN=c_sync_offset and with period c_sync_period
       v_sosi.channel := INCR_UVEC(v_sosi.channel, 1);
       v_sosi.data    := INCR_UVEC(v_sosi.data, g_pkt_len);
       v_sosi.data    := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
       v_sosi.err     := INCR_UVEC(v_sosi.err, 1);
 
+      -- Force bsn error in one snk_in block, to verify src_out.err(g_bsn_err_bi) bit
+      if g_verify_bsn_err = true then
+        if I = g_bsn_err_at_pkt_index then
+          v_sosi.bsn := c_bsn_error;
+        end if;
+      end if;
+
       -- Send packet
       proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_pkt_len, TO_UINT(v_sosi.channel), TO_UINT(v_sosi.err), v_sosi.sync, v_sosi.bsn, clk, stimuli_en, stimuli_src_in, stimuli_src_out);
 
@@ -235,9 +253,39 @@ begin
 
   -- Verify that the output is incrementing data, like the input stimuli
   proc_dp_verify_data("verify_snk_in.data",    c_rl, c_data_max,   c_unsigned_1,                      clk, verify_en_valid, verify_snk_out.ready, verify_snk_in.valid, verify_snk_in.data,    prev_verify_snk_in.data);
-  proc_dp_verify_data("verify_snk_in.bsn",     c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_sop,   verify_snk_out.ready, verify_snk_in.sop,   verify_snk_in.bsn,     prev_verify_snk_in.bsn);
+  gen_verify_bsn_increment : if g_verify_bsn_err = false generate
+    proc_dp_verify_data("verify_snk_in.bsn",   c_rl, c_unsigned_0, to_unsigned(c_verify_bsn_gap, 32), clk, verify_en_sop,   verify_snk_out.ready, verify_snk_in.sop,   verify_snk_in.bsn,     prev_verify_snk_in.bsn);
+    gen_verify_err : if g_nof_pkt = 1 generate
+      -- Assume verifying g_nof_pkt = 1 is sufficient. Verifing g_nof_pkt > 1 is more difficult,
+      -- because the merged output error field is the bitwise OR of the input error fields
+      proc_dp_verify_data("verify_snk_in.err", c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_eop,   verify_snk_out.ready, verify_snk_in.eop,   verify_snk_in.err,     prev_verify_snk_in.err);
+    end generate;
+  end generate;
   proc_dp_verify_data("verify_snk_in.channel", c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_sop,   verify_snk_out.ready, verify_snk_in.sop,   verify_snk_in.channel, prev_verify_snk_in.channel);
 
+  -- Verify that the output bsn error bit is set if an input block was missed in a merge
+  merged_pkt_err <= verify_snk_in.err(c_bsn_err_bi);
+
+  gen_verify_bsn_err : if g_verify_bsn_err = true generate
+    p_verify_bsn_err : process(clk)
+    begin
+      if rising_edge(clk) then
+        -- count number of merged packets
+        if verify_snk_in.sop = '1' then
+          merged_pkt_cnt <= merged_pkt_cnt + 1;
+        end if;
+        -- verify err field for merged packet with input bsn error
+        if verify_snk_in.sop = '1' then
+          if merged_pkt_cnt = c_exp_err_at_pkt_index + 1 and g_bsn_increment > 0 then
+            assert merged_pkt_err = '1' report "Unexpected sosi.err = 0" severity ERROR;
+          else
+            assert merged_pkt_err = '0' report "Unexpected sosi.err = 1" severity ERROR;
+          end if;
+        end if;
+      end if;
+    end process;
+  end generate;
+
   -- Verify output packet ctrl
   proc_dp_verify_sop_and_eop(clk, verify_snk_in.valid, verify_snk_in.sop, verify_snk_in.eop, verify_hold_sop);
 
@@ -256,7 +304,9 @@ begin
   u_dp_packet_merge : entity work.dp_packet_merge
   generic map (
     g_nof_pkt       => g_nof_pkt,
-    g_align_at_sync => g_align_at_sync
+    g_align_at_sync => g_align_at_sync,
+    g_bsn_increment => g_bsn_increment,
+    g_bsn_err_bi    => c_bsn_err_bi
   )
   port map (
     rst       => rst,
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
index e3c449afb2aa9b37f22e9b0ddf71c866d0ffa1ac..60fe18d02750d66821a9ea577a1cef2dcf705ffe 100644
--- a/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
@@ -45,7 +45,19 @@ end tb_tb_dp_fifo_fill_eop;
 architecture tb of tb_tb_dp_fifo_fill_eop is
   signal tb_end : std_logic := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
 begin
-  -- Try FIFO settings : GENERIC MAP (g_dut_use_dual_clock, g_dut_use_bsn, g_dut_use_empty, g_dut_use_channel, g_dut_use_sync, g_dut_fifo_rl, g_dut_fifo_size, g_dut_fifo_fill, g_dut_use_rd_fill_32b, g_dut_use_gap, g_dut_use_random_ctrl)
+  -- Try FIFO settings
+  -- g_dut_use_dual_clock  : boolean := true;
+  -- g_dut_use_bsn         : boolean := false;
+  -- g_dut_use_empty       : boolean := false;
+  -- g_dut_use_channel     : boolean := false;
+  -- g_dut_use_sync        : boolean := false;
+  -- g_dut_fifo_rl         : natural := 1;  -- internal RL,  use 0 for look ahead FIFO, default 1 for normal FIFO
+  -- g_dut_fifo_size       : natural := 128;
+  -- g_dut_fifo_fill       : natural := 100;  -- selectable >= 0 for dp_fifo_fill
+  -- g_block_size          : natural := 14;
+  -- g_dut_use_rd_fill_32b : boolean := false;
+  -- g_dut_use_gap         : boolean := true;
+  -- g_dut_use_random_ctrl : boolean := true
 
   u_dut_sc_1             : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false);
   u_dut_sc_1_no_gap      : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false, g_dut_use_gap => false);
@@ -59,4 +71,8 @@ begin
   u_dut_dc_1_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => true,  g_dut_fifo_rl => 1, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
   u_dut_sc_0_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 0, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
   u_dut_dc_0_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => true,  g_dut_fifo_rl => 0, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
+
+  u_dut_sc_1_blk_gt_fill : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false, g_dut_use_gap => false,
+                                                                        g_dut_fifo_fill => 10, g_block_size => 20);
+
 end tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge.vhd
index db1e7726c2d5e800beec5d17c4889c7705f72776..e62fe8c16a891094fb94ad976a6b7b9ad54ba95e 100644
--- a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge.vhd
@@ -45,30 +45,39 @@ begin
   --     g_flow_control_stimuli   : t_dp_flow_control_enum := e_active;  -- always active, random or pulse flow control
   --     g_flow_control_verify    : t_dp_flow_control_enum := e_active;  -- always active, random or pulse flow control
   --     -- specific
-  --     g_data_w                 : NATURAL := 4;
-  --     g_nof_repeat             : NATURAL := 20;
-  --     g_nof_pkt                : NATURAL := 3;
-  --     g_pkt_len                : NATURAL := 29;
-  --     g_pkt_gap                : NATURAL := 0;
-  --     g_align_at_sync          : BOOLEAN := FALSE;
-  --     g_use_dp_packet_unmerge  : BOOLEAN := FALSE
+  --     g_data_w                 : natural := 4;
+  --     g_nof_repeat             : natural := 20;
+  --     g_nof_pkt                : natural := 3;
+  --     g_pkt_len                : natural := 29;
+  --     g_pkt_gap                : natural := 0;
+  --     g_align_at_sync          : boolean := false;
+  --     g_verify_bsn_err         : boolean := false;
+  --     g_bsn_increment          : natural := 0;
+  --     g_bsn_err_at_pkt_index   : natural := 3;
+  --     g_use_dp_packet_unmerge  : boolean := false
 
-  u_act_act_8_nof_0      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, false, false);
-  u_act_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, false, false);
-  u_act_act_8_nof_2      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, false, false);
-  u_act_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
-  u_act_act_8_nof_4      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, false, false);
-  u_act_act_8_nof_5      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, false, false);
-  u_act_act_8_nof_6      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, false, false);
-  u_act_act_8_nof_7      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, false, false);
+  u_act_act_8_nof_0      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_2      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_4      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_5      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_6      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, false, false, 1, 0, false);
+  u_act_act_8_nof_7      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, false, false, 1, 0, false);
 
-  u_rnd_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
-  u_rnd_rnd_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, false, false);
-  u_pls_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
-  u_pls_rnd_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_random, 8, c_nof_repeat, 3, 29, 0, false, false);
-  u_pls_pls_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_pulse,  8, c_nof_repeat, 3, 29, 0, false, false);
+  u_rnd_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 2, 0, false);
+  u_rnd_rnd_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 3, 0, false);
+  u_pls_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 4, 0, false);
+  u_pls_rnd_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 5, 0, false);
+  u_pls_pls_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_pulse,  8, c_nof_repeat, 3, 29, 0, false, false, 6, 0, false);
 
-  u_rnd_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29, 0, false, false);
-  u_rnd_act_8_nof_3_gap  : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, false, false);
+  u_rnd_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0, false);
+  u_rnd_act_8_nof_3_gap  : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, false, false, 1, 0, false);
+
+  u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 0, 10, false);
+  u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 10, false);
+  u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 11, false);
+  u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 12, false);
+  u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 13, false);
 
 end tb;
diff --git a/libraries/base/ring/src/vhdl/ring_lane.vhd b/libraries/base/ring/src/vhdl/ring_lane.vhd
index 27ac241d28a492ad505d8a3900bf25bcbec00f0c..374faeb6d6c02848496fae5dac13f8e24548e6b9 100644
--- a/libraries/base/ring/src/vhdl/ring_lane.vhd
+++ b/libraries/base/ring/src/vhdl/ring_lane.vhd
@@ -21,16 +21,11 @@
 -------------------------------------------------------------------------------
 --
 -- Author: R. van der Walle
-
+--
 -- Purpose: Implement the function of a complete ring lane by combining ring_lane/tx.
--- Description: See https://support.astron.nl/confluence/x/jyu7Ag
+-- Description:
+-- . See "L5 SDPFW Design Document: Ring" at https://support.astron.nl/confluence/x/jyu7Ag
 -- Remark:
--- . Note that the dp_fifo_fill_eop in dp_block_validate_err cannot handle
---   continues stream of blocks without a gap between blocks the dp_fifo_fill_eop
---   needs 1 cycle to process a block. Streaming without gaps may cause the fifo
---   to overflow. Bursts of blocks can be handled by increasing gvalidate_err_fifo_size.
-
--------------------------------------------------------------------------------
 
 library IEEE, common_lib, mm_lib, dp_lib;
 use IEEE.std_logic_1164.all;