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

Monday, 31 December 2012

Configuration Specification

Formal Definition

A configuration is a construct that defines how component instances in a given block are bound to design entities in order to describe how design entities are put together to form a complete design.

Simplified Syntax

for instance_label:component_name

use entity library_name.entity_name(arch_name);

for instance_label:component_name

use configuration library_name.config_name;

Description

Each component instantiation refers to some design entity (entity/architecture pair) and the association is specified by a configuration specification. Component specification appears in the declarative part of the unit, where the instances are used. This way components can be configured within architecture which instances them without using a separate configuration declaration. The specification is simpler, but also less flexible. Example 1 contains a configuration specification for the same component as in the Example 1 in theconfiguration declaration description.

When the ports and generics in component declaration do not match with their counterparts in entity declaration, so called binding indication can be applied. Simply speaking this is an explicit notification on how the ports and generics in the entity should be bound to ports and generics of the component instance. The generic map and port map clauses are used for this purpose. This technique is used in Example 1. In practice, however, it is recommended to match the generics and ports of components and respective entities as this improves readability.

If no configuration (either in the form of a declaration or specification) is supported for a component, so called default binding will occur. This means that for such a component an entity will be selected such that its name, port names, port types, generics etc. match those in the corresponding component declaration. If the entity has more than one architecture, the last analyzed of them will be used.

Examples

Example 1

entity INVERTER is
generic (PropTime : TIME := 5 ns);
port ( IN1 : in BIT; OUT1 : out BIT);
end INVERTER;
architecture STRUCT_I of INVERTER is
begin
OUT1 <= not IN1 after PropTime;
end STRUCT_I;
entity TEST_INV is end TEST_INV;
architecture STRUCT_T of TEST_INV is
signal S1, S2 : BIT := '1';
-- INV_COMP component declaration:
component INV_COMP is
generic (TimeH : TIME);
port ( IN_A : in BIT; OUT_A : out BIT );
end component;
for LH : INV_COMP
use entity INVERTER (STRUCT_I)
   -- indicates generic and port aspects:
generic map (PropTime => TimeH)
port map (IN1 => IN_A, OUT1 => OUT_A);
begin
-- instantiation of INV_COMP component:
LH : INV_COMP generic map (10 ns)
  port map (S1, S2);
end STRUCT_T;

Architecture STRUCT_T of the entity TEST_INV uses a component INV_COMP. The binding of the component to the entity INVERTER and architecture STRUCT_I is realized by the configuration specification which appears in the declarative part of the architecture.

Important Notes

  • Synthesis tools do generally not support configurations. Users are required to ensure that component and entity names, ports and generics match (default binding).
  • For a configuration of some design entity, both the entity and the configuration must be declared in the same library.

Saturday, 29 December 2012

Constant

Formal Definition

Constant is an object whose value cannot be changed once defined for the design. Constants may be explicitly declared or they may be sub-elements of explicitly declared constants, or interface constants. Constants declared in packages may also be deferred constants.

Simplified Syntax

constant constant_name : type := value;

Description

A constant is an object whose value may never be changed during the simulation process.

The constant declaration contains one or more identifiers, a subtype indication and an expression which specifies the value of the constant declared in the particular statement. The identifiers specify names of the constants. Each name appearing in the identifier list creates a separate object.

The object type in the constant declaration can be of scalar or composite type and it can be constrained. A constant cannot be of the file or access type. If a constant is an array or a record then none of its elements can be of the file or access type.

The expression used in the constant declaration must refer to a value of the same type as specified for the constant (Example 1).

If a constant is declared an array other than string, bit_vector or std_logic_vector, then the value for the constant must be specified using aggregates (Example 2).

A constant declared in a package can be deferred, i.e. it can be declared without specifying its value, which is given later on, in the package body (Example 3).

Constants improve the clarity and readability of a project. Moreover, they simplify incorporating changes in the project. For example, if a design contains a bus with a fixed width, aconstant representing the number of bits in the bus can be used. When the width of the bus is to be changed, it is sufficient to alter the constant declaration only.

