From c1f9638e9bb4a9a1558036b01db92f42e83e3378 Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Wed, 10 Dec 2014 10:58:40 +0000
Subject: [PATCH] Port to RadioHDL.

---
 libraries/base/common/hdllib.cfg              |   2 +-
 .../base/common/src/vhdl/common_mem_mux.vhd   | 108 ++++++++++++++++++
 2 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 libraries/base/common/src/vhdl/common_mem_mux.vhd

diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg
index 97391edb72..7e09ef2d9b 100644
--- a/libraries/base/common/hdllib.cfg
+++ b/libraries/base/common/hdllib.cfg
@@ -127,7 +127,7 @@ synth_files =
     $UNB/Firmware/modules/common/src/vhdl/common_fifo_rd.vhd
     $UNB/Firmware/modules/common/src/vhdl/common_blockreg.vhd
     $UNB/Firmware/modules/common/src/vhdl/common_fifo_dc_lock_control.vhd
-    $UNB/Firmware/modules/common/src/vhdl/common_mem_mux.vhd
+    src/vhdl/common_mem_mux.vhd
     $UNB/Firmware/modules/common/src/vhdl/common_reg_cross_domain.vhd
     $UNB/Firmware/modules/common/src/vhdl/common_reg_r_w.vhd
     $UNB/Firmware/modules/common/src/vhdl/common_reg_r_w_dc.vhd
diff --git a/libraries/base/common/src/vhdl/common_mem_mux.vhd b/libraries/base/common/src/vhdl/common_mem_mux.vhd
new file mode 100644
index 0000000000..3ed2542df1
--- /dev/null
+++ b/libraries/base/common/src/vhdl/common_mem_mux.vhd
@@ -0,0 +1,108 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2011
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Purpose: Combines an array of MM interfaces into a single MM interface.
+-- Description:
+--   The common_mem_mux unit combines an array of mosi's and miso's to one
+--   single set of mosi and miso. Should be used to decrease the amount of
+--   memory interfaces to the SOPC.
+-- Remarks:
+-- . In simulation selecting an unused element address will cause a simulation
+--   failure. Therefore the element_address is only accepted when it is in the
+--   g_nof_mosi-1 DOWNTO 0 range.
+-- 
+-------------------------------------------------------------------------------
+
+
+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_mux IS
+  GENERIC (    
+    g_nof_mosi    : POSITIVE := 256;     -- Number of memory interfaces in the array.                       
+    g_mult_addr_w : POSITIVE := 8;       -- Address width of each memory-interface element in the array.
+    g_rd_latency  : NATURAL := 0
+  );
+  PORT (
+    clk      : IN  STD_LOGIC := '0';   -- only used when g_rd_latency > 0
+    mosi     : IN  t_mem_mosi;
+    miso     : OUT t_mem_miso;
+    mosi_arr : OUT t_mem_mosi_arr(g_nof_mosi - 1 DOWNTO 0); 
+    miso_arr : IN  t_mem_miso_arr(g_nof_mosi - 1 DOWNTO 0) := (OTHERS=>c_mem_miso_rst)
+  );
+END common_mem_mux;
+
+ARCHITECTURE rtl OF common_mem_mux IS
+  
+  CONSTANT c_upper_limit   : NATURAL := g_mult_addr_w + ceil_log2(g_nof_mosi); 
+
+  SIGNAL element_address_arr : t_natural_arr(0 TO g_rd_latency);
+
+BEGIN
+
+  gen_multiple : IF(g_nof_mosi > 1) GENERATE 
+    -- The activated element of the array is detected here
+    element_address_arr(0) <= TO_UINT(mosi.address(c_upper_limit-1 DOWNTO g_mult_addr_w));
+    
+    -- Master access, can be write or read
+    p_mosi_arr : PROCESS(mosi, element_address_arr)
+    BEGIN
+      FOR I IN 0 TO g_nof_mosi-1 LOOP
+        mosi_arr(I)    <= mosi;
+        mosi_arr(I).rd <= '0';
+        mosi_arr(I).wr <= '0';
+        IF I = element_address_arr(0) THEN
+          mosi_arr(I).rd <= mosi.rd;  
+          mosi_arr(I).wr <= mosi.wr; 
+        END IF;
+      END LOOP;
+    END PROCESS;
+    
+    -- Pipeline the address of the activated element to account for the read latency
+    p_clk : PROCESS(clk)
+    BEGIN
+      IF rising_edge(clk) THEN
+        element_address_arr(1 TO g_rd_latency) <= element_address_arr(0 TO g_rd_latency-1);
+      END IF;
+    END PROCESS;
+    
+    -- Slave response to read access after g_rd_latency clk cycles
+    p_miso : PROCESS(miso_arr, element_address_arr)
+    BEGIN
+      miso <= c_mem_miso_rst;
+      FOR I IN 0 TO g_nof_mosi-1 LOOP
+        IF I = element_address_arr(g_rd_latency) THEN
+          miso <= miso_arr(I);
+        END IF;
+      END LOOP;
+    END PROCESS;
+  END GENERATE; 
+  
+  gen_single : IF(g_nof_mosi = 1) GENERATE 
+    mosi_arr(0) <= mosi;
+    miso        <= miso_arr(0);
+  END GENERATE;
+    
+END rtl;
-- 
GitLab