diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
index fb263f5b4ccdd775cd50e95c9b7d44f38751bab2..d5c96ea99d864ddf79b199ce24fe9c532dc776bf 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd
@@ -335,7 +335,8 @@ begin
     g_use_mm_output           => true,
     g_rd_latency              => 1,  -- Required for st_xst
     -- for mms_dp_bsn_monitor_v2
-    g_nof_clk_per_sync        => c_sdp_N_clk_sync_timeout_xsub,  -- Using c_sdp_N_clk_sync_timeout_xsub as g_nof_clk_per_sync is used for BSN monitor timeout.
+    -- Using c_sdp_N_clk_sync_timeout_xsub as g_nof_clk_per_sync is used for BSN monitor timeout.
+    g_nof_clk_per_sync        => c_sdp_N_clk_sync_timeout_xsub,
     g_nof_input_bsn_monitors  => g_P_sq,
     g_use_bsn_output_monitor  => true
     )
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 688042034a72ccd9de6c174478ae02b121eb4516..4012eabd8272c77d113e651524ae650d6c441aa3 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
@@ -244,17 +244,14 @@ begin
   -----------------------------------------------------------------------------
   u_dp_packet_merge : entity dp_lib.dp_packet_merge
   generic map(
+    g_use_ready     => false,  -- no flow control
     g_nof_pkt       => c_nof_blocks_per_packet,
     g_bsn_increment => 1
   )
   port map(
     rst     => dp_rst,
     clk     => dp_clk,
-
-    snk_out => OPEN,
     snk_in  => dp_repack_beamlet_src_out,
-
-    src_in  => c_dp_siso_rdy,
     src_out => dp_packet_merge_src_out
   );
 
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
index 6eb6479310aaf40180e891d1d9f5fe5e049f64b3..ebd79dc6d47bbcaa1214e1a8e1f58b93717e6c49 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd
@@ -435,6 +435,7 @@ architecture str of sdp_station is
   constant c_validate_channel          : boolean := true;
   constant c_validate_channel_mode     : string  := "=";
   constant c_sync_timeout              : natural := sel_a_b(g_sim, g_sim_sync_timeout, c_sdp_N_clk_sync_timeout);
+  constant c_sync_timeout_xst          : natural := sel_a_b(g_sim, g_sim_sync_timeout, c_sdp_N_clk_sync_timeout_xsub);
 
   -- Use same Tx FIFO size for all lanes in the ring to ease the code, no need to optimize Tx FIFO RAM usage per lane.
   -- The tr_10GbE uses dp_fifo_fill_eop, so rely on releasing packets (beamlets, crosslets) at eop instead
@@ -1224,7 +1225,7 @@ begin
         g_bsn_at_sync_check_channel => c_bsn_at_sync_check_channel,
         g_validate_channel          => c_validate_channel,
         g_validate_channel_mode     => c_validate_channel_mode,