The visibility of constants depends on the place of their declaration. The constants defined in the package can be used by several design units. The constant declaration in the design entity is seen by all the statements of the architecture bodies of this entity. The constants defined in the declaration part of the design unit is seen in all bodies related to this design, including the process statement. The constant defined in the process can only be used in this process.

Examples

Example 1

type WeekDay is (Mon,Tue,Wed,Thu,Fri,Sat,Sun);
constant StartDay : WeekDay := Sat;
constant LogicalGND : Bit := '0';
constant BusWidth, QueueLength : Integer := 16;
constant CLKPeriod : Time := 15 ns;
constant MaxSimTime : Time := 200 * CLKPeriod;

Each of the six constants above is of a scalar type. Both BusWidth and QueueLength are expected to be integer numbers of the same value, therefore they were specified using one declaration. Note that you can either explicitly specify the constant's value or using an expression based on other constants (see the MaxSimTime constant).

Example 2

type NumericCodeType is array (7 downto 0) of Integer range 0 to 9;
constant EntryCode : NumericCodeType := (2,6,4,8,0,0,1,3);
constant DataBusReset: Std_Logic_Vector(7 downto 0) := "00000000";

Both constants are of complex types, but DataBusReset is of the Std_Logic_Vector, thus it can be assigned its value directly. EntryCode is also a one-dimensional array, but its elements are integers so the value for the constant must be specified using an aggregate numeric code type (2,6,4,8...).

Example 3

package Timing is
constant Reset : Std_Logic;
end package Timing;
package body Timing is
constant Reset: Std_Logic := '0';
end package body Timing;

Note that the Reset constant is declared in the package without a concrete value assigned to it because the complete declaration of this constant is given in the package body.

Important Notes

· By definition, a constant may not be assigned any values by the simulation process.

· Use constants as often as possible as they create more readable and maintainable code.

· Use constants to define data parameters and lookup tables, which may substitute function calls the simulation time of such lookups is significantly shorter than that of function calls.

Delay

Formal Definition

Delay is a mechanism allowing introducing timing parameters of specified systems.

Syntax:

delay_mechanism ::= transport | [ reject time_expression ] inertial

Description

The delay mechanism allows introducing propagation times of described systems. Delays are specified in signal assignment statements. It is not allowed to specify delays in variable assignments.

There are two delay mechanism available in VHDL: inertial delay (default) and transport delay.

The transport delay is defined using the reserved word transport and is characteristic for transmission lines. New signal value is assigned with specified delay independently from the width of the impulse in waveform (i.e. the signal is propagated through the line - Example 1).

Inertial delay is defined using the reserved word inertial and is used to model the devices, which are inherently inertial. In practice this means, that impulses shorter than specified switching time are not transmitted (Example 2).

Inertial delay specification may contain a reject clause. This clause can be used to specify the minimum impulse width that will be propagated, regardless of the switching time specified (Example 3).

If the delay mechanism is not specified then by default it is inertial.

Examples

Example 1

B_OUT <= transport B_IN after 1 ns;

The value of the signal B_IN is assigned to the signal B_OUT with 1 ns delay. The distance between subsequent changes of B_IN is not important - all changes are transmitted to B_OUT with specified delay (Fig. 1).

VHDL_transport_delay

Figure 1. Example of transport delay

Example 2

L_OUT <= inertial L_IN after 1 ns;

The signal value L_IN is assigned to the signal L_OUT with 1 ns delay. Not all changes of the signal L_IN, however, will be transmitted: if the width of an impulse is shorter than 1 ns then it will not be transmitted. See Fig. 2 and the change of L_IN at 13 ns and again at 13.7 ns.

VHDL_inertial_delay

Figure 2. Example of inertial delay

Example 3

Q_OUT <= reject 500 ps inertial Q_IN after 1 ns;

The signal value Q_IN is assigned to the signal Q_OUT with 1 ns delay. Although it is an inertial delay with switching time equal to 1 ns, the reject time is specified to 500 ps (.5 ns) and only impulses shorter than 500 ps will not be transmitted (Fig. 3).

VHDL_inertial_delay_with_rejection

Figure 3. Example of inertial delay with rejection limit.

Important Notes

· Delay mechanisms can be applied to signals only. It is not allowed to specify delays in variable assignments.

