fiz
fiz

Reputation: 936

How to Transfer Array Data in VHDL?

Annoyingly I know how to do this easily in C++ but not in VHDL. I want to quickly and easily transfer data from a constrained 3D array to a 2D array e.g:

2d_array[N][M]
3d_array[i][N][M]

2d_array=3d_array[i]

So my VHDL looks like this:

    type buff_array is array(2 downto 0, 7 downto 0) of std_logic_vector(31 downto 0);
    type ram_array is array(7 downto 0) of std_logic_vector(31 downto 0);
    shared variable ram: ram_array;
    shared variable buff: buff_array;

And I'd want to do something like this:

if we = '1' then
                buff(pua, addr) := d;
                ram:=buff(poa);
            end if;

Any ideas?

Also I know I could do a quick for loop but I wanted to try and avoid the extra logic

Upvotes: 1

Views: 4919

Answers (4)

Martin Thompson
Martin Thompson

Reputation: 16832

Re:

I know I could do a quick for loop but I wanted to try and avoid the extra logic

A for loop just copying values from one place to another will not be any logic - the compiler will unroll the loop and just create the wiring you've described.

It's a common misconception that having a for loop makes for big logic. All it really means is that it duplicates the logic within the loop that many times, so if the logic in the loop is trivial, so is the unrolled version. It doesn't create counters and comparators etc.

(And, forgive the presumption, as a relative newbie to VHDL, don't fret about the amount of logic. Certainly, keep an eye on things by synthesising blocks as you go, but you may be surprised by a) how good the tools are and b) how big the devices are these days :) Avoid premature optimisation, just like in software!

Upvotes: 4

user1155120
user1155120

Reputation:

This merely illustrates Morten's answer for those wanting to understand the issue and solution otherwise obscured by shared variable name changes and lack of LRM reference.

This example analyzes:

library ieee;
use ieee.std_logic_1164.all;

package declare is 
--  type buff_array is array(2 downto 0, 7 downto 0) of std_logic_vector(31 downto 0);
    type ram_array is array(7 downto 0) of std_logic_vector(31 downto 0);
    type buff_array is array (2 downto 0) of ram_array;  -- added declaration
    shared variable ram: ram_array;
    shared variable buff: buff_array;
end package;

library ieee;
use ieee.std_logic_1164.all;
use work.declare.all;

entity ramarray is
end entity;

architecture foo of ramarray is
    signal we:   std_logic;
begin
    we <= '1';
SOMELABEL:
    process (we)
    begin
        if we = '1' then
            ram := buff(1);  -- unchanged
        end if;
    end process;

end architecture;

Multidimensional slices are not allowed[1]. Separating the indexes for each dimension by converting buff into an array of an array type of an array subtype allows you to have the same base type on both sides of the assignment operator providing a slice name to a single dimensional array whose element type is ram_array.


[1] IEEE Std 1076-2008, Section 8.5 Slice names "A slice name denotes a one-dimensional array composed of a sequence of consecutive elements of another one-dimensional array. A slice of a signal is a signal; a slice of a variable is a variable; a slice of a constant is a constant; a slice of a value is a value."

See also Fast Track Change Proposal FT-15 Slicing of multidimensional arrays and arrays of arrays from June 2004, still in progress.

Upvotes: 1

Morten Zilmer
Morten Zilmer

Reputation: 15924

Quick fix is to declare buff_array as:

type buff_array is array(2 downto 0) of ram_array;

And then of course put declaration of buf_array after declaration of ram_array.

Example for 2D/3D array:

type array_2d_t is array(2 downto 0, 1 downto 0) of std_logic_vector(31 downto 0);
type array_3d_t is array(3 downto 0) of array_2d_t;
shared variable array_2d_v : array_2d_t;
shared variable array_3d_v : array_3d_t;
...
array_2d_v := array_3d_v(1);

Upvotes: 2

user1818839
user1818839

Reputation:

You can only assign entire arrays if they are of the same type. So given

type ram_array is array(7 downto 0) of std_logic_vector(31 downto 0);

you can declare variables - or even arrays - of that type.

signal buf : ram_array;
signal ram_2d: array(2 downto 0) of ram_array;

Now buf <= ram_2d(1) ought to work.

Upvotes: 4

Related Questions