-        g_sync_timeout              => c_sync_timeout
+        g_sync_timeout              => c_sync_timeout_xst
       )
       port map (
         mm_rst => mm_rst,
diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 8d500138501b9273d8bad9a735033150efd979c9..1d3533b137fdbd8d27f60afb547b4febd902487b 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -1,8 +1,8 @@
 hdl_lib_name = dp
 hdl_library_clause_name = dp_lib
-hdl_lib_uses_synth = mm common common_mult easics  
-hdl_lib_uses_sim = 
-hdl_lib_technology = 
+hdl_lib_uses_synth = mm common common_mult easics
+hdl_lib_uses_sim =
+hdl_lib_technology =
 
 synth_files =
     src/vhdl/dp_stream_pkg.vhd
@@ -10,7 +10,7 @@ synth_files =
     src/vhdl/dp_example_dut.vhd
     src/vhdl/dp_packetizing_pkg.vhd
     src/vhdl/dp_packet_pkg.vhd
-    
+
     src/vhdl/dp_eop_extend.vhd
     src/vhdl/dp_validate.vhd
     src/vhdl/dp_ready.vhd
@@ -30,6 +30,7 @@ synth_files =
     src/vhdl/dp_pipeline.vhd
     src/vhdl/dp_pipeline_arr.vhd
     src/vhdl/dp_pipeline_ready.vhd
+    src/vhdl/dp_add_flow_control.vhd
     src/vhdl/dp_block_resize.vhd
     src/vhdl/dp_block_validate_length.vhd
     src/vhdl/dp_block_validate_bsn_at_sync.vhd
@@ -147,7 +148,7 @@ synth_files =
     src/vhdl/dp_packet_unmerge.vhd
 
     src/vhdl/dp_offload_tx_legacy.vhd
-    src/vhdl/dp_offload_tx_len_calc.vhd  
+    src/vhdl/dp_offload_tx_len_calc.vhd
     src/vhdl/dp_sync_insert.vhd
     src/vhdl/dp_sync_insert_v2.vhd
     src/vhdl/dp_sync_recover.vhd
@@ -192,20 +193,20 @@ synth_files =
     src/vhdl/dp_selector_arr.vhd
     src/vhdl/dp_selector.vhd
     src/vhdl/mms_dp_scale.vhd
-    
+
     tb/vhdl/dp_stream_player.vhd
     tb/vhdl/dp_sosi_recorder.vhd
     tb/vhdl/dp_stream_rec_play.vhd
     tb/vhdl/dp_statistics.vhd
-     
+
     tb/vhdl/tb_dp_pkg.vhd
-    
-test_bench_files = 
-    
+
+test_bench_files =
+
     tb/vhdl/dp_phy_link.vhd
     tb/vhdl/dp_stream_stimuli.vhd
     tb/vhdl/dp_stream_verify.vhd
-    
+
     tb/vhdl/tb_dp_strobe_total_count.vhd
     tb/vhdl/tb_dp_block_select.vhd
     tb/vhdl/tb_dp_block_validate_length.vhd
@@ -266,6 +267,7 @@ test_bench_files =
     tb/vhdl/tb_dp_concat_field_blk.vhd
     tb/vhdl/tb_dp_packet.vhd
     tb/vhdl/tb_dp_packet_merge.vhd
+    tb/vhdl/tb_dp_packet_merge_unmerge.vhd
     tb/vhdl/tb_dp_packetizing.vhd
     tb/vhdl/tb_dp_pad_insert_remove.vhd
     tb/vhdl/tb_dp_pipeline.vhd
@@ -344,6 +346,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_packetizing.vhd
     tb/vhdl/tb_tb_dp_packet.vhd
     tb/vhdl/tb_tb_dp_packet_merge.vhd
+    tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
     tb/vhdl/tb_tb_dp_concat_field_blk.vhd
     tb/vhdl/tb_tb_dp_pipeline.vhd
     tb/vhdl/tb_tb_dp_pipeline_ready.vhd
@@ -360,7 +363,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_throttle_xon.vhd
     tb/vhdl/tb_tb_dp_counter.vhd
     tb/vhdl/tb_tb_dp_xonoff.vhd
-    
+
     tb/vhdl/tb_tb_tb_dp_backpressure.vhd
     tb/vhdl/tb_dp_offload_tx_v3.vhd
     tb/vhdl/tb_tb_dp_offload_tx_v3.vhd
@@ -368,7 +371,7 @@ test_bench_files =
     tb/vhdl/tb_dp_selector_arr.vhd
     tb/vhdl/tb_mms_dp_scale.vhd
 
-regression_test_vhdl = 
+regression_test_vhdl =
     tb/vhdl/tb_dp_fifo_to_mm.vhd
     tb/vhdl/tb_dp_fifo_xonoff.vhd
     tb/vhdl/tb_dp_latency_adapter.vhd
@@ -403,8 +406,8 @@ regression_test_vhdl =
     tb/vhdl/tb_tb_dp_reverse_n_data.vhd
     tb/vhdl/tb_tb_dp_reverse_n_data_fc.vhd
     tb/vhdl/tb_tb_dp_example_dut.vhd
-    tb/vhdl/tb_tb_dp_fifo_dc.vhd  
-    tb/vhdl/tb_tb_dp_fifo_dc_mixed_widths.vhd  
+    tb/vhdl/tb_tb_dp_fifo_dc.vhd
+    tb/vhdl/tb_tb_dp_fifo_dc_mixed_widths.vhd
     tb/vhdl/tb_tb_dp_fifo_fill.vhd
     tb/vhdl/tb_tb_dp_fifo_fill_sc.vhd
     tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
@@ -417,6 +420,7 @@ regression_test_vhdl =
     tb/vhdl/tb_tb3_dp_mux.vhd
     tb/vhdl/tb_tb_dp_packet.vhd
     tb/vhdl/tb_tb_dp_packet_merge.vhd
+    tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
     tb/vhdl/tb_tb_dp_concat_field_blk.vhd
     tb/vhdl/tb_tb_dp_pad_insert_remove.vhd
     tb/vhdl/tb_tb_dp_pipeline.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd b/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..739917a35ef9a1b434fd9992a04d6b3eebe57d5d
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd
@@ -0,0 +1,153 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2023
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+-- Purpose: Provide flow control
+-- Description:
+-- . This component can add src_in.ready flow control to a logic function
+--   that no flow control.
+-- - If g_use_ready = false, then src_in is ignored, so no flow control is
+--   added and the dp_add_flow_control component reduces to wires.
+-- - If g_use_ready = true then use flow control by src_in.ready.
+--   . If g_pipeline_ready = false then dp_add_flow_control = dp_pipeline,
+--     and then snk_in and src_in.ready are used combinatorially by
+--     dp_pipeline.
+--   . If g_pipeline_ready = true then dp_add_flow_control = dp_pipeline_ready,
+--     and then the registered input snk_in_reg is used and the src_in.ready
+--     is registered.
+--
+-- . The block diagram shows how the dp_add_flow_control is used.
+--
+--                            g_use_ready
+--                            g_pipeline_ready
+--                            g_in_latency
+--                            g_out_latency
+--                           _____________________
+--                          | dp_add_flow_control |
+--                          |                     |
+--   snk_out <--------------| snk_out      src_in |<---------- src_in
+--                          |                     |
+--             d.src_out -->| snk_in       src_out|--> src_out
+--             r.src_out -->| snk_in_reg          |
+--                          |_____________________|
+--
+--                     ________            _______
+--                    /        \          |       |
+--   snk_in --------->| p_comb | --> d -->| p_reg |--> r
+--                    \________/          |_______|
+--                         |                  |
+--                         \-----------<------/
+--
+-- . The logic function is implemented in combinatorial process p_comb and the
+--   internal state of it is kept in a clocked process p_reg.
+-- . The p_reg increases the ready latency (RL) of p_reg.src_out by 1, because
+--   p_comb does not use src_in.ready. Instead p_comb drives d.src_out based
+--   on the snk_in.sop, eop, valid.
+--   - With g_use_ready = true and g_pipeline_ready = true use a
+--     dp_pipeline_ready to restore the RL from 2 to 1 for the src_out output.
+--     With the dp_pipeline_ready a few register stages are needed to store
+--     src_out to be able to adapt the RL and to be able to register the
+--     src_in.ready. The advantage of dp_pipeline_ready is that it register the
+--     src_in.ready, so that may ease achieving timing closure.
+--   - The alternative with g_use_ready = true and g_pipeline_ready = false is
+--     to use a dp_pipeline the d.src_out in combination with src_in.ready, to
+--     keep the RL at 1 by means of dp_pipeline. The dp_pipeline adds a
+--     register to store src_out. The p_reg.src_out is kept as well, to keep
+--     the internal state of the function.
+-- . If the p_comb also needs to apply flow control itself, then p_comb can
+--   output a ready or d.ready signal that is or-ed with the input
+--   src_in.ready and then applied to the src_in input of dp_add_flow_control.
+-- . The g_in_latency and g_out_latency are only used when g_use_ready = true
+--   and g_pipeline_ready = true. When g_pipeline_ready = false, then the
+--   assumption is that snk_in and src_out both have RL = 1.
+-- Remark:
+-- . Default use g_use_ready = true and g_pipeline_ready = false for solution
+--   that fits both flow control or no flow control with the least logic. The
+--   flow control logic may even get entirely optimized away during synthesis
+--   when snk_in.ready = '1' fixed.
+
+library IEEE,common_lib;
+  use IEEE.std_logic_1164.all;
+  use IEEE.numeric_std.all;
+  use common_lib.common_pkg.all;
+  use work.dp_stream_pkg.all;
+
+entity dp_add_flow_control is
+  generic (
+    g_use_ready       : boolean := true;
+    g_pipeline_ready  : boolean := false;
+    g_in_latency      : natural := 1;
+    g_out_latency     : natural := 1
+  );
+  port (
+    rst         : in  std_logic;
+    clk         : in  std_logic;
+
+    snk_out     : out t_dp_siso;
+    snk_in      : in  t_dp_sosi;  -- combinatorial input
+    snk_in_reg  : in  t_dp_sosi;  -- registered input
+
+    src_in      : in  t_dp_siso := c_dp_siso_rst;
+    src_out     : out t_dp_sosi
+  );
+end dp_add_flow_control;
+
+architecture str of dp_add_flow_control is
+begin
+  no_flow_control : if g_use_ready = false generate
+    -- Only wires
+    snk_out <= c_dp_siso_rdy;
+    src_out <= snk_in_reg;
+  end generate;
+
+  use_flow_control : if g_use_ready = true generate
+    gen_dp_pipeline : if g_pipeline_ready = false generate
+      u_dp_pipeline : entity work.dp_pipeline
+        port map (
+          rst          => rst,
+          clk          => clk,
+          -- ST sink
+          snk_out      => snk_out,
+          snk_in       => snk_in,
+          -- ST source
+          src_in       => src_in,
+          src_out      => src_out
+        );
+    end generate;
+
+    gen_dp_pipeline_ready : if g_pipeline_ready = true generate
+      u_dp_pipeline_ready : entity work.dp_pipeline_ready
+        generic map (
+          g_in_latency  => g_in_latency + 1,  -- + 1 to account of registered input
+          g_out_latency => g_out_latency
+        )
+        port map (
+          rst          => rst,
+          clk          => clk,
+          -- ST sink
+          snk_out      => snk_out,
+          snk_in       => snk_in_reg,
+          -- ST source
+          src_in       => src_in,
+          src_out      => src_out
+        );
+    end generate;
+  end generate;
+end str;
diff --git a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
index 78269fecf91b5630c8e666924ea27304019fed4c..14dfd8a984cda38fe936af12e313163de94bf2e8 100644
--- a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
+++ b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
@@ -42,140 +42,11 @@
 --   dynamic nof_pkt control. When the nof_pkt control input is used, g_nof_pkt sets
 --   the maximum number of packets that can be merged.
 -- . the nof_pkt control input is read on completion of the current block. The current
---   working value is kept in r (t_reg). nof_pkt = 0 is ignored.
+--   working value is kept in r (t_reg).
 -- . with g_align_at_sync=true the merge can be forced to restart at a snk_in.sync.
---
--- Issues:
---
--- Design steps:
--- A) No flow control
--- . Start with the Gaisler p_comb, p_reg template:
---
---                  /----------------------------\
---                  |            nxt_r       r   |
---                  |   /------\   .         .   |
---                  \-->|      |   .         .   |
---     snk_in  -------->|      | ---> p_reg -----*--> src_out
---     snk_out <--------|p_comb| <------------------- src_in
---                      \------/                         .
---                                                       .
---                                                  snk --> src : latency + 1
---
---   The following signals are registered in r: outputs, internal states. Typically do not yet
---   add pipelining registers, because these are not functional and can be added later using
---   common_pipeline or dp_pipeline components. For the design start with a timing diagram of the
---   input and output for merging e.g. 3 packets. Draw the sop and eop and also draw the case that
---   there is a data invalid gap between packets. There needs to be a packet counter so, also
---   draw this signal.
--- . Using the timing diagram now assing each of the v fields. Try to keep the implementation
---   for each field seperate, i.e. do not combine multiple fields into one if then else statement.
---   The reason is that keeping each field implementation seperate makes the code more clear and
---   also eases making modifications later on. Mark the implementation section by a comment line.
--- . Typically use r in the if condition and at the right of the := assignment. Depending only
---   on r for implementing v has the advantage that the order of the code section is not important,
---   i.e. similar as with seperate combinatorial processes. However for some cases it can be
---   beneficial to use v in the condition or in the assignment, e.g. as with v_busy.
--- . If the component will not support flow control, then the snk - src latency may be made
---   > 1. However to prepare for adding flow control later on it is prefered to keep the input -
---   output latency at 1. Keeping the snk - src latency at 1 typically also makes the
---   implementation more clear, because if more latency is needed then it may be better to
---   partition the function over two or more components. The snk - src latency of 1 is not
---   functional, because the nxt_r with latency 0 also could be used as output. However the
---   registering of outputs can be functional. From digital implementation point of view it is
---   appropriate though to continue with the r outputs and assign these to the entity outputs.
--- . When the architecture HDL implementation looks clean coded then compile it. When it compiles
---   OK commit it.
--- . Next step is to add a test bench. For dp_packet_merge it is beneficial to first also implement
---   the reverse function dp_packet_unmerge, because that allows the test bench to have the same
---   stimuli input counter data also appear as counter data at the output for verification.
---   Furthermore even though the reverse function may not be needed yet in an application it
---   happens quite often that it will become useful in the future.
--- . For the stimuli and verification use the counter data procedures from tb_dp_pkg.vhd. The
---   test bench consists of stimuli --> DUT --> reverse DUT --> verification. First keep data
---   valid active and use nof_pkt > 1. When that works OK, commit the DUT and the test bench.
---   After that try the extreme values for control, i.e. nof_pkt = 0 should yield no output and
---   nof_pkt = 1 should yield output = input. Then add dynamic in_en to get data not valid gaps
---   during and between the packets. Also try dynamic changing of nof_pkt. When that all
---   works commit the VHDL files.
---
--- B) Add flow control using dp_latency_adapter:
---
---                  /----------------------------\
---                  |            nxt_r       r   |
---                  |   /------\   .         .   |     /-------\
---                  \-->|      |   .         .   |     |dp     |
---     snk_in  -------->|      | ---> p_reg -----*---->|latency|---> src_out
---     snk_out <--------|p_comb| <---------------------|adapter|<--- src_in
---        .             \------/             .         \-------/  .
---        .                                  .                    .
---        .                                  .                    .
---        .                                  .                    .
---      RL=1                               RL=2                 RL=1
---
--- C) Add flow control using dp_hold_input
--- . Adding flow control implies adding dp_hold_input to connect to the snk_in/skn_out and using
---   pend_src_out/hold_src_in instead in p_comb:
---
---                 |-----| <---------------------------------------------\
---                 |     |                               nxt_r       r   |
---                 |     |                      /------\   .         .   |
---                 | dp  |                      |      |   .         .   |
---     snk_in  --> |hold | --> pend_src_out --> |      | ---> p_reg -----*--> src_out
---     snk_out <-- |input| <-- hold_src_in  <-- |p_comb| <------------------- src_in
---        .        |-----|         .            \------/                         .
---        .                        .                                             .
---      RL=1                     RL=0                                          RL=1
---
---   The ready latency (RL) at the input is RL=1. The RL at the output must also be RL=1. The
---   dp_hold_input effectively achieves that the pend_src_out/hold_src_in have RL=0.
---   The snk - src latency of the function is 1, so at the output the RL then becomes RL=1 again.
---   Inside p_comb the v output valid now only get assigned with the pend_src_out valid when
---   src_in.ready='1'. Internally in dp_hold_input the next_src_out.valid = pend_src_out.valid
---   AND src_in.ready, and similar for the sop, eop amd sync. Therefore the p_comb can also use
---   next_src_out instead of pend_src_out in combination with src_in.ready. The advantage of
---   using next_src_out is that it makes the code more compact. The advantange of using
---   pend_src_out and src_in.ready explicitly is that it may make it more clear how src_in.ready
---   is used.
--- . Typically the p_comb can simply pass on src_in to hold_src_in, however it may also control
---   hold_src_in by itself if this function also needs some extra flow control, e.g. to halt or
---   flush the input.
--- . Most components only need to pass on the src_in.xon to hold_src_in.xon. Hence this can be
---   the last statement in p_comb.
--- . In the test bench now also apply the src_in.ready to verify that the component behaves
---   correctly for allways active ready and random ready flow control.
--- . Make a multi-test bench tb_tb_dp_packet_merge to verify different tb settings for the DUT
---   stimuli and add it to the overall DP module tb_tb_tb_dp_backpressure regression test bench.
---
--- D) Potential alternative to add flow control using dp_pipeline
---
--- . This scheme has not been verified yet, but it could work:
---
---                  /-----------------------------\
---                  |            nxt_r        r   |     dp_pipeline_stream
---                  |   /------\   .          .   |  <--select none or one-->
---                  \-->|      |---o-> p_reg -----/      ____    /-----\
---                      |      |   |                    |dp  |   |dp   |
---     snk_in  -------->|      |   \------------------->|pipe|-->|pipe |--> src_out
---     snk_out <--------|p_comb|<-----------------------|line|<--|line |--- src_in
---        .             \------/   .                    |____|   |ready|      .
---        .               RL=0     .                             \-----/      .
---      RL=1                     RL=1                                        RL=1
---
--- . dp_pipeline_stream = wires or dp_pipeline or dp_pipeline_ready
---   - dp_pipeline pipelines the sosi
---   - dp_pipeline_ready pipelines the siso and also the sosi
--- . without flow control there is no siso, so then dp_pipeline_stream degenerates
---   to common_pipeline.
--- . The nxt_r contains combinatorially (= functionally) already what src_out will become in
---   the next cycle and because it is combinatorially related to the input it preserves the
---   RL=1 (whereas p_reg has RL=2). Leading nxt_r through dp_pipeline includes the flow control
---   to it.
--- . Compared to using dp_hold_input using dp_pipeline costs twice more registers, because
---   dp_pipeline internally has a register stage and p_reg is still needed. Still synthesis
---   may be able to optimize away some redundant registers.
--- . 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.
+-- . Optional flow control dependent on g_use_ready and g_pipeline_ready, see
+--   description of dp_add_flow_control.
+
 
 library IEEE,common_lib;
 use IEEE.std_logic_1164.all;
