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 4db670eeaf24b1653ec13873b2b39d4e73a8ce94..ecf7c188d520a23fcb59490729641fc08fbee70b 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd
@@ -20,7 +20,7 @@
 
 -------------------------------------------------------------------------------
 --
--- Author: R. van der Walle, E. Kooistra (payload error support)
+-- Author: R. van der Walle, E. Kooistra
 -- Purpose:
 -- The beamformer data output (BDO) packetizes the beamlet data into UDP/IP packets.
 -- Description: see references
@@ -47,6 +47,9 @@ use work.sdp_bdo_pkg.all;
 entity sdp_beamformer_output is
   generic (
     g_beamset_id           : natural := 0;
+    -- For g_nof_destinations_max > 1 the transpose is always used
+    -- For g_nof_destinations_max = 1 then the transpose is only used
+    -- when g_use_transpose = true, else the identity is used
     g_use_transpose        : boolean := false;
     g_nof_destinations_max : natural := 1;
     g_sim_force_bsn_error  : boolean := true
@@ -85,24 +88,30 @@ entity sdp_beamformer_output is
 end sdp_beamformer_output;
 
 architecture str of sdp_beamformer_output is
-  constant c_data_w         : natural := c_nof_complex * c_sdp_W_beamlet;  -- 16b
-  constant c_beamlet_index  : natural := g_beamset_id * c_sdp_S_sub_bf;  -- call beamset 'id' and beamlet 'index'
+  constant c_data_w                 : natural := c_nof_complex * c_sdp_W_beamlet;  -- 16b
+  constant c_beamset_beamlet_index  : natural := g_beamset_id * c_sdp_S_sub_bf;  -- call beamset 'id' and beamlet 'index'
 
   -- Use c_fifo_fill = c_fifo_size - margin so that FIFO does not get read out too soon.
   -- The dp_fifo_fill_eop takes care that the FIFO gets read out whenever there is an
   -- eop in the FIFO, so that no payload gets stuck in the FIFO. Thanks to the use of eop
   -- it possible to pass on blocks of variable length.
-  -- Make fifo size large enough for adding header, muxing c_sdp_N_beamsets beamsets and
+  -- Make c_fifo_size large enough for adding header, muxing c_sdp_N_beamsets beamsets and
   -- delaying output to be able to realign snk_in.err field from snk_in.eop to src_out.sop.
-  constant c_fifo_fill      : natural := c_sdp_cep_payload_nof_longwords;  -- 976
-  constant c_fifo_size      : natural := true_log_pow2(c_sdp_cep_payload_nof_longwords) * c_sdp_N_beamsets;  -- 2048
-
+  constant c_nof_words_multi     : natural := largest(func_sdp_bdo_nof_ch_per_packet_first_destinations_look_up_table(g_nof_destinations_max));
+  constant c_nof_longwords_one   : natural := c_sdp_cep_payload_nof_longwords;  -- = 976
+  constant c_nof_longwords_multi : natural := c_nof_words_multi / 2;
+  constant c_fifo_size_one       : natural := true_log_pow2(c_nof_longwords_one) * c_sdp_N_beamsets;  -- = 2048
+  constant c_fifo_size_multi     : natural := true_log_pow2(c_nof_longwords_multi) * c_sdp_N_beamsets;  -- = 2048
+  constant c_fifo_size           : natural := sel_a_b(g_nof_destinations_max = 1, c_fifo_size_one, c_fifo_size_multi);
+  -- Rely on input eop instead of FIFO fill level, therefore set c_fifo_fill =
+  -- g_fifo_size - (g_fifo_af_margin + 2) as explained in dp_fifo_fill_eop
+  constant c_fifo_fill           : natural := c_fifo_size - 6;
 
   -- Multi destination info (mdi)
-  constant c_nof_destinations_w      : natural := ceil_log2(g_nof_destinations_max + 1);
-  constant c_mdi_slv_w               : natural := c_nof_destinations_w * 2 +
-                                                  c_sdp_bdo_reorder_nof_blocks_w +
-                                                  c_sdp_nof_beamlets_per_block_w;
+  constant c_nof_destinations_w  : natural := ceil_log2(g_nof_destinations_max + 1);
+
+  constant c_beamlet_index_per_destination_mat : t_natural_matrix(1 to g_nof_destinations_max, 0 to g_nof_destinations_max - 1) :=
+                                                   func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(g_nof_destinations_max);
 
   -- . field_sel = '0' for DP (dynamic), '1' for MM (fixed or programmable via MM of dp_offload_tx_v3)
   constant c_cep_hdr_field_sel : std_logic_vector(c_sdp_cep_nof_hdr_fields - 1 downto 0) :=
@@ -115,6 +124,7 @@ architecture str of sdp_beamformer_output is
   --   per beamlet and nof_beamlets_per_block dual pol beamlets per time slot.
   signal nof_blocks_per_packet      : natural;
   signal nof_beamlets_per_block     : natural;
+  signal beamlet_index              : natural;
 
   signal snk_in_concat              : t_dp_sosi;
   signal snk_in_concat_data         : std_logic_vector(c_data_w - 1 downto 0);
@@ -126,10 +136,10 @@ architecture str of sdp_beamformer_output is
   signal dp_packet_reorder_word     : t_sdp_dual_pol_beamlet_in_word;
   signal dp_repack_longword_src_out : t_dp_sosi;
   signal dp_repack_longword         : t_sdp_dual_pol_beamlet_in_longword;
-  signal dp_fifo_data_src_out   : t_dp_sosi;
-  signal dp_fifo_data_src_in    : t_dp_siso;
-  signal dp_pipeline_data_src_out        : t_dp_sosi;
-  signal dp_pipeline_data_src_in         : t_dp_siso;
+  signal dp_fifo_data_src_out       : t_dp_sosi;
+  signal dp_fifo_data_src_in        : t_dp_siso;
+  signal dp_pipeline_data_src_out   : t_dp_sosi;
+  signal dp_pipeline_data_src_in    : t_dp_siso;
   signal dp_offload_tx_src_out      : t_dp_sosi;
   signal dp_offload_tx_src_in       : t_dp_siso;
   signal ip_checksum_src_out        : t_dp_sosi;
@@ -137,32 +147,23 @@ architecture str of sdp_beamformer_output is
   signal dp_pipeline_ready_src_out  : t_dp_sosi;
   signal dp_pipeline_ready_src_in   : t_dp_siso;
 
-  signal dbg_bsn_offset     : std_logic;
-  signal payload_err        : std_logic_vector(0 downto 0);
-  signal station_info       : std_logic_vector(15 downto 0) := (others => '0');
+  signal dbg_force_bsn_error  : std_logic := '0';
+  signal payload_err          : std_logic_vector(0 downto 0);
+  signal station_info         : std_logic_vector(15 downto 0) := (others => '0');
 
   -- Multiple destinations info (mdi)
-  signal multi_destinations_info        : t_sdp_bdo_destinations_info;
-  signal mdi_hdr_eth_dst_mac            : std_logic_vector(c_network_eth_mac_addr_w - 1 downto 0);
-  signal mdi_hdr_ip_dst_addr            : std_logic_vector(c_network_ip_addr_w - 1 downto 0);
-  signal mdi_hdr_udp_dst_port           : std_logic_vector(c_network_udp_port_w - 1 downto 0);
-
-  -- . index for destination MAC/IP/UDP
-  signal mdi_destination_index          : natural;
-  signal mdi_destination_index_slv      : std_logic_vector(c_nof_destinations_w - 1 downto 0);
-  -- . header fields
+  signal multi_destinations_info    : t_sdp_bdo_destinations_info;
+  signal s_DN                       : natural := 1;  -- number of destinations
+  signal s_DI                       : natural := 0;  -- destination index
+  signal mdi_eth_dst_mac            : std_logic_vector(c_network_eth_mac_addr_w - 1 downto 0);
+  signal mdi_ip_dst_addr            : std_logic_vector(c_network_ip_addr_w - 1 downto 0);
+  signal mdi_udp_dst_port           : std_logic_vector(c_network_udp_port_w - 1 downto 0);
+
   signal mdi_nof_blocks_per_packet                      : natural;
-  signal mdi_nof_blocks_per_packet_slv                  : std_logic_vector(c_sdp_bdo_reorder_nof_blocks_w - 1 downto 0);
+  signal mdi_nof_beamlets_per_block_first_destinations  : natural;
+  signal mdi_nof_beamlets_per_block_last_destination    : natural;
   signal mdi_nof_beamlets_per_block_per_destination     : natural;
-  signal mdi_nof_beamlets_per_block_per_destination_slv : std_logic_vector(c_sdp_nof_beamlets_per_block_w - 1 downto 0);
   signal mdi_beamlet_index_per_destination              : natural;
-  signal mdi_beamlet_index_per_destination_slv          : std_logic_vector(c_nof_destinations_w - 1 downto 0);
-  signal mdi_fifo_in_slv                                : std_logic_vector(c_mdi_slv_w - 1 downto 0);
-  signal mdi_fifo_out_slv                               : std_logic_vector(c_mdi_slv_w - 1 downto 0);
-  signal mdi_hdr_destination_index                      : natural;
-  signal mdi_hdr_nof_blocks_per_packet                  : natural;
-  signal mdi_hdr_nof_beamlets_per_block_per_destination : natural;
-  signal mdi_hdr_beamlet_index_per_destination          : natural;
 
   -- Default set all data path driven header fields to 0
   signal dp_offload_tx_hdr_fields : std_logic_vector(1023 downto 0) := (others => '0');
@@ -193,7 +194,7 @@ begin
     -- tb_lofar2_unb2c_sdp_station_bf.vhd, this will cause two times payload
     -- errors, one when BSN goes wrong and one when BSN goes ok again.
     if g_sim_force_bsn_error = true then
-      dbg_bsn_offset <= '0';
+      dbg_force_bsn_error <= '0';
       if v_ref_time = 0 ns then
         if in_sosi.sop = '1' then
           -- Use start of input as reference time, rather than e.g. fixed 50 us,
@@ -217,7 +218,7 @@ begin
         --             because the bsn is restored after first block, so the
         --             merged blocks do not have incrementing bsn
         -- . index >= 5 : bsn ok and payload_error = '0'.
-        dbg_bsn_offset <= '1';
+        dbg_force_bsn_error <= '1';
         snk_in_concat.bsn <= INCR_UVEC(in_sosi.bsn, 1);
       end if;
     end if;
@@ -307,71 +308,46 @@ begin
         snk_in   => dp_repack_beamlet_src_out,
         src_out  => dp_packet_reorder_src_out,
 
-        -- Streaming data output info per destination index
-        destination_index                      => mdi_destination_index,
-        nof_blocks_per_packet                  => mdi_nof_blocks_per_packet,
-        nof_beamlets_per_block_per_destination => mdi_nof_beamlets_per_block_per_destination,
-        beamlet_index_per_destination          => mdi_beamlet_index_per_destination
+        -- Streaming data output info dependent on DN = nof_destinations
+        nof_blocks_per_packet                     => mdi_nof_blocks_per_packet,
+        nof_beamlets_per_block_first_destinations => mdi_nof_beamlets_per_block_first_destinations,
+        nof_beamlets_per_block_last_destination   => mdi_nof_beamlets_per_block_last_destination
       );
 
     -----------------------------------------------------------------------------
