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