You are on page 1of 224

VHDL

P L A N O F

T H E T A L K

Module I Introduction to VHDL Module II Modeling Digital Systems Module III Basic Language Concepts Module IV Modeling Delays Module V Dataflow Style of Modeling Module VI Behavioral Style of Modeling Module VII Structural Style of Modeling Module VIII Subprograms Module IX Advanced Concepts Module X Orcad Simulation

Module I
Introduction to VHDL

What is VHDL?
VHSIC Very High Speed Integrated Circuit

H Hardware
D Description L Language

Hardware Description Languages


A Language to describe hardware at multiple levels of Abstraction Ability to represent hardware parallelism Ability to represent timing relationships Ability to represent logic structure

Why a new Language?


Languages like C/C++ lack concept to timing relationship Writing code to represent Parallelism or Concurrency is very difficult

The Role of HDL

Interoperability: models at multiple levels of abstraction Technology independence: portable model Design re-use and rapid prototyping

Traditional vs. HD Languages


Procedural programming languages provide the how or recipes : for computation for data manipulation for execution on a specific hardware model Systems can be described from many different points of view : Behavior: what does it do? Structure: what is it composed of? Functional properties: how do I interface to it? Physical properties: how fast is it?

What is HARDWARE & What kind of DESCRIPTION?


Hardware Description Language = "Programming language for modeling hardware (Digital)

The word 'hardware', is used in a wide variety of contexts which range from complete systems like personal computers on one side to the small logical gates on their internal integrated circuits on the other side. This is why different descriptions exist for the hardware functionality. Complex systems are often described by the behavior that is observable from the outside. Abstract behavioral models are used in this case that hide all the implementation details. The description of a basic logic gate, on the other hand, may consist of only one Boolean equation, which is a very short and precise description.

H I S T O R Y

O F
V H D L

Designed by IBM, Texas Instruments, & Intermetrics as part of the DoD funded VHSIC program. Standardized by IEEE in 1987: IEEE 1076-1987 Enhanced version of the language defined in 1993: IEEE 1076-1993 Additional standardized packages provide definitions of data types & expressions of timing data IEEE 1164 (data types) IEEE 1076.3 (numeric) IEEE 1076.4 (timing)

Why do we describe systems


Design Specification
unambiguous definition of components and interfaces in a large design

Design Simulation
verify system/subsystem/chip performance prior to design implementation

Design Synthesis
automated generation of a hardware design

Digital System Design Flow

Synthesis Design Flow

Module II
Modeling Digital Systems

Systems Hierarchy

What elements should be in a description


Descriptions should be at multiple levels of abstraction The descriptive elements must be common to multiple levels of hierarchy The elements should enable meaningful and accurate simulation of hardware described using the elements Elements should have attributes of time as well as function The elements should enable the generation of hardware elements that realize a correct physical implementation Existence of a mapping from elements to VLSI devices

Abstraction
Abstraction is hiding of details Differentiation between essential and nonessential information Creation of abstraction levels On every abstraction level only the essential information is considered, nonessential information is left out Equability of the abstraction All information of a model on one abstraction level contains the same degree of abstraction

Abstraction Levels in IC Design


Functional description of the model No system clock Simulatable, only, but not synthesizable

Design is represented as a net list with logic gates (AND, OR, NOT, ...) and storage elements Design is divided into combinational logic and storage elements Synthesizable Description
Different cells of the target technology are placed on the chip Connections are routed. After the layout has been verified, the circuit is ready for the production process

Abstraction Levels and VHDL

Information Content of Abstraction Levels

What elements should be in a description


VHDL was conceived for the description of digital systems
From switches to networked systems
Keeping in mind the pragmatic issues of design re-use & portability of descriptions

Portability across technology generations Portability across a range of cost/performance points

Attributes of digital systems serve as the starting point


Language features designed to capture the key attributes

Attributes of Digital Systems

Digital systems are about signals and their values


Events, propagation delays, concurrency

Signal value changes at specific points in time


Time ordered sequence of events produces a waveform

Attributes of Digital Systems : Timing

Computation of events takes place at specific points in time Need to wait for an event (in this case the clock) Timing is an attribute of both synchronous and asynchronous systems

Attributes of Digital Systems : Timing

Example
Asynchronous communication No global clock Still need to wait for events on specific signals

Attributes of Digital Systems : Signal Values

Attributes of Digital Systems : Multiple Drivers

Modeling Digital Systems


We seek to describe attributes of digital systems common to multiple levels of abstraction
events, propagation delays, concurrency waveforms and timing signal values shared signals

Hardware description languages must provide constructs for naturally describing these attributes of a specific design
simulators use such descriptions for mimicking the physical system synthesis compilers use such descriptions for synthesizing manufacturable hardware specifications that conform to this description

Simulation vs. Synthesis

Simulation of Digital Systems

Digital systems are modeled as the generation of events


Value Transitions on signals

Discrete event simulations manage the generation and ordering of events


Correct sequencing of event processing Correct sequencing of computations caused by events

Synthesis and Hardware Inference

Module III
Basic Language Concepts

Design Units
Primary design units Entity Configuration Package Declaration These are not dependent on other design units

Secondary design units Package body Architecture


Design units are created in design files

Now you know the layout of a VHDL program!

Basic Rules, Syntax, and Constraints


Case Insensitive Can Handle Analog Modeling (VHDL-AMS) Statements end with ; (May span multiple lines) White space characters are delimiters in the syntax Allows Libraries and importing them in the current file Comments start with - - List Delimiter is , Signal Assignment Operator <= User defined names could be : Letters Numbers Underscore (It should start with a letter) The naming convention is that VHDL keywords are written in lower case letters while user defined identifiers are written in upper case letters. If something has to be highlighted it is done by writing it in bold letters

Describing Design Entities

Primary programming abstraction is a design entity


Register, logic block, chip, board, or system

What aspects of a digital system do we want to describe? Interface: how do we connect to it Function: what does it do?

Describing the Interface : The Entity Construct

The interface is a collection of ports Ports have a type Ports have a mode

Example Entity Descriptions

Example Entity Descriptions : IEEE 1164

Port Modes
Indicates the driver direction
Types of modes:
IN OUT INOUT BUFFER

Mode in

Mode out

Mode inout

Mode buffer

It differs from the inout mode in that:


1. It cannot have more than one source 2. Only kind of signal that can be connected to it can be another buffer port or a signal with utmost one source.

Bottom Line

Describing Behaviour : The Architecture Construct

