diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
index a3cd031036e188413dfa5fa7bef82621b956b959..465d40a409d52b0ce5e8323c441a30f918a9e770 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd
@@ -191,7 +191,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
   CONSTANT c_tb_clk_period       : TIME := 100 ps; -- use fast tb_clk to speed up M&C
 
   CONSTANT c_nof_block_per_sync  : NATURAL := 16;
-  CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; 
+  CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft;
   CONSTANT c_pps_period          : NATURAL := c_nof_clk_per_sync;
   CONSTANT c_wpfb_sim            : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
   CONSTANT c_stat_data_sz        : NATURAL := c_wpfb_sim.stat_data_sz;  -- = 2
@@ -253,7 +253,6 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
   CONSTANT c_exp_remnant_subband_phase    : REAL := g_sp_remnant_phase + c_subband_phase_offset + c_subband_weight_phase;
   CONSTANT c_exp_remnant_subband_ampl     : REAL := REAL(c_wg_remnant_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain;
 
-  TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL;
   TYPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1);           -- 512
   TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_beamlets_sdp-1);  -- 2*488 = 976
 
@@ -271,43 +270,22 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
   CONSTANT c_bf_remnant_y_weight_re       : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
   CONSTANT c_bf_remnant_y_weight_im       : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
 
-  -- Model the SDP beamformer for one g_sp and S_pn-1 = 11 remnant signal inputs
-  FUNCTION bf_calculate_expected_beamlet(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase,
-                                         rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL) RETURN t_real_arr IS  -- 0:3 = ampl, phase, re, im
-    CONSTANT c_nof_rem : REAL := REAL(c_sdp_S_pn - 1);  -- BF for one g_sp and 11 remnant signal inputs
-    VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im     : REAL;
-    VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL;
-    VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL;
-    VARIABLE v_tuple                                     : t_real_arr(0 TO 3);
-  BEGIN
-    v_sp_ampl   := sp_subband_ampl * sp_bf_gain;
-    v_sp_phase  := sp_subband_phase + sp_bf_phase;
-    v_sp_re     := COMPLEX_RE(v_sp_ampl, v_sp_phase);
-    v_sp_im     := COMPLEX_IM(v_sp_ampl, v_sp_phase);
-    v_rem_ampl  := rem_subband_ampl * rem_bf_gain;
-    v_rem_phase := rem_subband_phase + rem_bf_phase;
-    v_rem_re    := COMPLEX_RE(v_rem_ampl, v_rem_phase);
-    v_rem_im    := COMPLEX_IM(v_rem_ampl, v_rem_phase);
-    v_sum_re    := v_sp_re + c_nof_rem * v_rem_re;  -- BF sum re
-    v_sum_im    := v_sp_im + c_nof_rem * v_rem_im;  -- BF sum im
-    v_sum_ampl  := COMPLEX_RADIUS(v_sum_re, v_sum_im);
-    v_sum_phase := COMPLEX_PHASE(v_sum_re, v_sum_im);
-    v_tuple     := (0 => v_sum_ampl, 1 => v_sum_phase, 2 => v_sum_re, 3 => v_sum_im);
-    RETURN v_tuple;
-  END;
-
+  -- Model the SDP local beamformer for one g_sp and S_pn - 1 remnant signal inputs
   -- . Beamlet internal
-  CONSTANT c_exp_beamlet_x_tuple          : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
+  CONSTANT c_nof_remnant                  : NATURAL := c_sdp_S_pn - 1;
+  CONSTANT c_exp_beamlet_x_tuple          : t_real_arr(0 TO 3) := func_sdp_beamformer(
                                               c_exp_subband_ampl, c_exp_subband_phase, g_bf_x_gain, g_bf_x_phase,
-                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase);
+                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase,
+                                              c_nof_remnant);
   CONSTANT c_exp_beamlet_x_ampl           : REAL := c_exp_beamlet_x_tuple(0);
   CONSTANT c_exp_beamlet_x_phase          : REAL := c_exp_beamlet_x_tuple(1);
   CONSTANT c_exp_beamlet_x_re             : REAL := c_exp_beamlet_x_tuple(2);
   CONSTANT c_exp_beamlet_x_im             : REAL := c_exp_beamlet_x_tuple(3);
 
-  CONSTANT c_exp_beamlet_y_tuple          : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
+  CONSTANT c_exp_beamlet_y_tuple          : t_real_arr(0 TO 3) := func_sdp_beamformer(
                                               c_exp_subband_ampl, c_exp_subband_phase, g_bf_y_gain, g_bf_y_phase,
-                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase);
+                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase,
+                                              c_nof_remnant);
   CONSTANT c_exp_beamlet_y_ampl           : REAL := c_exp_beamlet_y_tuple(0);
   CONSTANT c_exp_beamlet_y_phase          : REAL := c_exp_beamlet_y_tuple(1);
   CONSTANT c_exp_beamlet_y_re             : REAL := c_exp_beamlet_y_tuple(2);
