prepared by P.Bakowski
This chapter starts with the presentation of language lexical elements allowing to build identifiers. The identifiers are the names of objects such as constants, variables or signals and the names of literals.
The objects may be seen as forms or containers, the literals are contentsof objects. Each object is characterized by its type or form. Some objects are simple, some are complex or composed. The content of variables and signals vary during the simulation process. The content of constants is always the same.
We will present elementary operators that can be applied to basic objects. We will illustrate how to build arithmetical and logical expressions from basic objects and operators. The operators must correspond to the nature and to the type of the involved objects.
There are three classes of basic objects in VHDL: the variables, the constants and the signals. The variables and constants are well known programming objects. The signals are hardware oriented; they evolve along the time flow. Given their great importance and specific meaning, the signals will be studied later in a separate chapter..
Contents: identifiers, bit strings, data types, enumeration types, arrays, physical types, records, subtypes, object declarations, alias, attributes, operators and expressions, access type , exercises
Identifier567, Toto, Alu_in, Cin, Ir4, Address_bus, ..
Note that similar like in the ADA language the case of letters is not considered significant, so the identifiers ireste and IRESTE are the same. The use of underline character generates different identifiers, so May_21 and May21 are different identifiers.
see also delimiters
Base B stands for binary, O for octal and X for hexadecimal.
B"10111011" -- length is 8 X"774" -- length is 12, equivalent to B"0111_0111_0100"
The range of integer is implementation defined, though it is guaranteed to cover - 2147483647 to +2147483647.
Composite types:
An example of an unconstrained array type declaration:
Determination of the array size represented by symbol <> is deferred until an array is declared to belong to this unconstrained type. There are two predefined array types, both of which are unconstrained. They are defined as:
The types positive and natural are subtypes of integer defined in the standard package: .
A contiguous slice of a one-dimensional array can be referred to by using a range as an index. For example reg(16 to 31) is an sixteen element array which is part of the array reg.
In order to initialize the array we can use a positional association as follows:
In this case the elements are listed in the order of the index range, starting with the left bound of the range. We can use also a named association where the index for each element is explicitly given:
Note that the elements can be written in any order. The keyword others can be used to indicate the default value to be used for all elements that are not explicitly listed:
The following is a complete example of a memory block declaration and initialization using others
type t_x01 is ('X','0','1'); type mot is array(31 downto 0) of t_x01; type memoire is array (0 to 1023) of mot; variable RAM:memoire:=(others =>(others =>'0'));
In order to refer to an element of record we use the name of the record followed by the element name.
message.mess_size message.mess_type
Aggregates can be used to initialize the records.
variable my_mess: message;
my_message := (2,4,"toto"); -- an aggregate to initialize message record my_message := (0 => 2,2 => "toto", 1 => 4); -- named association
For a variable of composite type, the default value is the composition of the default values for each element.
variable instruction : bit_vector(31 downto 0);
T'right
the right bound of T, result of type T
T'low
the lower bound of T, result of type T
(VHDL'93)
T'val(X)
returns the value (of base T) whose position is the universal integer value X
T'pred(X)
returns a value of type T whose value is the position number one less than the one of the parameter.
T'rightof(X)
returns the value that is to the right of parameter of type T
A'right(N)
the same as A'left(N) except that the right bound is returned
A'low(N)
the same as A'high(N) except that the low bound is returned
A'reverse_range(N)
returns range of A'ight(N) to A'left(N)
The relational operators =, /=, <, <=, > and >= must have the operands of the same type. They yield boolean results which are mainly used to build conditional statements:
if "0000" /= 16 then ...
For composite types like arrays and records, two values are equal if all of their corresponding elements are equal. The sign operators + and - have their usual meaning on numeric operands. In principle, the arithmetical operators cannot be used with bit and bit_vector operands.
The concatenation operator & forms new array with the contents of the right operand following the contents of the left operand. It can also concatenate a single new element to an array, or two individual elements to form an array.
The multiplication and division operators (*,/) may be applied only to integer and floating point types.
The modulus mod and remainder rem operators only work on integer types. The absolute value abs operator works on any numeric type.