Skip to content
Snippets Groups Projects
Commit 50fc5a7a authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Cosmetic changes. Added block diagram. To prepare for making similar common_mem_demux.

parent c1f9638e
No related merge requests found
...@@ -25,11 +25,29 @@ ...@@ -25,11 +25,29 @@
-- Description: -- Description:
-- The common_mem_mux unit combines an array of mosi's and miso's to one -- 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 -- single set of mosi and miso. Should be used to decrease the amount of
-- memory interfaces to the SOPC. -- slave memory interfaces to the MM bus.
--
-- g_rd_latency
-- ______________
-- strip index: | |
-- mosi.address[h:w] ---+-->| delay line |--\
-- | |____________| |
-- | |
-- selected v |
-- mosi -------> mosi_arr.wr[ ]-----------------------------> mosi_arr
-- rd |
-- selected v
-- miso <-------------------------------miso_arr[ ]<--------- miso_arr
--
-- . not selected mosi_arr get mosi but with wr='0', rd='0'
-- . not selected miso_arr are ignored
--
-- Remarks: -- Remarks:
-- . In simulation selecting an unused element address will cause a simulation -- . In simulation selecting an unused element address will cause a simulation
-- failure. Therefore the element_address is only accepted when it is in the -- failure. Therefore the element index is only accepted when it is in the
-- g_nof_mosi-1 DOWNTO 0 range. -- g_nof_mosi-1 DOWNTO 0 range.
-- . In case multiple common_mem_mux would be used in series, then only the
-- top one needs to account for g_rd_latency>0, the rest can use 0.
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -42,7 +60,7 @@ USE common_lib.common_mem_pkg.ALL; ...@@ -42,7 +60,7 @@ USE common_lib.common_mem_pkg.ALL;
ENTITY common_mem_mux IS ENTITY common_mem_mux IS
GENERIC ( GENERIC (
g_nof_mosi : POSITIVE := 256; -- Number of memory interfaces in the array. 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_mult_addr_w : POSITIVE := 8; -- Address width of each memory-interface element in the muliplexed array.
g_rd_latency : NATURAL := 0 g_rd_latency : NATURAL := 0
); );
PORT ( PORT (
...@@ -56,53 +74,59 @@ END common_mem_mux; ...@@ -56,53 +74,59 @@ END common_mem_mux;
ARCHITECTURE rtl OF common_mem_mux IS ARCHITECTURE rtl OF common_mem_mux IS
CONSTANT c_upper_limit : NATURAL := g_mult_addr_w + ceil_log2(g_nof_mosi); CONSTANT c_index_w : NATURAL := ceil_log2(g_nof_mosi);
CONSTANT c_total_addr_w : NATURAL := c_index_w + g_mult_addr_w;
SIGNAL element_address_arr : t_natural_arr(0 TO g_rd_latency); 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 BEGIN
gen_multiple : IF(g_nof_mosi > 1) GENERATE gen_single : IF g_nof_mosi=1 GENERATE
mosi_arr(0) <= mosi;
miso <= miso_arr(0);
END GENERATE;
gen_multiple : IF g_nof_mosi>1 GENERATE
-- The activated element of the array is detected here -- 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)); index_arr(0) <= TO_UINT(mosi.address(c_total_addr_w-1 DOWNTO g_mult_addr_w));
-- 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 -- Master access, can be write or read
p_mosi_arr : PROCESS(mosi, element_address_arr) p_mosi_arr : PROCESS(mosi, index_rw)
BEGIN BEGIN
FOR I IN 0 TO g_nof_mosi-1 LOOP FOR I IN 0 TO g_nof_mosi-1 LOOP
mosi_arr(I) <= mosi; mosi_arr(I) <= mosi;
mosi_arr(I).rd <= '0'; mosi_arr(I).rd <= '0';
mosi_arr(I).wr <= '0'; mosi_arr(I).wr <= '0';
IF I = element_address_arr(0) THEN IF I = index_rw THEN
mosi_arr(I).rd <= mosi.rd; mosi_arr(I).rd <= mosi.rd;
mosi_arr(I).wr <= mosi.wr; mosi_arr(I).wr <= mosi.wr;
END IF; END IF;
END LOOP; END LOOP;
END PROCESS; 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 -- Slave response to read access after g_rd_latency clk cycles
p_miso : PROCESS(miso_arr, element_address_arr) p_miso : PROCESS(miso_arr, index_rd)
BEGIN BEGIN
miso <= c_mem_miso_rst; miso <= c_mem_miso_rst;
FOR I IN 0 TO g_nof_mosi-1 LOOP FOR I IN 0 TO g_nof_mosi-1 LOOP
IF I = element_address_arr(g_rd_latency) THEN IF I = index_rd THEN
miso <= miso_arr(I); miso <= miso_arr(I);
END IF; END IF;
END LOOP; END LOOP;
END PROCESS; END PROCESS;
END GENERATE; END GENERATE;
gen_single : IF(g_nof_mosi = 1) GENERATE
mosi_arr(0) <= mosi;
miso <= miso_arr(0);
END GENERATE;
END rtl; END rtl;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment