ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 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