Implementation of the design Always connected with a specific entity One entity can have several architectures Entity ports are available as signals within the architecture Contains concurrent statements

Describing Behaviour : The Architecture Construct

Identifiers
There are two kinds of identifiers in VHDL: 1. Basic Identifiers 2. Extended Identifiers

Basic/Normal Identifiers

Extended Identifiers

Graphical characters includes: a) . b) ! c) @ d) e) $ etc

Reserved Words / Keywords

These have a specific meaning in the language, and therefore, cannot be used as basic identifiers

Data Objects
A data object, holds a value or a sequence of values of a certain specified type. Every data object, belongs to one of the following four classes : 1. 2. 3. 4. Constants Variables Signals File

Constants
An object of a constant class, can hold a single value of a given type. This value is assigned to the constant before simulation starts, and the value cannot be changed during the course of the simulation. For a constant declared within a subprogram, the value is assigned to the constant every time the subprogram is called.

constant zero4: bit_vector(0 to 3) := ('0','0','0','0'); Constant rise_time : TIME := 10ns;

Deferred Constants
Example
constant NO_OF_INPUTS : INTEGER;
The value of the constant has not been specified in this case. Such a constant is called a DEFERRED CONSTANT, and it can appear only

inside a package declaration.


The complete constant declaration with the associated value, must appear in the corresponding package body.

Variables
An object of variable class can hold a single value of a given type. However, in this case, different values can be assigned to the variable at different times, using a variable assignment operator := It can optionally be assigned initial values (done only once prior to simulation). variable symbol: type [:= initial_value]; If no initial value is specified for a variable object, a default value is used as an initial value. The default value is TLEFT, where T is the object type, and LEFT is a predefined attribute of a type, that gives the leftmost value in the set of values belonging to type T.

Variables Cont..

Signals
An object belonging to the signal class, holds a list of values, which includes the current value of the signal, and a set of possible future values, that are to appear on the signal. Future values can be assigned to the signal using a signal assignment statement.

Examples:

Signals vs. Variables

File
An object belonging to the file class, contains a sequence of values. Values can be read or written to the file using read procedures and write procedures respectively.

file file_names:file_type_name [[open mode] is string expression];


The mode specifies whether, the file is to be used as a read only or write only or in the append mode. file STIMULUS : TEXT open READ_MODE is /usr/home/add.sti; The file STIMULUS is declared to be one of the predefined file type TEXT. When the path is not specified, the file will have to be explicitly opened using a file open procedure. When no mode is specified, READ_MODE is used as the default mode.

Data Types
Every data object in VHDl, can hold a value, that belongs to a set of values. This set of values is specified by using a TYPE DECLARATION. A TYPE is a name, that has associated with it, a set of values and a set of operations. Certain types, and operations that can be performed on these objects are predefined in the language. The declarations for the predefined types of the language are contained in package STANDARD. The language also provides facility to define user customized data types, and the operations that can be performed on those data typed objects, as and when needed. The data types can be classified as: 1. Scalar Types 2. Composite Types 3. Access Types 4. File Types 5. Incomplete Types

SCALAR TYPES
Scalar types represents a single numeric value, or an enumeration value. Values belonging to these types, appear in sequential order. Every value has a position number associated with it. This number is the position of the value in the ordered list of values belonging to that type. The scalar types can broadly be classified under the following four categories: 1. 2. 3. 4. Enumeration Type Integer Type Physical Type Real (Floating Point) Type

Enumeration Types
An enumeration type declaration, defines two categories: 1. User Defined Enumeration Types 2. Predefined Enumeration Types User defined data types are frequently used to enhance readability when dealing with so called state machines, i.e. modules that behave differently, depending on the state of internal storage elements.
Instead of fixed bit patterns, the symbolic names of the data type values are used which will be mapped to a bit level representation automatically during synthesis. These enhances readability in the code.

User Defined Enumeration Types


These have a set of user defined values, consisting of identifiers and character literals. The order in which, values appear in the enumeration type declaration, defines their ordering, i.e., when using relational operators, a value is always les than a value that appears to its right in the order. The position of the leftmost element is 0. The values of an enumeration type are called ENUMERATION LITERALS. If the same literal is used in two different enumeration type declarations, the literal is said to be Overloaded. type MVL is (U, 0, 1, Z); signal CONTROL_A : MVL; type TWO_STATE is (0,1); signal CONTROL_B :TWO_STATE

User Defined Enumeration Types

Predefined Enumeration Types


The Predefined enumeration types are:

1. 2. 3. 4. 5. 6. 7.

CHARACTER BIT BOOLEAN SEVERITY_LEVEL FILE_OPEN_KIND FILE_OPEN_STATUS STD_ULOGIC

CHARACTER Type
It constitutes the 191 characters of the IS eight-bit coded character set. These values are called character literals, and are always written between two single quotes ( ).

Examples
A - 3 variable VAL: character :=$;

BIT and BOOLEAN Type


BIT type has two literals : 0 and 1 BOOLEAN type has two literals : False and True.

signal A: bit :=1;

variable TEST: Boolean :=FALSE

SEVERITY_LEVEL Type
It has the values:
NOTE, WARNING, ERROR and FAILURE. It is typically used in assertion statements.

FILE_OPEN_KIND and FILE_OPEN_STATUS Types

FILE_OPEN_KIND has the following values:


READ_MODE, WRITE_MODE and APPEND_MODE

FILE_OPEN_STATUS has the following values:


OPEN_OK, STATUS_ERROR, NAME_ERROR and MODE_ERROR

Std_ulogic Type

std_logic vs. std_ulogic

It is recommended to use the multi-valued logic system from the IEEE instead of the standard 'bit' data type. The new type is called 'std_ulogic' and is defined in the package 'std_logic_1164' which is placed in the library IEEE (i.e. it is included by the following statement: 'use IEEE.std_logic_1164.all'

Integer Scalar Type


The range of the INTEGER type is implementation dependent, but must at least cover the range from -(231 1) to +(231 1) Values belonging to an integer type are called integer literals. Literal 6E2 refers to 6*102

Real(floating point) Scalar Type

Floating point literals are values of a floating point type. Example : 16.26, 0.6, 0.002 These differ from integer literals by the presence of the dot (.) character. Thus, 0 is an integer literal, while 0.0 is a floating point literal. These can also be expressed in an exponential form. Example : 62.3E-2 (E represents power of 10, and value must be an integer) It provides at least six decimal digits of precision.

Physical Scalar Types


It contains values, that represent measurement of some physical quantity, like time, length, voltage, or current. Values of this type are expressed as integer multiples of a base unit. type CURRENT is range 0 to 1E9 units nA; uA = 1000 nA; mA = 1000 uA; Amp = 1000 mA; End units; CURRENT is defined to be a physical type, that contains values from 0 nA to 109 nA. The base unit is nano-ampere, while all others are derived units. The position number of a value is the number of base units represented by that value, i.e.; 2uA has a position of 2000.

Physical Scalar Types


The range of values may include negative values. Values of a physical type are called physical literals. The only predefined physical type is TIME. Its range is also implementation dependent, must at least being -(231 1) to +(231 1) Predefined physical subtype DELAY_LENGTH is also present, which represents non negative time values. Available time units : fs, ps, ns, us, ms, sec, min, hr

Composite Data Types


It represents a collection of values. An object belonging to a composite type, therefore, represents a collection of sub objects, one for each element of a composite type. It could have a value belonging to either a scalar type, a composite type, or an access type. This provides the capability of defining arbitrarily complex composite types, e.g. array of an array of records. There are two composite types: 1. Array Types 2. Record Types

Array Types
Arrays are a collection of a number of values of a single data type. type ADDRESS_WORD is array (0 to 63) of BIT;

Elements of an array can be accessed by specifying the index values into the array. E.g. signal ADDRESS_BUS : ADDRESS_WORD; ADDRESS_BUS(26) refers to the 27th element of ADDRESS_BUS array object.

Dimensional Array Types


The language allows for an arbitrary number of dimensions to be associated with an array.

An object X(5,2) declared of multi type, refers to the value of the element at the 2nd column and 5th row of 2-d object. Also, it can be in the form of array of an array. The index set can be of any type.

Unconstrained Array
The array types can be unconstrained also. In this case, the number of elements in the array is not specified in the type declaration, instead, an object declaration for an object of that type declares the number of elements of the array. The <> symbol is called BOX. type STACK_TYPE is array (INTEGER range <>) of ADDRESS_WORD; subtype STACK is STACK_TYPE (0 to 63); subtype STACK_ONE is STACK_TYPE (0 to 5); There are two predefined one-dimensional unconstrained array types in the language: 1. STRING (array of characters) (string literals are enclosed within double quotes) 2. BIT_VECTOR (array of bits)

variable MESSAGE : STRING (1 to 17) := Hello, VHDL world; VHDL does not allows a type, that is an unconstrained array of an unconstrained array.

Unconstrained Array Contd..


There are two one-dimensional unconstrained array types defined in the package STD_LOGIC_1164: 1. type STD_ULOGIC_VECTOR is array (NATURAL range<>) of STD_ULOGIC; 2. type STD_LOGIC_VECTOR is array (NATURAL range <>) of STD_LOGIC;

Examples
signal RASTER_LINE : STD_LOGIC_VECTOR (0 to 8);

Assignment to an Array
The language allows an array object to be assigned to another array object of the same type using a signal assignment statement. The assignment can be made to an entire array, or to an element of an array, or to a slice of an array. Examples variable OP_CODES : BIT_VECTOR (1 to 5); OP_CODES := 01001; -- A string literal is assigned OP_CODES := (0,1,0,0,1); -- Positional association is used OP_CODES := (2=>1,5=>1,others =>0); -- Named Association OP_CODES := (others => 0); OP_CODES(4) := 1; -- Assign to an element of an array DECODER_VALUE := DECODER; -- An entire array is assigned ADDRESS_BUS(1 to 3) <= XFF; -- Assign to a slice of an array An AGGREGATE is a set of comma separated elements, enclosed within parenthesis.

Record Types
It represents a collection of values, that may belong to different types. An object of a record type is composed of elements of same or different types. Three choices exist for value assignments: Assign one record to another (' STUDENT_2 <= STUDENT_1 '). This does not allow to set individual values, however. Aggregates are commonly used for this purpose, i.e. the different element values are grouped together (e.g. ' TODAY <= (26, JUL, 1988) '). The single elements are addressed via RECORD.ELEMENT constructs

Record Types Contd..

Access Types
Values belonging to an access type are pointers to a dynamically allocated object of some other type. These are similar to pointers in Pascal and C languages. type PTR is access MODULE; type FIFO is array (0 to 63, 0 to 7) of bit; type FIFO_PTR is access FIFO; PTR is an access type, whose values are addresses, that points to objects of type MODULE. Only variables can be an access type; that is, it is not permissible for a signal to be utilized as an access type. Every access type may also have the value null, which means that, it does not point to any object, i.e. null is the default value unless otherwise specified)

Incomplete Types
It is possible to have an access type, that points to an object, which has elements, that are also access types. This can lead to mutually dependent or recursive access types. Since a type must be declared before it is used, this can be done using the incomplete types. type type_name; Once an incomplete type has been declared, the type_name can now be used in any mutually dependent or recursive access type. However, a corresponding full type declaration, must follow later. type COMP; type COMP_PTR is access COMP; Full Type Declarations: type COMP is record COMP_NAME : STRING(1 to 10); end record;

File Types
Objects of file types, represent files in the host environment. They provide a mechanism, by which, a VHDL design, communicates with the host environment. type file-type-name is file of type_name; The type name is the type of values contained in the file.

type VECTORS is file of BIT_VECTOR; type NAMES is file of STRING;


A file can be opened, closed, read, written to, or tested for an end of file condition by using special procedures and functions, that are implicitly declared for every file type. Function ENDFILE, and procedures like READLINE, READ, WRITELINE, and WRITE are predefined in the package TEXTIO.

VHDL Standard Data Types

Attributes
Data can be obtained about VHDL objects such as types, arrays and signals. object attribute Example: consider the implementation of a signal

What types of information about this signal are useful? Occurrence of an event Elapsed time since last event Previous value, i.e., prior to the last event

Classes of Attributes
Value attributes Returns a constant value Function attributes Invokes a function that returns a value Signal attributes Creates a new signal Type Attributes Supports queries about the type of VHDL objects Range attributes Returns a range

Value Attributes
clk_process: process begin wait until (clkevent and clk = 1); if reset = 1 then state <= statetypeleft; Returns a constant value else state <= next_state; type statetype is (state0, state1, state2 state3); end if; end process clk_process; state_typeleft = state0 state_typeright = state3

Function Attributes
Use of attributes invokes a function call which returns a value

Function Attributes Cont.


Function array attributes

