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...

Saturday, 29 December 2012

Event

Formal Definition

A change in the current value of a signal, which occurs when the signal is updated with its effective value.

Description

The event is an important concept in VHDL. It relates to signals and it occurs on a signal if the current value of that signal changes. In other words, an event on a signal is a change of the signal's value.

It is possible to check whether an event occurred on a signal. Such an information can be obtained through the predefined attribute 'EVENT. The principal application of this attribute is checking for an edge of a clock signal (example 1). It is also possible to check when the last event on a signal occurred (attribute 'LAST_EVENT). See attributes for details.

An event on a signal, which is on sensitivity list of a process or is a part of an expression in a concurrent signal assignment, causes the process or assignment to resume (invoke). See sensitivity and resume for details.

Examples

Example 1

if CLK'event and CLK='1'
then
. . .

The condition above will be true only on rising edge of the CLK signal, i.e. when the actual value of the signal is '1' and there was an event on it (the value changed recently).

Important Notes

· Sensitivity list or sensitivity set require an event on any of their signals, i.e. a change of the signal's value. A transaction (an assignment to a signal, no matter whether the same or a different value) is not enough.

· The concept of event relates to signals only. There is no "event on a variable" in VHDL.

Exit Statement

Formal Definition

The exit statement is used to finish or exit the execution of an enclosing loop statement. If the exit statement includes a condition, then the exit from the loop is conditional.

Simplified Syntax

exit;

exit loop_label;

exit loop_label when condition;

Description

The exit statement terminates entirely the execution of the loop in which it is located. The execution of the exit statement depends on a condition placed at the end of the statement, right after the when reserved word. When the condition is TRUE (or if there is no condition at all) the exit statement is executed and the control is passed to the first statement after the end loop (example 1).

The loop label in the exit statement is not obligatory and can be used only in case of labeled loops. If no label is present then it is assumed that the exit statement relates to the innermost loop containing it. If an exit from a loop on a higher level of hierarchy is needed then the loop has to be assigned a label, which will be used explicitly in the exit statement. (Example 2).

Examples

Example 1

Loop_1: for count_value in 1 to 10 loop
exit Loop_1 when reset = '1';
A_1: A(count_value) := '0';
end loop Loop_1;
A_2: B <= A after 10 ns;

At the beginning of each iteration of the LOOP_1 loop, the reset ='1' ondition is checked. If the condition is FALSE, then the rest of the loop is executed (in this case it is the assignment labeled A_1). Otherwise, the control is passed to the next statement after the loop, denoted with the A_2 label.

Example 2

Loop_X: loop
           a_v := 0;
Loop_Y:    loop
Exit_1:       exit Loop_X when condition_1;
              Output_1(a_v) := Input_1(a_v);
              a_v := a_v + 1;
Exit_2:       exit when condition_2;
    end loop Loop_Y;
           Assign_Y: B(i) <= Output_1(i) after 10 ns;
Exit_3:   exit Loop_X when condition_3;
end loop Loop_X;
        Assign_X: A <=B after 10 ns;

There are two nested loops in the above example. When the condition_1 is TRUE, the Exit_1 statement will be executed. This will cause termination of the Loop_X loop and moving the execution to Assign_X. Next, the Loop_X will be terminated because its label is explicitly listed in the exit statement.

If condition_1 is not TRUE then the two assignments below it are performed and condition_2 is checked. If it is TRUE, then the Loop_Y is exited. Since there is no loop label within the exit statement, therefore it relates to the innermost loop. As a result, the next statement to be executed will be Assign_Y. Finally, when the condition_3 is TRUE the Loop_X is terminated. The Exit_3 loop label could be skipped because this statement is within the boundaries of the exit Loop_X loop.

Important Notes

· The exit statement is often confused with the next statement. The difference between the two is that the exit statement "exits" the loop entirely, while the next statement skips to the "next" loop iteration (in other words, "exits" only the current iteration of the loop).

Expression

Formal Definition

A formula that defines the computation of a value.

Syntax:

expression ::= relation { and relation }

               | relation { or relation }

               | relation { xor relation }

               | relation [ nand relation ]

               | relation [ nor relation ]

               | relation { xnor relation }

relation ::= shift_expression [ relational_operator shift_expression ]

shift_expression ::= simple_expression [ shift_operator simple_expression ]

simple_expression ::= [ + | - ] term { adding_operator term }

term ::= factor { multiplying_operator factor }

factor ::= primary [ ** primary ]

         | abs primary

         | not primary

primary ::= name

         | literal

         | aggregate

         | function_call

         | qualified_expression

         | type_conversion

         | allocator

         | ( expression )

