diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg
index 7b6228f14dc373da0cf3cc5a437e9fafbfde32fe..f62ff6389abc265b1fc5b55173359a581f483e52 100644
--- a/libraries/base/common/hdllib.cfg
+++ b/libraries/base/common/hdllib.cfg
@@ -109,6 +109,7 @@ synth_files =
     src/vhdl/common_fifo_rd.vhd
     src/vhdl/common_blockreg.vhd
     src/vhdl/common_fifo_dc_lock_control.vhd
+    src/vhdl/common_mem_master_mux.vhd
     src/vhdl/common_mem_bus.vhd
     src/vhdl/common_mem_mux.vhd
     src/vhdl/common_mem_demux.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
new file mode 100644
index 0000000000000000000000000000000000000000..a896efd8a1b3d430377d320045bee001f6848f08
--- /dev/null
+++ b/libraries/base/common/src/vhdl/common_mem_master_mux.vhd
@@ -0,0 +1,119 @@
+-------------------------------------------------------------------------------
+--
+-- 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: 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.
+--   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
+--   master that did the rd access.
+-- Remarks:
+-- . The mux_miso.waitrequest is not supported.
+--
+-------------------------------------------------------------------------------
+
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+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
+  );
+  PORT (
+    mm_clk          : IN  STD_LOGIC;
+    master_mosi_arr : IN  t_mem_mosi_arr(0 TO g_nof_masters-1) := (OTHERS=>c_mem_mosi_rst);
+    master_miso_arr : OUT t_mem_miso_arr(0 TO g_nof_masters-1) := (OTHERS=>c_mem_miso_rst);
+    mux_mosi        : OUT t_mem_mosi; 
+    mux_miso        : IN  t_mem_miso
+  );
+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);
+
+BEGIN
+
+  gen_single : IF g_nof_masters=1 GENERATE 
+    mux_mosi           <= master_mosi_arr(0);
+    master_miso_arr(0) <= mux_miso;
+  END GENERATE;
+    
+  gen_multiple : IF g_nof_masters>1 GENERATE 
+
+    -- Detect which master in the array is active
+    p_index : PROCESS(master_mosi_arr, index_reg)
+    BEGIN
+      -- default hold last active index instead of reset to 0 to ease observing index in wave window
+      index_pipeline(0) <= index_reg;
+      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
+          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);
+    
+        
+    -- 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;
+    
+    -- Slave response to read access after g_rd_latency mm_clk cycles
+    p_miso : PROCESS(mux_miso, index_pipeline)
+    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;
+        END IF;
+      END LOOP;
+    END PROCESS;
+    
+  END GENERATE; 
+  
+END rtl;