diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
index 33e2fc12e0ec47c425ba4980fb1c91ce752ca95c..1e2b7c0e3d1ffcade10c18e8c6f67c82986b6cf0 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
@@ -22,15 +22,29 @@
 -- Purpose:
 --   Construct beamformer data output (BDO) payloads for multiple destinations.
 -- Description:
--- * Get N_destinations from sdp_bdo_destinations_reg.
--- * Merge, reorder and unmerge beamlet data for N_destinations > 1 from:
---       (int8) [t] [N_blocks_per_packet][S_sub_bf / N_destinations] [N_pol_bf][N_complex]
+-- * The nof_destinations_max determines how to MM control the beamlet packet
+--   destination(s) MAC/IP/UDP port:
+--   . nof_destinations_max = 1 then use sdp_bdo_one_destination.vhd and
+--     MM program the one destination MAC/IP/UDP port from dp_offload_tx_v3.
+--   . nof_destinations_max > 1 then use sdp_bdo_multiple_destinations.vhd and
+--     MM program the one or more destination MAC/IP/UDP port via
+--     sdp_bdo_destinations_reg.
+-- * Get nof_destinations from sdp_bdo_destinations_reg. The nof_destinations
+--   is MM programmable between 1 and nof_destinations_max.
+-- * The nof_blocks_per_packet is not MM programmable, but based on
+--   nof_destinations to ensure that the packet fits in a jumbo frame or
+--   equal to c_sdp_bdo_reorder_nof_blocks_max to make maximum use of the
+--   available reorder buffer size.
+-- * Merge, reorder and unmerge beamlet data for nof_destinations > 1 from:
+--       (int8) [t] [nof_blocks_per_packet][S_sub_bf / nof_destinations] [N_pol_bf][N_complex]
 --     to:
---       (int8) [t] [S_sub_bf / N_destinations][N_blocks_per_packet] [N_pol_bf][N_complex]
+--       (int8) [t] [S_sub_bf / nof_destinations][nof_blocks_per_packet] [N_pol_bf][N_complex]
 --
 --   . where (int8) [N_pol_bf][N_complex] = c_sdp_W_dual_pol_beamlet = 32b
 --     dual polarization beamlet word
---   . where N_destinations packets together transport the S_sub_bf beamlets.
+--   . where nof_destinations packets together transport the S_sub_bf beamlets.
+-- * Only support transposed beamlet data output, because each destination
+--   must receive all blocks (= time samples) per beamlet.
 -- References:
 -- [1] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations
 --