qualified_expression ::= type_mark ' ( expression )

                       | type_mark ' aggregate

Description

Expressions define the way in which values are computed. They consist of operands and operators. For example, the expression "1 + 2" adds two integer numbers. The numbers are operands and the plus sign is a pre-defined adding operator. Each operand has a value and a type and the type of expression depends on the types of operands and the operation. The order in which the operations are performed depends on the priorities assumed in the language (see operators for details).

If an expression is constructed using logical operators and, or, xor or xnor, it may contain a sequence of operations, but if operations nand or nor are used, an expression may contain only one operation of this type (Example 1). If more are needed, parentheses can be used.

The expression is evaluated from left to right preserving precedence of operations. If this precedence is to be changed, parentheses (introducing highest priority) can be applied (Example 2).

An expression may consist of one or more relations. A relation is created from operands in the form of a shift expression in which the operands are connected with each other by the relation operator. The shift expression is written by shifting simple expressions using the shift operators.

The simple expression consists of the sign operator with operands being the terms connected with each other by the adding operator.

The term consists of factors, which are connected with each other by the multiplication operation.

The factor may be so-called primary, possibly preceded by the abs or not operators or two primaries connected with an operator **.

The primary can be the name, literal, aggregate, function call, type conversion, allocator (see respective topics for details). Example 3 presents an example of a complex expression with several operators.

Examples

Example 1

variable A, B, C, D : bit;
-- operator nand appears only once:
C := A nand B ;
-- operators and, or can be used more than once in one expression:
A := '1' and B and C or D;
-- multilevel nand operation modeled with parentheses:
A := (D nand B) nand C;

Two logical operations (nand and nor) may appear only once in an expression, unless parentheses are used.

Example 2

A := '1' and (B and (C or D));

Without the parentheses, first the and logical operation of '1' and B would be performed, then C would be and-ed to the result, and finally D would be or-ed with the rest. With the parentheses, first C would be or-ed with D, then and-ed with B and finally logical and would be performed on the result of the operations and logical '1'.

Example 3

A1 := a * (abs b) + 10 <= 256;

Expression composed of several operands. A1 must be of type BOOLEAN as the relation operator has higher precedence than arithmetic operations.

Important Notes

· Operators are defined for particular types of operands and this must be reflected in each expression.

· Different operators can be mixed in one expression as long as the operands are of correct (for each individual operator) type.

File Declaration

Formal Definition

A file declaration declares the file objects of a given file type.

Simplified Syntax

file identifier : subtype_indication [ file_open_information ];

where:

file_open_information ::= [ open file_open_kind_expression ] is file_logical_name

file_logical_name ::= string_expression

Description

The file declaration creates one or more file objects of the specified type. Such a declaration can be included in any declarative part in which the objects can be created, that is within architecture bodies, processes, blocks, packages or subprograms.

The optional parts of a declaration allow making an association between the file object and a physical file in the host file system. If these parts are attached to the declaration, the file is automatically opened for access. The optional file_open_kind_expression allows specifying how the physical file associated with the file object should be opened. The expression must have the predefined type file_open_kind value, which is declared in the standard package.

If the file_open_information is included in a given file declaration, then the file declared by the declaration is opened with an implicit call to FILE_OPEN when the file declaration is elaborated. If it is not, the file will not be opened.

If the file_open_kind_expression is not included in the file_open_information of a given file declaration, then the default value of READ_MODE is used during elaboration of the file declaration.

The file_logical_name must be an expression of predefined type STRING. The value of this expression is interpreted as a logical name for a file in the host system environment. The file_logical_name identifies an external file in the host file system that is associated with the file object. This association provides a mechanism for either importing data contained in an external file into the design during simulation or exporting data generated during simulation to an external file.

The files can also be declared in subprograms. In this case, the behavior is slightly different. The file is opened when the subprogram is called and is automatically closed again when the subprogram returns. Hence the file object, and its association with a physical file in the host file system, is purely local to the subprogram activation.

Examples

Example 1

type IntegerFile is file of INTEGER;
file F1: IntegerFile;

In this example no implicit FILE_OPEN is performed during elaboration.

Example 2

type IntegerFile is file of INTEGER;
file F2: IntegerFile is "test.dat";

The above example presents that an implicit call to FILE_OPEN is performed during elaboration. The OPEN_KIND parameter defaults to the READ_MODE mode.

Example 3

type IntegerFile is file of INTEGER;
file F3: IntegerFile open WRITE_MODE is "test.dat";

Example 3 presents an implicit call to FILE_OPEN being performed during elaboration. The OPEN_KIND parameter defaults to the WRITE_MODE mode.