-    -- FIFO: to align multi destination info
+    -- Look up table values and and output info dependent on DN and DI
     -----------------------------------------------------------------------------
-    mdi_destination_index_slv                      <= to_uvec(mdi_destination_index, c_nof_destinations_w);
-    mdi_nof_blocks_per_packet_slv                  <= to_uvec(mdi_nof_blocks_per_packet, c_sdp_bdo_reorder_nof_blocks_w);
-    mdi_nof_beamlets_per_block_per_destination_slv <= to_uvec(mdi_nof_beamlets_per_block_per_destination, c_sdp_nof_beamlets_per_block_w);
-    mdi_beamlet_index_per_destination_slv          <= to_uvec(mdi_beamlet_index_per_destination, c_nof_destinations_w);
-
-    -- Concat into slv
-    mdi_fifo_in_slv <= func_slv_concat(mdi_destination_index_slv,
-                                       mdi_nof_blocks_per_packet_slv,
-                                       mdi_nof_beamlets_per_block_per_destination_slv,
-                                       mdi_beamlet_index_per_destination_slv);
-
-    -- Similar purpose as u_common_fifo_err, but from input sop to output sop.
-    u_common_fifo_mdi : entity common_lib.common_fifo_sc
-    generic map (
-      g_dat_w => c_mdi_slv_w,
-      g_nof_words => c_sdp_N_beamsets + 2
-    )
-    port map (
-      rst    => dp_rst,
-      clk    => dp_clk,
-      wr_dat => mdi_fifo_in_slv,
-      wr_req => dp_packet_reorder_src_out.sop,
-      rd_dat => mdi_fifo_out_slv,
-      rd_req => dp_fifo_data_src_out.sop
-    );
-
-    -- Extract from slv
-    mdi_hdr_destination_index <= to_uint(func_slv_extract(c_nof_destinations_w,
-                                                          c_sdp_bdo_reorder_nof_blocks_w,
-                                                          c_sdp_nof_beamlets_per_block_w,
-                                                          c_nof_destinations_w,
-                                                          mdi_fifo_out_slv, 0));
-    mdi_hdr_nof_blocks_per_packet <= to_uint(func_slv_extract(c_nof_destinations_w,
-                                                              c_sdp_bdo_reorder_nof_blocks_w,
-                                                              c_sdp_nof_beamlets_per_block_w,
-                                                              c_nof_destinations_w,
-                                                              mdi_fifo_out_slv, 1));
-    mdi_hdr_nof_beamlets_per_block_per_destination <= to_uint(func_slv_extract(c_nof_destinations_w,
-                                                                               c_sdp_bdo_reorder_nof_blocks_w,
-                                                                               c_sdp_nof_beamlets_per_block_w,
-                                                                               c_nof_destinations_w,
-                                                                               mdi_fifo_out_slv, 2));
-    mdi_hdr_beamlet_index_per_destination <= to_uint(func_slv_extract(c_nof_destinations_w,
-                                                                      c_sdp_bdo_reorder_nof_blocks_w,
-                                                                      c_sdp_nof_beamlets_per_block_w,
-                                                                      c_nof_destinations_w,
-                                                                      mdi_fifo_out_slv, 3));
-
-    -- Select destination MAC/IP/UDP, pipeline to easing timing closure
-    p_pipeline : process(dp_clk)
+    -- Register output info dependent on DN and DI to ease timing closure
+    p_reg : process(dp_clk)
+      variable v_DN : natural;  -- number of destinations
+      variable v_DI : natural;  -- destination index
     begin
       if rising_edge(dp_clk) then
