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

Sunday, 23 December 2012

Package

Formal Definition

A package declaration defines the interface to a package.

Simplified Syntax

package package_name is

package_declarations

end package package_name;

Description

The package is a unit that groups various declarations, which can be shared among several designs. Packages are stored in libraries for greater convenience. A package consists of package declaration (mandatory) and may contain a single optional package body.

The purpose of a package is to declare shareable types, subtypes, constants, signals, files, aliases, component, attributes and groups. Once a package is defined, it can be used in multiple independent designs.

Items declared in a package declaration are visible in other design units if the use clause is applied (Example 1).

The two-part specification of a package (declaration and body) allows to declare the so-called deferred constants which have no value assigned in the package declaration (Example 2). The value for a deferred constant, however, must be declared in the package body accompanying the package declaration.

The VHDL Language Standard defines two standard packages, which must be available in any VHDL environment - package STANDARD and package TEXTIO. The former contains basic declarations of types, constants and operators, while the latter defines operations for manipulating text files. Both are located in the library STD. See respective topics for details.

Apart from the VHDL Language Standard there is another standard, which extends the language and supports the extensions in the form of a package: Std_Logic_1164.

Examples

Example 1

library Packages;
use Packages.AUXILIARY.all;
architecture STRUCT of Adder is
................
end architecture STRUCT;

All declarations, which are inside the AUXILIARY package, may be used in the architecture body STRUCT of the design entity Adder. The package itself is stored in the library Packages.

Example 2

library IEEE;
use IEEE.STD_LOGIC_1164.all;
package AUXILIARY is
type MUX_input is array (INTEGER range<>) of STD_LOGIC_VECTOR (0 to 7);
type operation_set is (SHIFT_LEFT, ADD);
subtype MUX_address is POSITIVE;
function Compute_Adress (IN1 : MUX_input) return MUX_address;
constant Deferred_Con : Integer;
end AUXILIARY;

Package AUXILIARY contains a function declaration and a deferred constant, thus a package body had to be declared for this package.

Important Notes

· Package declaration may contain a subprogram (function or procedure) declaration; subprogram body is not allowed here and must appear in the package body.

· Package body must accompany a package declaration if the declaration contains subprogram declarations or deferred constants.

Package Body

Formal Definition

A package body defines the bodies of subprograms and the values of deferred constants declared in the interface to the package.

Simplified Syntax

package body package_name is

package_body_declarations

subprogram bodies declarations

deferred constants declarations

end package body package_name;

Description

The package body includes complete definitions of subprogram body declarations as well as values of deferred constants declared in corresponding package declarations. Other declarations (similar to those of package declaration) are also allowed here, but are visible only inside the package body.

The deferred constant, which has been declared in a package declaration, may be used before its full declaration only in a default expression for a local generic parameter, local port or formal parameter of subprogram.

Examples

Example 1

library IEEE;
use IEEE.STD_LOGIC_1164.all;
package AUXILIARY is
  type MUX_input is array (INTEGER range<>) of STD_LOGIC_VECTOR (0 to 7);
  type operation_set is (SHIFT_LEFT, ADD);
  subtype MUX_Address is POSITIVE;
  function Compute_Address (IN1 : MUX_input) return MUX_address;
  constant Deferred_Con : Integer;
end AUXILIARY;
package body AUXILIARY is
  function Compute_Address (IN1 : MUX_input) return MUX_address is
  begin
  ............
  end;
  constant Deferred_Con : Integer := 177;
end package body AUXILIARY;

First, the package is specified here and then the accompanying package body. Note that both have the same name.

Important Notes

· Declarations other than values of deferred constants and subprogram bodies are not visible outside the package body and can be used only locally, inside it.

· Each package can have only one body.

Physical Type

Formal Definition

Physical type is a numeric scalar that represents some quantity. Each value of a physical type has a position number that is an integer value. Any value of a physical type is a straight multiple of the primary unit of measurement for that type.

Simplified Syntax

type type_name is range left_bound to right_bound

units

  primary_unit_name

  secondary_unit_name = number primary_unit_name

  secondary_unit_name = number primary_unit_name

  . . .

end units type_name

type type_name is range left_bound downto right_bound

units

  primary_unit_name

  secondary_unit_name = number primary_unit_name

  secondary_unit_name = number primary_unit_name

  . . .

end units type_name

Description

A physical type allows to define measurement units for some physical quantity, like length, time, pressure, capacity, etc.

The range, specified at the beginning of a physical type, defines the minimum and maximum values of a given quantity expressed in the base units (see primary unit declaration below). The bounds of the range of a physical type should be in the form of locally static expression. The expression is classified as 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 physical type must be of integer type. It is legal to use negative bounds.