NOTE: All file objects associated with the same external file should be of the same base type.

File Type

Formal Definition

A type that provides access to objects containing a sequence of values of a given type. File types are typically used to access files in the host system environment. The value of a file object is the sequence of values contained in the host system file.

Simplified Syntax

type type_name is file of type;

Description

The file type is used to define objects representing files in the host environment. The value of a file object is the sequence of values contained in the physical file.

The type mark in the file declaration defines the subtype of the values contained in the file. The subtype can be either constrained or unconstrained. The subtype cannot be based on a file type or an access type. If a composite type is used, the elements cannot be of an access type and in case of arrays, it must be a one-dimensional array. Example 1 shows several file type declarations.

When a file type is declared, several operations on objects of this type are implicitly defined. The list of the operations includes: opening a file, closing a file, reading from a file, writing to a file and checking the end of a file. For a file type declared as

type FT is file of SomeType;

the implicit operations are as follows:

procedure FILE_OPEN ( file anonymous: FT;

External_Name: in STRING;

Open_Kind: in FILE_OPEN_KIND := READ_MODE );

procedure FILE_OPEN ( Status: out FILE_OPEN_STATUS;

file anonymous: FT;

External_Name: in STRING;

Open_Kind: in FILE_OPEN_KIND := READ_MODE );

procedure FILE_CLOSE ( file anonymous: FT );

procedure READ ( file anonymous: FT; Value: out SomeType );

procedure WRITE ( file anonymous: FT; Value: in SomeType );

function ENDFILE ( file anonymous: FT ) return BOOLEAN;

Examples

Example 1

type POSITIVE_FILE is file of POSITIVE;
type BIT_VECTOR_FILE is file of BIT_VECTOR ( 0 to 7 );
type STRING_FILE is file of STRING;

Here, the first type declares a file of positive numbers, the second one - a file of 8-bit wide vectors of bits, and the third one - a file containing an indefinite number of strings of arbitrary length.

Important Notes

· File types are not supported by synthesis tools.

Floating Point Type

Formal Definition

Floating point type provides an approximation of the real number value.

Simplified Syntax

type type_name is real_number_left_bound downto real_number_right_bound;

type type_name is real_number_left_bound to real_number_right_bound;

Description

A floating point type is a numeric type consisting of real numbers which values are constrained by a specified range.

There exists only one predefined floating point type: REAL. The range of the values for the type REAL are implementation-dependent, but it is required by the standard that it covers the values from -1.0E38 to +1.0E38.

A user-defined floating point type can be constructed on the basis of the predefined REAL type by constraining its range (example 1). The bounds of the range of a user-defined floating point type should be in the form of locally static expression. The expression is classified as a 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 floating point type must also be of floating point type, not necessarily the same for both bounds (example 2). Negative bounds are allowed.

All floating point types (including user-defined) have the same set of arithmetic operators, namely: addition, subtraction, multiplication, division, absolute function and exponentiation.

Examples

Example 1

type Voltage_Level is range -5.5 to +5.5;
type Int_64K is range - 65536.00 to 65535.00;

Example 2

type APPROX_VALUES_DOWNTO is range (2.0**(N+1)) - 1.0 downto 0.0;
type APPROX_VALUES_TO is range 0.0 to (2.0**(N+1)) - 1.0;

Important Notes

· In order to add, subtract, multiply or divide integer object to/from a real object, type conversion of the integer object is needed. The only exception from this rule is multiplication and division of universal integer and universal real.

· The floating point types are not synthesizeable by any of the existing tools. Their use is thus very limited.

Function

Complete Definition:

A function call is a subprogram of the form of an expression that returns a value.

Simplified Syntax

function function_name (parameters) return type;

function function_name (parameters) return type is

declarations

begin

     sequential statements

end function function_name;

Description

The function is a subprogram that either defines an algorithm for computing values or describes a behavior. The important feature of functions is that they are used as expressions that return values of specified type. This is the main difference from another type of subprograms: procedures, which are used as statements.

The result returned by a function can be of either scalar or complex type.

Functions can be either pure (which is default) or impure. Pure functions always return the same value for the same set of actual parameters. Impure functions may return different values for the same set of parameters. Additionally, an impure function may have „side effects”, like updating objects outside of their scope, which is not allowed for pure functions.

The function definition consists of two parts:

· function declaration, which consists of name, parameter list and type of the values returned by the function;

· function body, which contains local declarations of nested subprograms, types, constants, variables, files, aliases, attributes and groups, as well as sequence of statements specifying the algorithm performed by the function.