type mem_array is array(0 to 7) of bit_vector(31 downto 0) mem_arrayleft = 0 mem_arrayright = 7 mem_arraylength = 8 (value kind attribute)

Range Attributes

Signal Attributes
Creates a new implicit signal

Signal Attributes: Example

Aliases

Type Conversions
Since VHDL is a strongly typed language one cannot assign a value of one data type to a signal of a different data type. In general, it is preferred to the same data types for the signals in a design, such as std_logic (instead of a mix of std_logic and bit types). Sometimes one cannot avoid using different types. To allow assigning data between objects of different types, one needs to convert one type to the other. Fortunately there are functions available in several packages in the ieee library, such as the std_logic_1164 and the std_logic_arith packages. As an example, the std_logic_1164 package allows the following conversions:

Type Conversions
The IEEE std_logic_unsigned and the IEEE std_logic_arith packages allow additional conversions such as from an integer to std_logic_vector and vice versa. The expression A and B which is of the type bit_vector has to be converted to the type std_logic_vector to be of the same type as the output signal out4. type_name (expression);
In order for the conversion to be legal, the expression must return a type that can be converted into the type type_name. Here are the conditions that must be fulfilled for the conversion to be possible 1. Type conversions between integer types or between similar array types are possible 2. Conversion between array types is possible if they have the same length and if they have identical element types or convertible element types. 3. Enumerated types cannot be converted.

Operators
P R E C E D E N C E

Operators in the same category, have the same precedence, and evaluation is done from left to right. Parenthesis may be used to override the left to right evaluation.

Logical Operators
The logic operators (and, or, nand, nor, xor and xnor) are defined for the bit, Boolean, std_logic and std_ulogic types and their vectors. They are used to define Boolean logic expression or to perform bit-per-bit operations on arrays of bits. They give a result of the same type as the operand (Bit or Boolean). These operators can be applied to signals, variables and constants. Notice that the nand and nor operators are not associative. One should use parentheses in a sequence of nand or nor operators to prevent a syntax error:
X nand Y nand Z will give a syntax error and should be written as (X nand Y) nand Z

Relational Operators
The relational operators test the relative values of two scalar types and give as result a Boolean output of TRUE or FALSE.

For discrete array types, the comparison is done on an element-per-element basis, starting from the left towards the right.

Examples

Shift Operators
These operators perform a bit-wise shift or rotate operation on a one-dimensional array of elements of the type bit (or std_logic) or Boolean.

Example

The operand is on the left of the operator and the number (integer) of shifts is on the right side of the operator. As an example, variable NUM1:bit_vector := 10010110; NUM1 srl 2; will result in the number 00100101. When a negative integer is given, the opposite action occurs, i.e. a shift to the left will be a shift to the right. As an example NUM1 srl 2 would be equivalent to NUM1 sll 2 and give the result 01011000.

Addition Operators
The addition operators are used to perform arithmetic operation (addition and subtraction) on operands of any numeric type. The concatenation (&) operator is used to concatenate two vectors together to make a longer one. In order to use these operators one has to specify the ieee.std_logic_unsigned.all or std_logic_arith package in addition to the ieee.std_logic_1164 package.

Example
An example of concatenation is the grouping of signals into a single bus [4]. signal MYBUS :std_logic_vector (15 downto 0); signal STATUS :std_logic_vector (2 downto 0); signal RW, CS1, CS2 :std_logic; signal MDATA :std_logic_vector ( 0 to 9); MYBUS <= STATUS & RW & CS1 & SC2 & MDATA; MYARRAY (15 downto 0) <= 1111_1111 & MDATA (2 to 9); NEWWORD <= VHDL & 93;

Unary Operators
The unary operators + and - are used to specify the sign of a numeric type.

Multiplying Operators
The multiplying operators are used to perform mathematical functions on numeric types (integer or floating point).

Multiplication Operator
The multiplication operator is also defined when one of the operands is a physical type and the other an integer or real type. The remainder (rem) and modulus (mod) are defined as follows:

A rem B = A (A/B)*B A mod B = A B * N

(in which A/B in an integer) (in which N is an integer)

The result of the rem operator has the sign of its first operand while the result of the mod operators has the sign of the second operand.

Miscellaneous Operators
These are the absolute value and exponentiation operators that can be applied to numeric types. The logical negation (not) results in the inverse polarity but the same type.

Module IV
Modelling Delays

Delay Models in VHDL


Inertial Delay Default delay model Suitable for modelling delays through devices such as gates Transport Delay Model delays through devices with very small inertia, e.g., wires All input events are propagated to output signals Delta Delay What about models where no propagation delays are specified? Infinitesimally small delay is automatically inserted by the simulator to preserve correct ordering of events

Inertial Delays : Example

Transport Delays: Example

Delta Delays : Example

Delta Delays: Behavior

Delay Models : Summary


Delay models Inertial For devices with inertia such as gates VHDL 1993 supports pulse rejection widths Transport Ensures propagation of all events Typically used to model elements such as wires Delta Automatically inserted to ensure functional correctness of code blocks that do not specify timing Enforces the data dependencies specified in the code

Summary
Primary unit of abstraction is a design entity Design units include Primary design units entity, configuration, package declaration Secondary design units architecture, package body Concurrent signal assignment statements Simple, selected, conditional Can be coalesced to form models of combinational circuits

Module V
Dataflow Style of Modelling

Design Description
A design is described using one or more concurrent statements in an architecture body (all statements within an architecture are executed concurrently) The execution of a concurrent statement is based on events on signals in its input list, i.e. ,at the same time. The order of concurrent statement within an architecture body is not important. Each concurrent statement will synthesize to a block of logic. The following concurrent statements are available in VHDL: Concurrent Signal Assignment Statement Concurrent Procedure Call Statement Concurrent Assertion Statement Component Instantiation Statement Generate Statement Process Statement Block Statement

Dataflow Style of Modelling


A Data flow model, specifies the functionality of the entity, without explicitly specifying its structure. This functionality shows the flow of information through the entity, which is expressed primarily using concurrent signal assignments statements and block statements. The structure of the entity is not explicitly specified in this modeling style, but it can be implicitly deduced.

Simple/Concurrent Signal Assignment

Simple Signal Assignment Statement


A statement is executed when an event(change of value) takes place on any signal in the RHS of an expression. The signals in the expression, forms the SENSITIVITY LIST for the signal assignment statement. Order of statement execution follows propagation of events in the circuit Textual order does not imply execution order An architecture body can have any number of concurrent signal assignment statements. The after clause, models the delay of the logic represented by the expression. Each concurrent signal assignment statement, creates a driver for the signal being assigned.

