diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg
index f62ff6389abc265b1fc5b55173359a581f483e52..d5624d00cb139209e894f47c91dbaab9f3d4f275 100644
--- a/libraries/base/common/hdllib.cfg
+++ b/libraries/base/common/hdllib.cfg
@@ -164,6 +164,7 @@ test_bench_files =
     tb/vhdl/tb_common_init.vhd
     tb/vhdl/tb_common_int2float.vhd
     tb/vhdl/tb_common_led_controller.vhd
+    tb/vhdl/tb_common_mem_master_mux.vhd
     tb/vhdl/tb_common_mem_bus.vhd
     tb/vhdl/tb_common_mem_mux.vhd
     tb/vhdl/tb_common_multiplexer.vhd
@@ -208,6 +209,7 @@ test_bench_files =
 
 regression_test_vhdl = 
     tb/vhdl/tb_common_fifo_rd.vhd
+    tb/vhdl/tb_common_mem_master_mux.vhd
     tb/vhdl/tb_common_mem_mux.vhd
     tb/vhdl/tb_common_paged_ram_crw_crw.vhd
     tb/vhdl/tb_common_pulser_us_ms_s.vhd
diff --git a/libraries/base/common/src/vhdl/common_mem_master_mux.vhd b/libraries/base/common/src/vhdl/common_mem_master_mux.vhd
index a896efd8a1b3d430377d320045bee001f6848f08..82e5fff65c07f3f870fe92a2869ff3ae607e4517 100644
--- a/libraries/base/common/src/vhdl/common_mem_master_mux.vhd
+++ b/libraries/base/common/src/vhdl/common_mem_master_mux.vhd
@@ -24,16 +24,20 @@
 -- Purpose: Multiplex an array of MM master interfaces to a single MM master
 --          interface
 -- Description:
---   This common_mem_master_mux is a simple multiplexer and does not provide
---   arbitration between the masters in the array. Therefore the precondition
---   is that the application takes care that the MM accesses of the multiple
---   masters in the array do not overlap.
---   For read accesses the g_rd_latency defines how much idle time there needs
---   to be after the last read access by one master and a next MM access by
---   another master.
+--   This common_mem_master_mux is a simple multiplexer that allows multiple
+--   masters to access the same MM port. The common_mem_master_mux does not
+--   provide arbitration between the masters in the array. Therefore the
+--   precondition is that the external application takes care that the MM
+--   accesses of the multiple masters in the array do not overlap in time.
+--
+--   Write accesses from multiple masters occur may without gaps. After a read
+--   access from one master the read latency must first be accounted for by
+--   the application introducing a gap, before a read access by another master
+--   can be multiplexed.
+--
 --   The common_mem_master_mux operates combinatorially, so it introduces no
---   extra latency. The mm_clk is needed to time the g_rd_latency of the
---   external mux_miso, to ensure that the read data.is passed on to the
+--   extra latency. The mm_clk is needed to hold the index of the master that
+--   is currently active, to ensure that the read data.is passed on to the
 --   master that did the rd access.
 -- Remarks:
 -- . The mux_miso.waitrequest is not supported.