At the core of a physical type declaration is the definition of a primary unit, and optionally, multiple secondary units. The primary unit serves as the base unit for representing values of the specified type. The secondary units are defined as multiplicity of primary units or previously specified secondary units. Their declarations may contain only integer literals.

Each value of a physical type has a corresponding position number, which is the number of primary units represented by that unit name. This way values specified in different units of the same type can be compared (Example 2).

For all physical types, both TIME and user-defined, relational and arithmetic operators can be used.

The VHDL standard predefines only one physical type: TIME, which is defined in the STANDARD package.

The value of one unit can be written in short form using the name of the unit only (i.e. without the value 1 - Example 3).

Examples

Example 1

type CAPACITY is range 0 to 1E5
units
  pF; -- picofarad
  nF = 1000 pF; -- nanofarad
  uF = 1000 nF; -- microfarad
  mF = 1000 uF; -- milifarad
  F = 1000 mF; -- farad
end units CAPACITY;

The primary unit in this example is one picofarad and the maximum value of the CAPACITY type object is 105 pF.

Example 2.

type DISTANCE is range 0 to 1E5
  units
    um; -- micrometer
    mm = 1000 um; -- millimeter
    in_a = 25400 um; -- inch
  end units DISTANCE;
variable Dis1, Dis2 : DISTANCE;
Dis1 := 28 mm;
Dis2 := 2 in_a - 1 mm;
if Dis1 < Dis2 then ...

Both, a comparison and an arithmetic operation can be performed on visually different measurement units as long as they are defined as the same type with the same base unit.

Example 3

SomeVar := mF;

This assignment means that the variable SomeVar will be assigned the value of 1 mF.

Important Notes

· Physical types are not synthesizeable. As a result, delays in signal assignments are not synthesizeable as well.

· It is not allowed to use floating point values in physical type declarations, i.e. if a conversion from millimeters to inches (25.4 mm = 1 in) would have to be performed, then millimeters could not be used as the base unit.

Port

Formal Definition

A channel for dynamic communication between a block and its environment.

Simplified Syntax

port ( port_declaration, port_declaration, &ldots;);

-- port declarations:

port_signal_name : in port_signal_type := initial_value

port_signal_name : out port_signal_type := initial_value

port_signal_name : inout port_signal_type := initial_value

port_signal_name : buffer port_signal_type := initial_value

port_signal_name : linkage port_signal_type := initial_value

Description

Ports are a part of the block interface: external - if defined by a design entity, or internal - if defined by a block statement. Each element listed in a port interface list declares a formal port, which provides a channel for dynamic communication between a block and its environment.

In practice, ports are most often used in entities and components, where they serve for declaring interface signals of a design entity (system design) or component, respectively.

In both cases, each interface element is a signal. It can be preceded by a keyword signal. After the signal's name, a mode is specified. The mode declares the direction of data flow through the port. There are five modes available in VHDL for ports:

· in input port. A variable or a signal can read a value from a port of mode in, but is not allowed to assign a value to it.

· out output port. It is allowed to make signal assignments to a port of the mode out, but it is not legal to read from it.

· inout bi-directional port. Both assignments to such a port and reading from it are allowed.

· buffer output port with read capability. It differs from inout in that it can be updated by at most one source, whereas inout can be updated by zero or more sources.

· linkage . The value of the port may be read or updated, but only by appearing as an actual corresponding to an interface object of mode linkage.

If a port is declared with a reserved word bus, then the signal declared by that port is a guarded signal of signal kind bus.

A port can be assigned a default value, which is specified by an expression evaluating to the same type as the port itself.

Examples

Example 1

entity Mux8to1 is
port (
     Inputs : in Std_Logic_Vector(7 downto 0);
     Select_s : in Std_Logic_Vector(2 downto 0);
     Output : out Std_Logic
     );
end Mux8to1;

Entity of a multiplexor 8-to-1 contains three ports: eight data inputs (specified as a vector), address inputs and one output.

Example 2

component MemDev is
port(
     Data : inout Std_Logic_Vector(7 downto 0);
     Addr : in Std_Logic_Vector(9 downto 0);
     NotCS : in Std_Logic;
     RdNotWr : in Bit
    );
end component MemDev;

Memory device is specified here as a component with four signals: data is a bi-directional data bus, address is a ten-bit input, and NotCS and RdNotWr are single inputs signals. Note that the keyword is in the header can be used in VHDL 93 only (in VHDL 87 it must be omitted).

Important Notes

· Ports declarations are signal declarations and port signals need not to be re-declared.

Procedure

Formal Definition

A procedure is a subprogram that defines algorithm for computing values or exhibiting behavior. Procedure call is a statement.

Simplified Syntax

procedure procedure_name ( formal_parameter_list )

procedure procedure_name ( formal_parameter_list ) is

  procedure_declarations

  begin

    sequential statements

  end procedure procedure_name;

Description

The procedure is a form of subprograms. It contains local declarations and a sequence of statements. Procedure can be called in any place of the architecture. The procedure definition consists of two parts:

· the procedure declaration, which contains the procedure name and the parameter list required when the procedure is called;

· the procedure body, which consists of the local declarations and statements required to execute the procedure.

PROCEDURE DECLARATION

The procedure declaration consists of the procedure name and the formal parameter list.

In the procedure specification, the identifier and optional formal parameter list follow the reserved word procedure (Example 1).

Objects classes constants, variables, signals, and files can be used as formal parameters. The class of each parameter is specified by the appropriate reserved word, unless the default class can be assumed (see below). In case of constants, variables and signals, the parameter mode determines the direction of the information flow and it decides which formal parameters can be read or written inside the procedure. Parameters of the file type have no mode assigned.

There are three modes available: in, out, and inout. When in mode is declared and object class is not defined, then by default it is assumed that the object is a constant. In case ofinout and out modes, the default class is variable. When a procedure is called, formal parameters are substituted by actual parameters. If a formal parameter is a constant, then actual parameter must be an expression. In case of formal parameters such as signal, variable and file, the actual parameters must be objects of the same class. Example 2 presents several procedure declarations with parameters of different classes and modes.

A procedure can be declared also without any parameters.

PROCEDURE BODY

Procedure body defines the procedure's algorithm composed of sequential statements. When the procedure is called it starts executing the sequence of statements declared inside the procedure body.

The procedure body consists of the subprogram declarative part After the reserved word is and the subprogram statement part placed between the reserved words begin and end. The key word procedure and the procedure name may optionally follow the end reserved word.

Declarations of a procedure are local to this declaration and can declare subprogram declarations, subprogram bodies, types, subtypes, constants, variables, files, aliases, attribute declarations, attribute specifications, use clauses, group templates and group declarations (Example 3).

A procedure can contain any sequential statements (including wait statements). A wait statement, however, cannot be used in procedures which are called from a process with a sensitivity list or from within a function. Examples 4 and 5 present two sequential statements specifications.

PROCEDURE CALL

A procedure call is a sequential or concurrent statement, depending on where it is used. A sequential procedure call is executed whenever control reaches it, while a concurrent procedure call is activated whenever any of its parameters of in or inout mode changes its value.

All actual parameters in a procedure call must be of the same type as formal parameters they substitute.

OVERLOADED PROCEDURES

The overloaded procedures are procedures with the same name but with different number or different types of formal parameters. The actual parameters decide which overloaded procedure will be called (Example 6).

Examples

Example 1

procedure Procedure_1 (variable X, Y: inout Real);

The above procedure declaration has two formal parameters: bi-directional variables X and Y of the real type.

Example 2

procedure Proc_1 (constant In1: in Integer; variable O1: out Integer);
procedure Proc_2 (signal Sig: inout Bit);

Procedure Proc_1 has two formal parameters: the first one is a constant and it is of mode in and of the integer type, the second one is an output variable of the integer type.

Procedure Proc_2 has only one parameter, which is a bi-directional signal of the type BIT.

Example 3

procedure Proc_3 (X,Y : inout Integer) is
  type Word_16 is range 0 to 65536;
  subtype Byte is Word_16 range 0 to 255;
  variable Vb1,Vb2,Vb3 : Real;
  constant Pi : Real :=3.14;
  procedure Compute (variable V1, V2: Real) is
  begin
    -- subprogram_statement_part
  end procedure Compute;
begin
    -- subprogram_statement_part
end procedure Proc_3;

The example above present different declarations which may appear in the declarative part of a procedure.

Example 4

procedure Transcoder_1 (variable Value: inout bit_vector (0 to 7)) is
begin
  case Value is
    when "00000000" => Value:="01010101";
    when "01010101" => Value:="00000000";
    when others => Value:="11111111";
  end case;
end procedure Transcoder_1;

The procedure Transcoder_1 transforms the value of a single variable, which is therefore a bi-directional parameter.

Example 5

procedure Comp_3(In1,R:in real; Step :in integer; W1,W2:out real) is
variable counter: Integer;
begin
  W1 := 1.43 * In1;
  W2 := 1.0;
  L1: for counter in 1 to Step loop
    W2 := W2 * W1;
    exit L1 when W2 > R;
  end loop L1;
  assert ( W2 < R )
    report "Out of range"
      severity Error;
end procedure Comp_3;

