Design using Standard Description Languages:Structure of a VHDL Design.
Structure of a VHDL Design
This chapter deals with some basic aspects of how to structure a VHDL design:
• Signals and multi-level logic;
• Interface signals and ports;
• Entity; how a module is presented to the outside world;
• Architecture; how to describe the functionality of a module;
• Configuration; how to join parts to a system.
Signals
Signals are very important in VHDL. Similarly to variables in any computer language, they carry data. A signal assignment specifies a logic value of a signal. After a signal assignment it can be tested or be used in other language constructs. Just as does a piece of wire, a signal connects an output and an input of two parts of a circuit (e.g., gate, flip flop, ... ). However, after synthesis, not every signal will turn into a piece of connecting wire. During synthesis signals can appear or disappear as a result of optimization.
Such a signal declaration consists of three parts. The first part is the so-called key word (reserved word). In this case SIGNAL. The second part as- signs a name to individual signals, namely a, b, and c. The third part determines the type of the signals, which is BIT in this case. The type of the signal defines the logic values which the signal can take. A signal of type BIT can show the logic values ’0’ or ’1’ (character literal). The assignment of the logic values 0 and 1 is denoted by a character framed by two apostrophes. As already mentioned, individual signals can receive values assigned, also it is possible to combine and evaluate signals in expressions.
Both declarations define an eight bit wide signal bus. However they are different in terms of index- ing the bus signals, which affects the position of the most significant bit (MSB). As regards bus_a, the MSB is carried by the signal bus_a(7), the signal with index seven. The least significant bit (LSB) is carried by the signal bus_a(0), the signal with index zero. Looking at bus_b, it is the exact opposite.
The value of a bus is always the same, independent of indexing. It corresponds with the well known way of reading bus values having the MSB in the first place. The bus value is a string of characters enclosed in quotation marks.
To prevent confusion and remove a possible source of error in the development team, a unique and consistent way of declaring bus signals within the design and its interfaces is highly recommended. This means: all buses are declared using ascending (TO) or descending (DOWNTO) indexing. The DOWNTO version has the advantage that the index of the individual signal corresponds with its equiva- lent of the binary value.
Multi-value logic
WHEN it comes to defining a bi-directional databus of a processor interface, it is obvious that a two-valued logic with the logic values ’0’ and ’1’ is not sufficient to describe the behavior correctly. In a system which contains multiple sources it must be guaranteed that only one source actively drives the data bus. All other sources have to set their bus driver to a high impedance value. If this were not the case bus contention would occur. The worst case would be that a signal would be driven with opposite logic values (0 and 1) at the same time, which causes higher power consumption and an increase in the probability of failure.
The IEEE library contains a so called pack- age which defines a nine-valued logic system (Std_logic_1164, see app. C) as an extension of the Standard but not of the language itself. Including this package into the design and using type definitions std_ulogic or std_logic instead of the type definition BIT makes it possible to describe additional values such as ’Z’ for high-
stands for ‘uninitialized’, which means that no logic value has yet been assigned to the signal. The logic values ’L’ and ’H’ describe soft values, e.g., caused by pull up or pull down resistors. These logic values can be overdriven by a forcing ’0’ or ’1’ value. If the logic value can be chosen freely, the character(’-’) symbolizes a ‘don’t care’ condition which provides additional degrees of freedom during synthesis.
What is the difference between the logic types std_ulogic and std_logic. In the form: The u in std_logic stands for unresolved. Derived from std_ulogic, std_logic provides a so called resolu- tion function. This function will be automatically called when more than one value should be as- signed to a signal at the same time (e.g., fig. 4.6). The resolution function takes the place of a referee and decides which logic value will be assigned to the multi-driven signals. This feature allows one to describe signals having a so called tri-state condition.
Today std_logic is the de facto standard. All CAE tools support the IEEE library. Compatibility of interfaces is an important condition for the re- use of VHDL components or for its purchase to increase synergy.
Initialization of Signals
A signal of type std_logic which has not been initialized correctly, or has not been assigned a logic value at the start of the simulation, takes the logic value defined in the type declaration at the first position which is ’U’. Types, representing a range of values (e.g., INTEGER) rather than an ENUMERATION are set to the value at the left boundary. To set up a user defined starting point at the beginning of the simulation, signal declaration allows an explicit initialization of the signal. This possibility must be used with great care, because signal initializations will be ignored during synthesis. Because of a random starting point the realized circuit can reach an unpredicted and, even worse, not simulated state. The explicit definition of a reset function avoids that kind of surprise. Furthermore, it is highly recommended that the circuit can change state from a random to a regular state of operation. When designing state machines this precaution is necessary and causes a small additional circuit complexity.
Ports
The interfaces of a VHDL component are signals black box into a component with well designed properties.
with additional properties. Apart from its type (e.g., std_logic), such a port is characterized by information of its signal direction: the so called mode (IN, OUT, INOUT, BUFFER, LINKAGE).
Entities
The entity defines the name of a functional unit and its interfaces to the outside world. The function of the component is not defined (fig. 4.8) so far. The completion of the empty box with a de- tailed plan (so called ARCHITECTURE) describing its internal structure and its behavior produces a model which can be simulated and changes the
The key word ENTITY is followed by the component name. In this case the component has two inputs, a 4-bit input bus and a 7-bit output bus, both listed in the port list PORT(...).
Design units
An entity is a design unit. Written to a file, that example can be compiled and tested for syntax. It is not possible to distribute design units such as architecture, package, and configuration to different files. However, they can be part of one file. The compiler treats every unit in a way as if written to separate files. If several files describe a project the required sequence of compilation is defined by the structure of the design and its dependencies. A typical sequence would start compiling packages (if present) followed by the entity, its architectures, and an optional configuration.
The library WORK
WORK is a VHDL reserved word and identifies the actual working library. Independent of sym- bolic and physical names of a library, WORK is
the location where a compiler stores its analyzed modules. Modules will be retrieved there during simulation at a later point in time. To access a library coming from another simulation environ- ment, its symbolic name (e.g., SIM_LIB) will be used.
Because of the separate external and internal point of view, namely interfaces and functions of a component, VHDL supports a hierarchical top down and bottom up design, which partitions, during a first step, the overall system into small modules (components) with simple interfaces. At a starting point of a design the key issue is the structure of the design rather than detailed thoughts about the module behavior and attempts to implement circuit functionality. The architecture supports both: it can define a circuit structure using individually connected components or describe its behavior by means of suitable statements. The entity decla- ration and its architecture represent a model of a piece of hardware, which can be simulated: the so called design entity.
Structure
A hardware structure is defined by its components as well as its interfaces and its signals. In this case (see fig. 4.9) the architecture looks more like a netlist.
Behave
Circuit behavior is determined by the processing of data between input and output, influenced by logical and physical timing to take signal and gate delays into account (fig. 4.10).
Normally this kind of description does not show any timing information of the circuit. The simula- tion of the decoder circuit is shown in figure 4.11. A purely structural architecture would be a result after synthesis. This third version of an architec- ture would contain all gate elements connected in a netlist. This means there are three alternative descriptions for one component, producing three
simulations on different levels of abstraction. The simulation results must be functionally identical.
The architecture is divided into a part containing declarations (that is, before the reserved word BE- GIN) and a part between BEGIN and END con- taining statements. All signals, constants, types, and components used within the architecture are defined in the declaration part. They are only valid within this architecture. Interfacing signals, present in the entity declaration, must not be de- clared again. The statements behind BEGIN con- tain the circuit description, e.g., by the placing and wiring of existing components or by using concur- rent statements. Each statement would represent a small part of the overall circuit.
Components
A hierarchical circuit design is formed by connect- ing individual design entities (entity architecture pairs). Design entities of lower hierarchical levels turn into components of a structural description in the level above. This is interesting to note that: a component is the substitute for a design entity. A configuration will define which particular design entity will replace the substitute. A working example applying components, their declaration, and instantiation is shown in section 4.2.8.
Component Declaration
A component to be used in an up to date descrip- tion must be made known (declared). Normally, the interface description in the component decla- ration, namely signal names connected to the indi- vidual type and their sequence, correspond exactly to the equivalent entity declaration. This informa- tion enables the compiler to find out whether the component is connected in the right way. On the other hand, the declaration does not provide infor- mation about where to find the equivalent design entity. Perhaps it is not available at all within the actual design hierarchy at compile time.
A component declaration is made within an archi- tecture or, in a global way, within a package.
Component Instantiation
If a component declaration is compared to the labelling of a drawer to mark its content, taking out and wiring a component can be seen as an instantiation (fig. 4.13). The instance is only an instance of the component declaration, not of the design entity. The connection to the design entity is made by the configuration. An individual name must be assigned to every instance, because a component might be instantiated more than once.
Wiring of components can be achieved in two ways. The quickest way to wire up signals is to list signals in the PORT MAP according to the sequence of the component declaration. Based on the declarations, the compiler tests only whether signals of the same type are connected to each other. If the sequence of signals is not maintained, it could mean that signals (e.g., a clock and a reset signal) are swapped. This could produce errors eventually detected at a late point in time of the design cycle.
A safe method is to assign every connection of the component to the associated signal in an unmis- takable way. In the first place, the PORT MAP shows the interface description as defined in the declaration followed by the sign ’=>’ pointing to the signal to be connected.
Configurations
A configuration statement is meaningful and nec- essary for several reasons. Firstly, it chooses from several versions of implementation (architectures) exactly one for a simulation and closes the gap between the entity declaration and the architecture. Secondly, it matches component instance and de- sign entity. Both declarations do not match exactly at times. A different name of the component and its entity, different notation of interfaces, its sequence, types, and numbers can be taken into account in the configuration. Flexibility and readability increase because of that. The parts of a hierarchical design form a circuit description which can be simulated.
Assuming that names of components and entities as well as names and modes of interfaces, are identical, a configuration is not necessary. In this case the simulator takes the architecture most recently compiled. According to these rules synthesis is performed. Here configurations are ignored as
Configuration Declarations
The configuration declaration is a separate compile unit and identifies, for each component, an entity architecture pair explicitly. The overall model can be configurated without modifying individual modules. A change in the design kit of the system only causes a new compilation of the configuration, provided all model versions are available. The skeleton of a typical configuration looks as follows:
The configuration receives a name (conf_name) related to the top level entity (entity_top). After that a corresponding architecture for this entity will be selected (FOR architecture_name_top).
If this architecture is hierarchically designed and if it contains components, the configura- tion will be two-dimensional. In a first step each component will be identified using in- stance_name:component_name to decide which library should provide a design entity to be connected to the component. This is because the standard library WORK must always be used. If there is an existing configuration for a lower hierarchy level, instead of using the statement USE ENTITY ..., it can be attached using
USE CONFIGURATION WORK.conf_name
Configuration Specification
There are some limits to using the configuration specification as a second possibility to configure. In this case it is not a separate design unit any longer. Being placed in the declaration part of the architecture it causes a loss of flexibility.
-- when declaring the architecture:
FOR U1, U2: hex_to_7seg
USE ENTITY WORK.hex_to_7seg(behave);
To match different naming conventions in declara- tions:
FOR ALL: hex_to_7seg
-- Having different port identifiers:
-- nibble_in in the entity,
-- nib in the component
USE ENTITY WORK.hex_to_7seg(behave) PORT MAP
(nibble_in => nib, display => disp);
Dual Digit Conversion ’Hex to 7Segment’
❑ Example (list 4.1):
This example shows declaration and instantiation of components and the design of a suitable configuration. A structural description will be used.
Comments
Post a Comment