diff --git a/libraries/base/mm/tb/vhdl/tb_mm_bus.vhd b/libraries/base/mm/tb/vhdl/tb_mm_bus.vhd
index de97abd7f027f5b624a3ac5cdbd389f939311511..0f2004618996296869492ed7badca472b843b59a 100644
--- a/libraries/base/mm/tb/vhdl/tb_mm_bus.vhd
+++ b/libraries/base/mm/tb/vhdl/tb_mm_bus.vhd
@@ -27,7 +27,7 @@
 --   . g_nof_slaves >= 1
 --   . g_waitrequest for g_pipeline_miso_wait = FALSE
 --   . g_pipeline_mosi
---   . g_pipeline_miso_rd
+--   . g_pipeline_miso_rdval
 --   . g_pipeline_miso_wait = FALSE
 --   . g_rd_latency >= 1 (using 0 is supported by mm_bus, but not by
 --     the common_ram_r_w in u_slaves)
@@ -54,14 +54,14 @@ USE common_lib.tb_common_mem_pkg.ALL;
 
 ENTITY tb_mm_bus IS
  GENERIC (
-    g_nof_slaves         : POSITIVE := 1;       -- Number of slave memory interfaces on the MM bus array.
-    g_base_offset        : NATURAL := 0;        -- Address of first slave on the MM bus
-    g_width_w            : POSITIVE := 4;       -- Address width of each slave memory in the MM bus array.
-    g_rd_latency         : NATURAL := 1;        -- Read latency of the slaves slave
-    g_waitrequest        : BOOLEAN := TRUE;    -- When TRUE model waitrequest by MM slaves, else fixed '0'
-    g_pipeline_mosi      : BOOLEAN := FALSE;
-    g_pipeline_miso_rd   : BOOLEAN := TRUE;
-    g_pipeline_miso_wait : BOOLEAN := FALSE
+    g_nof_slaves          : POSITIVE := 2;       -- Number of slave memory interfaces on the MM bus array.
+    g_base_offset         : NATURAL := 0;        -- Address of first slave on the MM bus
+    g_width_w             : POSITIVE := 4;       -- Address width of each slave memory in the MM bus array.
+    g_rd_latency          : NATURAL := 1;        -- Read latency of the slaves
+    g_waitrequest         : BOOLEAN := FALSE;     -- When TRUE model waitrequest by MM slaves, else fixed '0'
+    g_pipeline_mosi       : BOOLEAN := FALSE;
+    g_pipeline_miso_rdval : BOOLEAN := FALSE;
+    g_pipeline_miso_wait  : BOOLEAN := FALSE
   );
 END tb_mm_bus;
 
@@ -80,10 +80,13 @@ ARCHITECTURE tb OF tb_mm_bus IS
   CONSTANT c_width_arr       : t_nat_natural_arr := array_init(    g_width_w, g_nof_slaves);                -- Address width per slave
   CONSTANT c_rd_latency_arr  : t_nat_natural_arr := array_init( g_rd_latency, g_nof_slaves);                -- Read latency per slave
   