@@ -467,7 +445,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
 
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
-  SIGNAL ext_pps             : STD_LOGIC := '0'; 
+  SIGNAL ext_pps             : STD_LOGIC := '0';
 
   SIGNAL WDI                 : STD_LOGIC;
   SIGNAL INTA                : STD_LOGIC;
@@ -479,7 +457,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
 
   SIGNAL SA_CLK              : STD_LOGIC := '1';
   SIGNAL si_lpbk_0           : STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0);
-   
+
   -- back transceivers
   SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0);
   SIGNAL JESD204B_REFCLK      : STD_LOGIC := '1';
@@ -495,7 +473,7 @@ BEGIN
   ----------------------------------------------------------------------------
   ext_clk <= NOT ext_clk AFTER c_ext_clk_period/2;  -- External clock (200 MHz)
   eth_clk(0) <= NOT eth_clk(0) AFTER c_eth_clk_period/2;  -- Ethernet ref clock (125 MHz)
-  JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2;  -- JESD sample clock (200MHz) 
+  JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2;  -- JESD sample clock (200MHz)
   SA_CLK <= NOT SA_CLK AFTER c_sa_clk_period/2; -- Serial Gigabit IO sa clock (644 MHz)
   dest_rst <= '0' AFTER c_ext_clk_period * 10;
 
@@ -504,7 +482,7 @@ BEGIN
 
   ------------------------------------------------------------------------------
   -- External PPS
-  ------------------------------------------------------------------------------  
+  ------------------------------------------------------------------------------
   proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, gen_pps);
   jesd204b_sysref <= gen_pps;
   ext_pps <= gen_pps;
@@ -544,8 +522,8 @@ BEGIN
     -- Transceiver clocks
     SA_CLK       => SA_CLK,
     -- front transceivers
-    QSFP_1_RX    => si_lpbk_0, 
-    QSFP_1_TX    => si_lpbk_0, 
+    QSFP_1_RX    => si_lpbk_0,
+    QSFP_1_TX    => si_lpbk_0,
 
     -- LEDs
     QSFP_LED     => open,
@@ -553,7 +531,7 @@ BEGIN
     -- back transceivers
     JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA,
     JESD204B_REFCLK      => JESD204B_REFCLK,
-  
+
     -- jesd204b syncronization signals
     JESD204B_SYSREF => jesd204b_sysref,
     JESD204B_SYNC_N => jesd204b_sync_n
@@ -633,7 +611,7 @@ BEGIN
   -- MM slave accesses via file IO
   ------------------------------------------------------------------------------
   tb_clk  <= NOT tb_clk AFTER c_tb_clk_period/2;    -- Testbench MM clock
-  
+
   p_mm_stimuli : PROCESS
     VARIABLE v_bsn                                  : NATURAL;
     VARIABLE v_data_lo, v_data_hi                   : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
@@ -845,7 +823,7 @@ BEGIN
     mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3,                  0, tb_clk);  -- Write high part activates the init BSN
     mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk);  -- nof_block_per_sync
     mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0,       16#00000003#, tb_clk);  -- Enable BS at PPS
-    
+
     -- Release PPS pulser, to get first PPS now and to start BSN source
     WAIT FOR 1 us;
     pps_rst <= '0';
@@ -880,14 +858,14 @@ BEGIN
     mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO  0), tb_clk);
     mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk);
     proc_common_wait_some_cycles(tb_clk, 1);
-    
+
     -- Write scheduler BSN to trigger start of WG at next block
     v_bsn := TO_UINT(current_bsn_wg) + 2;
     ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
     v_bsn := c_bsn_start_wg;
     mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, v_bsn, tb_clk);  -- first write low then high part
     mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1,     0, tb_clk);  -- assume v_bsn < 2**31-1
-    
+
     ----------------------------------------------------------------------------
     -- Read weighted subband selector
     ----------------------------------------------------------------------------
@@ -1041,7 +1019,7 @@ BEGIN
 
     ---------------------------------------------------------------------------
     -- Read subband statistics
-    ---------------------------------------------------------------------------   
+    ---------------------------------------------------------------------------
     -- . the subband statistics are c_stat_data_sz = 2 word power values.
     -- . there are c_sdp_S_pn = 12 signal inputs A, B, C, D, E, F, G, H, I, J, K, L
     -- . there are c_sdp_N_sub = 512 subbands per signal input (SI, = signal path, SP)
@@ -1065,7 +1043,7 @@ BEGIN
           -- low part
           mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_addr, rd_data, tb_clk);
           v_data_lo := rd_data;
-        ELSE      
+        ELSE
           -- high part
           mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_addr, rd_data, tb_clk);
           v_data_hi := rd_data;