The Comp_3 procedure calculates two variables of mode out: W1 and W2, both of the REAL type. The parameters of mode in: In1 and R constants are of real type and Step of the integer type. The W2 variable is calculated inside the loop statement. When the value of W2 variable is greater than R, the execution of the loop statement is terminated and the error report appears.

Example 6

procedure Calculate (W1,W2: in Real; signal Out1:inout Integer);
procedure Calculate (W1,W2: in Integer; signal Out1: inout Real);
-- calling of overloaded procedures:
Calculate(23.76, 1.632, Sign1);
Calculate(23, 826, Sign2);

The procedure Calculate is an overloaded procedure as the parameters can be of different types. Only when the procedure is called the simulator determines which version of the procedure should be used, depending on the actual parameters.

Important Notes

· The Procedure declaration is optional - procedure body can exist without it. If, however, a procedure declaration is used, then a procedure body must accompany it.

· Subprograms (procedures and functions) can be nested.

· Subprograms can be called recursively.

· Synthesis tools usually support procedures as long as they do not contain the wait statements.

Process Statement

Formal Definition

A process statement defines an independent sequential process representing the behavior of some portion of the design.

Simplified Syntax

[process_label:] process [ ( sensitivity_list ) ] [ is ]

    process_declarations

    begin

     sequential_statements

    end process [ process_label ] ;

Description

The process statement represents the behavior of some portion of the design. It consists of the sequential statements whose execution is made in order defined by the user.

Each process can be assigned an optional label.

The process declarative part defines local items for the process and may contain declarations of: subprograms, types, subtypes, constants, variables, files, aliases, attributes, use clauses and group declarations. It is not allowed to declare signals or shared variables inside processes.

The statements, which describe the behavior in a process, are executed sequentially, in the order in which the designer specifies them. The execution of statements, however, does not terminate with the last statement in the process, but is repeated in an infinite loop. The loop can be suspended and resumed with wait statements. When the next statement to be executed is a wait statement, the process suspends its execution until a condition supporting the wait statement is met. See respective topics for details.

A process declaration may contain optional sensitivity list. The list contains identifiers of signals to which the process is sensitive. A change of a value of any of those signals causes the suspended process to resume. A sensitivity list is a full equivalent of a wait on sensitivity_list statement at the end of the process. It is not allowed, however, to use wait statements and sensitivity list in the same process. In addition, if a process with a sensitivity list calls a procedure, then the procedure cannot contain any wait statements.

Examples

Example 1

entity D_FF is
port (D,CLK : in BIT;
      Q : out BIT := '0';
      NQ : out BIT := '1' );
end entity D_FF;
architecture A_RS_FF of D_FF is
begin
  BIN_P_RS_FF: process (CLK)
  begin
    if CLK = '1' and CLK'Event then
      Q <= D;
      NQ <= not D;
    end if;
  end process;
end architecture A_RS_FF;

The flip-flop has two input ports: D, CLK and two output ports: Q and NQ. The value of the input signal D is assigned to the output Q when the value of the CLK changes from '0' to '1'. The change of the signal value initiates the process BIN_P_RS_FF, because the signal CLK is on the sensitivity list of this process. The change of the CLK value from the logical zero to the logical one is sensed by the use of the if statement.

The first part of if statement takes place when the actual value of the signal CLK is checked. The second part confirms that the signal CLK really changes its value (attribute 'Event is responsible for that). In the case when the logical value of this condition is TRUE, then the two assignment signal statement are executed.

Important Notes

  • Sensitivity list and explicit wait statements may not be specified in the same process.

Thursday, 20 December 2012

Range

Formal Definition

A specified subset of values of a scalar type.

Simplified Syntax

range left_bound to right_bound

range left_bound downto right_bound

range <>

Description

The range specifies a subset of values of a scalar type. This range can be null range if the set contains no values. A range can be either ascending or descending.

A range is called ascending if it is specified with the keyword to as the direction and the left bound value is smaller than the right bound (otherwise the range is null). A range isdescending if the range is specified with the keyword downto as the direction and the left bound is greater than the right bound (otherwise the range is null).

A value X belongs to a range if this range is not a null range and the following relation holds:

lower bound of the range <= X <= upper bound of the range

A range can be undefined. Such a range is used in declaration of unconstrained arrays and is illustrated in example 2.

Examples

Example 1

1 to 100
7 downto 0
5 to 0

The first range is an ascending range of the values of integer type. The second range is also of integer type, but descending. Finally, the third range is null.

Example 2

type Mem is array (NATURAL range <>) of Bit_Vector(7 downto 0);

The type Mem is declared as an unconstrained array of bytes (8-bit wide vectors of bits). Note the way an undefined range is declared.

Important Notes

· Ranges do not have to be bounded by discrete numbers. Enumeration types can also be used for ranges (for example 'a' to 'z').