-  CONSTANT c_pipeline_mosi      : NATURAL := sel_a_b(g_pipeline_mosi, 1, 0);
-  CONSTANT c_pipeline_miso_rd   : NATURAL := sel_a_b(g_pipeline_miso_rd, 1, 0);
-  CONSTANT c_pipeline_miso_wait : NATURAL := sel_a_b(g_pipeline_miso_wait, 1, 0);
-  CONSTANT c_read_latency       : NATURAL := c_pipeline_mosi + g_rd_latency + c_pipeline_miso_rd;
+  CONSTANT c_bus_pipelining      : BOOLEAN := g_pipeline_mosi OR g_pipeline_miso_rdval OR g_pipeline_miso_wait;
+  CONSTANT c_pipeline_mosi       : NATURAL := sel_a_b(g_pipeline_mosi, 1, 0);
+  CONSTANT c_pipeline_miso_rdval : NATURAL := sel_a_b(g_pipeline_miso_rdval, 1, 0);
+  CONSTANT c_pipeline_miso_wait  : NATURAL := sel_a_b(g_pipeline_miso_wait, 1, 0);
+  CONSTANT c_read_latency        : NATURAL := c_pipeline_mosi + g_rd_latency + c_pipeline_miso_rdval;
+  
+  CONSTANT c_adapt_waitrequest   : BOOLEAN := g_waitrequest AND g_pipeline_miso_wait;
 
   CONSTANT c_data_w     : NATURAL := 32;
   CONSTANT c_test_ram   : t_c_mem := (latency  => g_rd_latency,
@@ -95,12 +98,19 @@ ARCHITECTURE tb OF tb_mm_bus IS
   SIGNAL mm_clk   : STD_LOGIC := '1';
   SIGNAL tb_end   : STD_LOGIC;
 
-  SIGNAL master_mosi    : t_mem_mosi := c_mem_mosi_rst;
-  SIGNAL master_miso    : t_mem_miso := c_mem_miso_rst;
-  SIGNAL slave_mosi_arr : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
-  SIGNAL slave_miso_arr : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
-  SIGNAL ram_mosi_arr   : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
-  SIGNAL ram_miso_arr   : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
+  -- MM bus
+  SIGNAL master_mosi      : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL master_miso      : t_mem_miso := c_mem_miso_rst;
+  SIGNAL bus_mosi_arr     : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL bus_miso_arr     : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
+  -- MM slaves with waitrequest latency adapters for ports that have pipelined flow control
+  SIGNAL busw_mosi_arr    : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL busw_miso_arr    : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
+  -- MM slaves with waitrequest for ports that are enabled and NC for ports that are not connected
+  SIGNAL slave_mosi_arr   : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL slave_miso_arr   : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
+  SIGNAL ram_mosi_arr     : t_mem_mosi_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL ram_miso_arr     : t_mem_miso_arr(0 TO g_nof_slaves-1) := (OTHERS=>c_mem_miso_rst);
 
   -- Debug signals for monitoring in simulation Wave window
   SIGNAL dbg_c_base_arr        : t_nat_natural_arr(0 TO g_nof_slaves-1) := c_base_arr;
@@ -109,13 +119,16 @@ ARCHITECTURE tb OF tb_mm_bus IS
   
 BEGIN
 
+  ASSERT NOT(g_nof_slaves=1 AND c_bus_pipelining=TRUE) REPORT "No support for MM bus pipelining with g_nof_slaves=1, because then the mm_bus reduces to wires." SEVERITY FAILURE;
+
   mm_clk <= NOT mm_clk OR tb_end AFTER mm_clk_period/2;
   mm_rst <= '1', '0' AFTER mm_clk_period*5;
 
+  -----------------------------------------------------------------------------
+  -- Write stimuli and readback to verify
+  -----------------------------------------------------------------------------
   p_stimuli : PROCESS
     VARIABLE v_wrdata  : INTEGER;  -- write data
-    VARIABLE v_rddata  : INTEGER;  -- read data
-    VARIABLE v_expdata : INTEGER;  -- expected data
   BEGIN
     tb_end <= '0';
     master_mosi   <= c_mem_mosi_rst;
@@ -126,7 +139,6 @@ BEGIN
     
     -- Repeat twice to have wr all, rd all, wr all, rd all
     v_wrdata := 0;
-    v_expdata := 0;
     FOR vR IN 0 TO c_repeat-1 LOOP
       -- Write the whole memory range
       FOR vI IN 0 TO g_nof_slaves-1 LOOP
@@ -134,21 +146,16 @@ BEGIN
           proc_mem_mm_bus_wr(g_base_offset + vI*c_slave_span + vJ, v_wrdata, mm_clk, master_miso, master_mosi);
           v_wrdata := v_wrdata + 1;
         END LOOP;
-        --proc_common_wait_some_cycles(mm_clk, 10);
+        proc_common_wait_some_cycles(mm_clk, 10);
       END LOOP;
       
       -- Read back the whole range and check if data is as expected
       FOR vI IN 0 TO g_nof_slaves-1 LOOP
         FOR vJ IN 0 TO c_slave_span-1 LOOP
           proc_mem_mm_bus_rd(g_base_offset + vI*c_slave_span + vJ, mm_clk, master_miso, master_mosi);
-          proc_common_wait_some_cycles(mm_clk, c_read_latency);
-          v_rddata := TO_UINT(master_miso.rddata(c_data_w-1 DOWNTO 0));
-          IF v_rddata /= v_expdata THEN
-            REPORT "Error! Readvalue is not as expected" SEVERITY ERROR;
-          END IF;
-          v_expdata := v_expdata + 1;
-          --proc_common_wait_some_cycles(mm_clk, 10);
+          --proc_common_wait_some_cycles(mm_clk, c_read_latency);  -- not needed, see p_verify
         END LOOP;
+        proc_common_wait_some_cycles(mm_clk, 10);
       END LOOP;
     END LOOP;
 
@@ -157,7 +164,91 @@ BEGIN
     WAIT;
   END PROCESS;
 
-  u_slaves : FOR I IN 0 TO g_nof_slaves-1 GENERATE
+  -- Use miso.rdval to know when to verify the rddata, rather than to wait for a fixed c_read_latency after
+  -- the mosi.rd. The advantage is that then rd accesses can be done on every mm_clk, without having to
+  -- wait for the c_read_latency. In case of g_pipeline_mosi = TRUE or g_pipeline_miso_wait = TRUE it is
+  -- even essential to use rdval, because then the latency between rd and rdval can become larger than 
+  -- c_read_latency and even variable (in case of g_waitrequest = TRUE). The disadvantage is that the MM
+  -- slave must support rdval, but that is ensured by mm_slave_enable.
+  p_verify : PROCESS
+    VARIABLE v_expdata : INTEGER := 0;  -- expected data
+    VARIABLE v_rddata  : INTEGER;       -- read data
+  BEGIN
+    WAIT UNTIL rising_edge(mm_clk);
+    IF master_miso.rdval = '1' THEN
+      v_rddata := TO_UINT(master_miso.rddata(c_data_w-1 DOWNTO 0));
+      IF v_rddata /= v_expdata THEN
+        REPORT "Error! Readvalue is not as expected" SEVERITY ERROR;
+      END IF;
+      v_expdata := v_expdata + 1;
+    END IF;
+  END PROCESS;
+
+
+  -----------------------------------------------------------------------------
+  -- The MM bus 
+  -----------------------------------------------------------------------------
+  u_mm_bus: ENTITY work.mm_bus
+  GENERIC MAP (
+    g_nof_slaves          => g_nof_slaves,
+    g_base_arr            => c_base_arr,
+    g_width_arr           => c_width_arr,
+    g_rd_latency_arr      => c_rd_latency_arr,
+    g_pipeline_mosi       => g_pipeline_mosi,
+    g_pipeline_miso_rdval => g_pipeline_miso_rdval,
+    g_pipeline_miso_wait  => g_pipeline_miso_wait
+  )
+  PORT MAP (
+    mm_clk         => mm_clk,
+    master_mosi    => master_mosi,
+    master_miso    => master_miso,
+    slave_mosi_arr => bus_mosi_arr,
+    slave_miso_arr => bus_miso_arr
+  );
+
+  -----------------------------------------------------------------------------
+  -- The MM bus interface with the MM slaves
+  -----------------------------------------------------------------------------
+  gen_slave_ports : FOR I IN 0 TO g_nof_slaves-1 GENERATE
+    -- Adapt the miso.waitrequest for slaves that use mosi flow control if the miso.waitrequest is pipelined in the mm_bus
+    u_slave_latency_adapter : ENTITY work.mm_latency_adapter
+    GENERIC MAP (
+      g_adapt       => c_adapt_waitrequest
+    )
+    PORT MAP (
+      mm_rst        => mm_rst,
+      mm_clk        => mm_clk,
+      -- MM input RL = 1
+      in_mosi       => bus_mosi_arr(I),
+      in_miso       => bus_miso_arr(I),
+      -- MM output RL = 0
+      out_mosi      => busw_mosi_arr(I),
+      out_miso      => busw_miso_arr(I)
+    );
+
+    -- Rewire not connected slaves and slave that do not need mosi flow control via miso.waitrequest
+    u_slave_enable : ENTITY work.mm_slave_enable
+    GENERIC MAP (
+      g_enable       => TRUE,
+      g_waitrequest  => g_waitrequest,
+      g_rd_latency   => c_rd_latency_arr(I)
+    )
+    PORT MAP (
+      mm_rst        => mm_rst,
+      mm_clk        => mm_clk,
+      -- MM input RL = 1
+      in_mosi       => busw_mosi_arr(I),
+      in_miso       => busw_miso_arr(I),
+      -- MM output RL = 0
+      out_mosi      => slave_mosi_arr(I),
+      out_miso      => slave_miso_arr(I)
+    );
+  END GENERATE;
+
+  -----------------------------------------------------------------------------
+  -- Model the MM slaves
+  -----------------------------------------------------------------------------
+  gen_slaves : FOR I IN 0 TO g_nof_slaves-1 GENERATE
     u_waitrequest_model : ENTITY work.mm_waitrequest_model
     GENERIC MAP (
       g_waitrequest => g_waitrequest,
@@ -190,22 +281,4 @@ BEGIN
     );
   END GENERATE;
 
-  d_dut: ENTITY work.mm_bus
-  GENERIC MAP (
-    g_nof_slaves         => g_nof_slaves,
-    g_base_arr           => c_base_arr,
-    g_width_arr          => c_width_arr,
-    g_rd_latency_arr     => c_rd_latency_arr,
-    g_pipeline_mosi      => g_pipeline_mosi,
-    g_pipeline_miso_rd   => g_pipeline_miso_rd,
-    g_pipeline_miso_wait => g_pipeline_miso_wait
-  )
-  PORT MAP (
-    mm_clk         => mm_clk,
-    master_mosi    => master_mosi,
-    master_miso    => master_miso,
-    slave_mosi_arr => slave_mosi_arr,
-    slave_miso_arr => slave_miso_arr
-  );
-
 END tb;