Scalar Types
BEGIN PROCESS(X)
VARIABLE a : INTEGER; VARIABLE b : int_type; BEGIN a := 1; --Ok 1 a := -1; --Ok 2 a := 1.0; --error 3 END PROCESS; END test;
The first two statements (1 and 2) show examples of a positive integer assignment and a negative integer assignment. Line 3 shows a non- integer assignment to an integer variable. This line causes the compiler to issue an error message. Any numeric value with a decimal point is con- sidered a real number value. Because VHDL is a strongly typed language,
for the assignment to take place, either the base types must match or a type-casting operation must be performed.
REAL TYPES Real types are used to declare objects that emulate
mathematical real numbers. They can be used to represent numbers out of the range of integer values as well as fractional values. The minimum range of real numbers is also specified by the Standard package in the Standard Library, and is from 1.0E38 to 1.0E38. These numbers are represented by the following notation:
or -number.number[E or -number]
Following are a few examples of some real numbers: ARCHITECTURE test OF test IS
SIGNAL a : REAL; BEGIN a <= 1.0; --Ok 1 a <= 1; --error 2 a <= -1.0E10; --Ok 3 a <= 1.5E-20; --Ok 4 a <= 5.3 ns; --error 5 END test;
Line 1 shows how to assign a real number to a signal of type REAL. All real numbers have a decimal point to distinguish them from integer values. Line 2 is an example of an assignment that does not work. Signal ais of type REAL, and a real value must be assigned to signal a. The value 1 is of type INTEGER, so a type mismatch is generated by this line.
Line 3 shows a very large negative number. The numeric characters to the left of the character E represent the mantissa of the real number, while the numeric value to the right represents the exponent.
Line 4 shows how to create a very small number. In this example, the exponent is negative so the number is very small.
Line 5 shows how a type TIMEcannot be assigned to a real signal. Even though the numeric part of the value looks like a real number, because of the units after the value, the value is considered to be of type TIME.
ENUMERATED TYPES An enumerated type is a very powerful tool
for abstract modeling. A designer can use an enumerated type to repre- sent exactly the values required for a specific operation. All of the values of an enumerated type are user-defined. These values can be identifiers or single-character literals. An identifier is like a name. Examples are x, abc, and black. Character literals are single characters enclosed in quotes, such as ‘X’,‘1’, and ‘0’.
A typical enumerated type for a four-state simulation value system looks like this:
TYPE fourval IS ( ‘X’, ‘0’, ‘1’, ‘Z’ );
This type contains four character literal values that each represent a unique state in the four-state value system. The values represent the following conditions:
■ ‘X’—An unknown value ■ ‘0’—A logical 0 or false value
■ ‘1’—A logical 1 or true value
■ ‘Z’—A tristate or open collector value
Character literals are needed for values ‘1’and ‘0’to separate these values from the integer values 1 and 0. It would be an error to use the val- ues 1 and 0 in an enumerated type, because these are integer values. The characters Xand Zdo not need quotes around them because they do not represent any other type, but the quotes were used for uniformity.
Another example of an enumerated type is shown here: TYPE color IS ( red, yellow, blue, green, orange );
In this example, the type values are very abstract—that is, not repre- senting physical values that a signal might attain. The type values in type colorare also all identifiers. Each identifier represents a unique value of the type; therefore, all identifiers of the type must be unique.
Each identifier in the type has a specific position in the type, determined by the order in which the identifier appears in the type. The first identifier has a position number of 0, the next a position number of 1, and so on. (Chapter 5, “Subprograms and Packages” includes some examples using position numbers of a type.)
A typical use for an enumerated type would be representing all of the instructions for a microprocessor as an enumerated type. For instance, an enumerated type for a very simple microprocessor could look like this:
TYPE instruction IS ( add, sub, lda, ldb, sta, stb, outa, xfr );
The model that uses this type might look like this:
PACKAGE instr IS
TYPE instruction IS ( add, sub, lda, ldb, sta, stb, outa, xfr );
END instr;
USE WORK.instr.ALL; ENTITY mp IS
PORT (instr : IN instruction; PORT (addr : IN INTEGER; PORT (data : INOUT INTEGER); END mp;
ARCHITECTURE mp OF mp IS BEGIN
PROCESS(instr)
TYPE regtype IS ARRAY(0 TO 255) OF INTEGER; VARIABLE a, b : INTEGER;
VARIABLE reg : regtype; BEGIN
--select instruction to CASE instr is --execute
WHEN lda =>
a := data; --load a accumulator
WHEN ldb =>
b := data; --load b accumulator
WHEN add =>
a := a 1 b; --add accumulators
WHEN sub =>
a := a -b; --subtract accumulators
WHEN sta =>
reg(addr) := a; --put a accum in reg array
WHEN stb =>
reg(addr) := b; --put b accum in reg array
WHEN outa =>
data <= a; --output a accum
WHEN xfr => --transfer b to a a := b;
END CASE;