diff --git a/libraries/dsp/beamformer/hdllib.cfg b/libraries/dsp/beamformer/hdllib.cfg
index 797f20092d3fe00b9e67852e286e608f667e457d..8bfd35cabbd50720afe8714a9c81bf54d9c4e7ad 100644
--- a/libraries/dsp/beamformer/hdllib.cfg
+++ b/libraries/dsp/beamformer/hdllib.cfg
@@ -1,7 +1,7 @@
 hdl_lib_name = beamformer
 hdl_library_clause_name = beamformer_lib
 hdl_lib_uses_synth = common common_mult technology mm dp
-hdl_lib_uses_sim = 
+hdl_lib_uses_sim = diag
 hdl_lib_technology = 
 
 synth_files =
diff --git a/libraries/dsp/beamformer/src/vhdl/beamformer.vhd b/libraries/dsp/beamformer/src/vhdl/beamformer.vhd
index ad850117a3f80eb80ed8dafee92e15693e926c98..64137f5a789665ea121fce22ca0ed072bdc7167e 100644
--- a/libraries/dsp/beamformer/src/vhdl/beamformer.vhd
+++ b/libraries/dsp/beamformer/src/vhdl/beamformer.vhd
@@ -124,7 +124,7 @@ BEGIN
     GENERIC MAP (
       g_technology     => g_technology,
       g_ram            => c_common_ram_crw_crw_ram,
-      g_init_file      => g_weights_file & "_" & NATURAL'IMAGE(i) & ".hex" 
+      g_init_file      => sel_a_b(g_weights_file="UNUSED", "UNUSED", g_weights_file & "_" & NATURAL'IMAGE(i) & ".hex") 
     )
     PORT MAP (
       rst_a     => mm_rst,
diff --git a/libraries/dsp/beamformer/tb/vhdl/tb_beamformer.vhd b/libraries/dsp/beamformer/tb/vhdl/tb_beamformer.vhd
index 96e61120495555a62541f2e987e57ead3637ed55..5d4021508ea610573978115aae47077e6028546a 100644
--- a/libraries/dsp/beamformer/tb/vhdl/tb_beamformer.vhd
+++ b/libraries/dsp/beamformer/tb/vhdl/tb_beamformer.vhd
@@ -22,21 +22,26 @@
 -- Author:
 -- . Daniel van der Schuur
 -- Purpose:
--- . 
+-- .
 -- Description:
--- . 
+-- .
 
-LIBRARY IEEE, common_lib, dp_lib, technology_lib;
+LIBRARY IEEE, common_lib, dp_lib, technology_lib, diag_lib, mm_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
 USE common_lib.common_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
+USE diag_lib.diag_pkg.ALL;
 USE common_lib.tb_common_pkg.ALL;
 USE technology_lib.technology_select_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
+USE mm_lib.mm_file_unb_pkg.ALL;
+USE mm_lib.mm_file_pkg.ALL;
 
 ENTITY tb_beamformer IS
   GENERIC (
+    g_tb_index     : NATURAL := 0;      -- use different index to avoid MM file conflict in multi tb
     g_technology   : NATURAL := c_tech_select_default;
     g_nof_inputs   : NATURAL := 2;
     g_nof_weights  : NATURAL := 32;
@@ -49,55 +54,180 @@ ARCHITECTURE tb OF tb_beamformer IS
   -----------------------------------------------------------------------------
   -- General
   -----------------------------------------------------------------------------
-  CONSTANT c_dp_clk_period : TIME :=  5 ns;
-  CONSTANT c_mm_clk_period : TIME := 25 ns;
+  CONSTANT c_dp_clk_period   : TIME :=  5 ns;
+  CONSTANT c_mm_clk_period   : TIME := 25 ns;
+  CONSTANT c_stimulus_period : TIME := 100 ns;
 
   SIGNAL tb_end            : STD_LOGIC := '0';
   SIGNAL dp_clk            : STD_LOGIC := '1';
   SIGNAL dp_rst            : STD_LOGIC;
   SIGNAL mm_clk            : STD_LOGIC := '1';
   SIGNAL mm_rst            : STD_LOGIC;
+  SIGNAL OK                : STD_LOGIC := '1';
+  SIGNAL verify_mm_en      : STD_LOGIC := '1';
+  SIGNAL verify_input_en   : STD_LOGIC := '0';
+  SIGNAL verify_sum_en     : STD_LOGIC := '0';
+
+  -----------------------------------------------------------------------------
+  -- Block generator
+  -----------------------------------------------------------------------------
+  CONSTANT c_bg_block_size      : NATURAL := g_nof_weights;
+  CONSTANT c_bg_gapsize         : NATURAL := c_bg_block_size;
+  CONSTANT c_bg_blocks_per_sync : NATURAL := 10; --not used
+  CONSTANT c_bg_ctrl            : t_diag_block_gen := ('1',                      -- enable
+                                                       '0',                      -- enable_sync
+                                                      TO_UVEC(     c_bg_block_size, c_diag_bg_samples_per_packet_w),
+                                                      TO_UVEC(c_bg_blocks_per_sync, c_diag_bg_blocks_per_sync_w),
+                                                      TO_UVEC(        c_bg_gapsize, c_diag_bg_gapsize_w),
+                                                      TO_UVEC(                   0, c_diag_bg_mem_low_adrs_w),
+                                                      TO_UVEC(   c_bg_block_size-1, c_diag_bg_mem_high_adrs_w),
+                                                      TO_UVEC(                   0, c_diag_bg_bsn_init_w));
+
+  -- MM
+  CONSTANT c_unb_nr                 : NATURAL := 0;
+  CONSTANT c_node_nr                : NATURAL := 0;   -- choose node 0 is FN 0
+  CONSTANT c_mm_file_ram_beamformer : STRING  := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_BEAMFORMER_" & int_to_str(g_tb_index);
+
+  SIGNAL block_gen_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0);
 
   -----------------------------------------------------------------------------
   -- beamformer
   -----------------------------------------------------------------------------
+  SIGNAL ram_beamformer_mosi : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL ram_beamformer_miso : t_mem_miso := c_mem_miso_rst;
+
+
   SIGNAL beamformer_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
   SIGNAL beamformer_src_out    : t_dp_sosi;
 
   SIGNAL beamformer_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0);
 
+  SIGNAL rd_data                : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+
 BEGIN
 
   -----------------------------------------------------------------------------
   -- Clocks and reset
-  -----------------------------------------------------------------------------
+  -------------------------------------------------------------------------------
   dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
   dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
 
   mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
   mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
 
+
+  mm_stimulus: PROCESS
+  BEGIN
+    IF verify_mm_en = '1' THEN
+      
+      proc_common_wait_until_low(mm_clk, mm_rst);
+      proc_common_wait_until_low(dp_clk, dp_rst);
+      proc_common_wait_some_cycles(dp_clk, 10);
+
+      FOR I IN 0 TO g_nof_inputs-1 LOOP
+        FOR J IN 0 TO g_nof_weights-1 LOOP
+          -- write MM page
+          mmf_mm_bus_wr(c_mm_file_ram_beamformer, I*g_nof_weights+J, J, mm_clk);
+        END LOOP;
+      END LOOP;
+      
+      FOR I IN 0 TO g_nof_inputs-1 LOOP
+        FOR J IN 0 TO g_nof_weights-1 LOOP
+          -- read back MM page
+          mmf_mm_bus_rd(c_mm_file_ram_beamformer, I*g_nof_weights+J, rd_data, mm_clk);
+          IF UNSIGNED(rd_data) /= J THEN
+              OK <= '0';
+          END IF;
+          ASSERT TO_UINT(rd_data)=J 
+            REPORT "MM Wrong weight, expected=" & int_to_str(J) & ", readback=" & int_to_str(INTEGER(TO_UINT(rd_data))) 
+            SEVERITY ERROR;
+          
+        END LOOP;
+      END LOOP;
+      verify_sum_en <= '1';
+    END IF;
+    verify_mm_en <= '0';  
+  END PROCESS;
+
+
+  stimulus: PROCESS
+  BEGIN
+    proc_common_wait_until_high(dp_clk, verify_sum_en);
+    -- loop over all weights adresses
+    FOR i IN 0 TO g_nof_weights-1 LOOP
+        beamformer_weight_addr <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, ceil_log2(g_nof_weights)));
+        WAIT FOR c_stimulus_period;
+        proc_common_wait_until_high(dp_clk, beamformer_src_out.valid);
+        IF UNSIGNED(beamformer_weight_addr)*g_nof_inputs /= UNSIGNED(beamformer_src_out.re) THEN
+            OK <= '0';
+        END IF;
+        ASSERT UNSIGNED(beamformer_weight_addr)*g_nof_inputs = UNSIGNED(beamformer_src_out.re) 
+          REPORT "Beamformer wrong weights" &
+                 ", expected=" & int_to_str(TO_SINT(beamformer_weight_addr)*g_nof_inputs) & 
+                 ", readback=" & int_to_str(TO_SINT(beamformer_src_out.re))
+          SEVERITY ERROR;
+    END LOOP;
+    tb_end <= '1';  -- end test
+    WAIT;
+  END PROCESS;
+
+
+
+  -----------------------------------------------------------------------------
+  -- Block generator:
+  -- . X pol = complex( 1, 1)
+  -- . Y pol = complex(-1,-1)
+  -----------------------------------------------------------------------------
+  u_mms_diag_block_gen : ENTITY diag_lib.mms_diag_block_gen
+  GENERIC MAP (
+    g_nof_streams        => 1,
+    g_buf_dat_w          => g_data_w,
+    g_buf_addr_w         => ceil_log2(TO_UINT(c_bg_ctrl.samples_per_packet)),
+    g_file_name_prefix   => "hex/mms_diag_block_gen",
+    g_diag_block_gen_rst => c_bg_ctrl
+  )
+  PORT MAP (
+    mm_clk           => mm_clk,
+    mm_rst           => mm_rst,
+
+    dp_clk           => dp_clk,
+    dp_rst           => dp_rst,
+
+    out_sosi_arr     => block_gen_src_out_arr
+  );
+
   -----------------------------------------------------------------------------
   -- beamformer for each TAB