@@ -185,10 +56,12 @@ use work.dp_stream_pkg.all;
 
 entity dp_packet_merge is
   generic (
-    g_nof_pkt       : natural;
-    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
+    g_use_ready       : boolean := true;
+    g_pipeline_ready  : boolean := false;
+    g_nof_pkt         : natural;
+    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;
@@ -200,7 +73,7 @@ entity dp_packet_merge is
     snk_out     : out t_dp_siso;
     snk_in      : in  t_dp_sosi;
 
-    src_in      : in  t_dp_siso;
+    src_in      : in  t_dp_siso := c_dp_siso_rdy;
     src_out     : out t_dp_sosi
   );
 end dp_packet_merge;
@@ -217,52 +90,32 @@ architecture rtl of dp_packet_merge is
     src_out     : t_dp_sosi;
   end record;
 
-  constant c_use_dp_latency_adapter : boolean := true;  -- when TRUE adjust RL from 2 to 1, else use dp_hold_input to keep RL at 1.
-
   signal r, nxt_r : t_reg;
-
-  signal dp_latency_adapter_snk_out : t_dp_siso;
-  signal dp_latency_adapter_snk_in  : t_dp_sosi;
-  signal dp_latency_adapter_src_in  : t_dp_siso;
-  signal dp_latency_adapter_src_out : t_dp_sosi;
 begin
