Aller au contenu

Types in VHDL

There are different types of signals depending on the needs. Each type is defined in a library.

std_logic

The std_logic type is used to declare 1-bit signals. It is part of the standard library std_logic_1164 library. This bit can take 9 different states:

Values Description
'0' Low logic state
'1' High logic state
'Z' High impedence
'U' Undefined
'X' Conflict (multiple drivers)
'W' Unknown, Weak
'H' Unknown, probably High
'L' Unknown, probably Low
'-' Don't care…

However, only the first three states can be synthesized. So if in simulation one of the other states is detected, the design may not behave as expected on FPGA. This is the advantage of this type type, it is thus easier to debug a circuit during simulations.

Declaration :

1
signal C : std_logic;

std_logic_vector

This type is used to represent signals composed of several bits, for example a bus, or a data signal. It is part of the standard library std_logic_1164. Each of the bits composing this vector has the same properties as a std_logic. It is imperative to indicate a size to this vector when declaring it:

1
signal C : std_logic_vector(7 downto 0);  -- here the signal is composed of 8 bits

As it is an array, it is possible to access each element that composes it, in reading as well as in writing, via indices of type integer :

1
2
3
4
5
6
7
8
signal D : std_logic;
signal E : std_logic_vector(3 downto 0);
.
.
.
C <= "11001001";
D <= C(3); -- 1
E <= C(4 downto 1); -- "0100"

enumerate

This type is used in particular to describe the different states that an automaton can take (state machine). The declaration is of high level, i.e. it does not involve vector size etc. It is the synthesizer which is in charge of converting the states into physical quantities (ie. electrical signals). Declaration:

1
2
3
4
5
type T_State is(
                ST_Reset ,
                ST_Wait  ,
                ST_Read
);

unsigned/signed

These types are used for arithmetic operations. They are defined in the standard library numeric_std library. Signed signals are represented in 2's complement. In the same way as for vectors std_logic_vector, it is imperative to indicate a size to these vectors when declaring them:

1
2
signal U : unsigned(7 downto 0);
signal S : signed(7 downto 0);

These signals should be used for arithmetic operations, otherwise it is better to use std_logic_vector. In the same way as for the std_logic_vector, it is possible to access the bits that make them up via an via an index of type integer.

boolean

The boolean type is defined in the standard package. It is an enumerate than can only take two values : true and false. It is used for conditional operations. The default value of any object of the boolean type is false.

natural/integer

These types of signals can also be used for arithmetic operations, in particular for counter/counter. The type natural is used for positive data signals, integer for positive and/or negative data. This time it is not necessary to specify a vector size in number of bits, but a range of values when declaring it. This is the type used as an index of vectors and arrays:

1
2
signal N : natural range 0 to 17;
signal I : integer range -4 to 29;

If no value range is specified, by default the range is 0 → \(2^{32} -1\) for a natural and \(-2^{31}\)\(2^{31} -1\) for an integer. It is therefore important, in order to avoid using more resources than necessary, to constrain correctly the possible range of values.

array

The array type is used to construct arrays of signals, or arrays (2 or more dimensional arrays). The most often, this type is used to describe memories : 1 dimensional array of signals. In the case of arrays of dimension greater than or equal to 2, the problem of the use of resources arises. Indeed for this type of array a very large number of multiplexers is necessary. Example of declaration:

1
type ram_type is array (5 downto 0) of std_logic_vector(7 downto 0);

We define a ram_type composed of 6 signals of 8 bits. A signal of this type is then addressable as well in reading as in writing. The index used must be of type integer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
signal SR_MyArray       : ram_type;
signal SR_Index         : integer range 0 to 5;
signal SC_ArrayOutput   : std_logic_vector(5 downto 0);
.
.
.
SR_MyArray(SR_Index)  <= "100011";
.
.
.
SC_ArrayOutput <= SR_MyArray(SR_Index);

For more flexibility, it is possible to declare unconstrain array types, and then set the size at signal declaration:

1
2
3
4
type ram_type_dynamic is array (natural range <>) of std_logic_vector(7 downto 0);

signal SR_Array_1        : ram_type_dynamic(0 to 3);
signal SR_Array_2        : ram_type_dynamic(0 to 61);

Record

The record type is used to build data structures that can be heterogeneous. It is the equivalent of struct in C.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
type my_record is record
value_1 : std_logic_vector(7 downto 0);
value_2 : std_logic;
value_3 : integer range -12 to 14;
value_4 : my_type; -- you can include your own types in the records
end record
.
.
.
signal SC_dataInput : my_record;
.
.
.
SC_dataInput.value_1 <= "01001101";
SC_dataInput.value_3 <= 7;
O_output             <= SC_dataInput.value_2;

It is possible to use records in tables:

1
2
3
4
5
6
7
8
9
type my_array is array (12 to 0) of my_record;
.
.
.
signal SR_Data : my_array;
.
.
.
SR_Data(4).value_1 <= "01001101";

line

It is possible to manipulate text files in VHDL to facilitate simulations. The manipulation of files is obviously not synthesizable, it doesn't make sense on FPGA or ASIC. The line type is the type that allows as its name indicates to manipulate lines.


Dernière mise à jour: March 19, 2024