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

Entity

Formal Definition

Entity is the description of the interface between a design and its external environment. It may also specify the declarations and statements that are part of the design entity. A given entity declaration may be shared by many design entities, each of which has a different architecture. Thus, an entity declaration can potentially represent a class of design entities, each having the same interface.

Simplified Syntax

entity entity_name is

generic (generic_list);

port (port_list);]

end entity entity_name;

Description

An entity specifies the interface between the specified design (formally called a design entity) and the environment in which it operates. On the other hand, an architecture is a description of the inner design operation and it must be assigned to an entity. The architecture can be assigned to one entity only but one entity may be assigned to a number of architectures.

The entity statement declares the design name (the identifier item in the Syntax example). In addition, it defines generic parameters (see generic) and ports (see port) of the design entity. Generic parameters provide static information (like timing parameters or bus width) to a design. Ports provide communication channels between the design and its environment. For each port, its mode (i.e. data flow) and type are defined.

Optionally, an entity may contain a declarative part. Any subprograms, types, subtypes, and constants can be declared here.

Declarations which are defined in an entity are visible to all architectures assigned to this entity.

An entity may contain its own statements, declared after the begin keyword. The statements here must be passive, which means they cannot alter values of any signals; Passive processes, concurrent assertion statements and passive concurrent procedure calls can be used here.

The entity declaration may be preceded by the library and use clauses. This way all declarations defined in a package will be visible for the entity and all architectures assigned to it.

Examples

Example 1

library IEEE;
use IEEE.std_logic_1164.all;
entity BCD_Decoder is
port (
   BCD : in Bit_Vector (2 downto 0);
   Enable : in Bit;
   LED : out Std_Ulogic_Vector (3 downto 0));
constant ZERO : Std_Ulogic_Vector(3 downto 0) := "0000";
begin
assert (BCD /= "111") report "BCD = 7 " severity note;
end entity BCD_Decoder;

The above example illustrates several important issues related to entities. First two lines contain a call to the IEEE library and to the std_logic_1164 package, respectively. These two lines are required because the Std_Ulogic_Vector type used for the output signal LED is not a standard type but it is defined in the mentioned package. If LED would be of Bit_Vector type then the two lines could have been omitted.

The BCD_Decoder identifier, which is following the entity keyword, is a name assigned by the designer to the entity. Note that this name is repeated at the very end of the entity.

The above listed entity contains the specification of ports only. In this case there are two inputs (BCD and Enable) and one output (LED). The mode for each of them is supported after a colon and is followed by a specification of the signal's type. See ports for more details on modes and types of ports.

The Declarative part of the above entity contains two declarations: constant and assert statements. The constant introduced here will be visible in all architectures of the BCD_Decoder entity. This type of a declaration makes sense if there are more than one such architectures. Otherwise, it might be better to place it in the architecture section to make the entity more clear. See constant for more details on constants.

The assert statement is a concurrent statement which will be active whenever any of the BCD_Decoder architectures is active. This particular statement will generate a Message listed in the report clause, whenever BCD will be equal to "111" ("BCD = 7"). Note that the condition in the assert statement should be interpreted as "if not condition - then report". Turn to assert for more information on this topic.

Important Notes

· The VHDL Language Reference Manual uses the name design entity for a complete specification of the design, i.e. both its interface (entity unit) and behavior or structure (architecture unit). Therefore entity and design entity are not the same concepts!

· The identifier for an entity must conform to VHDL identifier rules; it must start with a letter followed by an arbitrary combination of letters, digits and underline symbols.

· While it is not necessary to repeat the name of an entity at the end of the declaration, it is strongly recommended to do it for the sake of clarity of the description; for the same reason it is advised to add the entity keyword between the end and the entity name.

· It is possible to write an entity without any generics, ports and passive statements. In fact this is used in constructing testbenches (see testbench).

Enumeration Type

Formal Definition

The Enumeration type is a type whose values are defined by listing (enumerating) them explicitly. This type values are represented by enumeration literals (either identifiers or character literals).

Syntax:

type type_name is (type_element, type_element, ...);

Description

The enumeration type is a type with an ordered set of values, called enumeration literals, and consisting of identifiers and character literals. Each of enumeration literals must be unique within the given declaration type, but different enumeration types may use the same literals (example 1). In this case, it is said that such literals are overloaded. When such a literal is referenced in the source code, its is determined from the context, in which enumeration this literal has occurred.

All enumerated values are ordered and each of them has a numeric (integer) value assigned to it. The number indicates the position of the literal. The very first literal in the definition has position number zero and each subsequent has the number increased by one from its predecessor (example 2).

Each enumeration type defined has implicitly defined relational operators that can be used on the type values.

The package Standard contains declarations of several predefined enumeration types: BIT, BOOLEAN, CHARACTER, SEVERITY_LEVEL, FILE_OPEN_KIND and FILE_OPEN_STATUS. Apart from that the package Std_Logic_1164 defines another enumeration type, STD_ULOGIC.

Examples

Example 1

type NotGood is (X, '0', '1', X); -- illegal
type MyBit is (L, H);
type Test is ('0', '1', L, H);

The type Not Good is an illegal declaration as the literal X appears twice in the same declaration. On the other hand there is nothing incorrect in using L (LOW) and H (HIGH) twice because they are used in two different declarations.

Example 2

type FSM_States is (Init, Read, Decode, Execute, Write);

The type FSM_States defines five possible values, which are numbered from 0 to 4: the position number of Init is 0, position of Read is 1, Decode - 2, Execute - 3, and Write - 4.

Important Notes

· It is illegal to define an enumeration type with a range.

· It is assumed that the values are defined in ascending order. For this reason it is recommended to order the literals in such a way that the default value is the first one (it is referred to through the attribute 'left').

· Objects of enumeration types are typically synthesizable.

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.