Reputation: 936
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
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
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
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
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