ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2025
Просмотров: 3451
Скачиваний: 2
Data Types |
29 |
TYPE my_integer IS RANGE -32 TO 32; -- A user-defined subset of integers.
TYPE student_grade IS RANGE 0 TO 100;
--A user-defined subset of integers or naturals.
User-defined enumerated types:
TYPE bit IS ('0', '1');
-- This is indeed the pre-defined type BIT
TYPE my_logic IS ('0', '1', 'Z');
-- A user-defined subset of std_logic.
TYPE bit_vector IS ARRAY (NATURAL RANGE <>) OF BIT;
--This is indeed the pre-defined type BIT_VECTOR.
--RANGE <> is used to indicate that the range is unconstrained.
--NATURAL RANGE <>, on the other hand, indicates that the only
--restriction is that the range must fall within the NATURAL
--range.
TYPE state IS (idle, forward, backward, stop);
-- An enumerated data type, typical of finite state machines.
TYPE color IS (red, green, blue, white); -- Another enumerated data type.
The encoding of enumerated types is done sequentially and automatically (unless specified otherwise by a user-defined attribute, as will be shown in chapter 4). For example, for the type color above, two bits are necessary (there are four states), being ‘‘00’’ assigned to the first state (red), ‘‘01’’ to the second (green), ‘‘10’’ to the next (blue), and finally ‘‘11’’ to the last state (white).
3.3Subtypes
A SUBTYPE is a TYPE with a constraint. The main reason for using a subtype rather than specifying a new type is that, though operations between data of di¤erent types are not allowed, they are allowed between a subtype and its corresponding base type.
Examples: The subtypes below were derived from the types presented in the previous examples.
TLFeBOOK
30 |
Chapter 3 |
SUBTYPE natural IS INTEGER RANGE 0 TO INTEGER'HIGH;
-- As expected, NATURAL is a subtype (subset) of INTEGER.
SUBTYPE my_logic IS STD_LOGIC RANGE '0' TO 'Z';
--Recall that STD_LOGIC=('X','0','1','Z','W','L','H','-').
--Therefore, my_logic=('0','1','Z').
SUBTYPE my_color IS color RANGE red TO blue;
--Since color=(red, green, blue, white), then
--my_color=(red, green, blue).
SUBTYPE small_integer IS INTEGER RANGE -32 TO 32; -- A subtype of INTEGER.
Example: Legal and illegal operations between types and subtypes.
SUBTYPE my_logic IS STD_LOGIC RANGE '0' TO '1';
SIGNAL a: BIT;
SIGNAL b: STD_LOGIC;
SIGNAL c: my_logic;
...
b |
<= |
a; |
-- |
illegal (type mismatch: BIT versus STD_LOGIC) |
b |
<= |
c; |
-- |
legal (same "base" type: STD_LOGIC) |
3.4Arrays
Arrays are collections of objects of the same type. They can be one-dimensional (1D), two-dimensional (2D), or one-dimensional-by-one-dimensional (1Dx1D). They can also be of higher dimensions, but then they are generally not synthesizable.
Figure 3.1 illustrates the construction of data arrays. A single value (scalar) is shown in (a), a vector (1D array) in (b), an array of vectors (1Dx1D array) in (c), and an array of scalars (2D array) in (d).
Indeed, the pre-defined VHDL data types (seen in section 3.1) include only the scalar (single bit) and vector (one-dimensional array of bits) categories. The predefined synthesizable types in each of these categories are the following:
Scalars: BIT, STD_LOGIC, STD_ULOGIC, and BOOLEAN.
Vectors: BIT_VECTOR, STD_LOGIC_VECTOR, STD_ULOGIC_VECTOR, INTEGER, SIGNED, and UNSIGNED.
TLFeBOOK
Data Types |
31 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
|||||||||||||
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
|||||||
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
|||||||||||||
(a) (b) (c) (d)
Figure 3.1
Illustration of (a) scalar, (b) 1D, (c) 1Dx1D, and (d) 2D data arrays.
As can be seen, there are no pre-defined 2D or 1Dx1D arrays, which, when necessary, must be specified by the user. To do so, the new TYPE must first be defined, then the new SIGNAL, VARIABLE, or CONSTANT can be declared using that data type. The syntax below should be used.
To specify a new array type:
TYPE type_name IS ARRAY (specification) OF data_type;
To make use of the new array type:
SIGNAL signal_name: type_name [:= initial_value];
In the syntax above, a SIGNAL was declared. However, it could also be a CONSTANT or a VARIABLE. Notice that the initial value is optional (for simulation only).
Example: 1Dx1D array.
Say that we want to build an array containing four vectors, each of size eight bits. This is then an 1Dx1D array (see figure 3.1). Let us call each vector by row, and the complete array by matrix. Additionally, say that we want the leftmost bit of each vector to be its MSB (most significant bit), and that we want the top row to be row 0. Then the array implementation would be the following (notice that a signal, called x, of type matrix, was declared as an example):
TYPE |
row IS |
ARRAY (7 DOWNTO 0) OF STD_LOGIC; |
-- 1D array |
|
TYPE |
matrix |
IS ARRAY (0 TO 3) OF row; |
-- 1Dx1D |
array |
SIGNAL x: matrix; |
-- 1Dx1D |
signal |
||
TLFeBOOK
32 |
Chapter 3 |
Example: Another 1Dx1D array.
Another way of constructing the 1Dx1D array above would be the following:
TYPE matrix IS ARRAY (0 TO 3) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
From a data-compatibility point of view, the latter might be advantageous over that in the previous example (see example 3.1).
Example: 2D array.
The array below is truly two-dimensional. Notice that its construction is not based on vectors, but rather entirely on scalars.
TYPE matrix2D IS ARRAY (0 TO 3, 7 DOWNTO 0) OF STD_LOGIC;
-- 2D array
Example: Array initialization.
As shown in the syntax above, the initial value of a SIGNAL or VARIABLE is optional. However, when initialization is required, it can be done as in the examples below.
... :="0001"; |
-- for 1D |
array |
|
... :=('0','0','0','1') |
-- for 1D |
array |
|
... :=(('0','1','1','1'), ('1','1','1','0')); |
-- |
for 1Dx1D or |
|
-- |
2D array |
||
Example: Legal and illegal array assignments.
The assignments in this example are based on the following type definitions and signal declarations:
TYPE row IS ARRAY (7 DOWNTO 0) OF STD_LOGIC;
-- 1D array
TYPE array1 IS ARRAY (0 TO 3) OF row;
-- 1Dx1D array TYPE array2 IS ARRAY (0 TO 3) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
-- 1Dx1D TYPE array3 IS ARRAY (0 TO 3, 7 DOWNTO 0) OF STD_LOGIC;
-- 2D array
SIGNAL x: row;
SIGNAL y: array1;
SIGNAL v: array2;
SIGNAL w: array3;
TLFeBOOK
Data Types |
33 |
--------- Legal scalar assignments: ---------------
--The scalar (single bit) assignments below are all legal,
--because the "base" (scalar) type is STD_LOGIC for all signals
--(x,y,v,w).
x(0) |
<= |
y(1)(2); |
-- notice two pairs of parenthesis |
|||
-- (y is 1Dx1D) |
||||||
x(1) |
<= |
v(2)(3); |
-- two pairs of parenthesis (v is 1Dx1D) |
|||
x(2) |
<= |
w(2,1); |
-- a single pair of parenthesis (w is 2D) |
|||
y(1)(1) |
<= x(6); |
|||||
y(2)(0) |
<= v(0)(0); |
|||||
y(0)(0) |
<= w(3,3); |
|||||
w(1,1) <= x(7); |
||||||
w(3,0) <= v(0)(3); |
||||||
--------- |
Vector assignments: |
--------------------- |
||||
x <= |
y(0); |
-- |
legal (same data types: ROW) |
|||
x <= |
v(1); |
-- |
illegal (type mismatch: ROW x |
|||
-- |
STD_LOGIC_VECTOR) |
|||||
x <= |
w(2); |
-- |
illegal (w must have 2D index) |
|||
x <= |
w(2, 2 DOWNTO 0); |
-- |
illegal (type mismatch: ROW x |
|||
-- |
STD_LOGIC) |
|||||
v(0) |
<= |
w(2, 2 DOWNTO 0); |
-- |
illegal (mismatch: STD_LOGIC_VECTOR |
||
-- |
x STD_LOGIC) |
|||||
v(0) |
<= |
w(2); |
-- |
illegal (w must have 2D index) |
||
y(1) |
<= |
v(3); |
-- |
illegal (type mismatch: ROW x |
||
-- |
STD_LOGIC_VECTOR) |
|||||
y(1)(7 DOWNTO 3) <= x(4 DOWNTO 0); |
-- legal (same type, |
|||||
-- same size) |
||||||
v(1)(7 DOWNTO 3) <= v(2)(4 |
DOWNTO 0); |
-- legal (same type, |
||||
-- same size) |
||||||
w(1, |
5 DOWNTO 1) <= v(2)(4 |
DOWNTO 0); |
-- illegal (type mismatch) |
|||
3.5Port Array
As we have seen, there are no pre-defined data types of more than one dimension. However, in the specification of the input or output pins (PORTS) of a circuit (which is made in the ENTITY), we might need to specify the ports as arrays of vectors. Since TYPE declarations are not allowed in an ENTITY, the solution is to declare
TLFeBOOK
34 |
Chapter 3 |
user-defined data types in a PACKAGE, which will then be visible to the whole design (thus including the ENTITY). An example is shown below.
------- Package: --------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
----------------------------
PACKAGE my_data_types IS
TYPE vector_array IS ARRAY (NATURAL RANGE <>) OF
STD_LOGIC_VECTOR(7 DOWNTO 0);
END my_data_types;
--------------------------------------------
------- |
Main code: ------------------------- |
|
LIBRARY ieee; |
||
USE |
ieee.std_logic_1164.all; |
|
USE |
work.my_data_types.all; |
-- user-defined package |
--------------------------- |
||
ENTITY mux IS
PORT (inp: IN VECTOR_ARRAY (0 TO 3);
... ); END mux;
... ;
--------------------------------------------
As can be seen in the example above, a user-defined data type, called vector_array, was created, which can contain an indefinite number of vectors of size eight bits each (NATURAL RANGE <> signifies that the range is not fixed, with the only restriction that it must fall within the NATURAL range, which goes from 0 to þ2,147,483,647). The data type was saved in a PACKAGE called my_data_types, and later used in an ENTITY to specify a PORT called inp. Notice in the main code the inclusion of an additional USE clause to make the user-defined package my_data_types visible to the design.
Another option for the PACKAGE above would be that shown below, where a CONSTANT declaration is included (a detailed study of PACKAGES will be presented in chapter 10).
------- Package: -------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
TLFeBOOK
Data Types |
35 |
----------------------------
PACKAGE my_data_types IS
CONSTANT b: INTEGER := 7;
TYPE vector_array IS ARRAY (NATURAL RANGE <>) OF
STD_LOGIC_VECTOR(b DOWNTO 0);
END my_data_types;
-------------------------------------------------
3.6Records
Records are similar to arrays, with the only di¤erence that they contain objects of di¤erent types.
Example:
TYPE birthday IS RECORD
day: INTEGER RANGE 1 TO 31;
month: month_name;
END RECORD;
3.7Signed and Unsigned Data Types
As mentioned earlier, these types are defined in the std_logic_arith package of the ieee library. Their syntax is illustrated in the examples below.
Examples:
SIGNAL x: SIGNED (7 DOWNTO 0);
SIGNAL y: UNSIGNED (0 TO 3);
Notice that their syntax is similar to that of STD_LOGIC_VECTOR, not like that of an INTEGER, as one might have expected.
An UNSIGNED value is a number never lower than zero. For example, ‘‘0101’’ represents the decimal 5, while ‘‘1101’’ signifies 13. If type SIGNED is used instead, the value can be positive or negative (in two’s complement format). Therefore, ‘‘0101’’ would represent the decimal 5, while ‘‘1101’’ would mean 3.
To use SIGNED or UNSIGNED data types, the std_logic_arith package, of the ieee library, must be declared. Despite their syntax, SIGNED and UNSIGNED data types are intended mainly for arithmetic operations, that is, contrary to
TLFeBOOK
36 |
Chapter 3 |
STD_LOGIC_VECTOR, they accept arithmetic operations. On the other hand, logical operations are not allowed. With respect to relational (comparison) operations, there are no restrictions.
Example: Legal and illegal operations with signed/unsigned data types.
LIBRARY ieee; |
|||
USE ieee.std_logic_1164.all; |
|||
USE ieee.std_logic_arith.all; |
-- extra package necessary |
||
... |
|||
SIGNAL |
a: IN SIGNED (7 DOWNTO 0); |
||
SIGNAL |
b: IN SIGNED (7 DOWNTO 0); |
||
SIGNAL |
x: OUT SIGNED (7 DOWNTO 0); |
||
... |
|||
v <= a |
+ b; |
-- legal (arithmetic operation OK) |
|
w <= a |
AND b; |
-- illegal (logical operation not OK) |
|
Example: Legal and illegal operations with std_logic_vector.
LIBRARY ieee; |
|||
USE ieee.std_logic_1164.all; |
-- no extra package required |
||
... |
|||
SIGNAL |
a: IN STD_LOGIC_VECTOR (7 DOWNTO 0); |
||
SIGNAL |
b: IN STD_LOGIC_VECTOR (7 DOWNTO 0); |
||
SIGNAL |
x: OUT STD_LOGIC_VECTOR (7 DOWNTO 0); |
||
... |
|||
v <= a |
+ b; |
-- illegal (arithmetic operation not OK) |
|
w <= a |
AND b; |
-- legal (logical operation OK) |
|
Despite the constraint mentioned above, there is a simple way of allowing data of type STD_LOGIC_VECTOR to participate directly in arithmetic operations. For that, the ieee library provides two packages, std_logic_signed and std_logic_unsigned, which allow operations with STD_LOGIC_VECTOR data to be performed as if the data were of type SIGNED or UNSIGNED, respectively.
Example: Arithmetic operations with std_logic_vector.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all; |
-- extra package included |
...
TLFeBOOK