diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd
index c79b23ab4cf4021ac721c5007a7620173c127b20..84c934a7ec8f039fc74bf031b1c20ab2f6292a52 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd
@@ -37,7 +37,7 @@ package sdp_bdo_pkg is
   constant c_sdp_bdo_nof_destinations_max   : natural := 16;
   constant c_sdp_bdo_reorder_nof_blocks_max : natural := largest(16, c_sdp_cep_nof_blocks_per_packet);
 
-  constant c_sdp_bdo_destinations_info_nof_hdr_fields : natural := c_sdp_bdo_nof_destinations_max * 3 + 3;  -- = 52 fields
+  constant c_sdp_bdo_destinations_info_nof_hdr_fields : natural := c_sdp_bdo_nof_destinations_max * 3 + 4;  -- = 52 fields
 
   type t_sdp_bdo_destinations_info is record
     eth_destination_mac_arr     : t_slv_48_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
@@ -45,21 +45,37 @@ package sdp_bdo_pkg is
     udp_destination_port_arr    : t_slv_16_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
     nof_destinations            : natural;
     nof_destinations_act        : natural;
+    nof_destinations_max        : natural;
     nof_blocks_per_packet_act   : natural;
   end record;
 
   constant t_sdp_bdo_destinations_info_rst : t_sdp_bdo_destinations_info :=
     ( (others => (others => '0')),
       (others => (others => '0')),
-      (others => (others => '0')), 0, 0, 0 );
+      (others => (others => '0')),
+      1,
+      1,
+      c_sdp_bdo_nof_destinations_max,
+      c_sdp_cep_nof_blocks_per_packet);
 
-  -- Determine actual nof_destinations and actual nof_blocks_per_packet
+  -- Parse user input to determine actual nof_destinations
   function func_sdp_bdo_parse_nof_destinations(nof_destinations : natural) return natural;
-  function func_sdp_bdo_nof_blocks_per_packet_look_up_table return t_natural_arr;
 
-  -- Determine nof_beamlets_per_block per destination
+  -- Use functions that return look up tables to precalculate the values as
+  -- constant arrays
+
+  -- . Look up table arrays for t_natural_arr(1 to c_sdp_bdo_nof_destinations_max).
+  function func_sdp_bdo_nof_blocks_per_packet_look_up_table return t_natural_arr;
+  function func_sdp_bdo_reorder_nof_blocks_look_up_table return t_natural_arr;
+  function func_sdp_bdo_reorder_nof_ch_look_up_table return t_natural_arr;
   function func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table return t_natural_arr;
   function func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table return t_natural_arr;
+  function func_sdp_sdo_nof_ch_per_packet_first_destination_look_up_table return t_natural_arr;
+  function func_sdp_sdo_nof_ch_per_packet_last_destination_look_up_table return t_natural_arr;
+
+  -- Look up table matrix for:
+  --   t_natural_matrix(1 to c_sdp_bdo_nof_destinations_max,      -- N_destinations
+  --                    0 to c_sdp_bdo_nof_destinations_max - 1)  -- destination index
   function func_sdp_sdo_beamlet_index_per_destination_look_up_matrix return t_natural_matrix;
 end package sdp_bdo_pkg;
 
@@ -79,33 +95,62 @@ package body sdp_bdo_pkg is
   function func_sdp_bdo_nof_blocks_per_packet_look_up_table return t_natural_arr is
     variable v_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
   begin