-  -----------------------------------------------------------------------------   
+  -----------------------------------------------------------------------------
+  u_mm_file_ram_beamformer : ENTITY mm_lib.mm_file GENERIC MAP(c_mm_file_ram_beamformer) PORT MAP(mm_rst, mm_clk, ram_beamformer_mosi, ram_beamformer_miso);
+
+  gen_arts_tab_beamformer_snk_in_arr : FOR i IN 0 TO g_nof_inputs-1 GENERATE
+    beamformer_snk_in_arr(i) <= block_gen_src_out_arr(0); -- Copy the block gen stream 'g_nof_inputs' times
+  END GENERATE;
+
   u_beamformer : ENTITY work.beamformer
   GENERIC MAP (
+
     g_technology   => g_technology,
     g_nof_inputs   => g_nof_inputs,
     g_nof_weights  => g_nof_weights,
-    g_data_w       => g_data_w
+    g_data_w       => g_data_w,
+    g_weights_file => "UNUSED"
   )
   PORT MAP (
     dp_clk      => dp_clk,
     dp_rst      => dp_rst,
-
     mm_clk      => mm_clk,
     mm_rst      => mm_rst,
 
+    ram_mosi    => ram_beamformer_mosi,
+    ram_miso    => ram_beamformer_miso,
+
     weight_addr => beamformer_weight_addr,
 
     snk_in_arr  => beamformer_snk_in_arr,
     src_out     => beamformer_src_out
   );
 
+
 END tb;