The Muffin Boy
The Muffin Boy

Reputation: 314

Read and Write from 2D array in VHDL

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; 

Upvotes: 0

Views: 5398

Answers (1)

Jonathan Drolet
Jonathan Drolet

Reputation: 3388

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;

Upvotes: 1

Related Questions