-        mdi_hdr_eth_dst_mac  <= multi_destinations_info.eth_destination_mac_arr(mdi_hdr_destination_index);
-        mdi_hdr_ip_dst_addr  <= multi_destinations_info.ip_destination_address_arr(mdi_hdr_destination_index);
-        mdi_hdr_udp_dst_port <= multi_destinations_info.udp_destination_port_arr(mdi_hdr_destination_index);
+        v_DN := multi_destinations_info.nof_destinations_act;
+        v_DI := to_uint(dp_fifo_data_src_out.channel);
+
+        s_DN <= v_DN;
+        s_DI <= v_DI;
+
+        -- Variable values that depend on DN set via MM and/or on current DI
+        -- from dp_packet_unmerged that is passed on via
+        -- dp_fifo_data_src_out.channel.
+        -- . Use s_DN to ease timing closure. Use v_DI to ensure that the mdi
+        --   values are valid at dp_pipeline_data_src_out.sop
+        mdi_eth_dst_mac  <= multi_destinations_info.eth_destination_mac_arr(v_DI);
+        mdi_ip_dst_addr  <= multi_destinations_info.ip_destination_address_arr(v_DI);
+        mdi_udp_dst_port <= multi_destinations_info.udp_destination_port_arr(v_DI);
+
+        -- . Account for beamset offset in beamlet index
+        mdi_beamlet_index_per_destination <= c_beamset_beamlet_index + c_beamlet_index_per_destination_mat(s_DN, v_DI);
+        -- . In total there are S_sub_bf = 488 beamlets for nof_destinations.
+        --   The packet for last destination contains the same number of
+        --   beamlets as the first destinations, or less beamlets.
+        if v_DI < s_DN - 1 then
+          mdi_nof_beamlets_per_block_per_destination <= mdi_nof_beamlets_per_block_first_destinations;
+        else
+          mdi_nof_beamlets_per_block_per_destination <= mdi_nof_beamlets_per_block_last_destination;
+        end if;
       end if;
     end process;
   end generate;