· Delays are not synthesizable.

· The Inertial delay is the default delay and the reserved word inertial can be omitted.

Driver

Formal Definition

A container for a projected output waveform of a signal. The value of the signal is a function of the current values of its drivers. Each process that assigns to a given signal implicitly contains a driver for that signal. A signal assignment statement affects only the associated driver(s).

Description

Each signal assignment statement defines a driver for each scalar signal that is a target of this assignment. In case of signals of complex type, each element has its own driver. Inside processes each signal has only one driver, no matter how many assignment to it are specified.

When an assignment statement is executed, a new value is assigned to the signal driver. The value of the signal is determined based on all its drivers using the resolution function.

Examples

signal DataBus : Std_Logic_Vector (7 downto 0) := "ZZZZZZZZ";
P1: process (A,B)
begin
. . .
DataBus <= "11111111";
end process P1;
P2: process (A,B)
begin
. . .
DataBus <= "00000000";
end process P2;

Signal DataBus is assigned values in two processes, therefore it will have two drivers (one per each process). The assignments will result in a change of the value of respective drivers, which will result in assigning the "XXXXXXXX" value to the DataBus.

Important Notes

· Drivers are not associated with signal declarations but with signal assignments.

· If a signal has more than one driver in an architecture, it must be of a resolved type.

Entity

Formal Definition

Entity is the description of the interface between a design and its external environment. It may also specify the declarations and statements that are part of the design entity. A given entity declaration may be shared by many design entities, each of which has a different architecture. Thus, an entity declaration can potentially represent a class of design entities, each having the same interface.

Simplified Syntax

entity entity_name is

generic (generic_list);

port (port_list);]

end entity entity_name;

Description

An entity specifies the interface between the specified design (formally called a design entity) and the environment in which it operates. On the other hand, an architecture is a description of the inner design operation and it must be assigned to an entity. The architecture can be assigned to one entity only but one entity may be assigned to a number of architectures.

The entity statement declares the design name (the identifier item in the Syntax example). In addition, it defines generic parameters (see generic) and ports (see port) of the design entity. Generic parameters provide static information (like timing parameters or bus width) to a design. Ports provide communication channels between the design and its environment. For each port, its mode (i.e. data flow) and type are defined.

Optionally, an entity may contain a declarative part. Any subprograms, types, subtypes, and constants can be declared here.

Declarations which are defined in an entity are visible to all architectures assigned to this entity.

An entity may contain its own statements, declared after the begin keyword. The statements here must be passive, which means they cannot alter values of any signals; Passive processes, concurrent assertion statements and passive concurrent procedure calls can be used here.

The entity declaration may be preceded by the library and use clauses. This way all declarations defined in a package will be visible for the entity and all architectures assigned to it.

Examples

Example 1

library IEEE;
use IEEE.std_logic_1164.all;
entity BCD_Decoder is
port (
   BCD : in Bit_Vector (2 downto 0);
   Enable : in Bit;
   LED : out Std_Ulogic_Vector (3 downto 0));
constant ZERO : Std_Ulogic_Vector(3 downto 0) := "0000";
begin
assert (BCD /= "111") report "BCD = 7 " severity note;
end entity BCD_Decoder;

The above example illustrates several important issues related to entities. First two lines contain a call to the IEEE library and to the std_logic_1164 package, respectively. These two lines are required because the Std_Ulogic_Vector type used for the output signal LED is not a standard type but it is defined in the mentioned package. If LED would be of Bit_Vector type then the two lines could have been omitted.

The BCD_Decoder identifier, which is following the entity keyword, is a name assigned by the designer to the entity. Note that this name is repeated at the very end of the entity.

The above listed entity contains the specification of ports only. In this case there are two inputs (BCD and Enable) and one output (LED). The mode for each of them is supported after a colon and is followed by a specification of the signal's type. See ports for more details on modes and types of ports.

The Declarative part of the above entity contains two declarations: constant and assert statements. The constant introduced here will be visible in all architectures of the BCD_Decoder entity. This type of a declaration makes sense if there are more than one such architectures. Otherwise, it might be better to place it in the architecture section to make the entity more clear. See constant for more details on constants.

