One concept unique to VHDL (when compared to software programming languages and to its main rival, Verilog) is the concept of a design unit. Design units in VHDL (which may also be referred to as library units) are segments of VHDL code that can be compiled separately and stored in a library.

 

You have been introduced to two design units already: the entity and the architecture. There are actually five types of design units in VHDL; entities, architectures, packages, package bodies, and configurations. Entities and architectures are the only two design units that you must have in any VHDL design description. Packages and configurations are optional.

 

Entities

A VHDL entity is a statement (indicated by the entity keyword) that defines the external specification of a circuit or sub-circuit. The minimum VHDL design description must include at least one entity and one corresponding architecture.

 

When you write an entity declaration, you must provide a unique name for that entity and a port list defining the input and output ports of the circuit. Each port in the port list must be given a name, direction (or mode, in VHDL jargon) and a type. Optionally, you may also include a special type of parameter list (called a generic list) that allows you to pass additional information into an entity.

 

An example of an entity declaration is given below:

 

entity fulladder is

    port (X: in bit;

              Y: in bit;

              Cin: in bit;

              Cout: out bit;

              Sum: out bit);

end fulladder;

 

Architectures

A VHDL architecture declaration is a statement (beginning with the architecture keyword) that describes the underlying function and/or structure of a circuit. Each architecture in your design must be associated (or bound) by name with one entity in the design.

 

VHDL allows you to create more than one alternate architecture for each entity. This feature is particularly useful for simulation and for project team environments in which the design of the system interfaces (expressed as entities) is performed by a different engineer than the lower-level architectural description of each component circuit, or when you simply want to experiment with different methods of description.

 

An architecture declaration consists of zero or more declarations (of items such as intermediate signals, components that will be referenced in the architecture, local functions and procedures, and constants) followed by a begin statement, a series of concurrent statements, and an end statement, as illustrated by the following example:

 

architecture concurrent of fulladder is

begin

    Sum <= X xor Y xor Cin;

    Cout <= (X and Y) or (X and Cin) or (Y and Cin);

end concurrent;

 

Packages and package bodies

A VHDL package declaration is identified by the package keyword, and is used to collect commonly-used declarations for use globally among different design units. You can think of a package as a common storage area, one used to store such things as type declarations, constants, and global subprograms. Items defined within a package can be made visible to any other design unit in the complete VHDL design, and they can be compiled into libraries for later re-use.

 

A package can consist of two basic parts: a package declaration and an optional package body. Package declarations can contain the following types of statements:

 

•  Type and subtype declarations

•  Constant declarations

•  Global signal declarations

•  Function and procedure declarations

•  Attribute specifications

•  File declarations

•  Component declarations

•  Alias declarations

•  Disconnect specifications

•  Use clauses

 

Items appearing within a package declaration can be made visible to other design units through the use of a use statement, as we will see.

 

If the package contains declarations of subprograms (functions or procedures) or defines one or more deferred constants (constants whose value is not immediately given), then a package body is required in addition to the package declaration. A package body (which is specified using the package body keyword combination)  must have the same name as its corresponding package declaration, but it can be located anywhere in the design, in the same or a different source file.

 

The relationship between a package and package body is somewhat akin to the relationship between an entity and its corresponding architecture. (There may be only one package body written for each package declaration, however.) While the package declaration provides the information needed to use the items defined within it (the parameter list for a global procedure, or the name of a defined type or subtype), the actual behavior of such things as procedures and functions must be specified within package bodies.

 

An example of a package is given below:

 

package conversion is

    function to_vector (size: integer; num: integer) return std_logic_vector;

end conversion;

 

package body conversion is

    function to_vector(size: integer; num: integer) return std_logic_vector is

        variable ret: std_logic_vector (1 to size);

        variable a: integer;

    begin

        a := num;

        for i in size downto 1 loop

            if ((a mod 2) = 1) then

                ret(i) := ‘1’;

            else

                ret(i) := ‘0’;

            end if;

            a := a / 2;

        end loop;

        return ret;

    end to_vector;

end conversion;

 

Examples of global procedures and functions can be found in the section Modularity Features.

 

Configurations

The final type of design unit available in VHDL is called a configuration declaration. You can think of a configuration declaration as being roughly analogous to a parts list for your design. A configuration declaration (identified with the configuration keyword)  specifies which architectures are to be bound to which entities, and it allows you to change how components are connected in your design description at the time of simulation. (Configurations are not generally used for synthesis, and may not be supported in the synthesis tool that you will use.)

 

Configuration declarations are always optional, no matter how complex a design description you create. In the absence of a configuration declaration, the VHDL standard specifies a set of rules that provide you with a default configuration. For example, in the case where you have provided more than one architecture for an entity, the last architecture compiled will take precedence and will be bound to the entity.

 

A simple example of a configuration is given below:

 

configuration this_build of rcomp is

    for structure

        for COMP1: compare use entity work.compare(compare1);

        for ROT1: rotate use entity work.rotate(rotate1);

    end for;

end this_build;