StanOverflow
StanOverflow

Reputation: 567

Initialize dynamic VHDL array

--in the package
type t_array is array (natural range <>) of std_logic_vector (7 downto 0);
type p_array is access t_array;

--in my testbench
variable my_array : p_array := null;
begin
my_array := new t_array(0 to 19);
my_array := ( X"00",X"00",X"00",X"00",X"FF",
              X"FF",X"FF",X"FF",X"00",X"00",
              X"FF",X"FF",X"FF",X"FF",X"FF",
              X"FF",X"FF",X"FF",X"FF",X"FF" );

Error: Target type util_lib.tb_pkg.p_array in variable assignment is different from expression type util_lib.tb_pkg.t_array.

How can I compactly assign all the elements of the array?

Upvotes: 2

Views: 1182

Answers (3)

Jim Lewis
Jim Lewis

Reputation: 3963

If you like one step, you can also do:

--in my testbench
variable my_array : p_array := null;
begin
my_array := new t_array'( X"00",X"00",X"00",X"00",X"FF",
              X"FF",X"FF",X"FF",X"00",X"00",
              X"FF",X"FF",X"FF",X"FF",X"FF",
              X"FF",X"FF",X"FF",X"FF",X"FF" );

You can also to do this in an initialization:

--in my testbench
variable my_array : p_array := new t_array'(
              X"00",X"00",X"00",X"00",X"FF",
              X"FF",X"FF",X"FF",X"00",X"00",
              X"FF",X"FF",X"FF",X"FF",X"FF",
              X"FF",X"FF",X"FF",X"FF",X"FF" );

begin

Upvotes: 2

user1155120
user1155120

Reputation:

Your error message:

Error: Target type util_lib.tb_pkg.p_array in variable assignment is different from expression type util_lib.tb_pkg.t_array.

tells us the subtype of the target doesn't match the right hand expression.

That can be cured several ways:

library ieee;
use ieee.std_logic_1164.all;

package initialize is 
--in the package
type t_array is array (natural range <>) of std_logic_vector (7 downto 0);
type p_array is access t_array;
end package;

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

entity testbench is
end entity;

architecture fum of testbench is

begin
    process
    --in my testbench
    variable my_array : p_array := null;
    begin
        my_array := new t_array(0 to 19);
        my_array (my_array'range) := ( 
                      X"00",X"00",X"00",X"00",X"FF",
                      X"FF",X"FF",X"FF",X"00",X"00",
                      X"FF",X"FF",X"FF",X"FF",X"FF",
                      X"FF",X"FF",X"FF",X"FF",X"FF" );
        wait;
    end process;
end architecture;

here using a slice name with the range provided by my_array'range.

Without the range the target name is interpreted as an access type name. As a slice name with a discrete range the target name denotes the value of the object type denotes:

IEEE Std 1076-2008 8. Names 8.1 General Paragraph 3 - 4:

Certain forms of name (indexed and selected names, slice names, and attribute names) include a prefix that is a name or a function call. If the prefix of a name is a function call, then the name denotes an element, a slice, or an attribute, either of the result of the function call, or (if the result is an access value) of the object designated by the result. Function calls are defined in 9.3.4.

A prefix is said to be appropriate for a type in either of the following cases:
— The type of the prefix is the type considered.
— The type of the prefix is an access type whose designated type is the type considered.

Here it helps to understand designate is a synonym for denote used to describe the relationship between a value of an access type and the object it references.

paragraph 5:

The evaluation of a name determines the named entity denoted by the name. The evaluation of a name that has a prefix includes the evaluation of the prefix, that is, of the corresponding name or function call. If the type of the prefix is an access type, the evaluation of the prefix includes the determination of the object designated by the corresponding access value. In such a case, it is an error if the value of the prefix is a null access value. It is an error if, after all type analysis (including overload resolution), the name is ambiguous.

In this case you can use a slice name that encompasses the entire array.

You can use a selected name for the access type object designates:

architecture fie of testbench is

begin
    process
        variable my_array : p_array := null;
    begin
    my_array := new t_array(0 to 19);
    my_array.all := ( X"00",X"00",X"00",X"00",X"FF",
                      X"FF",X"FF",X"FF",X"00",X"00",
                      X"FF",X"FF",X"FF",X"FF",X"FF",
                      X"FF",X"FF",X"FF",X"FF",X"FF" );
        wait;
    end process;
end architecture;

8.3 Selected names paragraph 5:

For a selected name that is used to denote the object designated by an access value, the suffix shall be the reserved word all. The prefix shall belong to an access type.

Using these methods distinguishes between assignment to an object of an access type (which isn't the type of the composite in the right hand expression) and the allocated object designated by the object of the access type.

Upvotes: 1

user1818839
user1818839

Reputation:

(1). Dereference your poincough access type.

my_array.all := (...);

(2) Initialise it from a function

begin
    my_array := new_array(20);

The gory details of initialising it can be buried in the function, which could calculate the values algorithmically, copy them from a constant array, or even read the contents from file.

constant initialiser : t_array := (...);

function new_array(length : natural range initialiser'range) return t_array is
   variable temp : p_array := new t_array(0 to length - 1);
begin
   -- either this
   for i in temp'range loop
      temp(i) := initialiser(i);
   end loop;
   -- or simply this
   temp.all := initialiser(temp'range);
   return temp;
end new_array;

(note the constraint on arguments to new_array : that ensures it won't create an array larger than the initialiser.)

Upvotes: 4

Related Questions