-  -- Map t_reg outputs to entity outputs
+  -- Map logic function outputs to entity outputs
   nof_pkt_out <= TO_UVEC(r.nof_pkt, ceil_log2(g_nof_pkt + 1));
 
-  no_dp_latency_adapter : if c_use_dp_latency_adapter = false generate
-    snk_out <= src_in;
-    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
-    snk_out <= dp_latency_adapter_snk_out;
-    dp_latency_adapter_snk_in <= r.src_out;
-
-    u_dp_latency_adapter : entity work.dp_latency_adapter
+  u_dp_add_flow_control : entity work.dp_add_flow_control
     generic map (
-      g_in_latency  => 2,
-      g_out_latency => 1
+      g_use_ready       => g_use_ready,
+      g_pipeline_ready  => g_pipeline_ready
     )
     port map (
-      rst          => rst,
-      clk          => clk,
-      -- ST sink
-      snk_out      => dp_latency_adapter_snk_out,
-      snk_in       => dp_latency_adapter_snk_in,
-      -- ST source
-      src_in       => dp_latency_adapter_src_in,
-      src_out      => dp_latency_adapter_src_out
-    );
+      rst         => rst,
+      clk         => clk,
 
-    dp_latency_adapter_src_in <= src_in;
-    src_out <= dp_latency_adapter_src_out;
-  end generate;
+      snk_out     => snk_out,
+      snk_in      => nxt_r.src_out,  -- combinatorial input
+      snk_in_reg  => r.src_out,  -- registered input
+
+      src_in      => src_in,
+      src_out     => src_out
+    );
 
-  -- p_reg
+  -- p_reg function state register
   r <= nxt_r when rising_edge(clk);
 
+  -- Logic function
   p_comb : process(rst, r, snk_in, nof_pkt)
     variable v : t_reg;
   begin
@@ -355,7 +208,7 @@ begin
 
     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;  -- take err field of first packet
       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.
       end if;
diff --git a/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd b/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd
index 1fe7ebd08f82c15f48ac1e5622692e84b2afd121..9a8401456e7753a45023be5912ec77afb4eb0af7 100644
--- a/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd
+++ b/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd
@@ -19,17 +19,38 @@
 --
 --------------------------------------------------------------------------------
 
--- Purpose: Unmerge each input packet into g_nof_pkt output packets. Below is the
---          waveform when g_nof_pkt = 3. The numbers in snk_in.sop and snk_in.eop
---          match pkt_cnt.
---                    _                             _                             _
--- snk_in.sop   _____|0|___________________________|1|___________________________|2|_
---                                                _                             _
--- snk_in.sop   _________________________________|0|___________________________|1|___
---                    _         _         _         _         _         _         _
--- src_out.sop  _____|0|_______|1|_______|2|_______|0|_______|1|_______|2|_______|0|_
---                            _         _         _         _         _         _
--- src_out.eop  _____________|0|_______|1|_______|2|_______|0|_______|1|_______|2|___
+-- Author: E. Kooistra
+-- Purpose: Unmerge each input packet into output packets of length g_pkt_len.
+-- Description:
+-- . The merged packet length of the snk_in input packets must be an integer
+--   multiple of g_pkt_len. The number of output packets g_nof_pkt_max is only
+--   used to determine the maximum supported pkt_cnt range. The actual number
+--   of output packets has to be <= g_nof_pkt_max, and is determined by input
+--   packet length / g_pkt_len. Hence the dp_packet_unmerge can dynamically
+--   handle different sizes of input packets, provided that their length is an
+--   integer multiple of g_pkt_len.
+-- . The pkt_cnt is passed on as src_out.channel index.
+-- . The g_bsn_increment sets the BSN increment for the unmerged output
+--   packets relative to the BSN of the snk_in input packet. When
+--   g_bsn_increment = 0, then all unmerged output packets get the same BSN as
+--   the input packet.
+-- . The input snk_in.err and snk_in.empty are valid at the snk_in.eop, but
+--   that is too late to apply them to the unmerged packets. Therefor assume
+--   that the snk_in.err and snk_in_eop are already valid at the snk_in.sop
+--   and remain valid until the snk_in.eop. Hence these signals are then valid
+--   when snk_in.valid = '1'. Use same snk_in.err and snk_in.empty value for
+--   all unmerged packets.
+--                      _                       _                       _
+--   snk_in.sop   _____| |_____________________| |_____________________| |_
+--                                            _                       _
+--   snk_in.eop   ___________________________| |_____________________| |___
+--                      _       _       _       _       _       _       _
+--   src_out.sop  _____|0|_____|1|_____|2|_____|0|_____|1|_____|2|_____|0|_
+--                            _       _       _       _       _       _
+--   src_out.eop  ___________|0|_____|1|_____|2|_____|0|_____|1|_____|2|___
+--
+-- . Optional flow control dependent on g_use_ready and g_pipeline_ready, see
+--   description of dp_add_flow_control.
 
 library IEEE,common_lib;
 use IEEE.std_logic_1164.all;