The assert statement is a concurrent statement which will be active whenever any of the BCD_Decoder architectures is active. This particular statement will generate a Message listed in the report clause, whenever BCD will be equal to "111" ("BCD = 7"). Note that the condition in the assert statement should be interpreted as "if not condition - then report". Turn to assert for more information on this topic.

Important Notes

· The VHDL Language Reference Manual uses the name design entity for a complete specification of the design, i.e. both its interface (entity unit) and behavior or structure (architecture unit). Therefore entity and design entity are not the same concepts!

· The identifier for an entity must conform to VHDL identifier rules; it must start with a letter followed by an arbitrary combination of letters, digits and underline symbols.

· While it is not necessary to repeat the name of an entity at the end of the declaration, it is strongly recommended to do it for the sake of clarity of the description; for the same reason it is advised to add the entity keyword between the end and the entity name.

· It is possible to write an entity without any generics, ports and passive statements. In fact this is used in constructing testbenches (see testbench).

Enumeration Type

Formal Definition

The Enumeration type is a type whose values are defined by listing (enumerating) them explicitly. This type values are represented by enumeration literals (either identifiers or character literals).

Syntax:

type type_name is (type_element, type_element, ...);

Description

The enumeration type is a type with an ordered set of values, called enumeration literals, and consisting of identifiers and character literals. Each of enumeration literals must be unique within the given declaration type, but different enumeration types may use the same literals (example 1). In this case, it is said that such literals are overloaded. When such a literal is referenced in the source code, its is determined from the context, in which enumeration this literal has occurred.

All enumerated values are ordered and each of them has a numeric (integer) value assigned to it. The number indicates the position of the literal. The very first literal in the definition has position number zero and each subsequent has the number increased by one from its predecessor (example 2).

Each enumeration type defined has implicitly defined relational operators that can be used on the type values.

The package Standard contains declarations of several predefined enumeration types: BIT, BOOLEAN, CHARACTER, SEVERITY_LEVEL, FILE_OPEN_KIND and FILE_OPEN_STATUS. Apart from that the package Std_Logic_1164 defines another enumeration type, STD_ULOGIC.

Examples

Example 1

type NotGood is (X, '0', '1', X); -- illegal
type MyBit is (L, H);
type Test is ('0', '1', L, H);

The type Not Good is an illegal declaration as the literal X appears twice in the same declaration. On the other hand there is nothing incorrect in using L (LOW) and H (HIGH) twice because they are used in two different declarations.

Example 2

type FSM_States is (Init, Read, Decode, Execute, Write);

The type FSM_States defines five possible values, which are numbered from 0 to 4: the position number of Init is 0, position of Read is 1, Decode - 2, Execute - 3, and Write - 4.

Important Notes

· It is illegal to define an enumeration type with a range.

· It is assumed that the values are defined in ascending order. For this reason it is recommended to order the literals in such a way that the default value is the first one (it is referred to through the attribute 'left').

· Objects of enumeration types are typically synthesizable.

Event

Formal Definition

A change in the current value of a signal, which occurs when the signal is updated with its effective value.

Description

The event is an important concept in VHDL. It relates to signals and it occurs on a signal if the current value of that signal changes. In other words, an event on a signal is a change of the signal's value.

It is possible to check whether an event occurred on a signal. Such an information can be obtained through the predefined attribute 'EVENT. The principal application of this attribute is checking for an edge of a clock signal (example 1). It is also possible to check when the last event on a signal occurred (attribute 'LAST_EVENT). See attributes for details.

An event on a signal, which is on sensitivity list of a process or is a part of an expression in a concurrent signal assignment, causes the process or assignment to resume (invoke). See sensitivity and resume for details.

Examples

Example 1

if CLK'event and CLK='1'
then
. . .

The condition above will be true only on rising edge of the CLK signal, i.e. when the actual value of the signal is '1' and there was an event on it (the value changed recently).

Important Notes

· Sensitivity list or sensitivity set require an event on any of their signals, i.e. a change of the signal's value. A transaction (an assignment to a signal, no matter whether the same or a different value) is not enough.

· The concept of event relates to signals only. There is no "event on a variable" in VHDL.