Featured post

Top 5 books to refer for a VHDL beginner

VHDL (VHSIC-HDL, Very High-Speed Integrated Circuit Hardware Description Language) is a hardware description language used in electronic des...

Sunday, 23 December 2012

Operators

Definition:

Operators are means for constructing expressions.

Syntax:

adding_operator ::= + | - | &

logical_operator ::= and | or | nand | nor | xor | xnor

miscellaneous_operator ::= ** | abs | not

multiplying_operator ::= * | / | mod | rem

relational_operator ::= = | /= | < | <= | > | >=

shift_operator ::= sll | srl | sla | sra | rol | ror

Description

VHDL has a wide set of different operators, which can be divided into groups of the same precedence level (priority). The table below lists operators grouped according to priority level, highest priority first.

Table 1. Operator priority

miscellaneous operators

** | abs | not

multiplying operators

* | / | mod | rem

sign operators

+ | -

adding operators

+ | - | &

shift operators

sll | srl | sla | sra | rol | ror

relational operators

= | /= | < | <= | > | >=

logical operators

and | or | nand| nor | xor | xnor

The expressions are evaluated form left to right, operations with higher precedence are evaluated first. If the order should be different from the one resulting from this rule, parentheses can be used (Example 1).

The operands, connected with each other by an operator, are evaluated before the operation described by that operator is carried out. For some operators the right operand is evaluated only when the left operand has a certain value assigned to it. The logical operators such as and, or, nand, nor defined for the BIT and BOOLEAN operands belong to those operators.

The operators for the predefined types are defined in the STANDARD package in the STD library. These operators are functions, which always return the same value when they are called with the same values of the actual parameters. These functions are called the pure function (see function for details).

LOGICAL OPERATORS

The logical operators and, or, nand, nor, xor, xnor and not are defined for BIT and BOOLEAN types, as well as for one-dimensional arrays containing the elements of BIT and BOOLEAN. All these operators have the lowest priority, except for the operator not, which has the highest priority. The results of the logical operators for the predefined types are presented in the tables 2 through 8. The BIT type is represented by the values '0' and '1', while the Boolean type by True and False.

Table 2. Operator not

A

not A

True

'1'

False

'0'

False

'0'

True

'1'

Table 3. Operator and

A

B

A and B

True

'1'

True

'1'

True

'1'

True

'1'

False

'0'

False

'0'

False

'0'

True

'1'

False

'0'

False

'0'

False

'0'

False

'0'

Table 4. Operator or

A

B

A or B

True

'1'

True

'1'

True

'1'

True

'1'

False

'0'

True

'1'

False

'0'

True

'1'

True

'1'

False

'0'

False

'0'

False

'0'

Table 5. Operator xor

A

B

A xor B

True

'1'

True

'1'

False

'0'

True

'1'

False

'0'

True

'1'

False

'0'

True

'1'

True

'1'

False

'0'

False

'0'

False

'0'

Table 6. Operator nand

A

B

A nand B

True

'1'

True

'1'

False

'0'

True

'1'

False

'0'

True

'1'

False

'0'

True

'1'

True

'1'

False

'0'

False

'0'

True

'1'

Table 7. Operator nor

A

B

A nor B

True

'1'

True

'1'

False

'0'

True

'1'

False

'0'

False

''0'

False

'0'

True

'1'

False

'0'

False

'0'

False

'0'

True

'1'

Table 8. Operator xnor

A

B

A xnor B

True

'1'

True

'1'

True

'1'

True

'1'

False

'0'

False

''0'

False

'0'

True

'1'

False

'0'

False

'0'

False

'0'

True

'1'

RELATIONAL OPERATORS

The relational operators allow checking relation between operands, i.e. to state whether they are equal, not equal or are ordered in a way defined by operator (Table 9). Both operands must be of the same type, and the result received is always of the Boolean type.

Table 9. Relational operations

=

Equality

/=

Inequality

<

Ordering „less than”

<=

Ordering „less than or equal”

>

Ordering „greater than”

>=

Ordering „greater than or equal”

The operators: equality and inequality are predefined for all types available in the language except the file type. For other relations the operands must be of a scalar type or one-dimensional array types.

The equality operator returns the value TRUE only when both operands have the same values, and FALSE when the values are different. The inequality operator returns the value TRUE when the operators are different and FALSE when they are equal. There are certain rules that are used to compare operands depending on their type: in case of the scalar type, the operand values are equal only when the values are the same. Two values of the composite type are equal only when each value of the left operand corresponds to the value of the right operand and vice versa. In the record the corresponding elements have identical identifiers, and in the array the corresponding elements are those which appear at the same positions of arrays. In particular two null arrays of the same type are always equal.

The operators: <, <=, >, and >= return the TRUE logical value only when the condition in the given relation is met, otherwise the FALSE value is returned (Example 4).

SHIFT OPERATORS

The shift operators are defined for the one-dimensional array with the elements of the type BIT or BOOLEAN. For the shift operator an array is the left operand L and integer is the right operand R. The right operand represents the number of positions the left operand should be shifted. As the result of shifting, the value of the same type as the left operand is returned. Table 10 below shows predefined shift operators.

Table 10. Shift operators

sll

Shift left logical

srl

Shift right logical

sla

Shift left arithmetic

sra

Shift right arithmetic

rol

Rotate left logical

ror

Rotate right logical

The operator sll returns the value of the L left operand, after it has been shifted R number of times. If R is equal to 0 or L is the null array, the left operand L is returned. The single left logical operation replaces L with concatenation of the rightmost (L'Length -1) elements of L and a single value T'Left, where T is the element type of L. If R > the single shift operation is repeated R number of times. If R is a negative number, the value of the expression L srl -R is returned.

The operator srl returns the value of the left operand L after it has been shifted to right R times. In case when R is equal to 0 or L is the null array, the left operand L is returned. The single shifting operation replaces the operand L with the concatenation of the leftmost L'Length -1 elements of L and a single value T'Left, where T is the element type of L. If R is a negative number then the value of expression L sll -R is returned, otherwise the single shift operation is repeated R number of times.

The operator sla returns the value of the left operand L after it has been shifted to the left R number of times. In case when R is equal to 0 or L is the null array the left operand L is returned. The single shift operation replaces L with concatenation of the rightmost L'Length -1 elements of L and a single value L'Right. If R is a negative number, the value of the expression L sra -R is returned, otherwise the single shift operation is repeated R number of times.

The operator sra returns the value of the left operand L after it has been shifted to the right R number of times. In case when R is equal to 0 or L is the null array, the left operand L is returned. The single shift operation replaces L with a value, which is the result of concatenation whose left argument is the leftmost L'Length -1 elements of L and whose right argument is L'Left. If R is a negative number, the value of the expression L sla -R is returned, otherwise the single shift operation is repeated R number of times.

The operator rol returns the value of the L left operand after it has been rotated to the left R times. In case when R is equal to 0 or L is the null array the left operand L is returned. The single shift operation replaces L with a value which is the result of concatenation of the rightmost L'Length -1 elements of L and a single value L'Left. If R > 1 the sing.le shift operation is repeated R times. If R > 1 is a negative number, the expression L ror -R is returned.

The operator ror returns the value of the L left operand after it has been rotated to the right R number of times. In case when R is equal to 0 or L is the null array, the left operand L is returned. The single shift operation replaces L with a value which is the result of concatenation whose left argument is the leftmost L'Length -1 elements of L and whose right argument is L'Right. If R > 1 the single shift operation is repeated R times. If R is a negative number, the expression L rol -R is returned.

ADDING OPERATORS

Adding operators consist of addition, subtraction and concatenation. The adding operators are shown in the Table 11 below.

Table 11. Adding operators

+

Addition

-

Subtraction

&

Concatenation

The adding and subtraction operators perform mathematical operations, and their operands can be of any numeric type.

The concatenation (&) operator is defined for elements of one-dimensional arrays. In the concatenation, the following situations can take place:

· When both operands are one-dimensional arrays of the same type, the concatenation connects the two arrays into one. The new array contains the elements from both arrays. The direction of the new array is the same as the direction in the array of the left operand, but if the left operand is the null array then it is the same as the direction of the right operand. In case when both operands are null arrays, the direction of the right operand is assumed (Example 6).

· When one of the operands is a one-dimensional array and the second operand is a scalar of the same type as the elements of that array, then the result of the concatenation is the same as in the first point. However, in this case the second operand is treated as a one-dimensional array which contains only one element (Example 6).

· In case when both operands are of the same scalar type, then the result of concatenation is one-dimensional array with elements of the same types as the operands (Example 6).

SIGN OPERATORS

Sign operators are unary operators, i.e. have only one, right operand, which must be of a numeric type. The result of the expression evaluation is of the same type as the operand. There are two sign operators (Table 12).

Table 12. Sign operators

+

Identity

-

Negation

When ( + ) sign operator is used, the operand is returned unchanged, but In case of ( - ) sign operator the value of operand with the negated sign is returned. Because of the lower priority, the sign operator in the expression cannot be directly preceded by the multiplication operator, the exponentiation operator (**) or the abs and not operators. When these operators are used then sign operator and its operand should be enclosed in parentheses (Example 7).

MULTIPLYING OPERATORS

The multiplication and division operators are predefined for all integers, floating point numbers. Under certain conditions, they may be used for operations on physical type objects as well. The mod and rem operators, on the other hand, are defined only for the integers. When mod and rem operators are used, then both the operands and the result are of the same integer type. The multiplying operators are shown in the Table 13.

Table 13. Multiplying operators

*

Multiplication

/

Division

mod

Modulus

rem

Remainder

MISCELLANEOUS

The two miscellaneous operators are shown in the Table 14.

Table 14. Miscellaneous operators

**

Exponentiation

abs

Absolute value

The abs operator has only one operand. It allows defining the operand's absolute value. The result is of the same type as the operand.

The exponentiation operator has two operands. This operator is defined for any integer or floating point number. The right operand (exponent) must be of integer type. When the exponent is the positive integer, then the left operand is repeatedly multiplied by itself. When the exponent is the negative number, then the result is a reverse of exponentiation with the exponent equal to the absolute value of the right operand (Example 9). If the exponent is equal to 0 the result will be 1.

Examples

Example 1

v := a + y * x;

The multiplication y*x is carried out first, then a is added to the result of multiplication. This is because the multiplication operator has higher level of priority than the adding operator.

Example 2

variable We1, We2, We3, Wy : BIT := '1';
Wy := We1 and We2 xnor We1 nor We3;

For the initial value of the variables We1, We2, We3 equal to '1', the result is assigned to the variable Wy and is equal to '0'.

Example 3

variable Zm1: REAL := 100.0;
variable Zm2 : BIT_VECTOR(7 downto 0) := ('0','0','0','0','0','0','0','0');
variable Zm3, Zm4 : BIT_VECTOR(1 to 0);
Zm1 /= 342.54 -- True
Zm1 = 100.0 -- True
Zm2 /= ('1', '0', '0', '0', '0', '0', '0', '0') -- True
Zm3 = Zm4 -- True

Example 4

Zm1 > 42.54 -- True
Zm1 >= 100.0 -- True
Zm2 < ('1', '0', '0', '0', '0', '0', '0', '0') -- True
Zm3 <= Zm2 -- True

Example 5

variable Zm5 : BIT_VECTOR(3 downto 0) := ('1','0','1','1');
Zm5 sll 1 -- ('0', '1', '1', '0')
Zm5 sll 3 -- ('1', '0', '0', '0')
Zm5 sll -3 -- Zm5 srl 3
Zm5 srl 1 -- ('0', '1', '0', '1')
Zm5 srl 3 -- ('0', '0', '0', '1')
Zm5 srl -3 -- Zm5 sll 3
Zm5 sla 1 -- ('0', '1', '1', '1')
Zm5 sla 3 -- ('1', '1', '1', '1')
Zm5 sla -3 -- Zm5 sra 3
Zm5 sra 1 -- ('1', '1', '0', '1')
Zm5 sra 3 -- ('1', '1', '1', '1')
Zm5 sra -3 -- Zm5 sla 3
Zm5 rol 1 -- ('0', '1', '1', '1')
Zm5 rol 3 -- ('1', '1', '0', '1')
Zm5 rol -3 -- Zm5 ror 3
Zm5 ror 1 -- ('1', '1', '0', '1')
Zm5 ror 3 -- ('0', '1', '1', '1')
Zm5 ror -3 -- Zm5 rol 3

Example 6

constant B1: BIT_VECTOR := "0000"; -- four element array
constant B2: BIT_VECTOR := "1111"; -- four element array
constant B3: BIT_VECTOR := B1 & B2; -- eight element array, ascending
-- direction, value "00001111"
subtype BIT_VECTOR_TAB is BIT_VECTOR (1 downto 0);
constant B4: BIT_VECTOR_TAB := "01";
constant B5: BIT_VECTOR:= B4 & B2; -- six element array, descending
-- direction, value "011111"
constant B6 : BIT := '0' ;
constant B7 : BIT_VECTOR := B2 & B6;-- five element array, ascending
-- direction, value "11110"
constant B8: BIT := '1';
constant B9: BIT_VECTOR := B6 & B8; -- two element array, ascending
-- direction value "01"
Example 7
z := x * ( -y) -- A legal expression
z := x / (not y) -- A legal expression

The same expressions without parentheses would be illegal.

Example 7

variable A,B :Integer;
variable C : Real;
C:= 12.34 * ( 234.4 / 43.89 );
A:= B mod 2;

Example 8

2 ** 8 = 256
3.8 ** 3 = 54.872
4 ** (-2) = 1 / (4**2) = 0.0625

Important Notes

· All predefined operators for standard types are declared in the package STANDARD.

· The operator not is classified as a miscellaneous operator only for the purpose of defining precedence. Otherwise, it is classified as a logical operator.

Package

Formal Definition

A package declaration defines the interface to a package.

Simplified Syntax

package package_name is

package_declarations

end package package_name;

Description

The package is a unit that groups various declarations, which can be shared among several designs. Packages are stored in libraries for greater convenience. A package consists of package declaration (mandatory) and may contain a single optional package body.

The purpose of a package is to declare shareable types, subtypes, constants, signals, files, aliases, component, attributes and groups. Once a package is defined, it can be used in multiple independent designs.

Items declared in a package declaration are visible in other design units if the use clause is applied (Example 1).

The two-part specification of a package (declaration and body) allows to declare the so-called deferred constants which have no value assigned in the package declaration (Example 2). The value for a deferred constant, however, must be declared in the package body accompanying the package declaration.

The VHDL Language Standard defines two standard packages, which must be available in any VHDL environment - package STANDARD and package TEXTIO. The former contains basic declarations of types, constants and operators, while the latter defines operations for manipulating text files. Both are located in the library STD. See respective topics for details.

Apart from the VHDL Language Standard there is another standard, which extends the language and supports the extensions in the form of a package: Std_Logic_1164.

Examples

Example 1

library Packages;
use Packages.AUXILIARY.all;
architecture STRUCT of Adder is
................
end architecture STRUCT;

All declarations, which are inside the AUXILIARY package, may be used in the architecture body STRUCT of the design entity Adder. The package itself is stored in the library Packages.

Example 2

library IEEE;
use IEEE.STD_LOGIC_1164.all;
package AUXILIARY is
type MUX_input is array (INTEGER range<>) of STD_LOGIC_VECTOR (0 to 7);
type operation_set is (SHIFT_LEFT, ADD);
subtype MUX_address is POSITIVE;
function Compute_Adress (IN1 : MUX_input) return MUX_address;
constant Deferred_Con : Integer;
end AUXILIARY;

Package AUXILIARY contains a function declaration and a deferred constant, thus a package body had to be declared for this package.

Important Notes

· Package declaration may contain a subprogram (function or procedure) declaration; subprogram body is not allowed here and must appear in the package body.

· Package body must accompany a package declaration if the declaration contains subprogram declarations or deferred constants.

Package Body

Formal Definition

A package body defines the bodies of subprograms and the values of deferred constants declared in the interface to the package.

Simplified Syntax

package body package_name is

package_body_declarations

subprogram bodies declarations

deferred constants declarations

end package body package_name;

Description

The package body includes complete definitions of subprogram body declarations as well as values of deferred constants declared in corresponding package declarations. Other declarations (similar to those of package declaration) are also allowed here, but are visible only inside the package body.

The deferred constant, which has been declared in a package declaration, may be used before its full declaration only in a default expression for a local generic parameter, local port or formal parameter of subprogram.

Examples

Example 1

library IEEE;
use IEEE.STD_LOGIC_1164.all;
package AUXILIARY is
  type MUX_input is array (INTEGER range<>) of STD_LOGIC_VECTOR (0 to 7);
  type operation_set is (SHIFT_LEFT, ADD);
  subtype MUX_Address is POSITIVE;
  function Compute_Address (IN1 : MUX_input) return MUX_address;
  constant Deferred_Con : Integer;
end AUXILIARY;
package body AUXILIARY is
  function Compute_Address (IN1 : MUX_input) return MUX_address is
  begin
  ............
  end;
  constant Deferred_Con : Integer := 177;
end package body AUXILIARY;

First, the package is specified here and then the accompanying package body. Note that both have the same name.

Important Notes

· Declarations other than values of deferred constants and subprogram bodies are not visible outside the package body and can be used only locally, inside it.

· Each package can have only one body.

Physical Type

Formal Definition

Physical type is a numeric scalar that represents some quantity. Each value of a physical type has a position number that is an integer value. Any value of a physical type is a straight multiple of the primary unit of measurement for that type.

Simplified Syntax

type type_name is range left_bound to right_bound

units

  primary_unit_name

  secondary_unit_name = number primary_unit_name

  secondary_unit_name = number primary_unit_name

  . . .

end units type_name

type type_name is range left_bound downto right_bound

units

  primary_unit_name

  secondary_unit_name = number primary_unit_name

  secondary_unit_name = number primary_unit_name

  . . .

end units type_name

Description

A physical type allows to define measurement units for some physical quantity, like length, time, pressure, capacity, etc.

The range, specified at the beginning of a physical type, defines the minimum and maximum values of a given quantity expressed in the base units (see primary unit declaration below). The bounds of the range of a physical type should be in the form of locally static expression. The expression is classified as locally static if it is possible to determine its value without running the code. The value of an expression used as a range for a physical type must be of integer type. It is legal to use negative bounds.

At the core of a physical type declaration is the definition of a primary unit, and optionally, multiple secondary units. The primary unit serves as the base unit for representing values of the specified type. The secondary units are defined as multiplicity of primary units or previously specified secondary units. Their declarations may contain only integer literals.

Each value of a physical type has a corresponding position number, which is the number of primary units represented by that unit name. This way values specified in different units of the same type can be compared (Example 2).

For all physical types, both TIME and user-defined, relational and arithmetic operators can be used.

The VHDL standard predefines only one physical type: TIME, which is defined in the STANDARD package.

The value of one unit can be written in short form using the name of the unit only (i.e. without the value 1 - Example 3).

Examples

Example 1

type CAPACITY is range 0 to 1E5
units
  pF; -- picofarad
  nF = 1000 pF; -- nanofarad
  uF = 1000 nF; -- microfarad
  mF = 1000 uF; -- milifarad
  F = 1000 mF; -- farad
end units CAPACITY;

The primary unit in this example is one picofarad and the maximum value of the CAPACITY type object is 105 pF.

Example 2.

type DISTANCE is range 0 to 1E5
  units
    um; -- micrometer
    mm = 1000 um; -- millimeter
    in_a = 25400 um; -- inch
  end units DISTANCE;
variable Dis1, Dis2 : DISTANCE;
Dis1 := 28 mm;
Dis2 := 2 in_a - 1 mm;
if Dis1 < Dis2 then ...

Both, a comparison and an arithmetic operation can be performed on visually different measurement units as long as they are defined as the same type with the same base unit.

Example 3

SomeVar := mF;

This assignment means that the variable SomeVar will be assigned the value of 1 mF.

Important Notes

· Physical types are not synthesizeable. As a result, delays in signal assignments are not synthesizeable as well.

· It is not allowed to use floating point values in physical type declarations, i.e. if a conversion from millimeters to inches (25.4 mm = 1 in) would have to be performed, then millimeters could not be used as the base unit.

Port

Formal Definition

A channel for dynamic communication between a block and its environment.

Simplified Syntax

port ( port_declaration, port_declaration, &ldots;);

-- port declarations:

port_signal_name : in port_signal_type := initial_value

port_signal_name : out port_signal_type := initial_value

port_signal_name : inout port_signal_type := initial_value

port_signal_name : buffer port_signal_type := initial_value

port_signal_name : linkage port_signal_type := initial_value

Description

Ports are a part of the block interface: external - if defined by a design entity, or internal - if defined by a block statement. Each element listed in a port interface list declares a formal port, which provides a channel for dynamic communication between a block and its environment.

In practice, ports are most often used in entities and components, where they serve for declaring interface signals of a design entity (system design) or component, respectively.

In both cases, each interface element is a signal. It can be preceded by a keyword signal. After the signal's name, a mode is specified. The mode declares the direction of data flow through the port. There are five modes available in VHDL for ports:

· in input port. A variable or a signal can read a value from a port of mode in, but is not allowed to assign a value to it.

· out output port. It is allowed to make signal assignments to a port of the mode out, but it is not legal to read from it.

· inout bi-directional port. Both assignments to such a port and reading from it are allowed.

· buffer output port with read capability. It differs from inout in that it can be updated by at most one source, whereas inout can be updated by zero or more sources.

· linkage . The value of the port may be read or updated, but only by appearing as an actual corresponding to an interface object of mode linkage.

If a port is declared with a reserved word bus, then the signal declared by that port is a guarded signal of signal kind bus.

A port can be assigned a default value, which is specified by an expression evaluating to the same type as the port itself.

Examples

Example 1

entity Mux8to1 is
port (
     Inputs : in Std_Logic_Vector(7 downto 0);
     Select_s : in Std_Logic_Vector(2 downto 0);
     Output : out Std_Logic
     );
end Mux8to1;

Entity of a multiplexor 8-to-1 contains three ports: eight data inputs (specified as a vector), address inputs and one output.

Example 2

component MemDev is
port(
     Data : inout Std_Logic_Vector(7 downto 0);
     Addr : in Std_Logic_Vector(9 downto 0);
     NotCS : in Std_Logic;
     RdNotWr : in Bit
    );
end component MemDev;

Memory device is specified here as a component with four signals: data is a bi-directional data bus, address is a ten-bit input, and NotCS and RdNotWr are single inputs signals. Note that the keyword is in the header can be used in VHDL 93 only (in VHDL 87 it must be omitted).

Important Notes

· Ports declarations are signal declarations and port signals need not to be re-declared.

Procedure

Formal Definition

A procedure is a subprogram that defines algorithm for computing values or exhibiting behavior. Procedure call is a statement.

Simplified Syntax

procedure procedure_name ( formal_parameter_list )

procedure procedure_name ( formal_parameter_list ) is

  procedure_declarations

  begin

    sequential statements

  end procedure procedure_name;

Description

The procedure is a form of subprograms. It contains local declarations and a sequence of statements. Procedure can be called in any place of the architecture. The procedure definition consists of two parts:

· the procedure declaration, which contains the procedure name and the parameter list required when the procedure is called;

· the procedure body, which consists of the local declarations and statements required to execute the procedure.

PROCEDURE DECLARATION

The procedure declaration consists of the procedure name and the formal parameter list.

In the procedure specification, the identifier and optional formal parameter list follow the reserved word procedure (Example 1).

Objects classes constants, variables, signals, and files can be used as formal parameters. The class of each parameter is specified by the appropriate reserved word, unless the default class can be assumed (see below). In case of constants, variables and signals, the parameter mode determines the direction of the information flow and it decides which formal parameters can be read or written inside the procedure. Parameters of the file type have no mode assigned.

There are three modes available: in, out, and inout. When in mode is declared and object class is not defined, then by default it is assumed that the object is a constant. In case ofinout and out modes, the default class is variable. When a procedure is called, formal parameters are substituted by actual parameters. If a formal parameter is a constant, then actual parameter must be an expression. In case of formal parameters such as signal, variable and file, the actual parameters must be objects of the same class. Example 2 presents several procedure declarations with parameters of different classes and modes.

A procedure can be declared also without any parameters.

PROCEDURE BODY

Procedure body defines the procedure's algorithm composed of sequential statements. When the procedure is called it starts executing the sequence of statements declared inside the procedure body.

The procedure body consists of the subprogram declarative part After the reserved word is and the subprogram statement part placed between the reserved words begin and end. The key word procedure and the procedure name may optionally follow the end reserved word.

Declarations of a procedure are local to this declaration and can declare subprogram declarations, subprogram bodies, types, subtypes, constants, variables, files, aliases, attribute declarations, attribute specifications, use clauses, group templates and group declarations (Example 3).

A procedure can contain any sequential statements (including wait statements). A wait statement, however, cannot be used in procedures which are called from a process with a sensitivity list or from within a function. Examples 4 and 5 present two sequential statements specifications.

PROCEDURE CALL

A procedure call is a sequential or concurrent statement, depending on where it is used. A sequential procedure call is executed whenever control reaches it, while a concurrent procedure call is activated whenever any of its parameters of in or inout mode changes its value.

All actual parameters in a procedure call must be of the same type as formal parameters they substitute.

OVERLOADED PROCEDURES

The overloaded procedures are procedures with the same name but with different number or different types of formal parameters. The actual parameters decide which overloaded procedure will be called (Example 6).

Examples

Example 1

procedure Procedure_1 (variable X, Y: inout Real);

The above procedure declaration has two formal parameters: bi-directional variables X and Y of the real type.

Example 2

procedure Proc_1 (constant In1: in Integer; variable O1: out Integer);
procedure Proc_2 (signal Sig: inout Bit);

Procedure Proc_1 has two formal parameters: the first one is a constant and it is of mode in and of the integer type, the second one is an output variable of the integer type.

Procedure Proc_2 has only one parameter, which is a bi-directional signal of the type BIT.

Example 3

procedure Proc_3 (X,Y : inout Integer) is
  type Word_16 is range 0 to 65536;
  subtype Byte is Word_16 range 0 to 255;
  variable Vb1,Vb2,Vb3 : Real;
  constant Pi : Real :=3.14;
  procedure Compute (variable V1, V2: Real) is
  begin
    -- subprogram_statement_part
  end procedure Compute;
begin
    -- subprogram_statement_part
end procedure Proc_3;

The example above present different declarations which may appear in the declarative part of a procedure.

Example 4

procedure Transcoder_1 (variable Value: inout bit_vector (0 to 7)) is
begin
  case Value is
    when "00000000" => Value:="01010101";
    when "01010101" => Value:="00000000";
    when others => Value:="11111111";
  end case;
end procedure Transcoder_1;

The procedure Transcoder_1 transforms the value of a single variable, which is therefore a bi-directional parameter.

Example 5

procedure Comp_3(In1,R:in real; Step :in integer; W1,W2:out real) is
variable counter: Integer;
begin
  W1 := 1.43 * In1;
  W2 := 1.0;
  L1: for counter in 1 to Step loop
    W2 := W2 * W1;
    exit L1 when W2 > R;
  end loop L1;
  assert ( W2 < R )
    report "Out of range"
      severity Error;
end procedure Comp_3;

The Comp_3 procedure calculates two variables of mode out: W1 and W2, both of the REAL type. The parameters of mode in: In1 and R constants are of real type and Step of the integer type. The W2 variable is calculated inside the loop statement. When the value of W2 variable is greater than R, the execution of the loop statement is terminated and the error report appears.

Example 6

procedure Calculate (W1,W2: in Real; signal Out1:inout Integer);
procedure Calculate (W1,W2: in Integer; signal Out1: inout Real);
-- calling of overloaded procedures:
Calculate(23.76, 1.632, Sign1);
Calculate(23, 826, Sign2);

The procedure Calculate is an overloaded procedure as the parameters can be of different types. Only when the procedure is called the simulator determines which version of the procedure should be used, depending on the actual parameters.

Important Notes

· The Procedure declaration is optional - procedure body can exist without it. If, however, a procedure declaration is used, then a procedure body must accompany it.

· Subprograms (procedures and functions) can be nested.

· Subprograms can be called recursively.

· Synthesis tools usually support procedures as long as they do not contain the wait statements.

Process Statement

Formal Definition

A process statement defines an independent sequential process representing the behavior of some portion of the design.

Simplified Syntax

[process_label:] process [ ( sensitivity_list ) ] [ is ]

    process_declarations

    begin

     sequential_statements

    end process [ process_label ] ;

Description

The process statement represents the behavior of some portion of the design. It consists of the sequential statements whose execution is made in order defined by the user.

Each process can be assigned an optional label.

The process declarative part defines local items for the process and may contain declarations of: subprograms, types, subtypes, constants, variables, files, aliases, attributes, use clauses and group declarations. It is not allowed to declare signals or shared variables inside processes.

The statements, which describe the behavior in a process, are executed sequentially, in the order in which the designer specifies them. The execution of statements, however, does not terminate with the last statement in the process, but is repeated in an infinite loop. The loop can be suspended and resumed with wait statements. When the next statement to be executed is a wait statement, the process suspends its execution until a condition supporting the wait statement is met. See respective topics for details.

A process declaration may contain optional sensitivity list. The list contains identifiers of signals to which the process is sensitive. A change of a value of any of those signals causes the suspended process to resume. A sensitivity list is a full equivalent of a wait on sensitivity_list statement at the end of the process. It is not allowed, however, to use wait statements and sensitivity list in the same process. In addition, if a process with a sensitivity list calls a procedure, then the procedure cannot contain any wait statements.

Examples

Example 1

entity D_FF is
port (D,CLK : in BIT;
      Q : out BIT := '0';
      NQ : out BIT := '1' );
end entity D_FF;
architecture A_RS_FF of D_FF is
begin
  BIN_P_RS_FF: process (CLK)
  begin
    if CLK = '1' and CLK'Event then
      Q <= D;
      NQ <= not D;
    end if;
  end process;
end architecture A_RS_FF;

The flip-flop has two input ports: D, CLK and two output ports: Q and NQ. The value of the input signal D is assigned to the output Q when the value of the CLK changes from '0' to '1'. The change of the signal value initiates the process BIN_P_RS_FF, because the signal CLK is on the sensitivity list of this process. The change of the CLK value from the logical zero to the logical one is sensed by the use of the if statement.

The first part of if statement takes place when the actual value of the signal CLK is checked. The second part confirms that the signal CLK really changes its value (attribute 'Event is responsible for that). In the case when the logical value of this condition is TRUE, then the two assignment signal statement are executed.

Important Notes

  • Sensitivity list and explicit wait statements may not be specified in the same process.