-    -- Determine nof_blocks_per_packet as function of number of destinations D. Use
-    -- look up table to precalculate the values as constants.
-    -- . Use same number of nof_blocks_per_packet for each destination.
-    -- . In total there are maximum c_sdp_bdo_reorder_nof_blocks_max = 16 blocks to
-    --   distribute over D destinations, so floor(16 / D) per destination yields:
-    --     D = 1:16 --> 16, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
-    for D in 1 to c_sdp_bdo_nof_destinations_max loop
-      v_arr(D) := c_sdp_bdo_reorder_nof_blocks_max / D;
-    end loop;
-    -- . With 1 destination c_sdp_cep_nof_blocks_per_packet = 4 can fit in a jumbo frame.
-    -- . With D destinations D * c_sdp_cep_nof_blocks_per_packet can fit in a jumbo frame,
-    --   because the number of beamlets per destination reduces by D.
+    -- Determine nof_blocks_per_packet as function of number of destinations
+    -- DN.
+    -- . With 1 destination c_sdp_cep_nof_blocks_per_packet = 4 can fit in a
+    --   jumbo frame.
+    -- . With DN destinations DN * c_sdp_cep_nof_blocks_per_packet can fit in
+    --   a jumbo frame, because the number of beamlets per destination reduces
+    --   by DN.
+    --     DN = 1:16 --> 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64
+    -- . In total there are maximum c_sdp_bdo_reorder_nof_blocks_max = 16
+    --   blocks to distribute over DN destinations.
     -- . Taking smallest yields the actual maximum number of blocks per packet
-    --   per destination, as function of number of destinations D:
-    --     D = 1:16 --> 4, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
-    for D in 1 to c_sdp_bdo_nof_destinations_max loop
-      v_arr(D) := smallest(v_arr(D), D * c_sdp_cep_nof_blocks_per_packet);
+    --   per destination, as function of number of destinations DN:
+    --     DN = 1:16 --> 4, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+      v_arr(DN) := smallest(c_sdp_bdo_reorder_nof_blocks_max, DN * c_sdp_cep_nof_blocks_per_packet);
     end loop;
     return v_arr;
   end func_sdp_bdo_nof_blocks_per_packet_look_up_table;
 
+  function func_sdp_bdo_reorder_nof_blocks_look_up_table return t_natural_arr is
+    constant c_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                       func_sdp_bdo_nof_blocks_per_packet_look_up_table;
+    variable v_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
+  begin
+    -- Determine reorder_nof_blocks as function of number of destinations DN.
+    -- . The number of blocks per destination is given by c_arr, so the number
+    --   of blocks that need to be merged for the reorder is DN * c_arr(DN):
+    --     DN = 1:16 --> 4, 16, 15, 16, 15, 12, 14, 16, 9, 10, 11, 12, 13, 14, 15, 16
+    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+      v_arr(DN) := DN * c_arr(DN);
+    end loop;
+    return v_arr;
+  end func_sdp_bdo_reorder_nof_blocks_look_up_table;
+
+  function func_sdp_bdo_reorder_nof_ch_look_up_table return t_natural_arr is
+    constant c_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                       func_sdp_bdo_reorder_nof_blocks_look_up_table;
+    variable v_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
+  begin
+    -- Determine reorder nof_ch as function of number of destinations DN.
+    -- . The number of blocks to reorder is given by c_arr, so the number
+    --   of ch (channels = words) that need to be reordered is c_sdp_S_sub_bf
+    --   * c_arr(DN):
+    --     DN = 1:16 --> 1952, 7808, 7320, 7808, 7320, 5856, 6832, 7808
+    --                   4392, 4880, 5368, 5856, 6344, 6832, 7320, 7808
+    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+      v_arr(DN) := c_sdp_S_sub_bf * c_arr(DN);
+    end loop;
+    return v_arr;
+  end func_sdp_bdo_reorder_nof_ch_look_up_table;
+
   function func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table return t_natural_arr is
     variable v_first_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
   begin
     -- Determine nof_beamlets_per_block for the first 1:DN-1 destinations, as
-    -- function of number of destinations DN. Use look up table to precalculate
-    -- the values as constants.
+    -- function of number of destinations DN.
     -- . In total there are c_sdp_S_sub_bf = 488 dual polarization beamlets to
     --   distribute over DN destinations, so ceil(488 / DN) yields the number of
     --   blocks for the first 1:DN-1 destinations:
@@ -122,8 +167,7 @@ package body sdp_bdo_pkg is
     variable v_last_arr  : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
   begin
     -- Determine nof_beamlets_per_block for the last destination with index DN,
-    -- as function of number of destinations DN. Use look up table to
-    -- precalculate the values as constants.
+    -- as function of number of destinations DN.
     -- . In total there are c_sdp_S_sub_bf = 488 dual polarization beamlets to
     --   distribute over DN destinations, so 488 - (DN-1) * ceil(488 / DN)
     --   beamlets remain for the last destination:
@@ -146,6 +190,46 @@ package body sdp_bdo_pkg is
     return v_last_arr;
   end func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table;
 
+  function func_sdp_sdo_nof_ch_per_packet_first_destination_look_up_table return t_natural_arr is
+    constant c_nof_blocks_arr   : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                                    func_sdp_bdo_nof_blocks_per_packet_look_up_table;
+    constant c_nof_beamlets_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                                    func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table;
+    variable v_len_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
+  begin
+    -- Determine nof_ch per packet for the first 1:DN-1 destinations, as
+    -- function of number of destinations DN.
+    -- The packet lengths follow from c_nof_blocks_arr * c_nof_beamlets_arr:
+    -- . c_nof_blocks_arr   =    4,   8,  12,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16
+    -- . c_nof_beamlets_arr =  488, 244, 163, 122,  98,  82,  70,  61,  55,  49,  45,  41,  38,  35,  33,  31
+    -- . v_len_arr          = 1952,1952,1956,1952,1568,1312,1120, 976, 880, 784, 720, 656, 608, 560, 528, 496
+    -- . nof octets         = 7808,7808,7824,7808,6272,5248,4480,3904,3520,3136,2880,2624,2432,2240,2112,1984
+    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+      v_len_arr(DN) := c_nof_blocks_arr(DN) * c_nof_beamlets_arr(DN);
+    end loop;
+    return v_len_arr;
+  end func_sdp_sdo_nof_ch_per_packet_first_destination_look_up_table;
+
+  function func_sdp_sdo_nof_ch_per_packet_last_destination_look_up_table return t_natural_arr is
+    constant c_nof_blocks_arr   : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                                    func_sdp_bdo_nof_blocks_per_packet_look_up_table;
+    constant c_nof_beamlets_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
+                                    func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table;
+    variable v_len_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
+  begin
+    -- Determine nof_ch per packet for the first 1:DN-1 destinations, as
+    -- function of number of destinations DN.
+    -- The packet lengths follow from c_nof_blocks_arr * c_nof_beamlets_arr:
+    -- . c_nof_blocks_arr   =    4,   8,  12,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16
+    -- . c_nof_beamlets_arr =  488, 244, 162, 122,  96,  78,  68,  61,  48,  47,  38,  37,  32,  33,  26,  23
+    -- . v_len_arr          = 1952,1952,1944,1952,1536,1248,1088, 976, 768, 752, 608, 592, 512, 528, 416, 368
+    -- . nof octets         = 7808,7808,7776,7808,6144,4992,4352,3904,3072,3008,2432,2368,2048,2112,1664,1472
+    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+      v_len_arr(DN) := c_nof_blocks_arr(DN) * c_nof_beamlets_arr(DN);
+    end loop;
+    return v_len_arr;
+  end func_sdp_sdo_nof_ch_per_packet_last_destination_look_up_table;
+
   function func_sdp_sdo_beamlet_index_per_destination_look_up_matrix return t_natural_matrix is
     constant c_len_arr   : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
                              func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table;
@@ -155,8 +239,7 @@ package body sdp_bdo_pkg is
     variable v_step          : natural;
   begin
     -- Determine beamlet index of first beamlet in packet per destination with
-    -- index DN, as function of number of destinations DN. Use look up table to
-    -- precalculate the values as constants.
+    -- index DN, as function of number of destinations DN.
     -- . Beamlet index for first destination starts at 0
     -- . Beamlet index for the other destinations increments with number of
     --   beamlets per previous destination given by c_len_arr.