Wednesday, July 22, 2015

VHDL Design Units

PROGRAM STRUCTURE

VHDL has five different types of primary constructs called design units
Ø  Entity Declaration
Ø  Architecture Body
Ø  Configuration Declaration
Ø  Package Declaration
Ø  Package Body

A Design unit may be the entire file or there may be more than one design unit in a file. The design unit has the context clause as its initial part, which applies to both primary and secondary units.

Entity Declaration, Configuration Declaration, Package Declaration are called primary units and the Architecture Body & Package Body are called as the secondary units.

ENTITY DECLARATION

The top of every design hierarchy must be an entity. Entities may range from primitive circuits to complex assemblies. An entity is modelled using an entity declaration and at least one architecture body. The entity declaration describes the external view of the entity, for example, the input and output signal names.

The entity declaration specifies the name of the entity being modelled and lists the set of interface ports. Ports are signals through which the entity communicates with the other models in its external environment.

Syntax

entity identifier is
          generic (generic_variable_declarations); -- optional
          port( input_and_output_variable_declarations);
          [Declarations]; --optional
          begin
          [statements]
end entity identifier;

generic_variable_declarations can be of the form

variable_name: variable_type:=variable_value; --:=variable_value is optional

input_and_output_variable_declarations can be of the form
            
variable_name:port_mode variable_type;

port_mode can be in, out, inout, buffer linkage

Eg.,

entity HALF_ADDER is
port (A, B: in BIT;
        SUM, CARRY: out BIT);
end HALF_ADDER;

The above example declares the entity for the identifier HALF_ADDER with A,B as inputs and SUM, CARRY as the outputs of type BIT.

ARCHITECTURE BODY

The architecture body contains the internal description of the entity that is used to implement a design entity. There may be more than one architecture for a design entity.

Each style of representation can be specified in a different architecture body or mixed within a single architecture body.

The internal details of an entity are specified by an architecture body using any of the following modeling styles:

1. As a set of interconnected components (to represent structure),
2. As a set of concurrent assignment statements (to represent dataflow),
3. As a set of sequential assignment statements (to represent behavior),
4. Any combination of the above three, called as Mixed modeling

Syntax

architecture identifier of entity_name is
          [declarations]
begin
[statements]
end architecture identifier;

Eg.,
For Dataflow Modeling

architecture HA_CONCURRENTof HALF_ADDER is
begin
SUM <= A xor B after 8 ns;
CARRY <= A and B after 4 ns;
end HA_CONCURRENT;

For Behavioral Modeling

architecture HA_SEQUENTIAL of HALF_ADDER is
begin
process(A,B)
begin
if (A=’0’ and B=’0’) then
SUM<=’0’;
CARRY<=’0’;
else if (A=’0’ and B=’1’) then
SUM<=’1’;
CARRY<=’0’;
else if (A=’1’ and B=’0’) then
SUM<=’1’;
CARRY<=’0’;
else if (A=’1’ and B=’1’) then
SUM<=’0’;
CARRY<=’1’;
else
    SUM <= ‘0’;
CARRY <= ‘0’;
end if;
end if;
end if;
end if;
end process;
end HA_CONCURRENT;

For Structural Modeling

architecture HA_STRUCTURE of HALF_ADDER is

component XOR2
port (X, Y: in BIT; Z: out BIT);
end component;

component AND2
port (L, M: in BIT; N: out BIT);
end component;

begin

X1: XOR2 port map (A, B, SUM);
A1: AND2 port map (A, B, CARRY);
end HA_STRUCTURE;

CONFIGURATION DECLARATION

A configuration declaration is used to create a configuration for an entity. It specifies the binding of one architecture body from the many architecture bodies that may be associated with the entity.

It may also specify the bindings of components used in the selected architecture body to other entities. An entity may have any number of different configurations.

A configuration declaration is used to select one of the possibly many architecture bodies that an entity may have, and to bind components, used to represent structure in that architecture body, to entities represented by an entity-architecture pair or by a configuration, that reside in a design library.

It is used to bind component instances to design entities and collect architectures to make a simulatable testbench. One configuration can create a functional simulation while another configuration can create the complete detailed logic design.

The significant nesting depth can occur on hierarchical designs. The architectures with instances of components in the hierarchy can be binded together. To avoid nesting depth a configuration can be used for each architecture level and a configuration of configuration.

Syntax

configuration identifier of entity_name is
          [declarations]
[block configuration]
end architecture identifier;

The allowed block configurations are
for component_instance_name: component_name
--use clause
end for;
for all: component_name
--use clause
end for;