@@ -415,7 +391,9 @@ begin
     g_empty_w        => c_byte_w,
     g_use_empty      => true,
     g_use_bsn        => true,
+    g_use_channel    => true,
     g_bsn_w          => 64,
+    g_channel_w      => c_nof_destinations_w,
     g_use_sync       => true,
     g_fifo_size      => c_fifo_size,
     g_fifo_fill      => c_fifo_fill,
@@ -438,7 +416,7 @@ begin
   u_common_fifo_err : entity common_lib.common_fifo_sc
   generic map (
     g_dat_w => 1,
-    g_nof_words => c_sdp_N_beamsets + 2
+    g_nof_words => g_nof_destinations_max * c_sdp_N_beamsets + 2
   )
   port map (
     rst    => dp_rst,
@@ -523,16 +501,20 @@ begin
   --
   --        DP    dp_bsn
 
-  p_assemble_offload_info : process(mdi_hdr_nof_blocks_per_packet, mdi_hdr_nof_beamlets_per_block_per_destination)
+  p_assemble_offload_info : process(mdi_nof_blocks_per_packet,
+                                    mdi_nof_beamlets_per_block_per_destination,
+                                    mdi_beamlet_index_per_destination)
   begin
     if g_nof_destinations_max = 1 then
       -- Use constant defaults for beamlet data output to one destination.
       nof_blocks_per_packet  <= c_sdp_cep_nof_blocks_per_packet;  -- = 4;
       nof_beamlets_per_block <= c_sdp_S_sub_bf;  -- = 488 dual pol beamlets;
+      beamlet_index          <= c_beamset_beamlet_index;
     else
       -- Use dynamic sizes for beamlet data output to multiple destination.
-      nof_blocks_per_packet  <= mdi_hdr_nof_blocks_per_packet;
-      nof_beamlets_per_block <= mdi_hdr_nof_beamlets_per_block_per_destination;
+      nof_blocks_per_packet  <= mdi_nof_blocks_per_packet;
+      nof_beamlets_per_block <= mdi_nof_beamlets_per_block_per_destination;
+      beamlet_index          <= mdi_beamlet_index_per_destination;
     end if;
   end process;
 
@@ -550,9 +532,9 @@ begin
 
   -- Use MM programmable destination MAC/IP/UDP from dp_offload_tx_v3 for one destination
   -- Use DP programmable destination MAC/IP/UDP from sdp_bdo_destinations_reg for multiple destinations
-  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "eth_dst_mac" ) downto field_lo(c_sdp_cep_hdr_field_arr, "eth_dst_mac" )) <= mdi_hdr_eth_dst_mac;
-  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "ip_dst_addr" ) downto field_lo(c_sdp_cep_hdr_field_arr, "ip_dst_addr" )) <= mdi_hdr_ip_dst_addr;
-  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "udp_dst_port") downto field_lo(c_sdp_cep_hdr_field_arr, "udp_dst_port")) <= mdi_hdr_udp_dst_port;
+  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "eth_dst_mac" ) downto field_lo(c_sdp_cep_hdr_field_arr, "eth_dst_mac" )) <= mdi_eth_dst_mac;
+  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "ip_dst_addr" ) downto field_lo(c_sdp_cep_hdr_field_arr, "ip_dst_addr" )) <= mdi_ip_dst_addr;
+  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "udp_dst_port") downto field_lo(c_sdp_cep_hdr_field_arr, "udp_dst_port")) <= mdi_udp_dst_port;
 
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_observation_id"                     ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_observation_id"                     )) <= sdp_info.observation_id;
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_station_info"                       ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_station_info"                       )) <= station_info;
@@ -565,7 +547,7 @@ begin
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id"                  ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id"                  )) <= gn_id;
 
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale"         ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale"         )) <= beamlet_scale;
-  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index"         ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index"         )) <= TO_UVEC(c_beamlet_index, c_halfword_w);
+  dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index"         ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index"         )) <= TO_UVEC(beamlet_index, c_halfword_w);
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet" )) <= TO_UVEC(nof_blocks_per_packet, c_octet_w);
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block") downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block")) <= TO_UVEC(nof_beamlets_per_block, c_halfword_w);
   dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period"          ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period"          )) <= sdp_info.block_period;