@@ -48,8 +62,8 @@ library IEEE, common_lib, dp_lib, reorder_lib;
 
 entity sdp_bdo_multiple_destinations is
   generic (
-    g_beamset_id    : natural := 0;
-    g_use_transpose : boolean := false
+    g_nof_destinations_max : natural := 1;
+    g_beamset_id           : natural := 0
   );
   port (
     mm_clk   : in  std_logic;
@@ -71,25 +85,17 @@ end sdp_bdo_multiple_destinations;
 architecture str of sdp_bdo_multiple_destinations is
   constant c_beamlet_index  : natural := g_beamset_id * c_sdp_S_sub_bf;
 
-  -- Reorder c_nof_ch = c_nof_ch_sel = c_nof_ch_in
-  constant c_reorder_nof_blocks_max : natural := c_sdp_bdo_reorder_nof_blocks_max;  -- = 16
-  constant c_reorder_nof_blocks_w   : natural := ceil_log2(c_reorder_nof_blocks_max + 1);
-  constant c_reorder_nof_ch_max     : natural := c_reorder_nof_blocks_max *
-                                                 c_sdp_nof_beamlets_per_block *
-                                                 c_sdp_nof_words_per_beamlet;  -- = 7808
-
-  -- Look up table constants as function of N_destinations
-  constant c_m                                            : natural := c_sdp_bdo_nof_destinations_max;  -- 16
-  constant c_nof_blocks_per_packet_arr                    : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_blocks_per_packet_look_up_table;
-  constant c_reorder_nof_blocks_arr                       : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_blocks_look_up_table;
-  constant c_reorder_nof_ch_arr                           : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_ch_look_up_table;
-  constant c_nof_beamlets_per_block_first_destination_arr : t_natural_arr(1 to c_m) := func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table;
-  constant c_nof_beamlets_per_block_last_destination_arr  : t_natural_arr(1 to c_m) := func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table;
-  constant c_nof_ch_per_packet_first_destination_arr      : t_natural_arr(1 to c_m) := func_sdp_sdo_nof_ch_per_packet_first_destination_look_up_table;
-  constant c_nof_ch_per_packet_last_destination_arr       : t_natural_arr(1 to c_m) := func_sdp_sdo_nof_ch_per_packet_last_destination_look_up_table;
+  -- Look up table constants as function of nof_destinations in range(g_nof_destinations_max)
+  constant c_m                                            : natural := g_nof_destinations_max;
+  constant c_reorder_nof_blocks_arr                       : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_blocks_look_up_table(g_nof_destinations_max);
+  constant c_reorder_nof_ch_arr                           : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_ch_look_up_table(g_nof_destinations_max);
+  constant c_nof_beamlets_per_block_first_destination_arr : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(g_nof_destinations_max);
+  constant c_nof_beamlets_per_block_last_destination_arr  : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(g_nof_destinations_max);
+  constant c_nof_ch_per_packet_first_destination_arr      : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_first_destination_look_up_table(g_nof_destinations_max);
+  constant c_nof_ch_per_packet_last_destination_arr       : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_last_destination_look_up_table(g_nof_destinations_max);
 
   constant c_beamlet_index_per_destination_mat : t_natural_matrix(1 to c_m, 0 to c_m - 1) :=
-                                                   func_sdp_sdo_beamlet_index_per_destination_look_up_matrix;
+                                                   func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(g_nof_destinations_max);
 
   constant c_nof_ch_per_packet_max  : natural := largest(c_nof_ch_per_packet_first_destination_arr);
   constant c_nof_ch_per_packet_w    : natural := ceil_log2(c_nof_ch_per_packet_max + 1);
@@ -97,10 +103,9 @@ architecture str of sdp_bdo_multiple_destinations is
   signal i_destinations_info     : t_sdp_bdo_destinations_info;
 
   -- Dynamic merge, reorder, unmerge packet sizes
-  -- . default use values for N_destinations = 1
-  signal nof_blocks_per_packet                    : natural := c_nof_blocks_per_packet_arr(1);
+  -- . default use values for nof_destinations = 1
   signal reorder_nof_blocks                       : natural := c_reorder_nof_blocks_arr(1);
-  signal reorder_nof_blocks_slv                   : std_logic_vector(c_reorder_nof_blocks_w - 1 downto 0);
+  signal reorder_nof_blocks_slv                   : std_logic_vector(c_sdp_bdo_reorder_nof_blocks_w - 1 downto 0);
   signal reorder_nof_ch                           : natural := c_reorder_nof_ch_arr(1);
   signal nof_beamlets_per_block_first_destination : natural := c_nof_beamlets_per_block_first_destination_arr(1);
   signal nof_beamlets_per_block_last_destination  : natural := c_nof_beamlets_per_block_last_destination_arr(1);
@@ -110,14 +115,12 @@ architecture str of sdp_bdo_multiple_destinations is
   signal nof_ch_per_packet                        : natural;
   signal nof_ch_per_packet_slv                    : std_logic_vector(c_nof_ch_per_packet_w - 1 downto 0);
 
-  -- . default use values for N_destinations = 1 and destination index = 0
+  -- . default use values for nof_destinations = 1 and destination index = 0
   signal beamlet_index_per_destination_bset_0     : natural := c_beamlet_index_per_destination_mat(1, 0);
   signal beamlet_index_per_destination            : natural := c_beamlet_index + c_beamlet_index_per_destination_mat(1, 0);
 
   signal select_copi            : t_mem_copi := c_mem_copi_rst;
   signal select_cipo            : t_mem_cipo := c_mem_cipo_rst;
-  signal r_identity             : t_reorder_identity;
-  signal d_identity             : t_reorder_identity;
   signal r_transpose            : t_reorder_transpose;
   signal d_transpose            : t_reorder_transpose;
 
@@ -137,6 +140,9 @@ begin
   -----------------------------------------------------------------------------
   -- Use dynamic sizes for beamlet data output to multiple destination.
   u_sdp_bdo_destinations_reg : entity work.sdp_bdo_destinations_reg
+    generic map (
+      g_nof_destinations_max => g_nof_destinations_max
+    )
     port map (
       -- Clocks and reset
       mm_clk   => mm_clk,
@@ -162,7 +168,6 @@ begin
   begin
     if rising_edge(dp_clk) then
       v_DN := i_destinations_info.nof_destinations_act;
-      nof_blocks_per_packet                    <= i_destinations_info.nof_blocks_per_packet_act;
       reorder_nof_blocks                       <= c_reorder_nof_blocks_arr(v_DN);
       reorder_nof_ch                           <= c_reorder_nof_ch_arr(v_DN);
       nof_beamlets_per_block_first_destination <= c_nof_beamlets_per_block_first_destination_arr(v_DN);
@@ -181,12 +186,12 @@ begin
   -----------------------------------------------------------------------------
   -- Use slv in port map to avoid vcom-1436: Actual expression (function call
   -- "TO_UVEC") of formal "nof_pkt" is not globally static.
-  reorder_nof_blocks_slv <= to_uvec(reorder_nof_blocks, c_reorder_nof_blocks_w);
+  reorder_nof_blocks_slv <= to_uvec(reorder_nof_blocks, c_sdp_bdo_reorder_nof_blocks_w);
 
   u_dp_packet_merge : entity dp_lib.dp_packet_merge
     generic map(
       g_use_ready     => false,  -- no flow control
-      g_nof_pkt       => c_reorder_nof_blocks_max,
+      g_nof_pkt       => c_sdp_bdo_reorder_nof_blocks_max,
       g_bsn_increment => 1
     )
     port map(
@@ -206,13 +211,15 @@ begin
   -----------------------------------------------------------------------------
   -- reorder_col_select
   -- . See tb_reorder_col_select_all.vhd for how to control col_select_copi /
-  --   cipo with p_reorder_identity or p_reorder_transpose.
+  --   cipo with p_reorder_transpose.
+  -- . Reorder nof_ch_sel = c_nof_ch_in = reorder_nof_ch, because the reorder
+  --   outputs all input.
   -----------------------------------------------------------------------------
   u_reorder_col_select : entity reorder_lib.reorder_col_select
     generic map (
       g_dsp_data_w  => c_sdp_W_dual_pol_beamlet / c_nof_complex,  -- = 32b / 2
-      g_nof_ch_in   => c_reorder_nof_ch_max,
-      g_nof_ch_sel  => c_reorder_nof_ch_max,
+      g_nof_ch_in   => c_sdp_bdo_reorder_nof_ch_max,
+      g_nof_ch_sel  => c_sdp_bdo_reorder_nof_ch_max,
       g_use_complex => false
     )
     port map (
@@ -245,37 +252,19 @@ begin
   p_dp_clk : process(dp_clk)
   begin
     if rising_edge(dp_clk) then
-      r_identity  <= d_identity;
       r_transpose <= d_transpose;
     end if;
   end process;
 
-  -- Pass on beamlet data in original order or in transposed order
-  select_copi <= r_transpose.select_copi when g_use_transpose else r_identity.select_copi;
-
-  p_reorder_identity : process(dp_rst, select_cipo, reorder_nof_ch, r_identity)
-    variable v : t_reorder_identity;
-  begin
-    if select_cipo.waitrequest = '0' then
-      -- Read from reorder_col_select page
-      v := func_reorder_identity(reorder_nof_ch, r_identity);
-    else
-      -- No read, new reorder_col_select page not available yet
-      v := c_reorder_identity_rst;
-    end if;
-    -- Synchronous reset
-    if dp_rst = '1' then
-      v := c_reorder_identity_rst;
-    end if;
-    d_identity <= v;
-  end process;
+  -- Pass on beamlet data in transposed order
+  select_copi <= r_transpose.select_copi;
 
-  p_reorder_transpose : process(dp_rst, select_cipo, nof_blocks_per_packet, nof_beamlets_per_block, r_transpose)
+  p_reorder_transpose : process(dp_rst, select_cipo, reorder_nof_blocks, nof_beamlets_per_block, r_transpose)
     variable v : t_reorder_transpose;
   begin
     if select_cipo.waitrequest = '0' then
       -- Read from reorder_col_select page
-      v := func_reorder_transpose(nof_blocks_per_packet, nof_beamlets_per_block, r_transpose);
+      v := func_reorder_transpose(reorder_nof_blocks, nof_beamlets_per_block, r_transpose);
     else
       -- No read, new reorder_col_select page not available yet
       v := c_reorder_transpose_rst;
@@ -288,14 +277,14 @@ begin
   end process;
 
   -----------------------------------------------------------------------------
-  -- dp_packet_unmerge for N_destinations
+  -- dp_packet_unmerge for nof_destinations
   -----------------------------------------------------------------------------
   nof_ch_per_packet_slv <= to_uvec(nof_ch_per_packet, c_nof_ch_per_packet_w);
 
   u_dp_packet_unmerge : entity dp_lib.dp_packet_unmerge
     generic map (
       g_use_ready     => false,  -- no flow control
-      g_nof_pkt       => c_reorder_nof_blocks_max,
+      g_nof_pkt       => g_nof_destinations_max,
       g_pkt_len       => c_nof_ch_per_packet_max,
       g_bsn_increment => 1
     )
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 098d853c91e7c3dac21ceae9d02aaecf8c7e9680..96dafef61e3282ebfe52d8fec163430eef388f16 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_pkg.vhd
@@ -34,121 +34,134 @@ use work.sdp_pkg.all;
 
 package sdp_bdo_pkg is
   -- Beamlet data output (BDO) for multiple destinations
-  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 + 4;  -- = 52 fields
+  -- Define the maximum number of destination to size the address span of the
+  -- MM register in sdp_bdo_destinations_reg. The actual nof_destinations_max
+  -- <= c_sdp_bdo_mm_nof_destinations_max is defined as revision constant, so
+  -- that it can differ per design revision.
+  constant c_sdp_bdo_mm_nof_destinations_max : natural := 32;
+
+  -- Define the maximum number of blocks (= time samples per beamlet) here as
+  -- a package constant, because it can be the same for all design revisions.
+  -- The actual reorder_nof_blocks_max depends slightly on
+  -- nof_destinations_max, because the number of blocks has to fit in a jumbo
+  -- frame. Therefore func_sdp_bdo_reorder_nof_blocks_look_up_table()
+  -- determines the actual reorder_nof_blocks.
+  -- The nof_blocks_per_packet = reorder_nof_blocks. The beamlet packets will
+  -- have the same nof_blocks_per_packet for each destination, because the
+  -- blocks represent beamlet time samples that have to be kept together per
+  -- destination. The beamlets are distributed to the different destinations
+  -- based on their beamlet index as defined by
+  -- func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table().
+  -- The minimum value is c_sdp_cep_nof_blocks_per_packet = 4 to fill a jumbo
+  -- frame when nof_destinations = 1.
+  -- The maximum value is a balance between having sufficiently large packets
+  -- nof_destinations > 1 and how many block RAM resources are available for
+  -- the reordering. Therefore c_sdp_bdo_reorder_nof_blocks_max = 16 is a
+  -- suitable compromise value.
+  constant c_sdp_bdo_reorder_nof_blocks_max : natural := 16;
+  constant c_sdp_bdo_reorder_nof_blocks_w   : natural := ceil_log2(c_sdp_bdo_reorder_nof_blocks_max + 1);
+  constant c_sdp_bdo_reorder_nof_ch_max     : natural := c_sdp_bdo_reorder_nof_blocks_max *
+                                                         c_sdp_nof_beamlets_per_block *
+                                                         c_sdp_nof_words_per_beamlet;  -- = 7808
+
+  -- 32 * 3 + 4 = 100 fields
+  constant c_sdp_bdo_destinations_info_nof_hdr_fields : natural := c_sdp_bdo_mm_nof_destinations_max * 3 + 4;
 
   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);
-    ip_destination_address_arr  : t_slv_32_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
-    udp_destination_port_arr    : t_slv_16_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
+    eth_destination_mac_arr     : t_slv_48_arr(c_sdp_bdo_mm_nof_destinations_max - 1 downto 0);
+    ip_destination_address_arr  : t_slv_32_arr(c_sdp_bdo_mm_nof_destinations_max - 1 downto 0);
+    udp_destination_port_arr    : t_slv_16_arr(c_sdp_bdo_mm_nof_destinations_max - 1 downto 0);
     nof_destinations            : natural;
     nof_destinations_act        : natural;
     nof_destinations_max        : natural;
-    nof_blocks_per_packet_act   : natural;
+    nof_blocks_per_packet       : natural;
   end record;
 
-  constant t_sdp_bdo_destinations_info_rst : t_sdp_bdo_destinations_info :=
+  constant c_sdp_bdo_destinations_info_rst : t_sdp_bdo_destinations_info :=
     ( (others => (others => '0')),
       (others => (others => '0')),
       (others => (others => '0')),
       1,
       1,
-      c_sdp_bdo_nof_destinations_max,
+      1,
       c_sdp_cep_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_parse_nof_destinations(nof_destinations, c_nof_destinations_max : natural) return natural;
 
   -- Use functions that return look up tables to precalculate the values as
   -- constant arrays
   -- . One ch (channel) = one 32b word = one dual polarization beamlet (Xre, Xim, Yre, Yim)
 
-  -- . 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 arrays for: t_natural_arr(1 to c_nof_destinations_max)
+  function func_sdp_bdo_reorder_nof_blocks_look_up_table(c_nof_destinations_max : natural) return t_natural_arr;
+  function func_sdp_bdo_reorder_nof_ch_look_up_table(c_nof_destinations_max : natural) return t_natural_arr;
+  function func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr;
+  function func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr;
+  function func_sdp_bdo_nof_ch_per_packet_first_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr;
+  function func_sdp_bdo_nof_ch_per_packet_last_destination_look_up_table(c_nof_destinations_max : natural) 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;
+  --   t_natural_matrix(1 to c_nof_destinations_max,      -- N_destinations
+  --                    0 to c_nof_destinations_max - 1)  -- destination index
+  function func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(c_nof_destinations_max : natural) return t_natural_matrix;
 end package sdp_bdo_pkg;
 
 package body sdp_bdo_pkg is
-  function func_sdp_bdo_parse_nof_destinations(nof_destinations : natural) return natural is
+  function func_sdp_bdo_parse_nof_destinations(nof_destinations, c_nof_destinations_max : natural) return natural is
   begin
     -- Parse input nof_destinations value
     if nof_destinations = 0 then
       return 1;
-    elsif nof_destinations > c_sdp_bdo_nof_destinations_max then
-      return c_sdp_bdo_nof_destinations_max;
+    elsif nof_destinations > c_nof_destinations_max then
+      return c_nof_destinations_max;
     else
       return nof_destinations;
     end if;
   end func_sdp_bdo_parse_nof_destinations;
 
-  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);
+  function func_sdp_bdo_reorder_nof_blocks_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    variable v_arr : t_natural_arr(1 to c_nof_destinations_max);
   begin
-    -- 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.
+    -- Determine reorder_nof_blocks = nof_blocks_per_packet as function of
+    -- c_sdp_bdo_reorder_nof_blocks_max and the number of destinations DN.
+    -- . With DN = 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.
+    --   a jumbo frame, because the number of beamlet indices 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 DN:
+    -- . In total there can be maximum c_sdp_bdo_reorder_nof_blocks_max = 16
+    --   blocks per packet, due to the size of the reorder buffer. Taking
+    --   smallest yields the actual number of blocks per packet, 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);
+    for DN in 1 to c_nof_destinations_max loop
+      v_arr(DN) := smallest(DN * c_sdp_cep_nof_blocks_per_packet, c_sdp_bdo_reorder_nof_blocks_max);
     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);
+  function func_sdp_bdo_reorder_nof_ch_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    constant c_arr : t_natural_arr(1 to c_nof_destinations_max) :=
+                       func_sdp_bdo_reorder_nof_blocks_look_up_table(c_nof_destinations_max);
+    variable v_arr : t_natural_arr(1 to c_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
+    -- . The number of blocks to reorder is given by c_arr, so the number of
+    --   ch (channels = words = dual pol, complex beamlets) that need to be
+    --   reordered is c_sdp_S_sub_bf * c_arr(DN):
+    --     DN = 1:16 --> 1952, 3904, 5856, 7808, 7808, 7808, 7808, 7808
+    --                   7808, 7808, 7808, 7808, 7808, 7808, 7808, 7808
+    for DN in 1 to c_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);
+  function func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    variable v_first_arr : t_natural_arr(1 to c_nof_destinations_max);
   begin
     -- Determine nof_beamlets_per_block for the first 1:DN-1 destinations, as
     -- function of number of destinations DN.
@@ -156,19 +169,19 @@ package body sdp_bdo_pkg is
     --   distribute over DN destinations, so ceil(488 / DN) yields the number of
     --   blocks for the first 1:DN-1 destinations:
     --     DN = 1:16 --> v_first_arr = 488, 244, 163, 122, 98, 82, 70, 61, 55, 49, 45, 41, 38, 35, 33, 31
-    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+    for DN in 1 to c_nof_destinations_max loop
       v_first_arr(DN) := ceil_div(c_sdp_S_sub_bf, DN);
     end loop;
     return v_first_arr;
-  end func_sdp_sdo_nof_beamlets_per_block_first_destination_look_up_table;
+  end func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table;
 
-  function func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table return t_natural_arr is
-    variable v_first_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_last_arr  : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
+  function func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    variable v_first_arr : t_natural_arr(1 to c_nof_destinations_max) :=
+                             func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(c_nof_destinations_max);
+    variable v_last_arr  : t_natural_arr(1 to c_nof_destinations_max);
   begin
-    -- Determine nof_beamlets_per_block for the last destination with index DN,
-    -- as function of number of destinations DN.
+    -- Determine remaining nof_beamlets_per_block for the last destination
+    -- with index DN, 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:
@@ -176,27 +189,26 @@ package body sdp_bdo_pkg is
     --     DN = 1:16 --> v_last_arr  = 488, 244, 162, 122, 96, 78, 68, 61, 48, 47, 38, 37, 32, 33, 26, 23
     --
     -- Remark:
-    -- . The v_last_arr may be < v_first_arr - 1, so the last destination may
-    --   contain much less beamlets than the others. In combination with
-    --   dp_packet_unmerge it is not feasible to distribute the beamlets evenly
-    --   over all destinations, using v_hi beamlets for some first destinations
-    --   and v_lo = v_hi - 1 for the remaining destinations. This is because
-    --   dp_packet_unmerge can only unmerge the same packet length for N - 1
-    --   blocks and then unmerge the remaining data in the last block until the
-    --   eop.
-    --
-    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+    -- . The v_last_arr(DN) may be < v_first_arr(DN) - 1, so the last
+    --   destination may contain much less beamlets than the others. In
+    --   combination with dp_packet_unmerge it is not feasible to distribute
+    --   the beamlets evenly over all destinations, using v_hi beamlets for
+    --   some first destinations and v_lo = v_hi - 1 for the remaining
+    --   destinations. This is because dp_packet_unmerge can only unmerge the
+    --   same packet length for N - 1 blocks and then unmerge the remaining
+    --   data in the last block until the eop.
+    for DN in 1 to c_nof_destinations_max loop
       v_last_arr(DN) := c_sdp_S_sub_bf - (DN - 1) * v_first_arr(DN);
     end loop;
     return v_last_arr;
-  end func_sdp_sdo_nof_beamlets_per_block_last_destination_look_up_table;
+  end func_sdp_bdo_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);
+  function func_sdp_bdo_nof_ch_per_packet_first_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    constant c_nof_blocks_arr   : t_natural_arr(1 to c_nof_destinations_max) :=
+                                    func_sdp_bdo_reorder_nof_blocks_look_up_table(c_nof_destinations_max);
+    constant c_nof_beamlets_arr : t_natural_arr(1 to c_nof_destinations_max) :=
+                                    func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(c_nof_destinations_max);
+    variable v_len_arr : t_natural_arr(1 to c_nof_destinations_max);
   begin
     -- Determine nof_ch per packet for the first 1:DN-1 destinations, as
     -- function of number of destinations DN.