@@ -39,8 +60,11 @@ use work.dp_stream_pkg.all;
 
 entity dp_packet_unmerge is
   generic (
-    g_nof_pkt   : natural := 1;  -- Nof packets to unmerge each incoming packet to
-    g_pkt_len   : natural := 1  -- Length of the unmerged packets
+    g_use_ready       : boolean := true;
+    g_pipeline_ready  : boolean := false;
+    g_nof_pkt_max     : natural := 1;  -- Maximum nof packets to unmerge each incoming packet to
+    g_pkt_len         : natural := 1;  -- Length of the unmerged packets
+    g_bsn_increment   : natural := 0
   );
   port (
     rst         : in  std_logic;
@@ -49,14 +73,133 @@ entity dp_packet_unmerge is
     snk_out     : out t_dp_siso;
     snk_in      : in  t_dp_sosi;
 
-    src_in      : in  t_dp_siso;
+    src_in      : in  t_dp_siso := c_dp_siso_rdy;
     src_out     : out t_dp_sosi
   );
 end dp_packet_unmerge;
 
 architecture rtl of dp_packet_unmerge is
+  -- Internal state of logic function
+  type t_reg is record
+    pkt_cnt     : natural range 0 to g_nof_pkt_max + 1;
+    val_cnt     : natural range 0 to g_pkt_len + 1;
+    src_out     : t_dp_sosi;
+  end record;
+
+  constant c_reg_rst : t_reg := (0, 0, c_dp_sosi_rst);
+
+  signal r : t_reg;
+  signal d : t_reg;
+
 begin
-  -- Temporary void component that assigns output = input
-  snk_out <= src_in;
-  src_out <= snk_in;
+  -- Map logic function outputs to entity outputs
+  u_dp_add_flow_control : entity work.dp_add_flow_control
+    generic map (
+      g_use_ready       => g_use_ready,
+      g_pipeline_ready  => g_pipeline_ready
+    )
+    port map (
+      rst         => rst,
+      clk         => clk,
+
+      snk_out     => snk_out,
+      snk_in      => d.src_out,  -- combinatorial input
+      snk_in_reg  => r.src_out,  -- registered input
+
+      src_in      => src_in,
+      src_out     => src_out
+    );
+
+  -- p_reg function state register
+  r <= d when rising_edge(clk);
+
+  -- Logic function
+  p_comb : process(rst, r, snk_in)
+    variable v : t_reg;
+  begin
+    -- Default
+    v := r;
+
+    -- Function
+    --                   _                 _                 _
+    --   snk_in.sop   __| |_______________| |_______________| |_______________|
+    --                                  _                 _                 _
+    --   snk_in.eop   _________________| |_______________| |_______________| |_
+    --                   _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _
+    --   snk_in.valid __|
+    --   v.val_cnt        0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
+    --   v.pkt_cnt        0     1     2     0     1     2     0     1     2
+    --                    ______________   _______________   _______________   _
+    --   v.busy        __|              |_|               |_|               |_|
+    --                    _     _     _     _     _     _     _     _     _
+    --   v.src_out.sop __|0|___|1|___|2|___|0|___|1|___|2|___|0|___|1|___|2|___|
+    --                       _     _     _     _     _     _     _     _     _
+    --   v.src_out.eop _____|0|___|1|___|2|___|0|___|1|___|2|___|0|___|1|___|2|_
+
+    -- input valid counter
+    if snk_in.sop = '1' then
+      v.val_cnt := 0;
+    elsif snk_in.valid = '1' then
+      if r.val_cnt < g_pkt_len - 1 then
+        v.val_cnt := r.val_cnt + 1;
+      else
+        v.val_cnt := 0;
+      end if;
+    end if;
+
+    -- output packet counter
+    if snk_in.sop = '1' then
+      v.pkt_cnt := 0;
+    elsif snk_in.valid = '1' and v.val_cnt = 0 then
+      v.pkt_cnt := r.pkt_cnt + 1;
+    end if;
+
+    -- output packet bsn, sync, sop and eop
+    -- . Default passes on snk_in.sync, valid, data, re, im
+    -- . The sync, valid can be passed on from snk_in, without checking
+    --   src_in.ready, because the fact that snk_in.valid is '1' is
+    --   sufficient for src_out.valid to be '1' too. The RL is taken care
+    --   of by gen_use_src_in_ready.
+    v.src_out         := snk_in;  -- passes on snk_in.sync, data, re, im
+    v.src_out.bsn     := r.src_out.bsn;
+    v.src_out.channel := r.src_out.channel;
+    v.src_out.empty   := r.src_out.empty;
+    v.src_out.err     := r.src_out.err;
+    v.src_out.sop     := '0';
+    v.src_out.eop     := '0';
+
+    -- . output sop, eop
+    if snk_in.valid = '1' then
+      if v.val_cnt = 0 then
+        v.src_out.sop := '1';
+      end if;
+      if v.val_cnt = g_pkt_len - 1 then
+        v.src_out.eop := '1';
+      end if;
+    end if;
+
+    -- . output bsn
+    if snk_in.sop = '1' then
+      v.src_out.bsn := snk_in.bsn;
+    elsif v.src_out.sop = '1' then
+      v.src_out.bsn := incr_uvec(r.src_out.bsn, g_bsn_increment);
+    end if;
+
+    -- . output channel
+    v.src_out.channel := TO_DP_CHANNEL(v.pkt_cnt);
+
+    -- . output err, empty. assume they are valid during entire input packet,
+    --   so not only at the snk_in.eop
+    if snk_in.valid = '1' then
+      v.src_out.empty := snk_in.empty;
+      v.src_out.err   := snk_in.err;
+    end if;
+
+    -- Synchronous reset
+    if rst = '1' then
+      v := c_reg_rst;
+    end if;
+
+    d <= v;
+  end process;
 end rtl;
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 6466f7e36b7f408b3d2687d849b74e35654a6358..42624ba3ea0b2b1778240d19a80e9e19e62df7b4 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge.vhd
@@ -21,7 +21,7 @@
 -------------------------------------------------------------------------------
 
 -- Purpose:
--- . Test bench for dp_packet_merge and dp_packet_unmerge
+-- . Test bench for dp_packet_merge
 -- Description:
 -- . The p_stimuli_st uses proc_dp_gen_block_data to generate g_nof_repeat packets for the DUT. The output of the DUT needs
 --   to be similar e.g. by means of an inverse DUT component so that the proc_dp_verify_* procedures can be used to verify
@@ -29,6 +29,8 @@
 --   verify that the test bench has yielded output results at all and that the output valid, sop, eop, and ready fits the
 --   streaming interface specification.
 -- . A seperate p_stimuli_mm process may be used to verify the nof_pkt input of the DUT.
+-- . Use separate tb_dp_packet_merge_unmerge to verify dp_packet_unmerge, to have easier control
+--   over expected output channel, err and empty of dp_packet_unmerge.
 -- Usage:
 -- > as 10
 -- > run -all
@@ -59,6 +61,7 @@ entity tb_dp_packet_merge is
     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_pipeline_ready         : boolean := true;
     g_data_w                 : natural := 4;
     g_nof_repeat             : natural := 24;
     g_nof_pkt                : natural := 3;
@@ -67,13 +70,13 @@ entity tb_dp_packet_merge is
     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