Implementation of Signals

Implementation of Signals (cont.)


In the absence of initialization, default values are determined by signal type Waveform elements describe time-value pairs Transactions are internal representations of signal value assignments Events correspond to new signal values A transaction may lead to the same signal value

Implementation of Signals (cont.)

Driver is set of future signal values: current signal value is provided by the transaction at the head of the list We can specify multiple waveform elements in a single assignment statement by specifying multiple future values for a signal

Example: Waveform Generation

Multiple waveform elements can be specified in a single signal assignment statement Describe the signal transitions at future point in time Each transition is specified as a waveform element

Issue of Multiple Drivers with Signal Assignment Statements


When there are more than one assignment to the same signal, the signal has more than one driver; and a mechanism is therefore needed to compute the effective value of the signal. Unresolved Data Type : Only One Driver Resolved Data Type : Possibly several drivers per signal Resolution conflicts are detected at run time and not during compilation.

Implementation of Signals
The basic structure of a signal assignment statement signal <= (value expression after time expression) RHS is referred to as a waveform element Every signal has associated with it a driver

Holds the current and future values of the signal a projected waveform Signal assignment statements modify the driver of a signal Value of a signal is the value at the head of the driver

Shared Signals

Resolved Signals

Resolution Function Behavior

Physical operation If any of the control signals activate the switch, the output signal is pulled low

VHDL model If any of the drivers attempt to drive the signal low (value at the head of the driver), the resolution functions returns a value of 0 Resolution function is invoked when any driver attempts to drive the output signal

Resolved Types: std_logic

Resolution Function: std_logic & resolved()

Pair wise resolution of signal values from multiple drivers Resolution operation must be associative

Example

Multiple components driving a shared error signal Signal value is the logical OR of the driver values

A Complete Example

Use of unconstrained arrays This is why the resolution function must be associative!

Conditional Signal Assignment


The signal assignment can be extended by the specification of conditions. The condition is appended after the new value and is introduced by the keyword ' when '. The keyword ' else ' is also strictly necessary (mandatory) after each condition as an unconditional signal assignment has to be present. It selects different values for the target signal, based on the specified condition. Equivalent to if else statement Condition is a Boolean expression. Whenever an event occurs on a signal used in either any of the waveform expressions(value expression is a waveform element), or any of the conditions, the conditional signal assignment statement is executed by evaluating the conditions one at a time.

Conditional Signal Assignment


For the first true condition found, the corresponding value (or values) of the waveform is scheduled to be assigned to the target signal. Example Z <= IN0 after 10ns when S0=0 and S1=0 else IN1 after 10ns when S0=1 and S1=0 else IN2 after 10ns when S0=0 and S1=1 else IN3 after 10ns; The statement is executed any time, an event occurs on signals IN0, IN1, IN2, IN3 S0 or S1. The first condition is checked, if false, the second condition is checked, if false, the third condition is checked and so on.

Conditional Signal Assignment

Unaffected Value
It is possible to assign a value of UNAFFECTED to a signal in a concurrent signal assignment statement. Such an assignment causes no change to the driver for the target signal; i.e. the target driver retains its previous/old value.

Selected Signal Assignment Statement


The behavior of the so called selected signal assignment is similar to the case statement. It selects different values for a target signal based on the value of a select expression. Whenever an event occurs on a signal in the select expression, or any signal used in any of the waveform expressions, the statement is executed. Based on the value of the select expression that matches the choice value specified, the value of the corresponding waveform is scheduled to be assigned to the target signal. The choices are not evaluated in sequence. All possible values of the select expression must be covered by the choices exactly once. Values not covered explicitly, may be covered by an others choice, which covers all such values.

Selected Signal Assignment Statement

BLOCK Statement
It can be used for three major purposes: 1. To disable signal drivers by using guards. 2. To limit the scope of declarations, including signal declarations. 3. To represent a portion of the design (modularity) Syntax: Block_label:block [(guard_expression)][is] [block_header] [block declarations] begin concurrent statements end block [Block_label];
The block_header if present, describes the interface of the block statement to its environment. Any declarations appearing within the block are visible only within the block.

BLOCK Statement Cont..


Any number of concurrent statements can appear within a block, possibly none. Block statements can be nested. The Block_label at the beginning is necessary, however, at the end, is optional, if present, however, must be the same as the one used at the beginning. If a GUARD expression appears in a block statement, there is an implicit signal called GUARD of type BOOLEAN declared within the block. Example BLAB : block(HANDLE) begin TOG <= guarded BOG after 5ns; End block; Guard expression HANDLE, whenever it is true, BOG is assigned to signal TOG after 5ns. If HANDLE is false, signal TOG returns the previous value.

An assertion statement is a concurrent statement, by virtue of its place of appearance within the model. If it appears inside a process, it is a sequential assertion statement, and if it appears outside a process, it is a concurrent assertion statement. Whenever an event occurs on a signal in the boolean expression of the assertion statement, the statement is executed.

Concurrent Assertion Statement

Example entity sr is port (s,r:in std_lgic;q,notq:out std_logic); end sr; architecture sr_assert of sr is begin assert not (s=0 and r=0); report Not valid inputs severity error; end sr_assert;

Module VI
Behavioral Style of Modelling

Behavioural style of Modelling


It specifies the behavior of an entity as a set of statements that are executed SEQUENTIALLY in the specified order. The behavior of the entity is expressed using sequentially executed, procedural code, which is very similar in syntax and semantics to that of a high level programming language like C or Pascal. A PROCESS STATEMENT IS THE PRIMARY MECHANISM USED TO MODEL THE BEHAVIOR OF AN ENTITY. A process statement itself is a concurrent statement, which can appear in the architecture body, and the sequential statements can be specified inside the process statement.

PROCESS Statement
It is a concurrent statement, which contains sequential statements, that describe the functionality of a portion of an entity in sequential terms. Syntax [process label]: process [(sensitivity list)][is] [process item declarations] begin sequential statements; end process [process label]; A set of signals to which, the process is sensitive, is defined by the SENSITIVITY LIST, i.e.; each time an event occurs on any of the signals in the sensitivity list, the sequential statements within the process are executed in a sequential order. The process then suspends after executing the last sequential statement, and waits for another event to occur on a signal in the sensitivity list.

Types of PROCESS Statements


