0

I'm trying to read and write from the 2D array I created: M. It seems to be working, but the first Read Operations always fails. I always populate the array before reading.

Sometimes when I read, there will be value there that was never inputted. I'm fairly new to VHDL programming, but is my 2D array correct? Am I accessing and writing to it correctly?

When EN and WEN are 1, I want to write. When EN is 1 and WEN is 0, I want to read.

Values from data_in go into the array. And when I'm 'reading' them they get outputted to data_out.

TIA, and if I haven't provided enough information please let me know.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY data_mem IS
PORT(
clk : IN STD_LOGIC;
addr : IN UNSIGNED(7 DOWNTO 0);
data_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
wen : IN STD_LOGIC;
en : IN STD_LOGIC;
data_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END data_mem;

ARCHITECTURE Description OF data_mem IS
signal tOUT : STD_LOGIC_VECTOR(31 DOWNTO 0);
type array2D is array (7 downto 0,31 downto 0) of std_logic;
signal M : array2D;

BEGIN
PROCESS(clk)
Begin
    if (falling_edge(clk)) then
        if (en = '1') then
            if (wen = '0') then
                --Read. data_out = M[addr]
                for i in 0 to 31 loop
                    tOUT(i) <= M(to_integer(addr),i);
                end loop;
            else
                --Write M[addr] <= data_in && data_out = 0
                for i in 0 to 31 loop
                    M(to_integer(addr),i) <= data_in(i);
                end loop;
                tOUT <= (tOUT'range => '0');
            end if;
        else
            --Function: N/A data_out = 0
            tOUT <= (tOUT'range => '0');
        end if; 
    end if;
END PROCESS;

data_out <= tOUT;
END Description; 
2
  • 1
    Since you're only ever accessing entire words, your code will be significantly simpler if you make your type declaration type array2D is array (7 downto 0) of std_logic_vector(31 downto 0). You won't have to do those for loops to pull out each 32-bit word that way. Same effect, though maybe not technically a "2D array". Commented Feb 11, 2015 at 21:22
  • 1
    That being said, I don't see anything wrong with the code you posted. It might be in whatever higher-level code you haven't posted. Commented Feb 11, 2015 at 21:23

1 Answer 1

1

The addr signal should be 2 downto 0, or the array (255 downto 0, 31 downto 0).

When addr is converted to integer, it takes a value ranging from 0 to 255 (8 bits). The first dimension of the array is defined as 7 downto 0, thus when addr if 8 or more, it is outside the range and comportement is undefined.

Moreover, I recommend against using 2D arrays as at least Xilinx does not synthesize them properly. Arrays of std_logic_vector or records works fine. As suggested in comments, you can use:

type array is array(7 downto 0) of std_logic_vector(31 downto 0);
...
    tOUT <= M(to_integer(addr));
    ...
    M(to_integer(addr)) <= data_in;
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I changed the array declaration to match that. I haven't finished the top-level yet, I'm just using a Quartus waveform file to test it. The output problem might have just been a hardware issue. Since the random numbers in the output would resemble the previous values.
Here's what the simulation looks like. There a random number in the output for some reason s10.postimg.org/safhowki0/Capture.jpg

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.