+    g_bsn_err_at_pkt_index   : natural := 6  -- force wrong snk_in.bsn for packet with this index, in range(g_nof_repeat)
   );
 end tb_dp_packet_merge;
 
 architecture tb of tb_dp_packet_merge is
   constant c_rl                       : natural := 1;
+  constant c_use_ready                : boolean := g_flow_control_verify /= e_active;
 
   constant c_pulse_active             : natural := 1;
   constant c_pulse_period             : natural := 7;
@@ -205,7 +208,7 @@ begin
     end loop;
 
     -- Determine expected sosi field values after end of stimuli
-    ---- . e_qual (account for merge size g_nof_pkt)
+    -- . e_qual (account for merge size g_nof_pkt)
     -- . e_at_least
     v_sosi.bsn     := std_logic_vector( unsigned(c_bsn_init) + c_verify_at_least * g_nof_pkt);
     v_sosi.channel := TO_DP_CHANNEL(c_channel_init           + c_verify_at_least * g_nof_pkt);
@@ -297,10 +300,12 @@ begin
   -- Merge every g_nof_pkt incomming packets into output packets
   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_bsn_increment => g_bsn_increment,
-    g_bsn_err_bi    => c_bsn_err_bi
+    g_use_ready      => c_use_ready,
+    g_pipeline_ready => g_pipeline_ready,
+    g_nof_pkt        => g_nof_pkt,
+    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,
@@ -316,30 +321,8 @@ begin
   ------------------------------------------------------------------------------
   -- Optional reverse DUT dp_packet_unmerge
   ------------------------------------------------------------------------------