1. Variable Assignment Statement 2. Sequential Signal Assignment Statement 3. WAIT Statement 4. IF Statement 5. CASE Statement 6. NULL Statement 7. LOOP Statement a) For iteration b) While iteration c) No iteration 8. EXIT Statement 9. NEXT Statement 10. Sequential Assertion Statement 11. Report Statement 12. Procedure Call Statement 13. Return Statement

Variable Assignment Statement


Variables can be declared and used inside a process statement. A variable is assigned a value, using this statement. Assign the value of an expression to a target variable. [ label: ] target := expression ; A := -B + C * D / E mod F rem G abs H; Sig := Sa and Sb or Sc nand Sd nor Se xor Sf xnor Sg; The expression is evaluate when the statement is executed, and the computed value is assigned to the variable object instantaneously, i.e.; at the current simulation time. A variable can also be declared outside of a process, or a subprogram. Such a variable can be read and updated by more than one process and are called SHARED VARIABLES.

Sequential Signal Assignment Statement


When a signal assignment statement is executed, the value of the expression is computed, and this value is scheduled to be assigned to the signal after the specified delay. The expression is evaluated at the time, the statement is executed, and not after the specified delay. If no delay is specified, a default delta delay is assumed. [ label: ] target <= [ delay_mechanism ] waveform ; sig1 <= sig2; Sig <= Sa and Sb or Sc nand Sd nor Se xor Sf xnor Sg; sig1 <= sig2 after 10 ns; clk <= '1' , '0' after TimePeriod/2 ; sig3 <= transport sig4 after 3 ns; sig4 <= reject 2 ns sig5 after 3 ns; -- increasing time order sig6 <= inertial '1' after 2 ns, '0' after 3 ns , '1' after 7 ns;

WAIT Statement
A process may be suspended by means of a sensitivity list, i.e.; when a process has a sensitivity list, it always suspends after executing the last sequential statement in the process. WAIT Statement provides an ALTERNATE way to suspend the execution of a process. There are three basic forms of wait statement: 1. wait on sensitivity list; 2. wait until boolean_expression; 3. wait for time_expression; Wait on sensitivity list until boolean_expression for time_expression; [ label: ] wait [ sensitivity clause ] [ condition clause ] ;

wait for 10 ns; -- timeout clause, specific time delay. wait until clk='1'; -- condition clause, Boolean condition wait until A>B and S1 or S2; -- condition clause, Boolean condition wait on sig1, sig2; -- sensitivity clause, any event on any

WAIT Statement Cont..


It is possible for a process not to have an explicit sensitiity list. In such a case, the process may have one or more wait statements. It must have at least one wait statement, otherwise, the process will never get suspended, and would remain in an infinite loop during the simulation. It is an ERROR, if both the sensitivity list and a wait statement are present within a process. The presence of a sensitivity list in a process, implieas the presence of an implicit wait on sensitivity list statement as the last statement in the process. wait for 0ns; Implies wait for one delta cycle. It is useful when one wants the process to e delayed so that, delta delayed signal assignments within a process can take effect.

IF Statement
It selects a sequence of statements for execution, based on the value of a condition. The condition can be any expression, that evaluates to a Boolean value.

IF Statement Cont..
It is executed by checking each condition sequentially, until the first true condition is found; then the set of sequential statements associated with this condition is executed. The if statement can have zero or more elsif clauses, and an optional else clause.

CASE Statement
It selects one of the branches for execution based on the value of the expression. Choices may be expressed as: a) single values b) Range of values c) Using others clause
All possible values of the expression must be covered in the case statement exactly once. The others clause can be used as a choice to cover the catch all values, and, if present, must be the last branch in the case statement.

CASE Statement Cont..

NULL Statement
It is a sequential statement, that does not cause any action to take place. Execution continues with the next statement. It is useful in an if statement or in a case statement, where, for certain conditions, it may be useful or necessary to explicitly specify that no action is to be performed.

Example: process begin If STROBE =0 then MARK_DET <= BKDET after 5ns; else null; end if; wait o STROBE,BKDET;

LOOP Statement
It is used to iterate through a set of sequential statements. [loop label:] iteration scheme loop sequential statements end loop [loop label]; There are three types of iteration schemes: 1. FOR Iteration Scheme 2. WHILE Iteration Scheme 3. No Iteration Scheme All kind of schemes may have exit and next statements. Loops operate in the usual way, i.e. they are used to execute the same some VHDL code a couple of times. Loop labels may be used to enhance readability, especially when loops are nested or the code block executed within the loop is rather long. The loop variable is the only object in VHDL which is implicitly defined. The loop variable can not be declared externally and is only visible within the loop.

FOR Iteration Scheme


If a for loop is to be synthesized, the range of the loop variable must not depend on signal or variable values (i.e., it has to be locally static).

WHILE Iteration Scheme


If a variable number of cycles is needed, the while statement will have to be used. While loops are executed as long as CONDITION evaluates to a 'true' value. Therefore this construct is usually not synthesizable.

No Iteration Scheme
In this, all statements in the loop body are repeatedly executed, until some other action causes the loop to exit. This can be achieved by using an exit statement, a next statement, or a return statement.

SUM:=1;J:=0; L2: loop J:=J+2; SUM:=SUM*10; exit when SUM > 100; end loop L2;

EXIT Statement
It is a sequential statement, that can be used only inside a loop. It causes execution to jump out of the innermost loop, or the loop whose label is specified. If no loop label is specified, the innermost loop is exited. If the when clause is used, the specified loop is exited only if, the given condition is true; otherwise, execution continues with the next statement. [ label: ] exit [ label2 ] [ when condition ] ; loop wait on A,B; exit when A=B; end loop;

NEXT Statement
It is a sequential statement, that can be used only inside a loop. It results in skipping the remaining statements in the current iteration of the specified loop; execution resumes with the first statement in the next iteration of this loop, if one exists. If n loop label is specified, the innermost loop is assumed.

[ label: ] next [ label2 ] [ when condition ] ; next; next outer_loop; next when A>B; next this_loop when C=D or done; -- done is a Boolean variable

Assertion Statement
These are useful in modeling constraints of an entity.

Used for internal consistency check or error message generation.


[ label: ] assert boolean_condition [ report string ] [ severity name ] ; assert a=(b or c); assert j<i report "internal error, tell someone"; assert clk='1' report "clock not up" severity WARNING; predefined severity names are: NOTE, WARNING, ERROR, FAILURE Default severity for assert is ERROR

Report Statement
It can be used to display a message. It is similar to the assertion statement, but without the assertion check. When a report statement is executed, it causes the specified string to be printed and the severity level to be reported to the simulator for proper action.