@@ -1082,7 +1060,7 @@ BEGIN
     sp_sst <= TO_UREAL(sp_ssts_arr2(c_pol_index)(g_subband));
     proc_common_wait_some_cycles(tb_clk, 1);
     proc_common_wait_some_cycles(ext_clk, 100);  -- delay for ease of view in Wave window
- 
+
     ---------------------------------------------------------------------------
     -- Read beamlet statistics
     ---------------------------------------------------------------------------
@@ -1128,17 +1106,17 @@ BEGIN
     END LOOP;
     proc_common_wait_some_cycles(tb_clk, 1);
     proc_common_wait_some_cycles(ext_clk, 100);  -- delay for ease of view in Wave window
- 
+
     ---------------------------------------------------------------------------
     -- Log WG, subband and beamlet statistics
-    --------------------------------------------------------------------------- 
-  
+    ---------------------------------------------------------------------------
+
     print_str("");
     print_str("WG:");
     print_str(". c_wg_ampl                            = " & int_to_str(c_wg_ampl));
     print_str(". c_exp_sp_power                       = " & real_to_str(c_exp_sp_power, 20, 1));
     print_str(". c_exp_sp_ast                         = " & real_to_str(c_exp_sp_ast, 20, 1));
-  
+
     print_str("");
     print_str("Subband weight:");
     print_str(". sp_subband_weight_gain               = " & real_to_str(sp_subband_weight_gain, 20, 6));
@@ -1230,8 +1208,8 @@ BEGIN
     ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong beamlet Y output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
 
     ---------------------------------------------------------------------------
-    -- End Simulation 
-    ---------------------------------------------------------------------------   
+    -- End Simulation
+    ---------------------------------------------------------------------------
     tb_almost_end <= '1';
     proc_common_wait_some_cycles(ext_clk, 100);  -- delay for ease of view in Wave window
     proc_common_stop_simulation(TRUE, ext_clk, tb_almost_end, tb_end);
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
index 0d6c1fd69a6e2b9fb53dc52eb7b877469314c054..e9acb892849a3dd48c28eccbade6d4261a574e98 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd
@@ -265,7 +265,6 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS
   CONSTANT c_exp_remnant_subband_phase    : REAL := g_sp_remnant_phase + c_subband_phase_offset + c_subband_weight_phase;
   CONSTANT c_exp_remnant_subband_ampl     : REAL := REAL(c_wg_remnant_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain;
 
-  TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL;
   TYPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1);           -- 512
   TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_beamlets_sdp-1);  -- 2*488 = 976
 
@@ -283,43 +282,22 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS
   CONSTANT c_bf_remnant_y_weight_re       : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
   CONSTANT c_bf_remnant_y_weight_im       : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
 
-  -- Model the SDP beamformer for one g_global_sp and g_nof_rn * S_pn - 1 remnant signal inputs
-  FUNCTION bf_calculate_expected_beamlet(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase,
-                                         rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL) RETURN t_real_arr IS  -- 0:3 = ampl, phase, re, im
-    CONSTANT c_nof_rem : REAL := REAL(g_nof_rn * c_sdp_S_pn - 1);  -- BF for one g_global_sp and N_rn * S_PN - 1 remnant signal inputs
-    VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im     : REAL;
-    VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL;
-    VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL;
-    VARIABLE v_tuple                                     : t_real_arr(0 TO 3);
-  BEGIN
-    v_sp_ampl   := sp_subband_ampl * sp_bf_gain;
-    v_sp_phase  := sp_subband_phase + sp_bf_phase;
-    v_sp_re     := COMPLEX_RE(v_sp_ampl, v_sp_phase);
-    v_sp_im     := COMPLEX_IM(v_sp_ampl, v_sp_phase);
-    v_rem_ampl  := rem_subband_ampl * rem_bf_gain;
-    v_rem_phase := rem_subband_phase + rem_bf_phase;
-    v_rem_re    := COMPLEX_RE(v_rem_ampl, v_rem_phase);
-    v_rem_im    := COMPLEX_IM(v_rem_ampl, v_rem_phase);
-    v_sum_re    := v_sp_re + c_nof_rem * v_rem_re;  -- BF sum re
-    v_sum_im    := v_sp_im + c_nof_rem * v_rem_im;  -- BF sum im
-    v_sum_ampl  := COMPLEX_RADIUS(v_sum_re, v_sum_im);
-    v_sum_phase := COMPLEX_PHASE(v_sum_re, v_sum_im);
-    v_tuple     := (0 => v_sum_ampl, 1 => v_sum_phase, 2 => v_sum_re, 3 => v_sum_im);
-    RETURN v_tuple;
-  END;
-
+  -- Model the SDP (remote) beamformer for one g_global_sp and g_nof_rn * S_pn - 1 remnant signal inputs
   -- . Beamlet internal
-  CONSTANT c_exp_beamlet_x_tuple          : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
+  CONSTANT c_nof_remnant                  : NATURAL := g_nof_rn * c_sdp_S_pn - 1;
+  CONSTANT c_exp_beamlet_x_tuple          : t_real_arr(0 TO 3) := func_sdp_beamformer(
                                               c_exp_subband_ampl, c_exp_subband_phase, g_bf_x_gain, g_bf_x_phase,
-                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase);
+                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase,
+                                              c_nof_remnant);
   CONSTANT c_exp_beamlet_x_ampl           : REAL := c_exp_beamlet_x_tuple(0);
   CONSTANT c_exp_beamlet_x_phase          : REAL := c_exp_beamlet_x_tuple(1);
   CONSTANT c_exp_beamlet_x_re             : REAL := c_exp_beamlet_x_tuple(2);
   CONSTANT c_exp_beamlet_x_im             : REAL := c_exp_beamlet_x_tuple(3);
 
-  CONSTANT c_exp_beamlet_y_tuple          : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
+  CONSTANT c_exp_beamlet_y_tuple          : t_real_arr(0 TO 3) := func_sdp_beamformer(
                                               c_exp_subband_ampl, c_exp_subband_phase, g_bf_y_gain, g_bf_y_phase,
-                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase);
+                                              c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase,
+                                              c_nof_remnant);
   CONSTANT c_exp_beamlet_y_ampl           : REAL := c_exp_beamlet_y_tuple(0);
   CONSTANT c_exp_beamlet_y_phase          : REAL := c_exp_beamlet_y_tuple(1);
   CONSTANT c_exp_beamlet_y_re             : REAL := c_exp_beamlet_y_tuple(2);
diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
index b9e41374bc59c4e914a1056b13817ea8b887bbda..c3f0bc73f755b154ea2f7b8e2f2ae37128371df8 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd
@@ -91,6 +91,18 @@ PACKAGE tb_sdp_pkg is
                                       cross_subband_ampl, cross_subband_phase, cross_esub_gain, cross_esub_phase : REAL)
                                       RETURN t_real_arr;  -- 0:3 = ampl, phase, re, im
 
+
+  -----------------------------------------------------------------------------
+  -- Beamformer (BF)
+  -----------------------------------------------------------------------------
+  -- Model the SDP beamformer for one signal input (sp) and nof_rem remnant signal inputs (rem)
+  -- . for local beamformer on one node use nof_rem = S_pn - 1
+  -- . for remote beamformer with nof_rn ring nodes use nof_rem = nof_rn * S_pn - 1
+  FUNCTION func_sdp_beamformer(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase,
+                               rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL;
+                               nof_rem : NATURAL)
+                               RETURN t_real_arr;  -- 0:3 = ampl, phase, re, im
+
 END PACKAGE tb_sdp_pkg;
 
 PACKAGE BODY tb_sdp_pkg IS
@@ -432,4 +444,30 @@ PACKAGE BODY tb_sdp_pkg IS
   END;
 
 
+  FUNCTION func_sdp_beamformer(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase,
+                               rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL;
+                               nof_rem : NATURAL)
+                               RETURN t_real_arr IS  -- 0:3 = ampl, phase, re, im
+    VARIABLE v_nof_rem : REAL := REAL(nof_rem);  -- BF for one sp and nof_rem remnant signal inputs
+    VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im     : REAL;
+    VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL;
+    VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL;
+    VARIABLE v_tuple                                     : t_real_arr(0 TO 3);
+  BEGIN
+    v_sp_ampl   := sp_subband_ampl * sp_bf_gain;
+    v_sp_phase  := sp_subband_phase + sp_bf_phase;
+    v_sp_re     := COMPLEX_RE(v_sp_ampl, v_sp_phase);
+    v_sp_im     := COMPLEX_IM(v_sp_ampl, v_sp_phase);
+    v_rem_ampl  := rem_subband_ampl * rem_bf_gain;
+    v_rem_phase := rem_subband_phase + rem_bf_phase;
+    v_rem_re    := COMPLEX_RE(v_rem_ampl, v_rem_phase);
+    v_rem_im    := COMPLEX_IM(v_rem_ampl, v_rem_phase);
+    v_sum_re    := v_sp_re + v_nof_rem * v_rem_re;  -- BF sum re
+    v_sum_im    := v_sp_im + v_nof_rem * v_rem_im;  -- BF sum im
+    v_sum_ampl  := COMPLEX_RADIUS(v_sum_re, v_sum_im);
+    v_sum_phase := COMPLEX_PHASE(v_sum_re, v_sum_im);
+    v_tuple     := (0 => v_sum_ampl, 1 => v_sum_phase, 2 => v_sum_re, 3 => v_sum_im);
+    RETURN v_tuple;
+  END;
+
 END tb_sdp_pkg;