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.