Procedure Call Statement


The specified procedure is called, whenever an event occurs on an input parameter.

PROPAGATE_DELAY ( in_sig=>q, out_sig => prop_q, delay => dy);

Return Statement
Causes the subprogram, that contains the return statement to terminate.

Multiple Processes
Since a process statement is a concurrent statement, it is possible to have more than one process within an architecture body. Processes within an architecture body communicate with each other using signals that are visible to all the processes. Variables declared within a process, cannot be used to pass information between processes, because their scope is limited to be within a process. Shared variables, however, could be used.

Concurrent Processes: Full Adder

Module VII
Structural Style of Modelling

Structural Style of Modelling


An entity is modeled as a set of components connected by signals, i.e.; as a net list. The behavior of the entity is not explicitly apparent from its model.

THE COMPONENT INSTANTIATION STATEMENT IS THE PRIMARY MECHANISM USED FOR DESCRIBING SUCH A MODEL OF AN ENTITY.
The component instantiation statements are concurrent statements, and their order of appearance in the architecture body is therefore not important. A component can, in general, be instantiated any number of times. However, each instantiation must have a unique component label. A purely structural architecture does not describe any functionality and contains just a list of components, their instantiation and the definition of their interconnections.

Component Declaration
A component instantiated in a structural description must first be declared using a component declaration, in the declaration part of the architecture body. A component declaration declares the name and the interface of a component. The interface specifies the mode and the type of ports. component component_name [is] [port (list of interface ports);] end component [component_name]; The component_name may or may not refer to the name of an entity already existing in a library. If it does not, it must be explicitly bound to an entity; otherwise, the model cannot be simulated. The binding information can be specified using a configuration.

Component Instantiation
A component instantiation statement defines a subcomponent of the entity in which it appears. It associates the signals in the entity with the ports of that subcomponent. component_label : component_name [port map (association_list)]; The component_label can be any legal identifier, and can be considered as the name of the instance. The component_name must be the name of the component declared earlier using a component declaration. The association list, associates signals in the entity, called ACTUALS, with the ports of a component, called FORMALS. An actual may be a signal or an expression or it can be the keyword open, to indicate a port that is not connected. There are two ways to perform the association of formals with the actuals: 1. Positional Association 2. Named Association

Positional Association
In positional association, the association list is of the form:

Actual1, actual2, actual3,,actualn Each actual in the component instantiation is mapped by position with each port in the component declaration. That is, the first port in the component declaration corresponds to the first actual in the component instantiation, the second with the second, and so on. The ordering of actuals is therefore important. If a port in a component instantiation is not connected to any signal, the keyword open can be used to signify that the port is not connected.
N3:NAND2 port map (S1, open, S3); The second input port of the NAND2 component is not connected to any signal. An input port may be left openonly if its declaration specifies an initial value.

Named Association
In named association, the ordering of the association is not important, since, the mapping between the actuals and the formals is explicitly specified. The port names from the component declaration, also called "formals", are associated with an arrow ' => ' with the signals of the entity ("actuals"). entity FULLADDER is port (A,B, CARRY_IN: in bit; SUM, CARRY: out bit); end FULLADDER; architecture STRUCT of FULLADDER is component HALFADDER port (A, B : in bit; SUM, CARRY : out bit); end component; ... signal W_SUM, W_CARRY1, W_CARRY2 : bit;

Modeling Structure

Structured Modeling

State Machines

Basic components Combinational component: output function and next state function Sequential component Natural process-based implementation

Example: State Machine

Example: Output and Next State Functions

Example: Clock Process

Generics
library IEEE; use IEEE.std_logic_1164.all; entity xor2 is generic (gate_delay : Time:= 2 ns); port(In1, In2 : in std_logic; z : out std_logic); end entity xor2; architecture behavioral of xor2 is begin z <= (In1 xor In2) after gate_delay; end architecture behavioral;

Enables the construction of parameterized models

architecture Generics in isgeneric_delay of Hierarchical Models half_adder component xor2 generic (gate_delay: Time); port (a, b : in std_logic; c : out std_logic); end component; component and2 generic (gate_delay: Time); port (a, b : in std_logic; c : out std_logic); end component; begin EX1: xor2 generic map (gate_delay => 6 ns) port map(a => a, b => b, c => sum); A1: and2 generic map (gate_delay => 3 ns) port map(a=> a, b=> b, c=> carry); end architecture generic_delay; Parameter values are passed through the hierarchy

Example: Full Adder

Example: Full Adder

Precedence of Generic Declarations

Generics: Properties

Generics are constant objects and can only be read The values of generics must be known at compile time They are a part of the interface specification but do not have a physical interpretation Use of generics is not limited to delay like parameters and are in fact a very powerful structuring mechanism

Example: N-Input Gate

Example: Using the Generic Narchitecture structural of full_adder is component generic_or Gate Input OR generic (n: positive);
port (in1 : in std_logic_vector ((n-1) downto 0); z : out std_logic); end component; ... ... -- remainder of the declarative region from earlier example ... begin H1: half_adder port map (a => In1, b => In2, sum=>s1, carry=>s3); H2:half_adder port map (a => s1, b => c_in, sum =>sum, carry => s2); O1: generic_or generic map (n => 2) port map (a => s2, b => s3, c => c_out); end structural; Full adder model can be modified to use the generic OR gate model via the generic map () construct Analogy with macros

Example: N-bit Register

Implementing Global Set/Reset in VHDL

TheWhat if we need to instantiate a large Generate Statement


number of components in a regular pattern? Need conciseness of description Iteration construct for instantiating components! The generate statement A parameterized approach to describing the regular interconnection of components a: for i in 1 to 6 generate a1: one_bit generic map (gate_delay) port map(in1=>in1(i), in2=> in2(i), cin=>carry_vector(i-1), result=>result(i), cout=>carry_vector(i),opcode=>opcode); end generate;

The Generate Statement: Example