@@ -49,7 +53,7 @@ USE common_lib.common_mem_pkg.ALL;
 ENTITY common_mem_master_mux IS
   GENERIC (
     g_nof_masters     : POSITIVE;  -- Number of MM masters
-    g_rd_latency      : NATURAL    -- Maximum read latency
+    g_rd_latency_min  : NATURAL    -- Minimum read latency
   );
   PORT (
     mm_clk          : IN  STD_LOGIC;
@@ -62,8 +66,8 @@ END common_mem_master_mux;
 
 ARCHITECTURE rtl OF common_mem_master_mux IS
   
-  SIGNAL index_reg           : NATURAL := 0;
-  SIGNAL index_pipeline      : t_natural_arr(0 TO g_rd_latency) := (OTHERS=>0);
+  SIGNAL index                : NATURAL := 0;
+  SIGNAL index_hold           : NATURAL := 0;
 
 BEGIN
 
@@ -75,41 +79,50 @@ BEGIN
   gen_multiple : IF g_nof_masters>1 GENERATE 
 
     -- Detect which master in the array is active
-    p_index : PROCESS(master_mosi_arr, index_reg)
+    -- The pre condition is that the input masters will only start an access
+    -- when the mux master is free. For a rd access this means that the
+    -- read latency of the rdval has passed. Therefor it is not necessary
+    -- that this common_mem_master_mux maintains an index pipeline
+    -- from rd until expected rdval. Instead it is sufficient to hold the
+    -- index of the active master, until the next master does an access. For
+    -- rd access hold the last active index to ensure that rdval will be
+    -- directed to the master that orginated the rd access. For wr access
+    -- hold last active index instead of reset to '0' to ease observation of
+    -- the index value in wave window.
+    p_index : PROCESS(master_mosi_arr, index_hold)
     BEGIN
-      -- default hold last active index instead of reset to 0 to ease observing index in wave window
-      index_pipeline(0) <= index_reg;
+      index <= index_hold;    -- default hold index of last active master
       FOR I IN 0 TO g_nof_masters-1 LOOP
         IF master_mosi_arr(I).wr='1' OR master_mosi_arr(I).rd='1' THEN
-          index_pipeline(0) <= I;    -- index of active master
+          index <= I;    -- index of active master
           EXIT;
         END IF;
       END LOOP;
     END PROCESS;
     
-    index_reg <= index_pipeline(0) WHEN rising_edge(mm_clk);    -- hold index
-    index_pipeline(1 TO g_rd_latency) <= index_pipeline(0 TO g_rd_latency-1) WHEN rising_edge(mm_clk);
+    index_hold <= index WHEN rising_edge(mm_clk);    -- hold index of last active master
     
         
-    -- Master access, can be write or read
-    p_mosi : PROCESS(master_mosi_arr)
-    BEGIN
-      mux_mosi <= c_mem_mosi_rst;   -- default clear, to avoid latches
-      FOR I IN 0 TO g_nof_masters-1 LOOP
-        IF I = index_pipeline(0) THEN   -- pass on selected master
-          mux_mosi <= master_mosi_arr(I);
-        END IF;
-      END LOOP;
-    END PROCESS;
+    -- Multiplex master access, can be write or read
+    mux_mosi <= master_mosi_arr(index);
     
-    -- Slave response to read access after g_rd_latency mm_clk cycles
-    p_miso : PROCESS(mux_miso, index_pipeline)
+    -- Multiplex slave read response
+    p_miso : PROCESS(mux_miso, index)
     BEGIN
       master_miso_arr <= (OTHERS=>mux_miso);  -- default assign to all, to avoid latches
       FOR I IN 0 TO g_nof_masters-1 LOOP
         master_miso_arr(I).rdval <= '0';
-        IF I = index_pipeline(g_rd_latency) THEN  -- check index for read response
-          master_miso_arr(I).rdval <= mux_miso.rdval;
+        -- If the minimal read latency is g_rd_latency_min = 0, then the mux
+        -- has to use the combinatorial index, else it use the registered
+        -- index, to ease achieving timing closure.
+        IF g_rd_latency_min=0 THEN
+          IF I = index THEN
+            master_miso_arr(I).rdval <= mux_miso.rdval;
+          END IF;
+        ELSE
+          IF I = index_hold THEN
+            master_miso_arr(I).rdval <= mux_miso.rdval;
+          END IF;
         END IF;
       END LOOP;
     END PROCESS;
diff --git a/libraries/base/common/tb/vhdl/tb_common_mem_master_mux.vhd b/libraries/base/common/tb/vhdl/tb_common_mem_master_mux.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..01ae0fb1529c6fcee7ffc3fae6882183b5143b60
--- /dev/null
+++ b/libraries/base/common/tb/vhdl/tb_common_mem_master_mux.vhd
@@ -0,0 +1,190 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: E. Kooistra
+-- Purpose: Test bench for common_mem_master_mux.vhd and also common_mem_bus
+-- Description:
+--   The test bench uses common_mem_master_mux to access a RAM via an array of
+--   masters. The array of masters is modelled using a stimuli from a single
+--   master that get demultiplexed to the array of masters using
+--   common_mem_bus. The address space of the RAM is defined by the g_base_arr
+--   and g_width_arr that define the common_mem_bus. Therefore this test bench
+--   implicitely also verifies common_mem_bus.vhd.
+--   
+--               stimuli            master              mux
+--               mosi               mosi_arr            mosi
+--   p_stimuli ----------> common -----------> common --------> RAM
+--                         mem                 mem
+--                         bus                 master
+--                                             mux
+--
+-- Remark:
+--   In an application it is typical to use common_mem_master_mux to connect
+--   mulitple masters to multiple slabes via a common_mem_bus MM bus.
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+USE work.common_pkg.ALL;
+USE work.common_mem_pkg.ALL;
+USE work.tb_common_pkg.ALL;
+USE work.tb_common_mem_pkg.ALL;
+
+ENTITY tb_common_mem_master_mux IS
+ GENERIC (
+    g_nof_masters    : POSITIVE := 2;   -- Number of master memory interfaces on the MM bus array.
+    g_base_arr       : t_nat_natural_arr := (0, 256);  -- Address base per slave port of common_mem_bus
+    g_width_arr      : t_nat_natural_arr := (4,   8)   -- Address width per slave port of common_mem_bus
+  );
+END tb_common_mem_master_mux;
+
+-- Usage:
+--   > as 10
+--   > run -all
+
+
+ARCHITECTURE tb OF tb_common_mem_master_mux IS
+
+  CONSTANT mm_clk_period   : TIME    := 10 ns;
+  
+  CONSTANT c_rd_latency      : NATURAL := 1; 
+  CONSTANT c_rd_latency_arr  : t_nat_natural_arr := array_init(c_rd_latency, g_nof_masters);
+  CONSTANT c_rd_latency_min  : NATURAL := smallest(c_rd_latency_arr);
+  CONSTANT c_addr_w          : NATURAL := largest(ceil_log2(largest(g_base_arr)), largest(g_width_arr)) + 1;
+  CONSTANT c_data_w          : NATURAL := 32;
+  CONSTANT c_test_ram        : t_c_mem := (latency  => c_rd_latency,
+                                           adr_w    => c_addr_w,
+                                           dat_w    => c_data_w,
+                                           nof_dat  => 2**c_addr_w,
+                                           init_sl  => '0');
+  SIGNAL mm_rst           : STD_LOGIC;
+  SIGNAL mm_clk           : STD_LOGIC := '1';
+  SIGNAL tb_end           : STD_LOGIC;
+
+  SIGNAL stimuli_mosi     : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL stimuli_miso     : t_mem_miso := c_mem_miso_rst;
+  SIGNAL master_mosi_arr  : t_mem_mosi_arr(0 TO g_nof_masters-1) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL master_miso_arr  : t_mem_miso_arr(0 TO g_nof_masters-1) := (OTHERS=>c_mem_miso_rst);
+  SIGNAL mux_mosi         : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL mux_miso         : t_mem_miso := c_mem_miso_rst;
+
+BEGIN
+
+  mm_clk <= NOT mm_clk OR tb_end AFTER mm_clk_period/2;
+  mm_rst <= '1', '0' AFTER mm_clk_period*5;
+
+  p_stimuli : PROCESS
+    VARIABLE v_base : NATURAL;
+    VARIABLE v_span : NATURAL;
+    VARIABLE v_data : INTEGER;
+  BEGIN
+    tb_end <= '0';
+    stimuli_mosi <= c_mem_mosi_rst;
+    
+    -- Wait until reset is released
+    proc_common_wait_until_low(mm_clk, mm_rst);
+    proc_common_wait_some_cycles(mm_clk, 10);
+    
+    -- Repeat twice to have wr all, rd all, wr all, rd all
+    FOR R IN 0 TO 1 LOOP
+      -- Write the whole memory range
+      FOR I IN 0 TO g_nof_masters-1 LOOP
+        v_base := g_base_arr(I);
+        v_span := 2**g_width_arr(I);
+        FOR J IN 0 TO v_span-1 LOOP
+          proc_mem_mm_bus_wr(v_base + J, R+J, mm_clk, stimuli_mosi);
+        END LOOP;
+      END LOOP;
+      
+      -- Read back the whole range in reverse order and check if data is as expected
+      FOR I IN g_nof_masters-1 DOWNTO 0 LOOP
+        v_base := g_base_arr(I);
+        v_span := 2**g_width_arr(I);
+        FOR J IN v_span-1 DOWNTO 0 LOOP
+          proc_mem_mm_bus_rd(v_base + J, mm_clk, stimuli_mosi);
+          proc_common_wait_some_cycles(mm_clk, c_rd_latency);
+          v_data := TO_UINT(stimuli_miso.rddata(31 DOWNTO 0));
+          IF v_data /= R+J THEN
+            REPORT "Error! Readvalue is not as expected" SEVERITY ERROR;
+          END IF;
+        END LOOP;
+      END LOOP;
+    END LOOP;
+
+    proc_common_wait_some_cycles(mm_clk, 10);
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;
+
+  -- Model multiple masters using stimuli from a single master
+  u_masters : ENTITY work.common_mem_bus
+  GENERIC MAP (
+    g_nof_slaves      => g_nof_masters,
+    g_base_arr        => g_base_arr,
+    g_width_arr       => g_width_arr,
+    g_rd_latency_arr  => c_rd_latency_arr,
+    g_pipeline_mosi   => FALSE,
+    g_pipeline_miso   => FALSE
+  )
+  PORT MAP (
+    mm_clk         => mm_clk,
+    master_mosi    => stimuli_mosi,
+    master_miso    => stimuli_miso,
+    slave_mosi_arr => master_mosi_arr,
+    slave_miso_arr => master_miso_arr
+  );
+  
+  -- DUT = device under test
+  u_dut: ENTITY work.common_mem_master_mux
+  GENERIC MAP (
+    g_nof_masters     => g_nof_masters,
+    g_rd_latency_min  => c_rd_latency_min
+  )
+  PORT MAP (
+    mm_clk          => mm_clk,
+    master_mosi_arr => master_mosi_arr,
+    master_miso_arr => master_miso_arr,
+    mux_mosi        => mux_mosi,
+    mux_miso        => mux_miso
+  );
+
+  -- Model master access to MM bus with multiple slaves using a single RAM
+  u_ram : ENTITY work.common_ram_r_w
+  GENERIC MAP (
+    g_ram       => c_test_ram,
+    g_init_file => "UNUSED"
+  )
+  PORT MAP (
+    rst       => mm_rst,
+    clk       => mm_clk,
+    wr_en     => mux_mosi.wr,
+    wr_adr    => mux_mosi.address(c_addr_w-1 DOWNTO 0),
+    wr_dat    => mux_mosi.wrdata(c_data_w-1 DOWNTO 0),
+    rd_en     => mux_mosi.rd,
+    rd_adr    => mux_mosi.address(c_addr_w-1 DOWNTO 0),
+    rd_dat    => mux_miso.rddata(c_data_w-1 DOWNTO 0),
+    rd_val    => mux_miso.rdval
+  );
+
+
+END tb;