I've written a memory module for an application. In order to address each memory location a simple 6-bit counter is used. I have tested most of the components (including the counter) and they seem to work properly.
Please take a look in the following VHDL code, which describes my top module. The signal cnt
seems to be completely undriven, since in my testbench has the value of zeros, while when I test the top module by hand has the value of 'U'.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LocalMemory is
port ( DATA_I : in std_logic_vector(127 downto 0);
DMX_I : in std_logic_vector(1 downto 0);
MEMEN1, MEMEN2, MEMEN3 : in std_logic;
RST_I : in std_logic;
CLK_I : in std_logic;
COL_SEL : in std_logic_vector(5 downto 0);
COL_SEL_EN : in std_logic;
CB_O : out std_logic_vector(127 downto 0); --Current block
RB_O : out std_logic_vector(127 downto 0)); --Reference block
end LocalMemory;
architecture Behavioral of LocalMemory is
---------------Define Components-------------------
--Demux
component LocalMemory_Demux is
port ( cb0_o : out std_logic_vector(127 downto 0);
rb1_o : out std_logic_vector(127 downto 0);
rb2_o : out std_logic_vector(127 downto 0);
rb3_o : out std_logic_vector(127 downto 0);
sel_i : in std_logic_vector(1 downto 0);
data_i : in std_logic_vector(127 downto 0)
);
end component;
--Submemory
component SubMemory is
port ( clk : in std_logic;
rst : in std_logic;
loadEn : in std_logic;
colsel: in std_logic_vector(3 downto 0);
array_in : in std_logic_vector (127 downto 0);
array_out : out std_logic_vector (127 downto 0)
);
end component;
--6 bit Addressing counter
component x6bit_counter is
port ( clk : IN STD_LOGIC;
enable : IN STD_LOGIC;
reset : IN STD_LOGIC;
load : IN STD_LOGIC;
l : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
q : OUT STD_LOGIC_VECTOR(5 DOWNTO 0)
);
end component;
--Output MUX
component mux3x1 is
generic
( N : integer := 128
);
port
( sel : in std_logic_vector(1 DOWNTO 0);
data_a : in std_logic_vector(N-1 DOWNTO 0);
data_b : in std_logic_vector(N-1 DOWNTO 0);
data_c : in std_logic_vector(N-1 DOWNTO 0);
data_out : out std_logic_vector(N-1 DOWNTO 0)
);
end component;
---------------End Component Definitions-------------
---------------Begin Signal Definitions--------------
signal rb_data_1: std_logic_vector(127 downto 0);
signal rb_data_2: std_logic_vector(127 downto 0);
signal rb_data_3: std_logic_vector(127 downto 0);
signal SubMem1_out: std_logic_vector(127 downto 0);
signal SubMem2_out: std_logic_vector(127 downto 0);
signal SubMem3_out: std_logic_vector(127 downto 0);
signal cnt: std_logic_vector(5 downto 0); -- Addressing signal
---------------End Signal Definitions----------------
begin
--MEMEN signals are used ONLY as "write enable" (not as "chip enable")!
DEMUX: LocalMemory_Demux port map (CB_O, rb_data_1, rb_data_2, rb_data_3, DMX_I, DATA_I);
SUBMEMORY1: SubMemory port map (CLK_I, RST_I, MEMEN1, cnt(3 downto 0), rb_data_1, SubMem1_out);
SUBMEMORY2: SubMemory port map (CLK_I, RST_I, MEMEN2, cnt(3 downto 0), rb_data_2, SubMem2_out);
SUBMEMORY3: SubMemory port map (CLK_I, RST_I, MEMEN3, cnt(3 downto 0), rb_data_3, SubMem3_out);
X6COUNTER: x6bit_counter port map(CLK_I, '1', RST_I, COL_SEL_EN, COL_SEL, cnt(5 downto 0));
OUT_MUX: mux3x1 port map (cnt(5 downto 4), SubMem1_out, SubMem2_out, SubMem3_out, RB_O);
end Behavioral;
Why is this happening? I spent an entire day trying to figure out. Here is also the counter code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity x6bit_counter is
port ( clk: in std_logic; -- Input clock
enable: in std_logic; -- Enable counting
reset: in std_logic; -- Input reset
load: in std_logic; -- Parallel load enable
l: in std_logic_vector (5 downto 0); -- Parallel load for the counter
q: out std_logic_vector (5 downto 0) -- Output of the counter
);
end x6bit_counter;
architecture Behavioral of x6bit_counter is
signal count :std_logic_vector (5 downto 0);
begin
process (clk, reset) begin
if (reset = '1') then
count <= (others=>'0');
elsif (rising_edge(clk)) then
if (load = '1') then
count <= l;
elsif (enable = '1') then
count <= count + 1;
end if;
end if;
end process;
q <= count;
end architecture;
EDIT Here is also my testbench. I tried to avoid it because is kinda large, however it may be helpful.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
-- entity declaration for your testbench.Dont declare any ports here
entity LocalMemory_TB is
end LocalMemory_TB;
architecture Behavioral of LocalMemory_TB is
-- Component Declaration for the Unit Under Test (UUT) component LocalMemory
--'test' is the name of the module needed to be tested.
port ( DATA_I : in std_logic_vector(127 downto 0);
DMX_I : in std_logic_vector(1 downto 0);
MEMEN1, MEMEN2, MEMEN3 : in std_logic;
RST_I : in std_logic;
CLK_I : in std_logic;
COL_SEL : in std_logic_vector(5 downto 0);
COL_SEL_EN : in std_logic;
CB_O : out std_logic_vector(127 downto 0); --Current block
RB_O : out std_logic_vector(127 downto 0) --Reference block
);
end component;
--declare inputs and initialize them
--Control
signal clk_i: std_logic;
signal rst_i: std_logic;
signal memen1, memen2, memen3: std_logic;
signal colsel: std_logic_vector(5 downto 0);
signal colsel_en: std_logic;
signal dmx: std_logic_vector(1 downto 0);
--Data
signal data_in: std_logic_vector(127 downto 0);
signal cb_o: std_logic_vector(127 downto 0);
signal rb_o: std_logic_vector(127 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut: LocalMemory port map (data_in, dmx, memen1, memen2, memen3, clk_i, rst_i, colsel, colsel_en,
cb_o, rb_o);
-- Clock process definitions( clock with 50% duty cycle is generated here).
clk_process :process
begin
clk_i <= '1';
wait for clk_period/2; --for 0.5 ns signal is '0'.
clk_i <= '0';
wait for clk_period/2; --for next 0.5 ns signal is '1'.
end process;
-- Stimulus process
stim_proc: process
begin
--Reset system
wait for 7 ns;
rst_i <= '1';
wait for 3 ns;
rst_i <='0';
-- Transfer the CB data directly to the AD processor.
wait for 20 ns;
dmx <= "00"; --Set the DEMUX to send the data directly to the PE (Current Block)
data_in <= x"5a66f4d4557c01e58f03f5ff7a36d35c";
wait for 10 ns;
data_in <= x"744a9d726e61c457d9aebe2b6b8c611c";
wait for 10 ns;
data_in <= x"9ef4c6abf16d1b81c336c14af6e79c3b";
wait for 10 ns;
data_in <= x"dd6ff9702da05e5dad9033c45ca55abb";
wait for 10 ns;
data_in <= x"33912670c16dd859d81bf33d563fa5be";
wait for 10 ns;
data_in <= x"7b1be71a108e3c57ce7c9160fb85c4dc";
wait for 10 ns;
data_in <= x"d9eb83b5f818811cba69871d452fd852";
wait for 10 ns;
data_in <= x"1e3c42932d31fed283ca4db3aae52bc9";
wait for 10 ns;
data_in <= x"0299e7b052c48fbe9ca7be5805b65ea7";
wait for 10 ns;
data_in <= x"cee8a11fdb770b3afff7bb168ed586a2";
wait for 10 ns;
data_in <= x"c02474deb26c5fcb2edc018b27acb1c1";
wait for 10 ns;
data_in <= x"9a13d57b383f335620bb499bd2be281d";
wait for 10 ns;
data_in <= x"9f9ab151b55bb00433e986a11d349286";
wait for 10 ns;
data_in <= x"2f8ec3fff56934040554160a4d76491e";
wait for 10 ns;
data_in <= x"3eb27198e00e31320332ad7d9cfdc35a";
wait for 10 ns;
data_in <= x"bd22cfd35228c4858fc82e63ae9acd25";
--Load data into memory.
--We're going to load 16 128-bit words on first submemory, row-by-row
wait for 10 ns;
memen1 <= '1';
dmx <= "01"; --Choose the first submemory in the DEMUX
data_in <= x"5a66f4d4557c01e58f03f5ff7a36d35c";
wait for 10 ns;
data_in <= x"744a9d726e61c457d9aebe2b6b8c611c";
wait for 10 ns;
data_in <= x"9ef4c6abf16d1b81c336c14af6e79c3b";
wait for 10 ns;
data_in <= x"dd6ff9702da05e5dad9033c45ca55abb";
wait for 10 ns;
data_in <= x"33912670c16dd859d81bf33d563fa5be";
wait for 10 ns;
data_in <= x"7b1be71a108e3c57ce7c9160fb85c4dc";
wait for 10 ns;
data_in <= x"d9eb83b5f818811cba69871d452fd852";
wait for 10 ns;
data_in <= x"1e3c42932d31fed283ca4db3aae52bc9";
wait for 10 ns;
data_in <= x"0299e7b052c48fbe9ca7be5805b65ea7";
wait for 10 ns;
data_in <= x"cee8a11fdb770b3afff7bb168ed586a2";
wait for 10 ns;
data_in <= x"c02474deb26c5fcb2edc018b27acb1c1";
wait for 10 ns;
data_in <= x"9a13d57b383f335620bb499bd2be281d";
wait for 10 ns;
data_in <= x"9f9ab151b55bb00433e986a11d349286";
wait for 10 ns;
data_in <= x"2f8ec3fff56934040554160a4d76491e";
wait for 10 ns;
data_in <= x"3eb27198e00e31320332ad7d9cfdc35a";
wait for 10 ns;
data_in <= x"bd22cfd35228c4858fc82e63ae9acd25";
wait for 10 ns;
memen1 <= '0';
memen2 <= '1';
dmx <= "10"; --Choose the second submemory in the DEMUX
--We're going to load 16 128-bit words on the second submemory, row-by-row
wait for 10 ns;
data_in <= x"37a606178b2bc2c72afb7c7ec4acad00";
wait for 10 ns;
data_in <= x"d90f2dffb3cd7bb64b46cba31ecf1cd3";
wait for 10 ns;
data_in <= x"2e329b73a9b92e936166c84be7ce3a59";
wait for 10 ns;
data_in <= x"740df7bc2088159b5e43def6f1b930ec";
wait for 10 ns;
data_in <= x"6e4a5aa2189bf541857590876f94104e";
wait for 10 ns;
data_in <= x"dd055289e8dbbc2369eed8c23d9704da";
wait for 10 ns;
data_in <= x"70aa8291980595d873291bd0e260a6d8";
wait for 10 ns;
data_in <= x"79ab2c84aad3b41294e6e694567b063e";
wait for 10 ns;
data_in <= x"17fcb7f29387a300e48f1c489f91e885";
wait for 10 ns;
data_in <= x"b92cccbfd0dbe194c2337f975700547a";
wait for 10 ns;
data_in <= x"54f97a2f7bc37c2553b0d8e4de90b633";
wait for 10 ns;
data_in <= x"53df47ccca031911b65216750cd1346a";
wait for 10 ns;
data_in <= x"e2627dea291898b15171a01142ec6ecb";
wait for 10 ns;
data_in <= x"9eba322028741dedbdd2c0441d506a66";
wait for 10 ns;
data_in <= x"38f3a16455e9d7997f7b8ee378e49cc5";
wait for 10 ns;
data_in <= x"278574a3fbb62fb41b5c78f6754dd3e6";
wait for 10 ns;
memen2 <= '0';
memen3 <= '1';
dmx <= "11"; --Choose the third submemory in the DEMUX
colsel_en <= '1'; --Activate memory reading
--Write-while-read.
--We're going to load 16 128-bit words on the third submemory, row-by-row, while reading from second submemory
wait for 10 ns;
data_in <= x"5d432c0dfa0694cbcc9d41e064beedfa";
colsel <= "010000";
wait for 20 ns;
data_in <= x"6d4af36838b54f29ab36ac7c0d2b6d61";
colsel <= "010001";
wait for 10 ns;
data_in <= x"8a27c1fde57e00e3f44211480b820299";
colsel <= "010010";
wait for 10 ns;
data_in <= x"e46448dfa5e810f94bbb58e98ef2fe99";
colsel <= "010011";
wait for 10 ns;
data_in <= x"d2c43e51734d17e5c46fd0a4c33c21e8";
colsel <= "010100";
wait for 10 ns;
data_in <= x"5bd9ce433104ba69616628eadc16611a";
colsel <= "010101";
wait for 10 ns;
data_in <= x"aec8737653358cf640106ce8afa14036";
colsel <= "010110";
wait for 10 ns;
data_in <= x"e349e161514369b6b5fe5dae6ac3795d";
colsel <= "010111";
wait for 10 ns;
data_in <= x"2975c6482c9dda8991d0953cd68e3531";
colsel <= "011000";
wait for 10 ns;
data_in <= x"38b5a0a3feb10c4718bb8610b51a25dd";
colsel <= "011001";
wait for 10 ns;
data_in <= x"5e130aa886a3fbd98e18416550f110da";
colsel <= "011010";
wait for 10 ns;
data_in <= x"ed8eb647e6d2be16b08f2b4c3cea953c";
colsel <= "011011";
wait for 10 ns;
data_in <= x"115af997f1f2aaf57b1410537201e806";
colsel <= "011100";
wait for 10 ns;
data_in <= x"9ffbc78227d10755c363a4c6481f92f7";
colsel <= "011101";
wait for 10 ns;
data_in <= x"46abc102a2e1365e7c5833293d2401b4";
colsel <= "011110";
wait for 10 ns;
data_in <= x"0a003050cea36f2070f9463d569bf818";
colsel <= "011111";
wait for 10 ns;
memen3 <= '0';
colsel_en <= '0'; --Stop memory reading
wait; -- Wait forever.
end process;
end;
l
input has a value ('011111' in particular). But no, I don't touch these signals in my testbench. \$\endgroup\$