@@ -205,18 +217,18 @@ package body sdp_bdo_pkg is
     -- . 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
+    for DN in 1 to c_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;
+  end func_sdp_bdo_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);
+  function func_sdp_bdo_nof_ch_per_packet_last_destination_look_up_table(c_nof_destinations_max : natural) return t_natural_arr is
+    constant c_nof_blocks_arr   : t_natural_arr(1 to c_nof_destinations_max) :=
+                                    func_sdp_bdo_reorder_nof_blocks_look_up_table(c_nof_destinations_max);
+    constant c_nof_beamlets_arr : t_natural_arr(1 to c_nof_destinations_max) :=
+                                    func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(c_nof_destinations_max);
+    variable v_len_arr : t_natural_arr(1 to c_nof_destinations_max);
   begin
     -- Determine nof_ch per packet for the first 1:DN-1 destinations, as
     -- function of number of destinations DN.
@@ -225,22 +237,22 @@ package body sdp_bdo_pkg is
     -- . 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
+    for DN in 1 to c_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;
+  end func_sdp_bdo_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;
-    variable v_index_mat : t_natural_matrix(1 to c_sdp_bdo_nof_destinations_max,
-                                            0 to c_sdp_bdo_nof_destinations_max - 1);
+  function func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(c_nof_destinations_max : natural) return t_natural_matrix is
+    constant c_len_arr   : t_natural_arr(1 to c_nof_destinations_max) :=
+                             func_sdp_bdo_nof_beamlets_per_block_first_destination_look_up_table(c_nof_destinations_max);
+    variable v_index_mat : t_natural_matrix(1 to c_nof_destinations_max,
+                                            0 to c_nof_destinations_max - 1);
     variable v_beamlet_index : natural;
     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.
+    -- index DI, 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.
@@ -280,10 +292,10 @@ package body sdp_bdo_pkg is
     --           v_beamlet_index += v_step
     --       print(lineStr)
     --
-    for DN in 1 to c_sdp_bdo_nof_destinations_max loop
+    for DN in 1 to c_nof_destinations_max loop
       v_beamlet_index := 0;
       v_step := c_len_arr(DN);
-      for DI in 0 to c_sdp_bdo_nof_destinations_max - 1 loop
+      for DI in 0 to c_nof_destinations_max - 1 loop
         if v_beamlet_index < c_sdp_S_sub_bf then
           v_index_mat(DN, DI) := v_beamlet_index;
         end if;
@@ -291,5 +303,5 @@ package body sdp_bdo_pkg is
       end loop;
     end loop;
     return v_index_mat;
-  end func_sdp_sdo_beamlet_index_per_destination_look_up_matrix;
+  end func_sdp_bdo_beamlet_index_per_destination_look_up_matrix;
 end sdp_bdo_pkg;