ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2025
Просмотров: 3454
Скачиваний: 2
Data Types |
37 |
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; |
-- |
legal (arithmetic operation OK), unsigned |
w |
<= |
a AND b; |
-- |
legal (logical operation OK) |
3.8Data Conversion
VHDL does not allow direct operations (arithmetic, logical, etc.) between data of di¤erent types. Therefore, it is often necessary to convert data from one type to another. This can be done in basically two ways: or we write a piece of VHDL code for that, or we invoke a FUNCTION from a pre-defined PACKAGE which is capable of doing it for us.
If the data are closely related (that is, both operands have the same base type, despite being declared as belonging to two di¤erent type classes), then the std_logic_1164 of the ieee library provides straightforward conversion functions. An example is shown below.
Example: Legal and illegal operations with subsets.
TYPE |
long IS INTEGER RANGE -100 |
TO 100; |
|||
TYPE |
short IS |
INTEGER RANGE -10 |
TO 10; |
||
SIGNAL x |
: short; |
||||
SIGNAL y |
: long; |
||||
... |
|||||
y <= |
2*x |
+ 5; |
-- error, type mismatch |
||
y <= |
long(2*x |
+ 5); |
-- OK, result converted into type long |
||
Several data conversion functions can be found in the std_logic_arith package of the ieee library. They are:
conv_integer(p) : Converts a parameter p of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an INTEGER value. Notice that STD_LOGIC_ VECTOR is not included.
conv_unsigned(p, b): Converts a parameter p of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an UNSIGNED value with size b bits.
conv_signed(p, b): Converts a parameter p of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to a SIGNED value with size b bits.
TLFeBOOK
38 |
Chapter 3 |
conv_std_logic_vector(p, b): Converts a parameter p of type INTEGER, UNSIGNED, SIGNED, or STD_LOGIC to a STD_LOGIC_VECTOR value with size b bits.
Example: Data conversion.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
...
SIGNAL a: IN UNSIGNED (7 DOWNTO 0);
SIGNAL b: IN UNSIGNED (7 DOWNTO 0);
SIGNAL y: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
...
y <= CONV_STD_LOGIC_VECTOR ((a+b), 8);
--Legal operation: a+b is converted from UNSIGNED to an
--8-bit STD_LOGIC_VECTOR value, then assigned to y.
Another alternative was already mentioned in the previous section. It consists of using the std_logic_signed or the std_logic_unsigned package from the ieee library. Such packages allow operations with STD_LOGIC_VECTOR data to be performed as if the data were of type SIGNED or UNSIGNED, respectively.
Besides the data conversion functions described above, several others are often o¤ered by synthesis tool vendors.
3.9 Summary
The fundamental synthesizable VHDL data types are summarized in table 3.2.
3.10 Additional Examples
We close this chapter with the presentation of additional examples illustrating the specification and use of data types. The development of actual designs from scratch will only be possible after we conclude laying out the basic foundations of VHDL (chapters 1 to 4).
Example 3.1: Dealing with Data Types
The legal and illegal assignments presented next are based on the following type definitions and signal declarations:
TLFeBOOK
Data Types |
39 |
Table 3.2
Synthesizable data types.
Data types |
Synthesizable values |
BIT, BIT_VECTOR |
‘0’, ‘1’ |
STD_LOGIC, STD_LOGIC_VECTOR |
‘X’, ‘0’, ‘1’, ‘Z’ (resolved) |
STD_ULOGIC, STD_ULOGIC_VECTOR |
‘X’, ‘0’, ‘1’, ‘Z’ (unresolved) |
BOOLEAN |
True, False |
NATURAL |
From 0 to þ2, 147, 483, 647 |
INTEGER |
From 2,147,483,647 to þ2,147,483,647 |
SIGNED |
From 2,147,483,647 to þ2,147,483,647 |
UNSIGNED |
From 0 to þ2,147,483,647 |
User-defined integer type |
Subset of INTEGER |
User-defined enumerated type |
Collection enumerated by user |
SUBTYPE |
Subset of any type (preor user-defined) |
ARRAY |
Single-type collection of any type above |
RECORD |
Multiple-type collection of any types above |
TYPE byte IS ARRAY (7 DOWNTO 0) OF STD_LOGIC; |
-- 1D |
|
-- array |
||
TYPE mem1 IS ARRAY (0 TO 3, 7 DOWNTO 0) OF STD_LOGIC; |
-- 2D |
|
-- array |
||
TYPE mem2 IS ARRAY (0 TO 3) |
OF byte; |
-- 1Dx1D |
-- array |
||
TYPE mem3 IS ARRAY (0 TO 3) |
OF STD_LOGIC_VECTOR(0 TO 7); |
-- 1Dx1D |
-- array |
||
SIGNAL a: STD_LOGIC; |
-- scalar signal |
|
SIGNAL b: BIT; |
-- scalar signal |
|
SIGNAL x: byte; |
-- 1D signal |
|
SIGNAL y: STD_LOGIC_VECTOR (7 DOWNTO 0); |
-- 1D |
signal |
SIGNAL v: BIT_VECTOR (3 DOWNTO 0); |
-- 1D |
signal |
SIGNAL z: STD_LOGIC_VECTOR (x'HIGH DOWNTO 0); |
-- 1D |
signal |
SIGNAL w1: mem1; |
-- 2D |
signal |
SIGNAL w2: mem2; |
-- 1Dx1D signal |
||
SIGNAL w3: mem3; |
-- 1Dx1D signal |
||
-------- Legal scalar |
assignments: --------------------- |
||
x(2) |
<= |
a; |
-- same types (STD_LOGIC), correct indexing |
y(0) |
<= |
x(0); |
-- same types (STD_LOGIC), correct indexing |
z(7) |
<= |
x(5); |
-- same types (STD_LOGIC), correct indexing |
b <= |
v(3); |
-- same types (BIT), correct indexing |
|
w1(0,0) |
<= x(3); |
-- same types (STD_LOGIC), correct indexing |
|
TLFeBOOK
40 |
Chapter 3 |
w1(2,5) <= y(7); |
-- same types (STD_LOGIC), correct indexing |
||||||
w2(0)(0) |
<= |
x(2); |
-- |
same |
types (STD_LOGIC), |
correct |
indexing |
w2(2)(5) |
<= |
y(7); |
-- |
same |
types (STD_LOGIC), |
correct |
indexing |
w1(2,5) |
<= w2(3)(7); |
-- same types (STD_LOGIC), correct indexing |
|
------- |
Illegal scalar assignments: |
-------------------- |
|
b <= a; |
-- type mismatch (BIT x STD_LOGIC) |
||
w1(0)(2) <= x(2); |
-- index of w1 |
must be 2D |
|
w2(2,0) |
<= a; |
-- index of w2 |
must be 1Dx1D |
------- |
Legal vector |
assignments: ---------------------- |
|
x <= "11111110";
y <= ('1','1','1','1','1','1','0','Z'); z <= "11111" & "000";
x <= (OTHERS => '1');
y <= (7 =>'0', 1 =>'0', OTHERS => '1');
z <= y; |
|||
y(2 DOWNTO 0) <= z(6 DOWNTO 4); |
|||
w2(0)(7 DOWNTO 0) <= "11110000"; |
|||
w3(2) |
<= y; |
||
z <= w3(1); |
|||
z(5 DOWNTO 0) <= w3(1)(2 TO 7); |
|||
w3(1) |
<= "00000000"; |
||
w3(1) |
<= (OTHERS => '0'); |
||
w2 |
<= |
((OTHERS=>'0'),(OTHERS=>'0'),(OTHERS=>'0'),(OTHERS=>'0')); |
|
w3 |
<= |
("11111100", ('0','0','0','0','Z','Z','Z','Z',), |
|
(OTHERS=>'0'), (OTHERS=>'0')); |
|||
w1 |
<= |
((OTHERS=>'Z'), "11110000" ,"11110000", (OTHERS=>'0')); |
|
------ Illegal array assignments: ---------------------- |
|||
x <= y; |
-- type mismatch |
||
y(5 TO 7) <= z(6 DOWNTO 0); |
-- wrong direction of y |
||
w1 |
<= |
(OTHERS => '1'); |
-- w1 is a 2D array |
w1(0, |
7 DOWNTO 0) <="11111111"; |
-- w1 is a 2D array |
|
w2 |
<= |
(OTHERS => 'Z'); |
-- w2 is a 1Dx1D array |
w2(0, |
7 DOWNTO 0) <= "11110000"; |
-- index should be 1Dx1D |
|
-- Example of |
data type independent array initialization: |
||
FOR i IN |
0 |
TO |
3 LOOP |
FOR j |
IN 7 |
DOWNTO 0 LOOP |
|
x(j) <= |
'0'; |
||
y(j) |
<= |
'0' |
|
TLFeBOOK
Data Types |
41 |
z(j) <= '0'; w1(i,j) <= '0'; w2(i)(j) <= '0'; w3(i)(j) <= '0';
END LOOP;
END LOOP;
---------------------------------------------------------
Example 3.2: Single Bit Versus Bit Vector
This example illustrates the di¤erence between a single bit assignment and a bit vector assignment (that is, BIT versus BIT_VECTOR, STD_LOGIC versus STD_ LOGIC_VECTOR, or STD_ULOGIC versus STD_ULOGIC_VECTOR).
Two VHDL codes are presented below. Both perform the AND operation between the input signals and assign the result to the output signal. The only di¤erence between them is the number of bits in the input and output ports (one bit in the first, four bits in the second). The circuits inferred from these codes are shown in figure 3.2.
---------------------------- |
----------------------------------- |
ENTITY and2 IS |
ENTITY and2 IS |
PORT (a, b: IN BIT; |
PORT (a, b: IN BIT_VECTOR (0 TO 3); |
x: OUT BIT); |
x: OUT BIT_VECTOR (0 TO 3)); |
END and2; |
END and2; |
---------------------------- |
----------------------------------- |
ARCHITECTURE and2 OF and2 IS |
ARCHITECTURE and2 OF and2 IS |
BEGIN |
BEGIN |
x <= a AND b; |
x <= a AND b; |
END and2; |
END and2; |
---------------------------- |
----------------------------------- |
Example 3.3: Adder
Figure 3.3 shows the top-level diagram of a 4-bit adder. The circuit has two inputs (a, b) and one output (sum). Two solutions are presented. In the first, all signals are of type SIGNED, while in the second the output is of type INTEGER. Notice in solution 2 that a conversion function was used in line 13, for the type of a þ b does not match that of sum. Notice also the inclusion of the std_logic_arith package (line 4 of each solution), which specifies the SIGNED data type. Recall that a SIGNED value is represented like a vector; that is, similar to STD_LOGIC_VECTOR, not like an INTEGER.
TLFeBOOK
42 |
Chapter 3 |
1 ----- Solution 1: in/out=SIGNED ----------
2LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 USE ieee.std_logic_arith.all;
5 ------------------------------------------
6ENTITY adder1 IS
7PORT ( a, b : IN SIGNED (3 DOWNTO 0);
8 |
sum : OUT SIGNED (4 DOWNTO 0)); |
9 |
END adder1; |
10 |
------------------------------------------ |
11 |
ARCHITECTURE adder1 OF adder1 IS |
12BEGIN
13sum <= a + b;
14END adder1;
15 ------------------------------------------
a |
x |
a(0) |
x(0) |
||||||
b |
b(0) |
||||||||
a(1) |
|||||||||
x(1)
b(1)
a(2)
x(2)
b(2)
a(3)
x(3)
b(3)
Figure 3.2
Circuits inferred from the codes of example 3.2.
a (3:0) |
+ |
sum (4:0) |
||||
b (3:0) |
||||||
Figure 3.3 |
||||||
4-bit adder of example 3.3. |
||||||
TLFeBOOK
Data Types |
43 |
Figure 3.4
Simulation results of example 3.3.
1 ------ Solution 2: out=INTEGER -----------
2LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 USE ieee.std_logic_arith.all;
5 ------------------------------------------
6ENTITY adder2 IS
7PORT ( a, b : IN SIGNED (3 DOWNTO 0);
8 |
sum : OUT INTEGER RANGE -16 TO 15); |
9 |
END adder2; |
10 |
------------------------------------------ |
11 |
ARCHITECTURE adder2 OF adder2 IS |
12BEGIN
13sum <= CONV_INTEGER(a + b);
14END adder2;
15 ------------------------------------------
Simulation results (for either solution) are presented in figure 3.4. Notice that the numbers are represented in hexadecimal 2’s complement form. Since the input range is from 8 to 7, its representation is 7 ! 7, 6 ! 6, . . . , 0 ! 0, 1 ! 15, 2 ! 14,
. . . , 8 ! 8. Likewise, the output range is from 16 to 15, so its representation is 15 ! 15, . . . , 0 ! 0, 1 ! 31, . . . , 16 ! 16. Therefore, 2H þ 4H ¼ 06H (that is, 2 þ 4 ¼ 6), 4H þ 8H ¼ 1CH (that is, 4 þ ( 8) ¼ 4), etc., where H ¼ Hexadecimal.
3.11Problems
The problems below are based on the following TYPE definitions and SIGNAL declarations:
TYPE array1 IS ARRAY (7 DOWNTO 0) OF STD_LOGIC;
TYPE array2 IS ARRAY (3 DOWNTO 0, 7 DOWNTO 0) OF STD_LOGIC; TYPE array3 IS ARRAY (3 DOWNTO 0) OF array1;
TLFeBOOK
44 |
Chapter 3 |
SIGNAL a : BIT;
SIGNAL b : STD_LOGIC;:
SIGNAL x : array1;
SIGNAL y : array2;
SIGNAL w : array3;
SIGNAL z : STD_LOGIC_VECTOR (7 DOWNTO 0);
Problem 3.1
Determine the dimensionality (scalar, 1D, 2D, or 1Dx1D) of the signals given. Also, write down a numeric example for each signal.
Problem 3.2
Determine which among the assignments in table P3.2 are legal and which are illegal. Briefly justify your answers. Also, determine the dimensionality of each assignment (on both sides).
Problem 3.3: Subtypes
Consider the pre-defined data types INTEGER and STD_LOGIC_VECTOR. Consider also the user-defined types ARRAY1 and ARRAY2 specified above. For each, write down a possible SUBTYPE.
Problem 3.4: ROM
Consider the implementation of a ROM (read-only memory). It can be done utilizing a 1Dx1D CONSTANT. Say that the ROM must be organized as a pile of eight words of four bits each. Create an array called rom, then define a signal of type rom capable of solving this problem. Choose the values to be stored in the ROM and declare them along with your CONSTANT, that is, ‘‘CONSTANT my_rom: rom :=(values);’’.
Problem 3.5: Simple Adder
Rewrite solution 1 of example 3.3, but this time with all input and output signals of type STD_LOGIC_VECTOR. (Suggestion: review section 3.8).
TLFeBOOK