From 4425272dbc39849fd9a2561ebe98e018575775ec Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Wed, 10 Dec 2014 11:47:46 +0000 Subject: [PATCH] Added common_mem_demux.vhd (inverse of common_mem_mux.vhd). --- libraries/base/common/hdllib.cfg | 1 + .../base/common/src/vhdl/common_mem_demux.vhd | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 libraries/base/common/src/vhdl/common_mem_demux.vhd diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg index 7e09ef2d9b..b5610d4767 100644 --- a/libraries/base/common/hdllib.cfg +++ b/libraries/base/common/hdllib.cfg @@ -128,6 +128,7 @@ synth_files = $UNB/Firmware/modules/common/src/vhdl/common_blockreg.vhd $UNB/Firmware/modules/common/src/vhdl/common_fifo_dc_lock_control.vhd src/vhdl/common_mem_mux.vhd + src/vhdl/common_mem_demux.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_demux.vhd b/libraries/base/common/src/vhdl/common_mem_demux.vhd new file mode 100644 index 0000000000..92a83222ce --- /dev/null +++ b/libraries/base/common/src/vhdl/common_mem_demux.vhd @@ -0,0 +1,127 @@ +------------------------------------------------------------------------------- +-- +-- 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: Decompose a single MM interface into an array of MM interfaces. +-- Description: +-- Inverse operation of common_mem_mux. +-- +-- g_rd_latency +-- ______________ +-- use index of mosi_arr | | +-- with active rd or wr ---+-->| delay line |--\ +-- | |____________| | +-- | | +-- selected v | +-- mosi_arr -----> mosi_address[h:w]-----------------------------> mosi +-- | +-- selected v +-- miso_arr <-------------------------------miso_arr[ ]<--------- miso +-- +-- . not selected mosi_arr are ignored +-- . not selected miso_arr get c_mem_miso_rst +-- +-- Remarks: +-- . In simulation selecting an unused element address will cause a simulation +-- failure. Therefore the element index is only accepted when it is in the +-- g_nof_mosi-1 DOWNTO 0 range. +-- . In case common_mem_demux and common_mem_mux would be used in series, then +-- only the one needs to account for g_rd_latency>0, the other can use 0. +-- +------------------------------------------------------------------------------- + + +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_demux 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 muliplexed array. + g_rd_latency : NATURAL := 0 + ); + PORT ( + clk : IN STD_LOGIC := '0'; -- only used when g_rd_latency > 0 + mosi_arr : IN t_mem_mosi_arr(g_nof_mosi - 1 DOWNTO 0); + miso_arr : OUT t_mem_miso_arr(g_nof_mosi - 1 DOWNTO 0); + mosi : OUT t_mem_mosi; + miso : IN t_mem_miso := c_mem_miso_rst + ); +END common_mem_demux; + +ARCHITECTURE rtl OF common_mem_demux IS + + CONSTANT c_index_w : NATURAL := ceil_log2(g_nof_mosi); + CONSTANT c_total_addr_w : NATURAL := c_index_w + g_mult_addr_w; + + SIGNAL index_arr : t_natural_arr(0 TO g_rd_latency); + SIGNAL index_rw : NATURAL; -- read or write access + SIGNAL index_rd : NATURAL; -- read response + +BEGIN + + gen_single : IF g_nof_mosi=1 GENERATE + mosi <= mosi_arr(0); + miso_arr(0) <= miso; + END GENERATE; + + gen_multiple : IF g_nof_mosi>1 GENERATE + -- The activated element of the array is detected here + p_index : PROCESS(mosi_arr) + BEGIN + index_arr(0) <= 0; + FOR I IN 0 TO g_nof_mosi-1 LOOP + IF mosi_arr(I).wr='1' OR mosi_arr(I).rd='1' THEN + index_arr(0) <= I; + END IF; + END LOOP; + END PROCESS; + + -- Pipeline the index of the activated element to account for the read latency + p_clk : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + index_arr(1 TO g_rd_latency) <= index_arr(0 TO g_rd_latency-1); + END IF; + END PROCESS; + + index_rw <= index_arr(0); + index_rd <= index_arr(g_rd_latency); + + -- Master access, can be write or read + p_mosi : PROCESS(mosi_arr, index_rw) + BEGIN + mosi <= mosi_arr(index_rw); + mosi.address(c_total_addr_w-1 DOWNTO g_mult_addr_w) <= TO_UVEC(index_rw, c_index_w); + END PROCESS; + + -- Slave response to read access after g_rd_latency clk cycles + p_miso : PROCESS(miso, index_rd) + BEGIN + miso_arr <= (OTHERS=>c_mem_miso_rst); + miso_arr(index_rd) <= miso; + END PROCESS; + END GENERATE; + +END rtl; -- GitLab