0

I have this code

--RAM module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

entity RAM is
  generic(
    address_length, data_length : integer);
  port(
    addr       : in    std_logic_vector(address_length-1 downto 0);
    dat        : inout std_logic_vector(data_length-1 downto 0);
    rd, wr, en : in    bit);
end entity RAM;

architecture RAM_impl of RAM is
  type mem is array(2**address_length-1 downto 0) of std_logic_vector(data_length-1 downto 0);
begin
  process(rd, wr, en)is
    variable cont : mem;
  begin
    if(en = '1')then
      if(wr = '1' and rd = '0')then
        cont(to_integer(unsigned(addr))) := dat;
      end if;
      if(rd = '1' and wr = '0')then
        dat <= cont(to_integer(unsigned(addr)));
      end if;
    end if;
  end process;
end architecture RAM_impl;


--Test module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

entity Example4RAM is
end entity Example4RAM;

architecture Tester of Example4RAM is
  signal rd, wr, en : bit;
  signal str        : std_logic_vector(15 downto 0);
  signal ext        : std_logic_vector(7 downto 0);
begin
  module : entity work.RAM(RAM_impl)
    generic map(
      address_length => 16,
      data_length    => 8)
    port map(str, ext, rd, wr, en);
  tt : process is
  begin
    str <= X"0001";
    ext <= "00000000";
    rd  <= '0'; wr <= '1';
    wait for 5 ns;
    en  <= '1';
    wait for 5 ns;
    rd  <= '0'; wr <= '0';
    wait for 10 ns;
    rd  <= '1'; wr <= '0';
  end process;
end architecture Tester;

When i run simulation on this RAM module str vector initializes fine but ext vector stays uninitialized. In RAM module str is in vector and ext is inout vector. Is this somehow making problem and does anyone know the solution? (I did change source since yesterday but it doesn't work still)

3
  • 1
    Without seeing the RAM entity (and possibly architecture) we can only guess in the dark. If the second parameter (why not use named association?) is "out" or "inout" mode, the answer is probably right there. Commented Oct 3, 2013 at 21:02
  • Brian is hinting that if ext is the data connection to RAM and it has a driver associated (e.g. mode inout) there are two drivers for ext ( RAM, process tt). The effective value of ext is the resolution of the two drivers. All 'U's and all '0's resolve to all 'U's, std_logic_vector is a resolved type or subtype (-2008). Without the RAM design description it's difficult to predict how to achieve success noting you don't drive ext to all 'Z's in process tt prior to reading the RAM and may not in RAM either, when rd is not true. Commented Oct 3, 2013 at 23:07
  • Edited code above, check out RAM. I am a beginner in VHDL so any suggestion will be helpful. Commented Oct 4, 2013 at 8:00

1 Answer 1

2

I added a RAM module and tinkered with the test stimulus slightly (ext is driven to all 'Z's when wr goes invalid (the behavioral model requires no hold over).

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity RAM is
    generic (
        constant address_length:    natural := 16;
        constant data_length:       natural := 8
    );
    port (
        signal str:     in      std_logic_vector (address_length-1 downto 0);
        signal ext:     inout   std_logic_vector (data_length-1  downto 0);
        signal rd:      in      BIT;
        signal wr:      in      BIT
    );
end entity; 

architecture RAM_impl of RAM is
    type ram_array is array (natural range address_length-1 downto 0) 
        of std_logic_vector (data_length-1 downto 0);
    signal mem_array: ram_array;
begin


MEMORY:
    process (str, ext, rd, wr)
        variable addr:  natural range 0 to 2**address_length -1 ;
    begin
        addr := TO_INTEGER(UNSIGNED(str));  -- heed the warnings
        if wr = '1' then
            mem_array(addr) <= ext;
        end if;
        if rd = '0' then
            ext <= (others => 'Z');
        else
            ext <= mem_array(addr);
        end if;
    end process;


end architecture;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.numeric_std.ALL;

entity Example4RAM is
end entity Example4RAM;

architecture Tester of Example4RAM is
signal rd,wr,clk: bit;
signal str: std_logic_vector(15 downto 0);
signal ext: std_logic_vector(7 downto 0);
begin

module: 
    entity work.RAM(RAM_impl) 
        generic map (
            address_length=>16,
            data_length=>8
        )
        port map (
            str,
            ext,
            rd,
            wr
        )
    ;

tt:
    process
    begin
        str<=X"0001";
        ext<="00000000";
        wait for 5 ns;
        rd<='0';wr<='1';
        wait for 5 ns;
        rd<='0';wr<='0';
        ext <= (others => 'Z');  -- ADDED
        wait for 10 ns;
        rd<='1';wr<='0'; 
        wait for 20 ns;  -- ADDED
        str <=X"0002";   -- ADDED
        wait for 20 ns;  -- ADDED
        wait;
    end process;
end architecture Tester;

The change to the stimulus includes a change to the RAM address showing that reading an uninitialized location returns 'U's (uu on the waveform):

RAM write followed by RAM read with a subsequent different address

ghdl -a exampleram.vhdl
ghdl -r Example4RAM --wave=Example4RAM.ghw
../../../../libraries/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning):   
NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
open *.ghw

Essentially, the process and the RAM drive ext with all 'Z's whenever either one shouldn't be driving a value out. Writing before reading hides the 'U' values from str address X"0001". As you see, if the address is changed to a location that is not initialized, the 'U's show up. Resolution delivers the RAM read data or provides write data to the RAM array on the bidirectional data bus (ext).

(This was done on a Mac with a ghdl mcode version (direct compile, like for Windows, requiring no explicit elaboration), and displayed using GTKWave).

The assertion warning (metavalue detected) comes from the default value assigned to str (all 'U's) at time zero (@0ms).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.