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

Tuesday, 18 December 2012

Subtype

Formal Definition

A type together with a constraint.

A value belongs to a subtype of a given type if it belongs to the type and satisfies the constraint; the given type is called the base type of the subtype. A type is a subtype of itself. Such a subtype is said to be unconstrained because it corresponds to a condition that imposes no restriction.

Simplified Syntax

subtype subtype_name is base_type range range_constraint;

Description

Subtype distinguishes a subset of values of some type.

The part of the subtype declaration is the subtype indication, which denotes some other type or subtype. The type_mark in a subtype_indication must refer to a type or a subtype that was declared earlier (Example 1).

The constraints given in the subtype indication must correspond to the subtype. For scalar types - range constrains can be applied, for arrays - index constraints are applicable. Records cannot have any constraints. Access type may have index type constraints only when their type_mark denotes an array type. If the subtype declaration does not contain any constraints then the subtype is the same as the (sub)type denoted by the type_mark.

A special form of the subtype indication may include a resolution function name (Example 2). This form is not allowed for declarations of access and file subtypes.

There are two predefined subtypes specified in the package STANDARD: natural and positive. Both are subtypes of the type INTEGER. The package Std_Logic_1164 also contains declarations of subtypes, which are constrained subtypes of the Std_Logic: X01, X01Z, UX01, and UX01Z.

Examples

Example 1

subtype DIGITS is INTEGER range 0 to 9;

INTEGER is a predefined type and the subtype DIGITS will constrain the type to ten values only, reducing the size of registers if the specification is synthesized.

Example 2

function RESOLVE_VALUE (anonymous: BIT_VECTOR) return BIT;
subtype BIT_NEW is RESOLVE_VALUE BIT;

The subtype BIT_NEW is a resolved version of the type BIT due to the reference to a resolution function RESOLVE_VALUE specified earlier.

Important Notes

· A subtype declaration does not define a new type.

· A subtype is the same type as its base type; thus, no type conversion is needed when objects of a subtype and its base type are assigned (in either direction). Also, the set of operations allowed on operands of a subtype is the same as the set of operations on its base type.

· Using subtypes of enumerated and integer types for synthesis is strongly recommended as synthesis tools infer an appropriate number of bits in synthesized registers, depending on the range.

Suspend

Formal Definition

Suspend is a process that stops executing and waits either for an event or for a time period to elapse.

Description

When a wait statement is encountered in a process, the process becomes suspended, i.e. it stops its execution until the condition supported by the wait statement is met. Depending upon the type of a wait statement there can be several conditions for resuming (continuing execution of) a suspended process:

  • timeout specified has expired (wait for statement)
  • a logical condition is met (wait until statement)
  • an event on a signal took place (wait on statement)

See wait statement for details.

Examples

Example 1

wait until CLK'event and CLK='0';

A process containing such a wait statement will be suspended until a falling edge on the CLK signal will be encountered.

Important Notes

  • If no condition is specified in a wait statement, the process suspends forever.

Monday, 17 December 2012

Testbench

Complete Definition:

Testbench is not defined by the VHDL Language Reference Manual and has no formal definition.

Simplified Syntax

entity testbench_ent is

end entity testbench_ent;

architecture testbench_arch of testbench_ent is

  signal declarations

  component declarations

begin

  component instantiations

  stimuli (test vectors)

end architecture testbench_arch;

Description

The testbench is a specification in VHDL that plays the role of a complete simulation environment for the analyzed system (unit under test, UUT). A testbench contains both the UUT as well as stimuli for the simulation.

The UUT is instantiated as a component of the testbench and the architecture of the testbench specifies stimuli for the UUT's ports, usually as waveforms assigned to all output and bidirectional ports of the UUT.

The entity of a testbench does not have any ports as this serves as an environment for the UUT. All the simulation results are reported using the assert and report statements.

Examples

Example 1