Instantiating an register entity dregister is port ( d : in std_logic_vector(7 downto 0); q : out std_logic_vector(7 downto 0); clk : in std_logic); end entity dregisters architecture behavioral of dregister is begin d: for i in dregrange generate reg: dff port map( (d=>d(i), q=>q(i), clk=>clk; end generate; end architecture register;

Instantiating interconnected components Declare local signals used for the interconnect

The Generate Statement: Example

Using the Generate Statement


Identify components with regular interconnect Declare local arrays of signals for the regular interconnections Write the generate statement Analogy with loops and multidimensional arrays Beware of unconnected signals! Instantiate remaining components of the design

Configurations

A design entity can have multiple alternative architectures A configuration specifies the architecture that is to be used to implement a design entity

Component Binding

We are concerned with configuring the architecture and not the entity Enhances sharing of designs: simply change the configuration

Default Binding Rules


architecture structural of serial_adder is component comb is port (a, b, c_in : in std_logic; z, carry : out std_logic); end component comb; component dff is port (clk, reset, d :in std_logic; q, qbar :out std_logic); end component dff; signal s1, s2 : std_logic; begin C1: comb port map (a => a, b => b, c_in => s1, z =>z, carry => s2); D1: dff port map(clk => clk, reset Search for entity with the same component name If multiple such entities exist, bind the last compiled architecture for that entity How do we get more control over binding?

Configuration Specification

We can specify any binding where ports and arguments match

Configuration Specification
Short form where applicable for all: half_adder use entity WORK.half_adder (behavioral); Not constrained by the name space Delayed binding when a specification is not present Will be available at a later step Analogous to unresolved symbol references during compilation of traditional programs

Configuration Declaration

Written as a separate design unit Can be written to span a design hierarchy Use of the for all clause

Subprograms, Packages, and Libraries

Essentials of Functions
function rising_edge (signal clock: std_logic) return boolean is ---declarative region: declare variables local to the function -begin -- body -return (expression) end rising_edge; Formal parameters and mode Default mode is of type in Functions cannot modify parameters Pure functions vs. impure functions Latter occur because of visibility into signals that are not parameters Function variables initialized on each call

Essentials of Functions (cont.)


function rising_edge (signal clock: std_logic) return boolean is ---declarative region: declare variables local to the function -begin -- body -return (expression) end rising_edge; Types of formals and actuals must match except for formals which are constants (default) Formals which are constant match actuals which are variable, constant or signal Wait statements are not permitted in a function! And therefore not in any procedure called by a functions

Placement of Functions

Function: Example

Function: Example
function to_bitvector (svalue : std_logic_vector) return bit_vector is variable outvalue : bit_vector (svaluelength-1 downto 0); begin for i in svaluerange loop -- scan all elements of the array case svalue (i) is when 0 => outvalue (i) := 0; when 1 => outvalue (i) := 1; when others => outvalue (i) := 0; end case; end loop; return outvalue; end to_bitvector

A common use of functions: type conversion Use of attributes for flexible function definitions Data size is determined at the time of the call Browse the vendor supplied packages for many examples

Summary: Essentials of Functions


Placement of functions Visibility Formal parameters Actuals can have widths bound at the call time Check the source listings of packages for examples of many different functions

Essentials of Procedures
procedure read_v1d (variable f: in text; v :out std_logic_vector) --declarative region: declare variables local to the procedure -begin -- body -end read_v1d;

Parameters may be of mode in (read only) and out (write only) Default class of input parameters is constant Default class of output parameters is variable Variables declared within procedure are initialized on each call

Procedures: Placement

Placement of Procedures

Procedures and Signals


procedure mread (address : in std_logic_vector (2 downto 0); signal R : out std_logic; signal S : in std_logic; signal ADDR : out std_logic_vector (2 downto 0); signal data : out std_logic_vector (31 downto 0)) is begin ADDR <= address; R <= 1; wait until S = 1; data <= DO; R <= 0; end mread; Procedures can make assignments to signals passed as input parameters Procedures may not have a wait statement if the encompassing process has a sensitivity list

Procedures and Signals


procedure mread (address : in std_logic_vector (2 downto 0); signal R : out std_logic; signal S : in std_logic; signal ADDR : out std_logic_vector (2 downto 0); signal data : out std_logic_vector (31 downto 0)) is begin ADDR <= address; R <= 1; wait until S = 1; data <= DO; R <= 0; end mread; Procedures may modify signals not in the parameter list, e.g., ports Signals may not be declared in a procedure Procedures may make assignments to signals not declared in the parameter list

Concurrent vs. Sequential Procedure Calls

Concurrent Procedure Calls

Variables cannot be passed into a concurrent procedure call Explicit vs. positional association of formal and actual parameters

Equivalent Sequential Procedure Call

Subprogram Overloading

Hardware components differ in number of inputs and the type of input signals Model each component by a distinct procedure Procedure naming becomes tedious

Subprogram Overloading
Consider the following procedures for the previous components dff_bit (clk, d, q, qbar) asynch_dff_bit (clk, d,q,qbar,reset,clear) dff_std (clk,d,q,qbar) asynch_dff_std (clk, d,q,qbar,reset,clear) All of the previous components can use the same name subprogram overloading The proper procedure can be determined based on the arguments of the call Example function * (arg1, arg2: std_logic_vector) return std_logic_vector; function + (arg1, arg2 :signed) return signed; -- the following function is from std_logic_arith.vhd

Subprogram Overloading
VHDL is a strongly typed language Overloading is a convenient means for handling user defined types We need a structuring mechanism to keep track of our overloaded implementations

Essentials of Packages
Package Declaration Declaration of the functions, procedures, and types that are available in the package Serves as a package interface Only declared contents are visible for external use Note the behavior of the use clause Package body Implementation of the functions and procedures declared in the package header Instantiation of constants provided in the package header

Example: Package Header std_logic_1164


package std_logic_1164 is type std_ulogic is (U, --Unitialized X, -- Forcing Unknown 0, -- Forcing 0 1, -- Forcing 1 Z, -- High Impedance W, -- Weak Unknown L, -- Weak 0 H, -- Weak 1 - -- Dont care ); type std_ulogic_vector is array (natural range <>) of std_ulogic; function resolved (s : std_ulogic_vector) return std_ulogic; subtype std_logic is resolved std_ulogic; type std_logic_vector is array (natural range <>) of std_logic; function and (l, r : std_logic_vector) return std_logic_vector; --..<rest of the package definition> end package std_logic_1164;

Example: Package Body


package body my_package is --- type definitions, functions, and procedures -end my_package;

Packages are typically compiled into libraries New types must have associated definitions for operations such as logical operations (e.g., and, or) and arithmetic operations (e.g., +, *) Examine the package std_logic_1164 stored in library IEEE

Essentials of Libraries

Design units are analyzed (compiled) and placed in libraries Logical library names map to physical directories Libraries STD and WORK are implicitly declared

Libraries

Packages
Packages are repositories for type definitions, procedures, and Functions

You might also like