-  no_dp_packet_unmerge : if g_use_dp_packet_unmerge = false generate
-    dp_packet_merge_src_in <= verify_snk_out;
-    verify_snk_in          <= dp_packet_merge_src_out;
-  end generate;
-
-  gen_dp_packet_unmerge : if g_use_dp_packet_unmerge = true generate
-    u_dp_packet_unmerge : entity work.dp_packet_unmerge
-    generic map (
-      g_nof_pkt => g_nof_pkt
-    )
-    port map (
-      rst       => rst,
-      clk       => clk,
-
-      snk_out   => dp_packet_merge_src_in,
-      snk_in    => dp_packet_merge_src_out,
-
-      src_in    => dp_packet_unmerge_src_in,
-      src_out   => dp_packet_unmerge_src_out
-    );
-
-    dp_packet_unmerge_src_in <= verify_snk_out;
-    verify_snk_in            <= dp_packet_unmerge_src_out;
-  end generate;
+  dp_packet_merge_src_in <= verify_snk_out;
+  verify_snk_in          <= dp_packet_merge_src_out;
 
   -- Map to slv to ease monitoring in wave window
   stimuli_data <= stimuli_src_out.data(g_data_w - 1 downto 0);
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..24e34cbaf24916cfd18356d48c1a80dfd0351acd
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd
@@ -0,0 +1,333 @@
+-- --------------------------------------------------------------------------
+-- Copyright 2023
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- ----------------------------------------------------------------------------
+
+-- Author: E. Kooistra
+-- Purpose:
+-- . Test bench for dp_packet_merge and dp_packet_unmerge
+-- Description:
+-- . The p_stimuli_st uses proc_dp_gen_block_data to generate g_nof_repeat packets for the DUT. The output of the DUT needs
+--   to be similar e.g. by means of an inverse DUT component so that the proc_dp_verify_* procedures can be used to verify
+--   that the counter data in the sosi data fields is passed on correctly. Furthermore the proc_dp_verify_* procedures
+--   verify that the test bench has yielded output results at all and that the output valid, sop, eop, and ready fits the
+--   streaming interface specification.
+-- Usage:
+-- > as 10
+-- > run -all
+--
+
+library IEEE, common_lib;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use common_lib.common_pkg.all;
+use common_lib.common_lfsr_sequences_pkg.all;
+use common_lib.tb_common_pkg.all;
+use work.dp_stream_pkg.all;
+use work.tb_dp_pkg.all;
+
+entity tb_dp_packet_merge_unmerge is
+  generic (
+    -- general
+    -- . always active, random or pulse flow control
+    g_flow_control_stimuli   : t_dp_flow_control_enum := e_active;
+    g_flow_control_verify    : t_dp_flow_control_enum := e_active;
+    -- specific
+    g_pipeline_ready         : boolean := true;
+    g_data_w                 : natural := 16;
+    g_nof_repeat             : natural := 24;
+    g_nof_pkt                : natural := 3;
+    g_pkt_len                : natural := 29;
+    g_pkt_gap                : natural := 0;
+    g_bsn_increment          : natural := 0
+  );
+end tb_dp_packet_merge_unmerge;
+
+architecture tb of tb_dp_packet_merge_unmerge is
+  constant c_rl                       : natural := 1;
+  constant c_use_ready                : boolean := g_flow_control_verify /= e_active;
+
+  constant c_pulse_active             : natural := 1;
+  constant c_pulse_period             : natural := 7;
+
+  constant c_sync_period              : natural := 10;
+  constant c_sync_offset              : natural := 7;
+
+  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_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));
+  -- verify that at least some packets have been merged, not exact to allow variation by p_stimuli_mm
+  constant c_verify_at_least          : natural := largest(1,c_nof_merged_sop / 2);
+
+  signal tb_end                     : std_logic := '0';
+  signal clk                        : std_logic := '1';
+  signal rst                        : std_logic := '1';
+  signal sl1                        : std_logic := '1';
+
+  -- use different slv lengths to have different random sequences
+  signal random_0                   : std_logic_vector(14 downto 0) := (others => '0');
+  signal random_1                   : std_logic_vector(15 downto 0) := (others => '0');
+  signal pulse_0                    : std_logic;
+  signal pulse_1                    : std_logic;
+  signal pulse_en                   : std_logic := '1';
+
+  signal stimuli_en                 : std_logic := '1';
+  signal stimuli_src_in             : t_dp_siso;
+  signal stimuli_src_out            : t_dp_sosi;
+  signal stimuli_data               : std_logic_vector(g_data_w - 1 downto 0);
+
+  signal dp_packet_merge_snk_in     : t_dp_siso;
+  signal dp_packet_merge_src_out    : t_dp_sosi;
+  signal dp_packet_merge_siso       : t_dp_siso;
+  signal dp_packet_merge_sosi       : t_dp_sosi;
+
+  signal prev_verify_snk_out        : t_dp_siso;
+  signal verify_snk_out             : t_dp_siso := c_dp_siso_rdy;
+  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 input_pkt_cnt              : natural := 0;
+  signal merged_pkt_cnt             : natural := 0;
+  signal exp_channel                : natural := 0;
+  signal exp_error                  : natural := 0;
+  signal exp_empty                  : natural := 0;
+
+  signal verify_hold_sop            : std_logic := '0';
+  signal verify_en_valid            : std_logic := '0';
+  signal verify_en_sop              : std_logic := '0';
+  signal verify_en_eop              : std_logic := '0';
+  signal verify_done                : std_logic := '0';
+  signal verify_value_en            : std_logic := sel_a_b(g_nof_pkt = 0, '0', '1');
+
+  signal expected_verify_snk_in     : t_dp_sosi;
+begin
+  clk <= (not clk) or tb_end after clk_period / 2;
+  rst <= '1', '0' after clk_period * 7;
+
+  random_0 <= func_common_random(random_0) when rising_edge(clk);
+  random_1 <= func_common_random(random_1) when rising_edge(clk);
+
+  proc_common_gen_duty_pulse(c_pulse_active, c_pulse_period,     '1', rst, clk, pulse_en, pulse_0);
+  proc_common_gen_duty_pulse(c_pulse_active, c_pulse_period + 1, '1', rst, clk, pulse_en, pulse_1);
+
+  ------------------------------------------------------------------------------
+  -- STREAM CONTROL
+  ------------------------------------------------------------------------------
+
+  stimuli_en           <= '1'                     when g_flow_control_stimuli = e_active else
+                          random_0(random_0'high) when g_flow_control_stimuli = e_random else
+                          pulse_0                 when g_flow_control_stimuli = e_pulse;
+
+  verify_snk_out.ready <= '1'                     when g_flow_control_verify = e_active  else
+                          random_1(random_1'high) when g_flow_control_verify = e_random  else
+                          pulse_1                 when g_flow_control_verify = e_pulse;
+
+  ------------------------------------------------------------------------------
+  -- DATA GENERATION
+  ------------------------------------------------------------------------------
+
+  -- Generate data path input data
+  p_stimuli_st : process
+    constant c_channel : natural := 0;
+    constant c_err     : natural := 0;
+    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_sosi.data := INCR_UVEC(TO_DP_DATA(c_data_init), -1);
+
+    stimuli_src_out <= c_dp_sosi_rst;
+    proc_common_wait_until_low(clk, rst);
+    proc_common_wait_some_cycles(clk, 5);
+
+    -- 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, g_bsn_increment);
+      -- insert sync starting at BSN = c_sync_offset and with period c_sync_period
+      v_sosi.sync := sel_a_b((unsigned(v_sosi.bsn) mod c_sync_period) = c_sync_offset, '1', '0');
+      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
+
+      -- Send packet
+      proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_pkt_len,
+                             c_channel, c_err, v_sosi.sync, v_sosi.bsn,
+                             clk, stimuli_en, stimuli_src_in, stimuli_src_out);
+
+      -- Insert optional gap between the packets
+      proc_common_wait_some_cycles(clk, g_pkt_gap);
+    end loop;
+
+    -- Determine expected sosi field values after end of stimuli
+    -- . e_qual (account for merge size g_nof_pkt)
+    -- . e_at_least
+    v_sosi.bsn := std_logic_vector(unsigned(c_bsn_init) + c_verify_at_least * g_nof_pkt);
+
+    -- . account for g_pkt_len
+    v_sosi.data := INCR_UVEC(v_sosi.data, g_pkt_len - 1);
+    v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
+    expected_verify_snk_in <= v_sosi;
+
+    -- Signal end of stimuli
+    -- . latency from stimuli to verify depends on the flow control, so wait
+    --   sufficiently long for last packet to have passed through
+    proc_common_wait_some_cycles(clk, 100);
+    if verify_value_en = '1' then
+      proc_common_gen_pulse(clk, verify_done);
+    end if;
+    proc_common_wait_some_cycles(clk, 50);
+    tb_end <= '1';
+    wait;
+  end process;
+
+  ------------------------------------------------------------------------------
+  -- DATA VERIFICATION
+  ------------------------------------------------------------------------------
+
+  -- Start verify after first valid, sop or eop
+  verify_en_valid <= '1' when verify_snk_in.valid = '1' and rising_edge(clk);
+  verify_en_sop   <= '1' when verify_snk_in.sop = '1'   and rising_edge(clk);
+  verify_en_eop   <= '1' when verify_snk_in.eop = '1'   and rising_edge(clk);
+
+  -- Verify that the stimuli have been applied at all
+  proc_dp_verify_value("verify_snk_in.valid",               clk, verify_done, sl1, verify_en_valid);
+  proc_dp_verify_value("verify_snk_in.sop",                 clk, verify_done, sl1, verify_en_sop);
+  proc_dp_verify_value("verify_snk_in.eop",                 clk, verify_done, sl1, verify_en_eop);
+  proc_dp_verify_value("verify_snk_in.data",    e_equal,    clk, verify_done, expected_verify_snk_in.data,    verify_snk_in.data);
+  proc_dp_verify_value("verify_snk_in.bsn",     e_at_least, clk, verify_done, expected_verify_snk_in.bsn,     verify_snk_in.bsn);
+
+  -- 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);
+
+  -- Verify that the output is incrementing BSN, like the input stimuli
+  proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, c_unsigned_0,
+                       clk, verify_en_sop, verify_snk_out.ready,
+                       verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
+
+  -- 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);
+
+  -- Verify output ready latency
+  proc_dp_verify_valid(clk, verify_en_valid, verify_snk_out.ready, prev_verify_snk_out.ready, verify_snk_in.valid);
+
+  -- Verify output verify_snk_in.sosi fields
+  p_verify_fields : process(clk)
+  begin
+    if rising_edge(clk) then
+      -- Use verify_snk_in.valid, because the assumption with dp_packet_unmerge
+      -- is that the channel (at sop) and err, empty (at eop) are valid during
+      -- the entire unmerged packet.
+      if verify_snk_in.valid = '1' then
+        -- Verify that output channel yields index of unmerged packet, in range(g_nof_pkt)
+        assert unsigned(verify_snk_in.channel) = exp_channel
+          report "Wrong unmerged verify_snk_in.channel"
+          severity ERROR;
+
+        -- Verify that output error is same per g_nof_pkt unmerged packets
+        assert unsigned(verify_snk_in.err) = exp_error
+          report "Wrong unmerged verify_snk_in.err"
+          severity ERROR;
+
+        -- Verify that output empty is same per g_nof_pkt unmerged packets
+        assert unsigned(verify_snk_in.empty) = exp_empty
+          report "Wrong unmerged verify_snk_in.empty"
+          severity ERROR;
+      end if;
+    end if;
+  end process;
+
+  ------------------------------------------------------------------------------
+  -- DUT dp_packet_merge
+  ------------------------------------------------------------------------------
+
+  -- Merge every g_nof_pkt incomming packets into output packets
+  u_dp_packet_merge : entity work.dp_packet_merge
+  generic map (
+    g_nof_pkt       => g_nof_pkt,
+    g_align_at_sync => false,  -- not used in this tb
+    g_bsn_increment => g_bsn_increment,
+    g_bsn_err_bi    => 0  -- not used in this tb
+  )
+  port map (
+    rst       => rst,
+    clk       => clk,
+
+    snk_out   => stimuli_src_in,
+    snk_in    => stimuli_src_out,
+
+    src_in    => dp_packet_merge_snk_in,
+    src_out   => dp_packet_merge_src_out
+  );
+
+  dp_packet_merge_snk_in <= dp_packet_merge_siso;
+
+  ------------------------------------------------------------------------------
+  -- TB stimuli for dp_packet_unmerge
+  ------------------------------------------------------------------------------
+  p_stimuli_unmerge : process(dp_packet_merge_src_out)
+  begin
+    dp_packet_merge_sosi     <= dp_packet_merge_src_out;
+    -- Use counter as err field stimulus, per merged packet. Use
+    -- offset to distinguish err and empty values
+    dp_packet_merge_sosi.err <= TO_DP_ERROR(merged_pkt_cnt);
+    dp_packet_merge_sosi.empty <= TO_DP_EMPTY(merged_pkt_cnt + 1);
+  end process;
+
+  ------------------------------------------------------------------------------
+  -- TB signals for verification of dp_packet_unmerge
+  ------------------------------------------------------------------------------
+  input_pkt_cnt <= input_pkt_cnt + 1 when rising_edge(clk) and stimuli_src_out.eop = '1';
+  merged_pkt_cnt <= merged_pkt_cnt + 1 when rising_edge(clk) and dp_packet_merge_src_out.eop = '1';
+
+  -- get expected value, aligned with output packet boundaries
+  exp_channel <= input_pkt_cnt mod g_nof_pkt when rising_edge(clk) and verify_snk_in.eop = '1';
+  exp_error <= merged_pkt_cnt when rising_edge(clk) and verify_snk_in.eop = '1';
+  exp_empty <= exp_error + 1;
+
+  ------------------------------------------------------------------------------
+  -- Optional reverse DUT dp_packet_unmerge
+  ------------------------------------------------------------------------------
+  u_dp_packet_unmerge : entity work.dp_packet_unmerge
+  generic map (
+    g_use_ready       => c_use_ready,
+    g_pipeline_ready  => g_pipeline_ready,
+    g_nof_pkt_max     => g_nof_pkt,
+    g_pkt_len         => g_pkt_len,
+    g_bsn_increment   => g_bsn_increment
+  )
+  port map (
+    rst       => rst,
+    clk       => clk,
+
+    snk_out   => dp_packet_merge_siso,
+    snk_in    => dp_packet_merge_sosi,
+
+    src_in    => verify_snk_out,
+    src_out   => verify_snk_in
+  );
+
+  -- Map to slv to ease monitoring in wave window
+  stimuli_data <= stimuli_src_out.data(g_data_w - 1 downto 0);
+  verify_data  <= verify_snk_in.data(g_data_w - 1 downto 0);
+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 46fbd725ba93af2716dab57266cc4a6f73bb8af1..8ae19f6b60bc83899124ef30cf2f886af2627a20 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
@@ -27,7 +27,7 @@ use dp_lib.tb_dp_pkg.all;
 -- Purpose: Verify multiple variations of tb_dp_packet_merge
 -- Description:
 -- Usage:
--- > as 3
+-- > as 8, to see that correct instances are generated
 -- > run -all
 
 entity tb_tb_dp_packet_merge is
@@ -41,6 +41,7 @@ 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_pipeline_ready         : boolean := true;
   --     g_data_w                 : natural := 4;
   --     g_nof_repeat             : natural := 20;
   --     g_nof_pkt                : natural := 3;
@@ -50,29 +51,29 @@ begin
   --     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, 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_act_act_8_nof_0      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 0, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_2      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 2, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_4      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 4, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_5      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 5, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_6      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 6, 29, 0, false, false, 1, 0);
+  u_act_act_8_nof_7      : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 7, 29, 0, false, false, 1, 0);
 
-  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_3      : entity work.tb_dp_packet_merge generic map ( e_random, e_active,  true, 8, c_nof_repeat, 3, 29, 0, false, false, 2, 0);
+  u_rnd_rnd_8_nof_3_comb : entity work.tb_dp_packet_merge generic map ( e_random, e_random, false, 8, c_nof_repeat, 3, 29, 0, false, false, 3, 0);
+  u_rnd_rnd_8_nof_3_reg  : entity work.tb_dp_packet_merge generic map ( e_random, e_random,  true, 8, c_nof_repeat, 3, 29, 0, false, false, 3, 0);
+  u_pls_act_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_active,  true, 8, c_nof_repeat, 3, 29, 0, false, false, 4, 0);
+  u_pls_rnd_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_random,  true, 8, c_nof_repeat, 3, 29, 0, false, false, 5, 0);
+  u_pls_pls_8_nof_3      : entity work.tb_dp_packet_merge generic map ( e_pulse,  e_pulse,   true, 8, c_nof_repeat, 3, 29, 0, false, false, 6, 0);
 
-  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_rnd_act_8_nof_1      : entity work.tb_dp_packet_merge generic map ( e_random, e_active, true, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0);
+  u_rnd_act_8_nof_3_gap  : entity work.tb_dp_packet_merge generic map ( e_random, e_active, true, 8, c_nof_repeat, 3, 29, 17, false, false, 1, 0);
 
-  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);
+  u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, true, 0, 10);
+  u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 10);
+  u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 11);
+  u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 12);
+  u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 13);
 end tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7fd9034f6fb81169d4c7b189a370006c2f78b9d7
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
@@ -0,0 +1,70 @@
+-- --------------------------------------------------------------------------
+-- Copyright 2023
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- ----------------------------------------------------------------------------
+
+library IEEE, dp_lib;
+use IEEE.std_logic_1164.all;
+use dp_lib.tb_dp_pkg.all;
+
+-- Author: E. Kooistra
+-- Purpose: Verify multiple variations of tb_dp_packet_merge_unmerge
+-- Description:
+-- Usage:
+-- > as 8, to see that correct instances are generated
+-- > run -all
+
+entity tb_tb_dp_packet_merge_unmerge is
+end tb_tb_dp_packet_merge_unmerge;
+
+architecture tb of tb_tb_dp_packet_merge_unmerge is
+  constant c_nof_repeat            : natural := 100;
+  signal tb_end : std_logic := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+begin
+  --     -- general
+  --     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_pipeline_ready         : boolean := true;
+  --     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_bsn_increment          : natural := 0;
+
+  u_act_act_8_nof_0       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 0, 29, 0, 1);
+  u_act_act_8_nof_1       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 1, 29, 0, 1);
+  u_act_act_8_nof_2       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 2, 29, 0, 1);
+  u_act_act_8_nof_3       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_act_act_8_nof_4       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 4, 29, 0, 1);
+  u_act_act_8_nof_4_bsn_0 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 4, 29, 0, 0);
+  --u_act_act_8_nof_4_bsn_2 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 4, 29, 0, 2);
+  u_act_act_8_nof_5       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 5, 29, 0, 1);
+  u_act_act_8_nof_6       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 6, 29, 0, 1);
+  u_act_act_8_nof_7       : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active,  true, 8, c_nof_repeat, 7, 29, 0, 1);
+
+  u_rnd_act_8_nof_3       : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active,  true, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_rnd_rnd_8_nof_3_comb  : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, false, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_rnd_rnd_8_nof_3_reg   : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random,  true, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_pls_act_8_nof_3       : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_active,  true, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_pls_rnd_8_nof_3       : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_random,  true, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_pls_pls_8_nof_3       : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_pulse,   true, 8, c_nof_repeat, 3, 29, 0, 1);
+
+  u_rnd_act_8_nof_1       : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active,  true, 8, c_nof_repeat, 1, 29,  0, 1);
+  u_rnd_act_8_nof_3_gap   : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active,  true, 8, c_nof_repeat, 3, 29, 17, 1);
+end tb;