entity Test_Decoder_bcd is
end entity Test_Decoder_bcd;
architecture Struct_1 of Test_Decoder_bcd is
component Decoder_bcd is
port (
  enable : in BIT;
  led : in std_ulogic_vector(3 downto 0);
  bcd : out BIT_VECTOR(1 downto 0));
end component Decoder_bcd;
signal bcd: BIT_VECTOR(1 downto 0) := "11";
signal Enable: BIT := '1';
signal led: std_ulogic_vector (3 downto 0);
begin
  U1: Decoder_bcd port map (Enable,led,bcd);
     bcd <= "00" after 5 ns,
            "01" after 15 ns,
            "10" after 25 ns,
            "11" after 35 ns;
      assert bcd = "00" and led = "0001"
        or bcd = "01" and led = "0010"
        or bcd = "10" and led = "0100"
        or bcd = "11" and led = "1000"
        report "There is an incorrect value on the output led"
        severity error;
end architecture Struct_1;

The design entity Test_Decoder_BCD is designed to verify correctness of the Decoder_BCD. This test bench applies stimuli to the bcd inputs and when the value of the sled signal is other than asingle '1' on the position corresponding to the binary value of the bcd signal, with all other bits equal to zero, the listed error is reported.

Important Notes

· Testbenches should allow automated verification of the UUT, with reports on success or failure of each sub-test.

· In case of sequential units under test, a clock signal should be supported in the testbench. Typically, it is realized as a separate process in the testbench architecture.

· In order to stop the simulation with a testbench, stimuli are often specified inside a process which contains a non-conditional wait statement at the end; such statement suspends the execution of the testbench forever.

Type

Formal Definition

A set of values and a set of operations.

Simplified Syntax

type type_name is type_definition;

type type_name;

Description

Each object in VHDL has to be of some type, which defines possible values and operations that can be performed on this object (and other objects of the same type). The set of operations of a type consists of:

· explicitly declared subprograms that have a parameter or result of the particular type; such subprograms can be either predefined (in standard packages) or user-defined;

· basic operations (assignments, allocators, selected names, indexed names, slice names)

· numeric literals, literal null, string literal, bit string literals, aggregates or predefined attributes - depending on particular type.

· There are four classes of types in VHDL:

· scalar types (values of these types have no elements),

· composite types (values of these types consist of element values),

· access types (provide access to objects of a given type) and

· files (provide access to objects that contain a sequence of values of a given type).

See respective topics for details.

Apart from predefined types (available through the packages Standard and Std_Logic_1164), the user can define his/her own types. A user-defined type can be of any of the four classes mentioned above. The rules for defining types are described in detail in the corresponding topics.

Important Notes

· A type defines not only a set of values, but also a set of operators.

· VHDL is strongly typed language which causes that two types defined in exactly the same way (i.e. lexically identical) but differing only by names will be considered different.

· If a translation from one type to another is required, then type conversion must be applied, even if the two types are very similar (like assigning a natural variable to an integer variable).

Type Conversion

Formal Definition

An expression that converts the value of a subexpression from one type to the designated type of the type conversion.

Simplified Syntax

type_mark ( expression )

Description

VHDL is a strongly typed language. This causes that objects of even closely related types need a conversion, if they are supposed to be used together.

The result of the conversion is an object, which type is the same as the type specified by the type_mark (Example 1). The type of the operand (the expression) must be known independently from the context. Moreover, the operand cannot be an aggregate, an allocator, the literal null, or a string literal.

A type conversion is restricted to closely related types, i.e. must conform to the following rules::

  • All abstract numeric types (integers and floating point numbers) are closely related types. When a floating-point number is converted into an integer, the result is rounded to the nearest integer.
  • Two arrays are closely related types if:
    • Both arrays have the same dimensions,
    • their elements are of the same type,
    • for each range, the index types are the same or closely related.
  • No other types are closely related.

If the type_mark indicates an unrestricted array type, then after the conversion the range boundaries are moved from the operand. If the type_mark indicates a restricted array type, then the range boundaries of the array are described based on this type. After the conversion, the elements values of the array are equal to the elements values before the conversion.

Examples

Example 1