The function declaration is optional and function body, which contains a copy of it, is sufficient for correct specification. However, if a function declaration exists, the function bodydeclaration must appear in the given scope.

FUNCTION DECLARATION

The function declaration can be preceded by an optional reserved word pure or impure, denoting the character of the function. If the reserved word is omitted it is assumed by default that the function is pure.

The function name, which appears after the reserved word function, can be either an identifier or an operator symbol (if the function specifies the operator). Specification of new functions for existing operators is allowed in VHDL and is called operator overloading. See respective topic for details.

The parameters of the function are by definition inputs and therefore they do not need to have the mode (direction) explicitly specified. Only constants, signals and files can be function parameters. The object class is specified by a reserved word (constant, signal or file, respectively) preceding the parameter's name. If no reserved word is used, it is assumed by default that the parameter is a constant.

In case of signal parameters the attributes of the signal are passed into the function, except for 'STABLE, 'QUIET, 'TRANSACTION and 'DELAYED, which may not be accessed within the function.

If a file parameter is used, it is necessary to specify the type of the data appearing in the opened file.

Example 1 contains several examples of function declarations.

FUNCTION BODY

Function body contains a sequence of statements that specify the algorithm to be realized within the function. When the function is called, the sequence of statements is executed.

A function body consists of two parts: declarations and sequential statements. At the end of the function body, the reserved word end can be followed by an optional reserved wordfunction and the function name. Examples 2 through 4 illustrate the function bodies.

IMPURE FUNCTIONS

If a function is explicitly specified as an impure (which is denoted with the reserved word impure, preceding the function declaration) it may return different results in different calls even with the same parameters. See Example 5.

Examples

Example 1

type Int_Data is file of NATURAL;
function Func_1 (A,B,X: REAL) return REAL;
function "*" (a,b: Integer_new) return Integer_new;
function Add_Signals (signal In1,In2: REAL) return REAL;
function End_Of_File (file File_name: Int_Data) return BOOLEAN;

The first function above is called Func_1, it has three parameters A, B and X, all of REAL type and returns a value also of REAL type.

· The second function defines a new algorithm for executing multiplication. Note that the operator is enclosed in double quotes and plays the role of the function name.

· The third function is based on signals as input parameters, which is denoted by the reserved word signal preceding the parameters.

· The fourth function declaration is a part of the function checking for end of file, consisting of natural numbers. Note that the parameter list uses the Boolean type declaration.

Example 2

function Transcod_1(Value: in bit_vector(0 to 7)) return bit_vector is
begin
   case Value is
     when "00000000" => return "01010101";
     when "01010101" => return "00000000";
     when others => return "11111111";
   end case;
end Transcod_1;

The case statement has been used to realize the function algorithm. The formal parameter appearing in the declaration part is the Value constant, which is a parameter of the Bit_vector type. This function returns a value of the same type.

Example 3

function Func_3 (constant A,B,X: real) return real is
begin
   return A*X**2+B;
end Func_3;

The formal parameters: A, B and X are constants of the real type. The value returned by this function is a result of calculating the A*X**2+B expression and it is also of the real type.

Example 4

function Func_4 (constant A,B,Step,LeftB,RightB: in real) return real is
variable counter, max, temp: real;
begin
counter:= LeftB;
max:=Func_3(A,B, counter);
L1:
     while counter <= RightB loop
temp:=Func_1(A,B, counter);
         if temp > max then
max:=temp;
         end if;
counter := counter + Step;
     end loop L1;
   return max;
end Func_4;

The fourth example is much more complicated. It calculates the maximum value of the Func_1 function.

All the formal parameters are constants of the real type. When the function is called, the A and B values appearing in the function are passed, Step is a determinant of calculation correctness. The LeftB and RightB values define the range in which we search for the maximum value of the function.

Inside the function body are contained definitions of variables counter, max and temp. They are used in the simple algorithm, which calculates all the function values in a given range and storing the maximum value returned by the function.

Example 5

variable number: Integer := 0;
impure function Func_5 (A: Integer) return Integer is
variable counter: Integer;
begin
counter := A * number;
number := number + 1;
   return counter;
end Func_5;

Func_ 5 is an impure function; its formal parameter A and returned value are constants of the integer type. When the function is invoked, output value depends on the variablenumber declared outside the function.

The number variable is additionally updated after each function call (it increases its value by 1). This variable affects the value calculated by the function, that is why the out function value is different for the same actual parameter value.

Important Notes

· Functions can be called recursively.

· Function body may not contain a wait statement or a signal assignment.

· Subprograms (functions and procedures) can be nested.