0
\$\begingroup\$

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;
\$\endgroup\$
2
  • \$\begingroup\$ Well, are the internal signals in the counter doing anything different? (using your testbench) \$\endgroup\$ May 7, 2016 at 18:10
  • \$\begingroup\$ Now that you mention it... they also seem to be 'zeros' even though the l input has a value ('011111' in particular). But no, I don't touch these signals in my testbench. \$\endgroup\$
    – Arkoudinos
    May 7, 2016 at 18:14

1 Answer 1

1
\$\begingroup\$

You have switched on your instantiation between reset and clock signals.

Do not use signal connection by position, it is error prone and code is difficult to mantain.

Use explicit port mapping like

UUT: test

port map(

clk_i <= clk ...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.