variable Data_Calc, Param_Calc : integer;
. . .
Data_Calc := Integer(74.94 * real(Param_Calc));

This assignment contains two type conversions: first Param_Calc is converted to a real value in order to multiply it with a universal real. Then the result of the multiplication is converted back to an integer and assigned to Data_Calc.

Important Notes

  • No conversion is needed between any type or subtype defined on its basis.
  • Two arrays may be closely related even if corresponding index positions have different directions.

Sunday, 16 December 2012

Use Clause

Formal Definition

Achieves direct visibility of declarations that are visible by selection.

Simplified Syntax

use library_name.package_name.item;

use library_name.package_name;

use library_name.package_name.all;

Description

The use clause makes visible items specified as suffixes in selected names listed in the clause. In practice, the use clause makes visible declarations specified in packages and has the following form:

use library_name.package_name.item

If a designer wants to have all declarations in a package visible, then the 'item' clause should be substituted by the reserved word all.

The use clause is valid for the design unit immediately following it and for all secondary design units assigned to this design unit (if it is a primary design unit).

Examples

library IEEE;
use IEEE.Std_Logic_1164.all;
library IEEE;
use IEEE.Std_Logic_1164.Std_ulogic;
use IEEE.Std_Logic_1164.Rising_edge;

In the first example, all declarations specified in the package Std_Logic_1164 (which belongs to the library IEEE) have been made visible.

The second example makes visible the Rising_Edge function, which is declared in the same package. The function uses the type Std_ulogic, therefore declaration of this type is also made visible.

Important Notes

· Using multiple value logic and resolution functions requires using library clause and use clause like in the first example.

Variable Assignment

Formal Definition

A variable assignment statement replaces the current value of a variable with a new value specified by an expression.

Simplified Syntax

variable_name := expression ;

Description

The variable assignment statement modifies the value of the variable. The new value of the variable is obtained by assigning an expression to this variable. In order to distinguish variable assignment from signal assignment, the variable assignment symbol is different (:=).

The expression assigned to a variable must give results of the same type as the variable. The target at the left-hand side of the assignment can be either a name of a variable or anaggregate.

In the first case, the target can be in the form of simple name, selected name, indexed name or slice name (Example 1).

In case of aggregate as the target of the assignment, the type of the aggregate must be determinable from the context, including the fact that the type must be of the composite type. Each element of the aggregate must be in the form of the locally static name, which represents variable (Example 2).

The element association of aggregate, similarly to names, may have forms that are more complex: selected name, indexed name or slice name (Example 3).

Examples

Example 1

variable X, Y : REAL;
variable A, B : BIT_VECTOR (0 to 7);
type BIT_RECORD is record
  bitfield : BIT;
  intfield : Integer;
end record;
variable C, D : BIT_RECORD;
X := 1000.0;
A := B;
A := "11111111";
A (3 to 6) := ('1','1','1','1');
A (0 to 5) := B (2 to 7);
A (7) := '0';
B (0) := A (6);
C.bitfield := '1';
D.intfield := C.intfield;

The above examples of variable assignments are grouped in the following way: after the declarations the first group is a group of assignments with simple names as targets, then slice names, indexed names and finally selected names.

Example 2

variable E : BIT;
variable I : INTEGER;
(E, I) := C;

The aggregate used above as a target for a variable assignment could be used for the variable C declared in such a way as in the Example 1. E will be assigned the value of C.bitfield and I - C.intfield.

Example 3

type BIT_VECTOR_RECORD is record
  a: BIT_VECTOR(0 to 7);
  b: Integer;
end record;
variable G, H : BIT_VECTOR_RECORD;
(C.bitfield, C.intfield) := D; -- aggregate with selected name
(G.a(0 to 7), K) := H; -- aggregate with sliced name
(G.a(0), K) := D; -- aggregate with indexed name

Aggregates can use different forms of names.

Important Notes

· Variable assignment can be labeled.

· Variable assignment takes effect immediately.

· Variable assignment can not be specified with a delay.