VHDL coding tips and tricks: Arrays and Records in VHDL - Part 2

Saturday, October 1, 2016

Arrays and Records in VHDL - Part 2

This is part two for the first post in this blog. Over the years it has received many questions through the comments and I have tried to answer them here.

1)How to initialize an integer array to zero.

type int_array_type is array(0 to 3) of integer;
signal int_array : int_array_type :=(0,0,0,0);

(OR)

signal int_array : int_array_type :=(others => 0);

2)Is it allowed to concatenate two integer arrays?

Yes, But all the right side operands have to be of the same data type as the left side one.

For example,

type int_array_type1 is array(0 to 3) of integer;
type int_array_type2 is array(0 to 7) of integer;
signal int_array1,int_array2 : int_array_type1 :=(1,2,3,4);
signal int_array3 : int_array_type2 :=(others => 0);

this is not allowed(even if the size matches):
int_array3 <= int_array1 & int_array2;

but this is allowed(because all operands involved are integer type):
int_array3(0 to 1) <= int_array1(0) & int_array2(0);

3)Why did you use 2 others to initialize a 4 element array of 8 bit elements to zero.
type array_type1 is array(0 to 3) of std_logic_vector(7 downto 0);
signal array1 : array_type1 := (others => (others => '0'));
Why not array1 <= (others=> '0');

Each others access a single dimension. For 2 or 3 dimensional arrays, you have to use 2 or 3 others statements within each other.

4)How to find the number of rows and columns of a 2D array?

type my1_2d is array(2 downto 0,3 downto 0) of std_logic_vector(7 downto 0);
type my2_2d is array(4 downto 0,5 downto 0) of std_logic_vector(7 downto 0);
type my3_2d is array(my1_2d'range(1),my2_2d'range(2)) of std_logic_vector(7 downto 0);

my3_2d will have the following range now:
type my3_2d is array(2 downto 0,5 downto 0) of std_logic_vector(7 downto 0);

my1_2d'range(n) is used to find the range of type my1_2d in dimension n. n starts from value 1.

5)Could we define a type using some values of the generic? Could we use this type in the ports of the same/other block? Any way around for the second question?

EXAMPLE (just to show the idea):
entity stream_TEST is
generic( 
NBR_STREAM: integer := 16;
NBIT_STREAM : integer := 10
);
port( 
stream1 : in STREAM;
stream2 : out STREAM
);
end stream_TEST;

ARCHITECTURE yy OF stream_TEST IS

Type STREAM is array(NBR_STREAM downto 0) of std_logic_vector(NBIT_STREAM downto 0);

BEGIN

END ARCHITECTURE;

This is not possible. One way to achieve this is to define the constants and new types in a package file and add it as a library in all the components where you want to use the new data type. See How to use vhdl packages to learn more about VHDL packages.

6)How do we declare and initialize an array of 10 elements each of 32 bits in size in VHDL?

type type_name is array(9 downto 0) of std_logic_vector(31 downto 0);
signal sig_name : type_name; 

(OR)

type WORD is array(31 downto 0) of std_logic;
type type_name is array(9 downto 0) of WORD;
signal sig_name : type_name;

7)The arrays on VHDL can have dimensions beyond 2D? For example, can I define a new type with a 5D array?

The answer is Yes. An example for a 5D array,
type my1_5d is array(2 downto 0,3 downto 0,4 downto 0,5 downto 0,6 downto 0) of std_logic;

8)In the below code, how do I access the LSB 4 bits of 'a' in signal r1.
type stuff is
record
: std_logic_vector(11 downto 0);
end record;
signal r1 : stuff := (=> x"fed");

r1.a(3 downto 0) will point to the LSB 4 bits of 'a', in signal r1.

9)Is it possible to create a large array of unsigned in separate file. I can store 32 values directly in my main file but if I have 256 values it is not convenient.

Yes, its possible. There are two ways to achieve this.

The easiest way is through a package file. Declare the array type and define a constant with the specific array type. The constant has to be assigned the unsigned values you want to have in the main file. Add this package as a library in the main file and initialize the array in main file with the name of the constant defined in the package file.

The second method is a bit too complicated. Here we store all the unsigned or signed(doesn't matter the type) values in a text file. Now write a function(in the main file) to read this file and return the mentioned array type. This function is used to initialize the array when declared in the main file. See a sample code here.

10)To initialize the whole array of a record to zero is there any easy statement like "others"? Or should it be initialized individually?

All the elements should be initialized individually.

Do you any questions regarding arrays and data types in VHDL? Let me know, I will try to answer them in Part 3..:)

Thanks.


5 comments:

  1. If the 2D array is in a text file. How can I make it read from the text file?

    ReplyDelete
  2. Considering an 8x8 array. Can you please tell me how do I select the first 3 elements of the first 3 rows to manipulate them.

    ReplyDelete
  3. Hi just few others tips for vector array + subtype

    --
    subtype sulv_rbits is std_ulogic_vector( NB_RBIT-1 downto 0);
    type sulv_index is array (1 to NB_RERRORS) of sulv_rbits;
    --
    variable vindex_error:sulv_index ;

    --initialize all bits
    vindex_error:= (others => sulv_rbits'(others =>'0')) ;

    -- test all bit from array = 0
    if vindex_error = sulv_index'(others =>(sulv_rbits'range =>'0')) then
    ..
    end if;

    -- test one index from array /= 0
    if vindex_error(i) /= (sulv_rbits'range =>'0')

    ReplyDelete
  4. Thank you very much, great contribution.

    ReplyDelete