Previous

VHDL Constructs

The top-level VHDL constructs work together to describe a design. The design description consists of the following constructs, which are further discussed in the chapter sections following this list.

Entities

A VHDL design consists of one or more entities. An entity represents one level of the design hierarchy and can consist of a complete design, an existing hardware component, or a VHDL-defined object. Entities have defined inputs and outputs and perform a defined function.

The following example shows the entity specification of a simple logic gate (a 2-input NAND gate).

   entity NAND2 is 
     port(I0, I1,: in BIT;    -- Two inputs, I0 and I1
     O: out BIT);     -- One output, O = (I0 and I1)'
   end NAND2;

NOTE

In a VHDL description, a comment is prefixed by two hyphens (--). Foundation Express ignores all characters from the hyphens to the end of the line. The only exceptions to this rule are comments that begin with --- pragma or --synopsys; these comments are Foundation Express compiler directives.


After an entity statement declares an entity specification, that entity can be used by other entities in a design. The internal architecture of an entity determines its function.

The following three examples show three different architectures for the entity NAND2. These three examples define equivalent implementations of NAND2. After optimization and synthesis, each implementation produces the same circuit, a 2-input NAND gate in the target technology. The architecture description style you use for this entity depends on your own preferences.

The first example shows how the entity NAND2 can be implemented with two components from the XC4000E library. The entity inputs A and B are connected to AND gate U0, producing an intermediate signal I. Signal I is then connected to inverter U1, producing the entity output Z.

   architecture STRUCTURAL of NAND2 is
     signal I:  BIT;
   
     component AND2 -- From a technology library
       port(I1, I2: in BIT;
           O1: out BIT);
     end component;
   
     component INV -- From a technology library
       port(I1: in BIT;
           O1: out BIT);
     end component;
   
   begin
     U0: AND2  port map (I1 => A, I2 => B, O1 => I);
     U1: INV port map (I1 => I, O1 => Z);
   end STRUCTURAL;

The following example shows how you can define the entity NAND2 by its logical function.

   architecture DATAFLOW of NAND2 is
   begin
     Z <= A nand B;
   end DATAFLOW;

The following example shows another implementation of NAND2.

   architecture RTL of NAND2 is
   begin
     process(A, B)
     begin
       if (A = '1') and (B = '1') then
         Z <= '0';
       else 
          <= '1';
       end if;
     end process;
   end RTL;

Architectures

An architecture determines an entity's function and consists of a declaration section and a collection of concurrent statements.

The following figure shows a block diagram of an architecture's organization. Not all architectures contain every construct shown.

Figure 3.2 Architecture Organization

Configurations

A design configuration specifies one combination of an entity and its associated architecture.


NOTE

Foundation Express supports only configurations that associate one top-level entity with an architecture.


Processes

Processes contain declarations and sequential statements. Sequential statements define algorithms. Unlike concurrent statements, sequential statements are executed in order. The statements' order allows you to perform step-by-step computations.

Processes are unique in that they behave like concurrent statements to the rest of the design, but they are internally sequential. In addition, only processes can define variables to hold intermediate values in a sequence of computations.

Because the statements in a process are sequentially executed, several constructs are provided to control the order of execution, such as if and loop statements. The “Sequential Statements” chapter further describes sequential statements.

Processes read and write signals and interface port values to communicate with the rest of the architecture and with the enclosing system. The following figure shows the organization of constructs in a process. Processes need not use all the constructs listed.

Figure 3.3 Process Organization

Subprograms

Subprograms, like processes, use sequential statements to define algorithms that compute values. Unlike processes, however, they cannot directly read or write signals from the rest of the architecture. All communication is through the subprogram's interface; each subprogram call has its own set of interface signals.

There are two types of subprograms; functions and procedures.

Subprograms are useful because you can use them to perform repeated calculations, often in different parts of an architecture.

The “Sequential Statements” chapter further describes subprograms.

Packages

You can collect constants, data types, component declarations, and subprograms into a VHDL package that can then be used by more than one design or entity. A package must contain at least one of the constructs listed in the following figure.

Figure 3.4 Typical Package Organization

The functions of the constructs in a typical package follow.

Packages are often sufficiently general so that you can use them in many different designs. For example, the std_logic_1164 package defines data types std_logic and std_logic_vector.

Using a Package

The use statement allows an entity to use the declarations in a package. The supported syntax of the use statement follows.

use LIBRARY_NAME.PACKAGE_NAME.ALL;

LIBRARY_NAME is the name of a VHDL library, and PACKAGE_NAME is the name of the included package. A use statement is usually the first statement in a package or entity specification source file. Express does not support different packages with the same name when they exist in different libraries. No two packages can have the same name.

Package Structure

Packages have two parts; the declaration and the body.

Holds private information, including local types and subprogram implementations (bodies)


NOTE

When a package declaration contains subprogram declarations, a corresponding package body must define the subprogram bodies.


Package Declarations

Package declarations collect information that one or more entities in a design need. This information includes data type declarations, signal declarations, subprogram declarations, and component declarations.


NOTE

Signals declared in packages cannot be shared across entities. If two entities both use a signal from a given package, each entity has its own copy of that signal.


Although you can declare all this information explicitly in each design entity or architecture in a system, it is often easier to declare system information in a separate package. Each design entity in the system can then use the system's package.

The syntax of a package declaration follows.

   package package_name is
     { package_declarative_item }
   end [ package_name ] ;

where package_name is the name of this package.

A package_declarative_item is any of these.

The following example shows a sample package declaration.

   package EXAMPLE is
   
     type BYTE is range 0 to 255;
     subtype NIBBLE is BYTE range 0 to 15;
   
     constant BYTE_FF: BYTE := 255;
   
     signal ADDEND: NIBBLE;
   
     component BYTE_ADDER
       port(A, B:          in BYTE;
            C:        out BYTE;
            OVERFLOW: out BOOLEAN);
     end component;
   
    function MY_FUNCTION (A: in BYTE) return BYTE;
   
   end EXAMPLE;

To use the example declarations above, add a use statement at the beginning of your design description as follows.

   use WORK.EXAMPLE.ALL;
   
   entity . . .
   
   architecture . . .

Package Bodies

Package bodies contain the implementations of subprograms listed in the package declaration. However, this information is never seen by designs or entities that use the package. Package bodies can include the implementations (bodies) of subprograms declared in the package declaration and in internal support subprograms.

The syntax of a package body follows.

   package body package_name is
     { package_body_declarative_item }
   end [ package_name ] ;

where package_name is the name of the associated package.

A package_body_declarative_item is any of these.

For an example of a package declaration and body, see the std_logic_arith package supplied with Foundation Express.

Next