use clause are of the form
use entity library_name.entity_name[(architecture_name)]
use configuration library_name.configuration_name

Eg.,

1.   library CMOS_LIB, MY_LIB;
configuration HA_BINDING of HALF_ADDER is
for HA-STRUCTURE
for X1:XOR2
use entity CMOS_LIB.XOR_GATE(DATAFLOW);
end for;
for A1:AND2
use configuration MY_LIB.AND_CONFIG;
end for;
end for;
end HA_BINDING;

2.   entity add32_test is --testbench
end add32_test;
configuration add32_test_config of add32_test is
for circuits –of add32_test
for all:add32
use configuration WORK.add32_config;
end for;
end for;
end configuration add32_test_config;

PACKAGE DECLARATION

A package declaration is used to store or encapsulate a set of common declarations like components, type, subtype, subprogram, procedures, and functions that can be shared across two or more design units.

These declarations can then be imported into other design units using a context clause.

Syntax

package identifier is
          [declarations]
end package identifier;

Eg.,
package EXAMPLE_PACK is

type SUMMER is (MAY, JUN, JUL, AUG, SEP);

component D_FLIP_FLOP
port (D, CK: in BIT; Q, QBAR: out BIT);
end component;

constant PIN2PIN_DELAY: TIME := 125 ns;

function INT2BIT_VEC (INT_VALUE: INTEGER)
return BIT_VECTOR;

end EXAMPLE_PACK;

The name of the package declared is EXAMPLE_PACK. It contains type, component, constant, and function declarations. The behavior of the function INT2BIT_VEC does not appear in the package declaration; only the function interface appears. The definition or body of the function appears in a package body.

Assume that this package has been compiled into a design library called DESIGN_LIB. Consider the following context clauses associated with an entity declaration.

library DESIGN_LIB;
use DESIGN_LIB.EXAMPLE_PACK.all;
entity RX is . . .

The library context clause makes the name of the design library DESIGN_LIB visible within this description, i.e., the name DESIGN_LIB can be used within the description. Then a use context clause to import all declarations in package EXAMPLE_PACK into the entity declaration of RX.

It is also possible to selectively import declarations from a package declaration into other design units. Eg.,

library DESIGN_LIB;
use DES[GN_LIB.EXAMPLE_PACK.D_FLIP_FLOP;
use DESIGN_LIB.EXAMPLE_PACK.PIN2PIN_DELAY;
architecture RX_STRUCTURE of RX is . . .

The two use context clauses make the component declaration for D_FLIP_FLOP and the constant declaration for PIN2PIN_DELAY, visible within the architecture body.

Another approach to selectively import items declared in a package is by using selected names. Eg.,

library DESIGN_LIB;
package ANOTHER_PACKAGE is
function POCKET_MONEY(MONTH:DESIGN_LIB.EXAMPLE_PACK.SUMMER)
return INTEGER;
constant TOTAL_ALU: INTEGER; -- A deferred constant.
end ANOTHER_PACKAGE;

The type SUMMER declared in package EXAMPLE_PACK is used in this new package by specifying a selected name, hence a use context clause is not necessary. Package ANOTHER_PACKAGE also contains a constant declaration with the value of the constant not specified, called as a deferred constant. The value of this constant is supplied in a corresponding package body.

PACKAGE BODY

A package body is primarily used to store the definitions of functions and procedures that were declared in the corresponding package declaration, and also the complete constant declarations for any deferred constants that appear in the package declaration. Hence a package body is always associated with a package declaration; a package declaration can have at most one package body associated with it.

The name of the package body must be the same as that of the package declaration with which it is associated.

Syntax

package body identifier is
[declarations]
end package body identifier;

Eg.,
package body EXAMPLE_PACK is
function INT2BIT_VEC (INT_VALUE: INTEGER)
return BIT_VECTOR is
begin
--Behavior of function described here.
end INT2BIT_VEC;
end EXAMPLE_PACK;

The name of the package body must be the same as that of the package declaration with which it is associated.

A package body is not necessary if the corresponding package declaration has no function and procedure declarations and no deferred constant declarations.

A package body can be associated with another package ANOTHER_PACKAGE as:

package body ANOTHER_PACKAGE is
constant TOTAL_ALU: INTEGER := 10; -- A complete constant
-- declaration.
function POCKET_MONEY -- Function body.
(MONTH: DESIGN_UB.EXAMPLE_PACK.SUMMER)
return INTEGER is
begin
case MONTH is
when MAY => return 5;
when JUL I SEP => return 6; -- When JUL or SEP.
when others => return 2;
end case;
end POCKET_MONEY;

end ANOTHER_PACKAGE;

3 comments: