Sei sulla pagina 1di 249

Close Ad

[ vhdl_course_notes ] [ questions ] VHDL COURSE NOTES 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 Application and Language Introduction What you will learn in this Lesson What is VHDL Application Areas Limitation of VHDL Levels of Abstraction Behavioral Versus RTL Exercise 1: Application of VHDL Exercise 2: Application of VHDL Exercise 3: VHDL for Synthesis

1.10 Main Language Concepts 1.11Entity 1.12Architecture 1.13 Representing Hierarchy 1.14 Local Declarations 1.15 Configurations 1.16 Exercise 4: Numbers of Architectures 1.17 Exercise 5: Local Signal Declarations

1.18 Exercise 6: Entities and Components 1.19 Processes and Types 1.20 Packages 1.21 Compilation and Libraries 1.22 The complete Picture 1.23 Exercise 7: Sequential Statement 1.24Exercise 8: VHDL Design Units 1.25 Exercise 9: Name of Directory 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 Signals and Data Types What You Will Learn in This Lesson The Concept of a Type Exercise 1: Declaration of types Standard Data Types Signals And Drivers Arrays Exercise 2: Array Assignments Concatenation and Aggregates Exercise 3: Statements Independent of Width

2.10 Type definition 2.11 Multi Valued Logic 2.12 Standard Logic 2.13 Exercise 4: Use of Standard Logic 2.14 Using Standard Logic

2.15Exercise 5: Which lines are legal VHDL 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 VHDL Operators What You Will Learn in This Lesson Logical Operators Exercise 1: Logical Operators Relational Operators Exercise 2: Relational Operators Arithmetic Operators Exercise 3: Arithmetic Operator Exercise 4: which code is Legal Concurrent and Sequential Statements What You Will Learn in this Lesson Concurrent Assignment Statements The Process Process Execution Complete Sensitivity List Exercise 1: Statement Execution Exercise 2: Signal Update in a Process Exercise 3: Sensitivity List The If Statement

4.10 The Case Statement 4.11 The For Loop 4.12 Exercise 4: If Statement Execution

4.13 Exercise 5: Case Statement Rule 4.14 Exercise 6: Where Can They Be Used 4.15 Exercise 7: For Loop Example 5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 Sequential Statements What You Will Learn in this Lesson Concurrent Versus Sequential Signal Assignment in a Process Exercise 1: Signal Update in a Process Multiple Process Calls(1) Multiple Process Calls(2) The Simulation Cycle Exercise 2: How Many Delta Cycles The Behavior of a Process

5.10 The Wait Statement 5.11 Exercise 4: Wait Statements 5.12 Variables 5.13 Variable Usage Model 5.14 Parity Generator Example 5.15Exercise 5: Variables versus Signals 6 6.1 6.2 6.3 Synthesis Issues What You will Learn in This Lesson Specifying Registers in VHDL Detecting a Rising Clock

6.4 6.5 6.6 6.7 6.8 6.9

Clock Process Rules Exercise 1: Incomplete Assignments Exercise 2: Incomplete Assignments Controlling Transparent Latches Definition of RTL Exercise 3: Partitioning Between Processes

6.10Exercise 4: Find the Latches 6.11 Finite State Machines 6.12 State Machine Code 6.13 Operation on Vectors 6.14 Overloading 6.15 Exercise 5: Operator Overloading (1) 6.16 Exercise 6: Operator Overloading (2) 6.17 Exercise 7: Operator Overloading (3) 6.18 Exercise 8: Operator Overloading (4) 6.19 Vector Arithmetic Packages 6.20 Synthesis of Operators 6.21 Resource Sharing 7 7.1 7.2 7.3 7.4 Overview of Synthesis for Xilinx Devices Introduction What we will cover Terminology PLD Synthesis Issues

7.5 7.6 7.7 7.8 7.9

Xilinx Device Architectures FPGA Technologies CPLD Technologies Where PLD Specific Issues Occur How the PLD Specific Issues Are Handled

7.10 Exercise 1: Inference 7.11 Exercise 2: Instantiation 8 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 Coding Styles Coding Styles Introduction Using Modules LogiBOX Facility Synthesis of Arithmetic Operators Exercise 1: LogiBox Exercise 2: Manual Resource Sharing Encoding for State Machines Use of One-Hot State Machines Safe State Machines

8.10 Exercise 3: Safe state machine 8.11 I/O Features 8.12 I/O Definitions 8.13 Using 3-state and Bidirectional I/O 8.14 Utilizing Registered I/Os 8.15Exercise 5: IOB Definition

8.16 Special Routing Requirements 8.17Exercise 6: Clock Buffer 8.18 Internal 3-state signals 8.19 Exercise 7: 3-state Inference 9 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 Design Flow and Control Introduction Generic Design Flow-Specification Generic Design Flow-Simulation and Synthesis Generic Design Flow-Implementation Exercise 1 RTL Simulation Simulation Support from Xilinx Synthesis Gate Level Simulation

9.10 Implementation 9.11 Exercise2: 9.12 Back Annotation 9.13 Exercise 3: 9.14 Post Layout Verification 9.15 Exercise 4: 9.16 Programming 9.17 Summary 10 Issues in Using VHDL for Programmable Logic Design

10.1 10.2 Why Use VHDL 10.3 Advantages of Simulation 10.4 Medium Term Advantages of Using VHDL 10.5 The Issues to watch for 10.6 Quality of Result Issues 10.7 Data path Issues 10.8 Issues to watch: Conclusions 10.9 Fitting VHDL into Your Design Flow 10.10 10.11 10.12 11 Examples 11.1Example for if statement 11.1.1 N-bit Comparator 11.1.2 Shift Register (shift_reg) 11.2Example for Array 11.2.1 Static Random Access Memory (SRAM) 11.2.2 Read Only Memory (ROM) Use for a Complete Design Board Level Simulation Conclusions

11.3 Example for Decoder 11.3.1 Hex2led

11.4 Example for case statement 11.4.1 Multiplexer (MUX)

11.5 Example for the for loop 11.5.1 Multiplier

VHDL COURSE NOTES

Application and Language Introduction

1.1 What you will learn in this Lesson


The first lesson will introduce you to how VHDL is being used on design projects, and also to some of the main language constructs. First we will look at the application of VHDL, covering its background, its strengths, and weaknesses, and a summary of the different styles of using the language. Then we will discuss the main concepts behind the language itself, and summarize the main constructs available. This will give you an overall picture of the types of facilities available, and some of the most important terminology. Finally in this chapter we will cover how the main constructs are used together in a typical design situation, to give you a big picture into which the details can be inserted as you work through the tutorial

1.2 What is VHDL


The V stands for VHSIC (Very High Speed Integrated Circuit), and the HDL stands for Hardware Description Language.

1.3 Application Areas


ELECTRONIC DESIGN PROCESS Let us now look at the stages involved in designing an electronic system, and see which are the main application areas of VHDL.

This Diagram shows the complete electronic design Process, from the requirements for the system, through hardware and software partitioning, down to the specification and implementation of the hardware and software parts of the completed system.

HARDWARE IMPLEMENTATION:

In the early 1990s, VHDL was being used primarily for complex ASIC design, using synthesis tools to automatically create and optimize the implementation. Then the use of VHDL with

synthesis has moved into the area of programmable logic design.

Modeling Specifications: There is also an increase in the use of VHDL for modeling specifications, both of hardware part of the system, and the complete system itself.

1.4 Limitation of VHDL


VHDL is primarily a digital design language. It currently has very limited capabilities in the analog area, and there is a lot of work going on to standardize an analog version of the language. The 1076 standard defines a language and its syntax, without describing any styles of using it on a design project. It is possible that VHDL code may need to be slightly modified before it can be used with different synthesis tool set than it was originally written for.

1.5 Levels of Abstraction


The different styles of writing VHDL code are to do with a concept known as abstraction. Abstraction defines how much detail about the design is specified in a particular description of it.

Lets look at the 4 main levels of abstraction to illustrate the principle.

Levels of Abstraction

Layout Level: The lowest level of abstraction is the layout level. This specifies information about the actual layout of the design on silicon, and may also specify detail timing information and analog effects.

Logic Level: Above the layout level is the logic level, where we interconnect logic gates and registers. Layout information is ignored, and the design contains information about the function, architecture, technology and detailed timing.

Register Transfer Level: At the Register Transfer Level we Use VHDL in a strict style that defines every register in the design, and the logic between them. The design still contains architecture information but not the details of the details of the technology. Absolute timing delays are not specified.

Behavioral: Above the RTL, we have the behavioral level. This level uses VHDL to describe the function of a design, without specifying the architecture of registers. Behavioral code can contain as much timing information as the designer requires representing his function.

1.6 Behavioral Versus RTL


So we see that there are at least two distinct styles of using VHDL: Behavioral, and RTL.

At RTL style the designer has control over the architecture of the registers in his design.

At Behavioral style the synthesis tools generates the architecture.

1.7 Exercise 1: Application of VHDL


Which stages in the electronic system design process can VHDL to be applied to? Please select one of the answers:

A- Only ASIC and programmable logic design. B- Only specifying the hardware part of the system. C- Only specifying the system before it is partitioning into hardware and software. D- All stages mentioned in choices A, B, and C.

1.8 Exercise 2: Application of VHDL


Which one of the following is a true statement? Please select one of the answers: A- VHDL has many features for modeling analog designs. B- It is a requirement to use RTL (Register Transfer Level) when describing stimulus in VHDL. C- The IEE standard 1076 defines all the necessary styles required to use VHDL on a real design. D- Different VHDL synthesis tools support different subsets of the language.

1.9 Exercise 3: VHDL for Synthesis


What restriction are placed on VHDL that is to be written for todays synthesis tools ? Please select one of the answers:

A- The code must be written in a behavioral style. B- The code must be written in an RTL style C- The code must be written at gate level. D- VHDL for synthesis can be written in any style.

1.10 Main Language Concepts


As the VHDL is a Language that allows us to describe hardware, it must be able to describe activities that happening in parallel. Such activities are said to be concurrent

1.11Entity
We will start to look at some VHDL syntax, starting with the main building block of any VHDL design, the entity.

The entity in VHDL describes the interface to a hierarchical block, without defining its behavior. The entity is equivalent to a symbol in schematic based design. Lets look at the syntax for this example of a HALF ADDER. The syntax for an entity starts with the keyword entity, followed by the name of the entity, and the keyword is. The inputs and outputs are contained within the port statement: This lists the direction, and states that each signal is a single bit. Finally we have the keyword end , end the name of the entity, followed by a semi-colon.

1.12Architecture
Now we will take a look at how the behavior of an entity is described, using an architecture.

Here we have the architecture of our entity HALFADD that we saw previously. The syntax begins with the keyword architecture, followed by a user defined name of architecture itself, which is BEHAVE in this example. We then have the keywords is, and begin. After the beginning of the architecture, we have the statements defining the actual behavior. In this case, we have two signal assignments: the result of A xor B is assigned to the output SUM and the result of A and B is being assigned to the output CARRY.

Entity Can Have Multiple Architecture

And finally it is important to note that an entity can have more than one architecture. One usual application of this is when a design is described at several levels of abstraction: there may be behavioral, RTL and gate level descriptions of the same design.

1.13 Representing Hierarchy


The entity and architecture are the main building blocks from which hierarchy is build. Lets now look at how hierarchy is represented in VHDL, using the well known example of a full adder being build from two half adders, and a gate.

entity FULADD is port (A, B, CIN : in bit; SUM, CARRY : out bit) ; End FULLADD;

The code is shown here for the entity of FULLADD. As you can see, all of the five ports are declared as single bits, in the same style as we saw for the HALF ADDER

Here we can see the architecture of FULLADD. Start by looking at the three lines of code between the begin and the end statements. Each of these statements creates an instance of another entity, similar to placing down a symbol in a schematic capture package.

Looking at the syntax, we have the instance name (u1), and following the colon we have the name of the entity we are making an instance of. Then we have the key words port map, and then a list of the signals within FULLADD that are connected to the ports of our design HALFADD

Entity HALFADD is Port (A, B: in bit ; SUM, CARRY : out bit); End HALFADD;

u1: HALFADD port map (A, B, I1, I2);

1.14 Local Declarations

Component Declarations

Architecture STRUCT of FULLADD is signal I1, I2, I3 : bit;

Component declarations

Begin u1: HALFADD port map (A, B, I1, I2); u2: HALFADD port map (I1, CIN, SUM, I3); u3: ORGATE port map (I3, I2, CARRY); end STRUCT;

Before we can make an instance of an entity such as HALFADD it is necessary to declare the interface to the entity locally in the FULLADD architecture. This is done with what is called a component declaration.

Component HALFADD port (A, B : in bit: SUM, CARRY : out bit); End component;

The component declaration has the same style of syntax as the entity. In 99% of situations, you will want your component to have the same name and the same port list, as your entity. There is no getting around this: the component declaration must be present.

entity HALFADD is port (A, B : in bit; SUM, CARRY : out bit) End HALFADD;

Complete code for the FULLADD design:

Entity FULLADD is

Port (A, B, CIN : in bit; SUM, CARRY : out bit); End FULLADD;

Architecture STRUCT of FULLADD is Signal I1, I2, I3 : bit; Component HALFADD Port (A, B : in bit; SUM, CARRY : out bit; End component; Component ORGATE Port (A, B : in bit; Z : out bit; End component;

Begin u1 :HALFADD port map (A, B, I1, I2); u2 :HALFADD port map (I1, CIN, SUM, I3);

u3 : ORGATE port map (I3, I2, CARRY);

end STRUCT;

The complete code for the FULLADD design is shown here. In an architecture, note that we declare the local signals and component before the begin, and the description of the designs function is between the begin and end.

1.15 Configurations

The next VHDL object we will look at, is called configuration. Consider that a full design hierarchy consists of entities, each of which can have multiple architectures.

The configuration is like a parts list, specifying which architecture is to be used for each entity in the design.

entity A B C D

arch Y X X Y

You are not required to give this parts list information for all of your design hierarchy. If no configuration information is specified for an entity, then the last architecture that was compiled by the simulator is the one that is used during the simulation. It is common for complete design to only have on architecture for every entity and not require configuration. Some simulators allow this, while others require at least a Default configuration. Always using a default configuration makes your code more portable.

Default Configuration:

here is the syntax for default configurations. A configuration has its own name, and is associated with the entity of the top level of hierarchy, before the end for and end <name> constructs.

Configuration CFG_A of A is For X end for; end CFG_A;

As we have said, we recommend that you always construct at least a default configuration for your design.

1.16 Exercise 4: Numbers of Architectures


How many architecture, can an entity have associated with it? Please select one of the answers.

A- One ore More B- More than One C- Only One D- None

1.17 Exercise 5: Local Signal Declarations

In which area of VHDL code must signals be declared which are local to architecture? Please select one of the answers.

A- In the ports list of the architectures entity. B- In an associated configurations. C- In In the architecture, after the begin key word. D- In he architecture, before the begin key word.

1.18 Exercise 6: Entities and Components


In the majority of situations, what are the similarities between a component declaration and its corresponding entity? Please select one of the answers.

A-There are unlikely to be any similarities. B- The entity and component will have the same name, but their port names will be different. C- The entity and component will have the different names, but their port names will be the same. D- The entity and component will have the same name, and their port names will be same.

1.19 Processes and Types

Process contains sequential statements: The process is a region of VHDL code, inside which statements execute in sequence. A process

exists inside an architecture, and multiple processes interact with each other concurrently.

entity ORGATE is port (A, B: in bit; Z: out bit); End ORGATE; Architecture BEHAVE of ORGATE is Begin OR_FUNC: process (A,B) begin if (A=1 or B=1) then else

Z<=0; End if; End process OR_FUNC;

Any VHDL model is seen by a simulator as a collection of processes. Each process executes its statements in sequence and the multiple processes are interacting concurrently, as this diagram shows. There can be any number of processes within an architecture.

Type: There are types pre-defined in the language standard, and the user can also define his own type. So far we have seen type bit, which can have the values of 0 and 1.

Examples for pre defined types: real , bit, integer, bit_vector, boolean. Examples for user defined types: States, cpu_instructions, network_packet, My_type.

Types are discussed in great detail in the next lesson.

1.20 Packages
A package contains a collection of definitions that may be referenced by many designs at the same time. Placing definitions that are common between designs in one location helps a design team to work more consistently.

A package is a separate design unit in VHDL. Therefore it exists outside of the design units that we have considered so far, such as entities, architectures and configurations.

A package may contain definitions of constant values, user defined date types, component declarations, and sub programs of VHDL code that are shared between different designs.

1.21 Compilation and Libraries

The final concepts of the language that we will cover in this introduction section are how VHDL source code is compiled, and how designs are grouped together into a library.

Compilation or Analysis:

When you have written your VHDL code as text in a file, the code is checked for syntax errors, and a library file is created. This process is known by some tools as compilation, and by other tools as analysis. We will use the word compilation in the rest of the tutorial.

Design Units:

The smallest item in VHDL that you can compile is a single design unit.

These are the entity, architecture, configurations and package, which can have a separate part called a package body. These five objects are the only design units defined in the VHDL language.

Compile into a library: When VHDL code is compiled, the resulting binary file is stored in a specific directory on your computers disc. In order to keep references to this file independent of a specific directory path, directories are given a logical name known as library All VHDL simulation and synthesis tools access a file that maps VHDL library names to physical directory pats on your system. VHDL also allows a library called WORK to be defined as the library into which design units are compiled if no library destination is specified.

1.22 The complete Picture


We will finish this lesson by looking at the complete picture of how they relate to each other in a typical design situation.

a complete design hierarchy is defined by multiple entities, which have at least one architecture. Many of these entities and architectures will reference one or more packages of common definitions. The link between each level of hierarchy, and specification of which architecture is to be used, is performed by the configuration.

Stimulus from a test bench:

And finally, the top level of hierarchy is usually used to contain both the design and the stimulus

you will apply during simulation, which is written in VHDL.

1.23 Exercise 7: Sequential Statement


Which area of VHDL code contains sequential statements (i.e. statements that execute in sequence)? Please select one of the answers.

A-The process, before the begin keyword B- The architecture. C- The process, after the begin keyword. D- The package.

1.24Exercise 8: VHDL Design Units


Which of the following is not a VHDL design unit? Please select one of the answers.

A- Architecture B- Entity C- Process D- Package

1.25 Exercise 9: Name of Directory


Which of the following VHDL terms describes the name given to the directory into which design units are compiled? Please select one of the answers.

A- A package B- A mapping file C- A library D- A design Unit.

Signals and Data Types

2.1 What You Will Learn in This Lesson


The aim of this lesson is to look at how signals can be assigned in VHDL, and to give an overview of the rules regarding the use of data types. First we will consider the concept of a data type, and look at the standard types that are defined as part of the language. Then we will describe the concept of array, which is like a bus within schematic base design. We will look at many different examples of how single bit and array signals can be manipulated within VHDL. Then we will look at how you can define your own data type, e.g enumerated type And finally we look at the definition of a type known as standard for describing signals in VHDL. .

2.2 The Concept of a Type


First we review the concept of a data type, and look at where the data type of a signal is specified.

Type concept:

Architecture STRUCT of FULLADD is

Signal N_SUM: bit; --Other declarations begin -- code end STRUCT;

Values allowed in a signal of type bit: 0 , 1. The VHDL language defines that every signal must have a data type associated with it when the signal is declared. The type defines a set of values, and an assignment to that signal must always be of a value defined by that set.

Specify in port or signal declarations

entity FULLADD is port (A, B, CIN : in bit; SUM, CARRY : out bit); end FULLADD; architecture STRUCT of FULLADD is signal N_SUM : bit; -- other declarations begin --code end STRUCT;

A signal is generally declared either in the port section of an entity, or within an explicit signal declaration in an architecture. When a signal is declared in either of these locations, its associated type must be specified: the type is bit in this example.

Types must match:

When we make an assignment to a signal, the types on either side of the signal assignment operator must match up.

SUM <= A xor B; Hence in this example , the result of A xor B must be of type bit for us to be able to assign it to the signal SUM.

2.3 Exercise 1: Declaration of types


Where in your VHDL code it is necessary to state the type of a specific signal that you declared? Please select one of the answers:

A- when the signal is declared. B- When the signal is first used in the code. C- In a package. D- It is not necessary to declare the type of a signal.

2.4 Standard Data Types


Pre-defined types:

Having reviewed the conceps of data type, we will now look at the standard types that predefined within the VHDL language. All of this types are specified as VHDL source code, and the language defines that they should be found in a package called STANDARD.

package STANDARD is type BOOLEAN is ( FALSE, TRUE); type BIT is (0, 1); -------------------------------------

end STANDARD;

Boolean Time:

The type Boolean defines two values: true and false. Boolean type is returned when two values are compared. Time is used to model simulation time, and consists of both a number, and units.

Bit, bit_vector:

Character, string:

As the name implies, type character defines a single character in VHDL, and type string defines an array of characters. Note the same differences with single and double quotes for bit and bit_vector.

Integer, real:

VHDL supports both integer and real data types: an integer must be a whole number, whereas a real can have any number of decimal places. Note the difference in how they are specified: a real must have a decimal point, an integer must not.

2.5 Signals And Drivers

We will look at the concepts behind an assignment to a signal.

Signal assignment statement:

A signal is assigned a new value with what is known as a signal assignment, as we have seen in the examples of half adder and full adder.

Signal Driver:

An assignment to a signal defines a driver on that signal. A buffer would not necessarily be used by a synthesis tool, unless the buffer is needed to drive a large load.

Multiple Drivers:

If more than one assignment is made to a signal, then that signal must be declared to be a special kind of type, known as resolved type. A resolved type has a function call associated with it to resolve the final value of the signal. This only used in very special cases in hardware. Normally it is illegal to use it.

2.6 Arrays

We will look at how arrays are defined and manipulated.

Elements of same type:

An array is a collection of objects, where each one is of the same type. The language defines two types of array: bit vector, and string.

Size When Declared:

The range of an array is defined when the array is declared. Example: Legal declaration: Signal Z_BUS: bit_vector (3 downto 0); Signal C_BUS: bit_vector (1 to 4);

This example shows two bit_vectors, where each one is four bits wide. The range may be declared using either the to or downto notation. However the appropriate keyword must be chosen.

Illegal declaration: Signal Z_BUS: bit_vector (0 downto 3); Signal C_BUS: bit_vector (3 to 0);

Array Assignments:
Two array objects can be assigned to each other, as long as they are of the same type and same size: Note that assignment is by position, and tot by index number. There is no concept of a most significant bit defined with the language.

Array slices:
A slice of an array may be referenced, including a single element. The direction of the slice (i.e. to or downto) must match the direction in which the array is declared.

Legal: Z_BUS (3 downto 2) <= 00; C_BUS(2 to 4) <= Z_BUS (3 downto 1);

Illegal: Z_BUS (2 to 1) <= 11

2.7 Exercise 2: Array Assignments


How are appropriate elements of an array matched up when two arrays are assigned to each other.

A- By matching their index numbers. B- By matching their position within the array. C- It depends on whether the arrays are defined as to or downto D- It doesnt matter.

2.8 Concatenation and Aggregates


Concatenation and aggregates are the two methods for associating signals together in order to assign them to array objects.

Concatenation:

VHDL provides the ability to associate single bits and vectors together, to form array structures. This is known as concatenation, and uses the ampersand (&) operator. The examples here show

that single bits, and bit vectors can be concatenated together to form new vectors.

Aggregates:

Another method of assigning to elements of an array is known as aggregate. An aggregate is contained within round brackets, and assignment to each element are separated by commas (,).

Specifying elements by name:

It is possible to specify the element of array to assign by name, as well as by position. This example also shown that, a range of the array can be specified, as long as the same value is being assigned to each element in the range.

others statement:

Aggregates have the ability to use the others statement, which will assign a value to all other elements of the array that have not been specified. Finally, not all synthesis tools support the use of aggregates, so you may be required to use concatenation to perform array manipulation.

2.9 Exercise 3: Statements Independent of Width


Which of the four methods shown most easily enables us to initialize the array Z_BUS in a way that is independent of its width?

Signal Z_BUS : bit_vector (3 downto 0);

Code A: Z_BUS <= 0000;

Code B: Z_BUS <= (1=>0, others =>0);

Code C: Z_BUS <= ( others =>0);

Code D: Z_BUS <= (0, 0, 0,0);

2.10 Type definition


Having looked at the standard types that are pre defined in the language, we will now look at how the user can define his own types in VHDL.

Enumerated type:

A user defined type in VHDL is known as an enumerated type. Types are most commonly defined inside a package, architecture or process.

Type declaration: Here is the syntax for defining an enumerated type.

Type MY_STATE is (RESET, IDLE, RW_CYCLE, INT_CYCLE);

After specifying the type name, we have a list of values that an object of the type can contain, with each value separated by comma (,).

Signals of defined type


Type MY_STATE is (RESET, IDLE, RW_CYCLE, INT_CYCLE); signal STATE: MY_STATE ; signal TWO_BIT : bit_vector (0 to 1); . STATE <= RESET;

STATE <= 00; STATE <= TWO_BIT;

Having defined the type, then we can define signals to be of that type. Here we have declared the signal STATE to be of type MY_STATE. We have toobserve the strict rules when using tis signals: we cannot assign anything to signal state which is not of type MY_STATE.

Synthesis of enumerated types:

type MY_STATE is (RESET, IDLE, RW_CYCLE, INT_CYCLE);

Encoding left to right in binary sequence

RESET 00 IDLE RW_CYCLE INT_CYCLE 01 10 11

Most synthesis tools can build logic from a signal which is of an enumerated type. Usually the signal has minimum number of bits required to represent the number of possible values. This example shows how each value is usually encoded in the hardware implementation.

2.11 Multi Valued Logic 2.12 Standard Logic Standard_logic_1464 package:

Type definitions are contained within a package called standard_logic_1164. Package

Standard logic type definitions are contained within a package called standard_logic_1164. We will see how to reference this package.

2.13 Exercise 4: Use of Standard Logic 2.14 Using Standard Logic

library and use clauses:

library IEEE; use IEEE.Std_logic_1164.all;

entity MYDESIGN is port (A,B, : in std_logic; z end MYDESIGN; : out std_logic);

The package of definitions is contained within a library called IEEE. It is necessary to reference both the library and the package, as shown in the diagram. You will use these lines of code before every entity you write that uses Standard Logic.

2.15Exercise 5: Which lines are legal VHDL

3 VHDL Operators
3.1 What You Will Learn in This Lesson Main operators:
Having learned about signals and their types, we now introduce the main operators that allow us to perform operations on these signals.

Logical:
We will cover the logical operators, such as and and or.

Relational:
Then we will look at the relational operators that used to compare different values.

Arithmetic:
And finally we will look at the arithmetic operators for performing mathematics.

3.2 Logical Operators And, or, nand, nor, xor, not:


And, or, nand, nor, and xor all have the same precedence, and execute from left to right across a statement. not has a higher precedence, and is therefore executed before the other operators in an expression.

Example:

Library IEEE: Use IEE.Std_Logic_1164.all;

Entity MYDESIGN is Port (A, B, C : in std_logic; Z : out std_logic);

End MYDESIGN;

Architecture MYD of MYDESIGN is Begin

Z <= A and not (B or C);

End MYD;

This example shows the simple use of logical operators. Note that the brackets are required, otherwise the not function will only be invert signal B.

3.3 Exercise 1: Logical Operators 3.4 Relational Operators >, >=, <, <=, /=, =

less than

greater than

less than or equal

greater than or equal

greater then or equal to

equal to

not equal to

These are the relation operators in VHDL.

Return a Boolean:

They each return a Boolean value, and are most often used within a if-then-else statement to control the flow of code depending on different conditions.

Operands of same type:

The rules for using relational operators are that the operands must be of the same type. For an array, the operands can be of different lengths: the operands are aligned to the left, and compared

to the right.

Arrays have no numerical meaning:


no numerical meaning, associated with a vector: it is just a collection of objects of the same type.

This array is a set of 1 s not the number 7.

3.5 Exercise 2: Relational Operators


What data type by a relational expression? A-Integer B-Bit

C- std_ulogic D- Boolean

3.6

Arithmetic Operators

+ - * / ** rem mod abs

addition

subtraction

multiplication

division

exponential

absolute value

modulus

remainder

The arithmetic operators are listed here. They are pre-defined for types integer, real, (except for modulus and remainder), and type time. As vectors do nt represent a numerical value, the arithmetic operators do can not be used with types bit_vector, std_ulogic_vector, or std_logic_vector.

Generally operands of same type:

Signal A, B, Z : integer; ------Z <= A + B;

Generally the operands need to be of the same type. Intis example we are adding two intigers and the result returned is also an integer.

3.7 Exercise 3: Arithmetic Operator 3.8 Exercise 4: which code is Legal

4 Concurrent and Sequential Statements


In this lesson we will look at the differences between concurrent statements that execute outside of a process and sequential statements that execute in sequence within a process.

4.1 What You Will Learn in this Lesson 4.2 Concurrent Assignment Statements
Concurrent statements are those which can execute at the same time in parallel. This differs from

sequential statements, which can only execute one at a time, in sequence.

Execute in parallel, order independent

The behavior of concurrent statement is independent of the order in which they are written. In this example, we can write either statement first, and the result is the same: the result of A+B is used as an input to the adder that defines Z.

Draw a picture
The easiest way to perceive this is to actually draw a schematic of the operations. Schematics are used to represent hardware, and so they are concurrent in nature. If we draw the two adders here, then we get the same diagram, no matter which adder we draw first.

Assign to self is OK for software

There are some things that you may have done when writing traditional software, they may not make much sense in describing the hardware. In software, X and Y are register locations: We take the contents of X, add it to Y, and store the result in register X.

Not OK for hardware

As a concurrent statement, the same line of code is describing an adder, with no implied storage registers. Hence we have described feedback around combinational logic. As you can see it is really important to think about the fact that you are describing hardware when you write VHDL.

4.3 The Process

Having reviewed the concepts behind concurrent and sequential statements, lets go on to look at how these types of statements interact in VHDL, through the VHDL process

Process syntax

MUX : process (A, B, SEL)

Begin

if SEL = 1 then

Z <= A;

else Z <= B; end if ; end process MUX;

as we have said, the process containes sequencial statements. It has an optional label, the key word process, and a sensitivity list. Following the key word begin, we have the sequencial statements, and then we have the sequencial statements, and then we have the key words end process followed by the label name.

Event on signal in sensitivity list

MUX : process (A, B, SEL)

Begin

if SEL = 1 then Z <= A; else Z <= B; end if ; end process MUX;

A process does not execute continuously: it is invoked when one of the signals in its sensitivity list changes value, or in VHDL- speak, has an event.

Multiple processes interact concurrently

While each process executes its statements in sequence, multiple processes interact with each oter concurrently, as depicted in this diagram. Each process executes when trere is event on one of the signals in its sensitivity list, causing events to occur on signals that is assign to.

Define multiple processes within architecture

Architecture ARCH of MYDESIGN is Begin --------concurrent statements

--------concurrent statements

--------concurrent statements end ARCH;

A process must be written within an architecture, and VHDL allows any number of processec to be described within the same architecture.

4.4 Process Execution


Having reviewed the principles of the process, we will now look in more detail at how a process executes.

Assignments to the same signal: concurrent versus sequential

Z <= A and B; Z <= C and D;

To put the execution of a process in context, we will look at two statements, each statement making an assignment to the same signal. First we will consider the behavior of these as concurrent statements, and then as sequential statements.

Concurrent: Two drivers

Architecture CONCURRENT of MULTIPLE is signal, Z, A, B, C, D: std_logic; begin Z<= A and B; Z<= C and D; End CONCURRENT;

When these two statements are concurrent, they define two drivers on the signal Z, and Z needs to be resolved data type to determine the final value.

Sequential: One driver, last assignment

Architecture SEQUENTIAL of MULTIPLE is signal, Z, A, B, C, D: std_logic; begin

process (A, B, C, D)

begin Z<= A and B; Z<= C and D;

end process; End SEQUENTIAL;

When these statements are sequential, their behaviour changes. The value that the signal is updated with is the last value assigned to it within the process execution.

4.5 Complete Sensitivity List

MUX example

MUX: process (A, B, SEL) Begin If SEL = 1 then Z <= A; Else Z <= B;

End if; End process MUX;

The code describes to one MUX : if there is an event on A, B or SEL then the process is called , and depending on the value, of SEL, either A or B is assigned to Z.

SEL missing: what is the behavior?

MUX: process (A, B) Begin If SEL = 1 then Z <= A; Else Z <= B; End if; End process MUX;

Let us consider the same piece of code, but without SEL in its sensitivity list.

Z is sometimes delayed

The process is only executed when there is an event on A or B. When there is an event on SEL, any corresponding change of Z lags behind by an event on either A or B. This error can be difficult to debug.

4.6 Exercise 1: Statement Execution 4.7 Exercise 2: Signal Update in a Process 4.8 Exercise 3: Sensitivity List 4.9 The If Statement If-then syntax

if CONDITION then --- sequential statements end if;

If-then-else syntax

if CONDITION then --- sequential statements else -- sequential statements end if;

The if statement tests a condition, and executes a different set of statements depending on the result. The two most basic forms are shown here : the if-then and if-then-else statements.

if-elsif syntax

The if-elsif statement allows a series of condition to be tested, and the first condition that is true will cause the statements that follow to be executed. This cannot happen for more then one branch of the structure: the flow then passes to the end if statement at the bottom.

if-elsif : first true statement is executed

The order in which the statements are written in the else-if structure is very important. More than one of the condition may be true, and it is the first true condition that causes the following set of statements to be executed.

4.10 The Case Statement

Considers possible values of object

case OBJECT is When VALUE_1 => -- statements when VALUE_2 => --statements

when VALUE_3 => --statements -- .

end case;

The case statement considers all of the possible values that an object can take, and executes a different branch, depending on the current value of the object.

Ranges, lists, others

process (A, B, C, X) begin case X is when 0 to 4 => Z <= B; when 5 => Z <= C; when 7 | 9 => Z <= A; when others =>

Z <= 0; end case; end process;

The case statement has some special syntax to give more control over specifying the possible values. This simple example shows a range 0 to 4, a list of values separated by the pipe | symbol, and the others clause, covering all other possible values of X that have not been specified.

Cover all conditions, only once


The rules about the case statement in VHDL are very strict: no possible values of the object can be specified more than once, and all possible values must be specified, either explicitly, or with an others close.

4.11 The For Loop

Iterates around loop, incrementing value


For I in 0 to 3 loop -- statements end loop;

The concept of the for loop is that it will iterate around a loop a fixed number of times, while incrementing a value through a fixed range. In this example we are incrementing the variable I from 0 to 3, and therefore making four passes around the loop.

No need to declare the loop variable

There is no need to declare the loop (I in this case ) variable in any other part of the code: it is implicitly declared within the loop.

Example
Here is an example using the for loop.

entity EX is port (A: in std_logic_vector (0 to 15); SEL : in integer range 0 to 15; Z : out std_logic); end EX;

architecture RTL of X is begin WHAT: process ( A, SEL) begin for I in 0 to 15 loop if SEL = I then Z <= A(I);

end if; end loop; end process WHAT; end RTL;

4.12 Exercise 4: If Statement Execution 4.13 Exercise 5: Case Statement Rule 4.14 Exercise 6: Where Can They Be Used 4.15 Exercise 7: For Loop Example

5 Sequential Statements
5.1 What You Will Learn in this Lesson
Our aim during this lesson is to explain further capabilities that a process can offer, we will show how a single process and then a multiple process execute, to build up a picture of a complete simulation in VHDL. Finally we will look at the wait statement and how it is affect the execution of a process.

5.2 Concurrent Versus Sequential

First lets review some of the concepts from previous lesson.

Process model:

Remember that our model of VHDL simulation consists of multiple processes executing sequentially, and interacting concurrently.

Process within architecture:


We said that this model maps to VHDL code by having any number of processes within architecture,

Concurrent in architecture:
and we said that the process is seen a single concurrent statement within the architecture.

Multiple Processes in architecture:

It is possible for architecture to contain any number of concurrent statements, and therefore any number of processes.

5.3 Signal Assignment in a Process


Our final review of the previous lesson is how signal values assigned within a process are actually updated.

Concurrent statements: multiple drivers


Remember that we looked at the example in section 4.4, where we have two assignments to the signal Z, made outside of the process. We saw that statements outside of a process are concurrent and so Z has two drivers and must be of of a resolved type, allowing the final value to be determined.

Inside process one driver:

Then we looked at this similar example, where the two assignments to Z are inside a process, and we said that a process can only define one driver on a signal. The language defines that within a process it is the last assignment made to a signal that takes affect, but only when the process suspends, which in this case is at the bottom of the process.

Different meaning

process ( A, B, C, D) begin Z <= A and B; Z<= C and D; end process;

is not equal to

architecture X of multiple is . begin

Z <= A and B; Z <= C and D; end X;

Hence the same two statements have a very different meaning, depending on whether they are executed inside or outside of a process.

5.4 Exercise 1: Signal Update in a Process


When is a signal updated with its new value as a result of having an assignment to it within a process? Select one of the answers A- immediately the assignment is made in the process Wrong B- when the process suspends Correct. C- at the next simulation time in the future Wrong D- at the end of simulation Wrong.

5.5 Multiple Process Calls(1)

Having reviewed the basic concept of how signals are updated within a process, we will now move on to see how a process can potentially be executed several times before all signals are updated.

Example: ignal assigned then read

Example: process (A, B, M) Begin Y <= A; M<=B; Z < = M; End process Example;

In this example we have a process with an assignment to a signal M, and the value of M is also read within the same process. Let us use this example to see how a process executes in more detail.

Event on B
Lets assume that there has been an event on the signal B, which has just transitioned from 0 to 1. The process is called because B is in its sensitivity list.

M assigned when the process suspends

The value of M is not updated when the line M< B; is executed, but when the process suspends at he bottom.

Z not updated Hence when the line Z<=M; is executed, the value of M is still 0, and Z is not updated with a 1 when the process suspends.

5.6 Multiple Process Calls(2) Process suspends: M updated, Z is not


After the process suspends, M is updated with the new value of 1, but Z remains with the value of 0.

Process called again


The process is now called again, because there has just been an event on M, and M is in sensitivity list.

Z to get 1 on the second call

Now on the second call, the assignment of M to Z will cause Z to be updated with the value of 1 when the process suspends at the bottom.

Z is finally updated
So when the process suspends this time, Z is finally updated with a 1.

5.7 The Simulation Cycle


Lets now look at how this small example fits into the more general picture of VHDL simulation.

Queue mechanism
At a given point of simulation time, there are two queues: one of signals to be updated, and one of processes to be executed.

Processes put on queue

When a signal is updated at specific point in simulation time, all processes that are sensitive to that signal are placed on a process Execution queue.

Signal updates on signal update queue

Each process executes in turn, and signals that are assigned to in each process are not updated immediately the process suspends, but are placed on the Signal Update queue. When all of the processes have executed, then the signals are updated.

Delta cycle
As a result of the signals being updated, further processes may be placed on the process execution queue. One loop around this sequence is known as a Delta Cycle.

5.8 Exercise 2: How Many Delta Cycles


How many delta cycles are executed at a single point of simulation time where either a signal is to be updated or a process executed?

Please select one of the answers

A- Always just one Wrong.

B- At least one Correct. There will be at least one, but any number of delta cycles are possible if processes are sensitive to signals that change values at this same point of simulation time. C- Always more than one Wrong.

D- None

Wrong.

5.9

The Behavior of a Process

With and without sensitivity list


The language defines to styles of describing a process: one with a sensitivity list , and one without it. The one with the sensitivity list automatically suspends when execution reaches the bottom: that with no sensitivity list only suspends when it executes a wait statement.

Infinite loop
A process without a sensitivity list is defined to be an infinite loop, so when execution reaches the bottom, it automatically starts to execute again from the fist line.

No waits if sensitivity lists


The language defines that a process with a sensitivity list cannot contain wait statements: therefore it is a shorthand way of writing a process with a single wait statement at the bottom, which waits for an event on one or more of the signals in the sensitivity list equivalent.

Sensitivity list form for synthesis


Hence by definition, the following two processes shown here are equivalent.

process (A, B) begin if (A=1 or B=1) then Z<=1; else Z<=0; end if; end process;

process begin if (A=1 or B=1) then Z<=1; else Z<=0; end if; wait on A, B; end process;

However, for describing combinational logic you are recommended to use the form with the

sensitivity list as it is accepted by all synthesis tools.

5.10 The Wait Statement


Having seen that the wait statement causes a process to suspend, lets now look at the four forms of wait statement, and the different ways in which they cause a process to execute.

Wait for : period of time


wait for <specific time>;

STIMULUS: process Begin SEL <= 0; BUS _B <=0000; BUS _A <=1111; wait for 10 ns; SEL <=1; Wait for 10 ns; ----------------------end process STIMULUS;

The first one is wait for, which causes the process to re-execute after a specific amount of time has passed, as we discussed earlier. This can be useful in test benches to create stimulus, where signals are required to change value over time.

wait on : signal event


wait on <signal list>;

process begin if (A=1 or B=1) then Z<=1; else Z <=0; end if; wait on A, B; end process;

the wait on statement waits for an event on one or more of the signals in a list before reexecuting.

wait until: condition and event

wait until <condition>; process begin wait until CLK =1;

Q<=D;

End process:

The wait until statement has a condition which returns either true or false. The statement waits for an event on one of the signals in the condition, and if as a result of the event the condition has become true, then the process re-executes.

Wait : forever

STIMULUS: process Begin SEL <= 0; BUS _B <=0000; BUS _A <=1111; wait for 10 ns; SEL <=1; Wait ; end process STIMULUS;

and finally it is possible just to say wait, which suspends a process forever. This can be useful in a test bench to prevent infinite loop feature of processes from causing your stimulus to repeat once complete.

5.11 Exercise 4: Wait Statements

From where in a process does execution commence when a wait statement causes the process to be re-invoked?

Please select one of the answers.

A- The top line of the process Wrong.

B- The bottom line of the process Wrong.

C- The line of the wait statement Wrong.

D- The line immediately below the wait statement. Correct. After a process suspends, it re executes from the line immediately below.

5.12 Variables
Lets look at a new type of object in VHDL, called the variable.

Process (A, B, C) Variable M, N : integer; Begin M:=A; N:=B; Z<=M+N; M:=C; Y<=M+N; End process;

Assigned immediately

The variable is an object in VHDL that can only be declared and used within a process. A variable is different to a signal in that it is assigned its value immediately, like in traditional software.

Use only in process declared

To make assignments easy to recognize, it is required to use the := notation, rater than the <= notation used for signal assignments. A variable can only be used within the process that it is declared: this is known as the scope of the variable.

Retains value

A variable retains its value between calls to a process, and so is possible to imply the behavior of a memory element if required. To prevent any problems when describing combinational logic,

always assign a value to your variable before you read its value, as we have done in this example.

Mix with signals: match types

And finally, it is possible to freely assign signals to variables, and variables to signals, as we have done in this example. However, note that the rules about matching data types still need to be observed.

5.13 Variable Usage Model


Having considered the rules about how a variable behaves in VHDL, lets now look at the situations where you are likely to use a variable in your design.

Intermediate values
Because a variable is updated immediately, it is commonly used to calculate an intermediate value within a process, which is then used later on in the process execution.

5.14 Parity Generator Example


In the code for our parity generator, we have a variable TMP. At the start of the process, TMP is assigned the value of 0, and then we make assignment to TMP within a for loop.

Loop index: attributes

Note the range of the for loop: Alow is the lowest index of array A (0 in this case), and Ahigh is the highest index of A (3 in this case). Hence we will loop once for each element of A, and the code is made independent of the size of A. Ahigh and Alow are known as attributes of A.

Unfold for loop In order to understand how this code works, lets unfold the for loop, substituting the value for I. This results in the sequence of variable assignments shown on the diagram. Next we need to think about the interconnection of xor operators being described.

TMP := 0;

for I in Alow to Ahigh loop TMP:= TMP xor A(I); end loop;

Think of operators and draw the function

Our first xor operator has inputs A(0) and TMP, which currently has the value of 0. Our second operator has inputs A(1) and TMP: in this case, the value of TMP is that which we calculated on the last line, so from the hardware point of view it is the output of the previous xor function.

The result is a chain of xor gates. When this structure is synthesized, it will not necessarily produce these exact xor gates. However this xor structure is the starting architecture that you give the synthesis tool to optimize from, and this can influence the resulting implementation.

5.15Exercise 5: Variables versus Signals

Lets consider the different behavior of variables and signals with an example.

Variables assigned immediately


Signal A, B, C, Y, Z : integer; Begin Process (A, B, C) Variable M, N : integer; Begin M:=A;

N:=B; Z<=M+N; M:=C; Y<=M+N; End process;

As we have said, a variable is assigned its value immediately. Hence in this example when we execute the line Z<=M+N; then the value of M+N is the value of A+B. The value that signal Z is to be updated with when the process suspends is calculated and stored when the assignment to Z is made. Hence in this example, z will be updated with the value of A+B when the process suspends.

Similar to Y
When we reach the assignment to Y, then M has been updated with the value of C, and so Y will be assigned the result of C+B when the process suspends.

Consider this for signals

Signal A, B, C, Y, Z : integer; Signal M, N : integer; Begin Process (A, B, C) M:=A; N:=B; Z<=M+N;

M:=C; Y<=M+N; End process;

Now consider the same example, except that M and N are signals instead of variables. Spend a few moments thinking about how the process will execute if there is an event on A, B, or C and Read the exercise question and select one of the answers.

In the example shown, what are the final values of Y and Z in terms of A, B, and C ?

A- Both Y and Z are C+B. Correct. Both Y and Z are C+B, because M and N are assigned at the end of the first call to the process, and M always gets the value of C. the process is then called again and Y and Z both get C+B.

B- Both Y and Z are A+B. Wrong. Neither Y or Z can be A+B, because M is not updated until the process suspends, and it is always updated with C. C- Y is C+B, Z is A+B. Wrong. Z cannot be A+B, because M is not updated until the process suspends, and it is always updated with C. D- Y is A+B, Z is C+B. Wrong. Y cannot be A+B, because M is not updated until the process suspends, and it is always updated with C.

6 Synthesis Issues

6.1 What You will Learn in This Lesson


There are three main subject areas that this lesson will cover.

-What is RTL STYLE?

First we will look at ways of describing registers in VHDL, building up a definition of what is a register transfer level style.

-Vector arithmetic
You will recall from the VHDL operators lesson that it is not possible to perform arithmetic on vectors in VHDL by default. However there is a way around this, and the next part of the chapter covers this subject.

-Synthesis of arithmetic operators. Finally we will look at how arithmetic operators can be synthresized in VHDL, and consider the effect this will have on how you should write your code for synthesis.

6.2 Specifying Registers in VHDL


So first lets look at how to describe registers in VHDL.

A Clocked Process
entity FLOP is port (D, CLK: in std_logic; Q : out std_logic); end FLOP;

architecture A of FLOP is begin process begin Wait until CLKevent and CLK=1; Q <=D; end process; end A;

The basic style of describing registers is to have a process which only executes when there is a rising edge of clock. Here, Q is only updated with the value of D on a rising clock, and will not be updated if D changes at any other time. Hence it describes the function of a register in hardware.

Registers on all signals


The signals which are assigned to within the process are only assigned new values on a rising clock edge. Hence ALL signals assigned to are implemented as the outputs of registers in the synthesized hardware.

Clocked process

This type of process, with a rising edge of clock detection as the first statement, is known a a clocked process. The lines of code within the process only get executed when there is a rising clock edge.

6.3 Detecting a Rising Clock

There are many ways to detect a rising edge of clock in VHDL, and some methods are supported by more synthesis tools than the others. Lets look at the different methods, and the issues in choosing which one to use.

Wait until forms

These two forms use the wait until statement. They both wait for an event on the clock, however the second form uses the additional CLKevent syntax to double check for the clock event. This version is more commonly supported by synthesis tools, and is therefore recommended.

These two forms use the sensitivity list to detect an event on the clock, followed by an if statement to check the sense of the event. As synthesis tools ignore the functionality implied by process sensitivity list, most tools only support the form with the CLKevent clause.

Function call

The Std_Logic_1164 package, which defines the Std_logic based data types, includes a function

call which checks for a rising edge of clock: the details are shown here. Some synthesis tools are able to detect a rising clock edge using this method.

If and wait styles most commonly used

The if and wait until styles, with the CLKevent syntax, are most commonly accepted by synthesis tools. You are recommended to use these forms of rising edge detection

6.4 Clock Process Rules

Lets look at some additional rules regarding the format of code within a clocked process.

Wait is first statement in process

The general rule about using the wait statement to detect the clock edge is that it must be first, and only wait statement in the process. All other statements describe combinational logic that has registered outputs.

If form: all logic within if statement

Th e rule regarding the if form of the clock process is that there should be no other statements outside of the if structure, and that the structure should have no else clause. All code inside the if statement describes combinational logic.

Asynchronous reset registers

to specify registers with asynchronous resets, then it is necessary to use the code structure shown here. In this case, an event on RST causes the process to execute, and Q to be reset to 0.

Otherwise it is only an event on the clock which can cause Q to be updated with D.

Asynchronous reset rules

The rule for the asynchronous reset form of the clocked process is similar to that for the if form: No other statements outside of the if structure, and ther should be no else clause after the edge detection.

6.5 Exercise 1: Incomplete Assignments


entity INCOMP_IF is port (EN, D : in std_logic; Q : out std_logic); end INCOMP_IF;

architecture A of INCOMP_IF is begin process (EN, D) if (EN = 1) then Q <= D; end if; end process; end A;

please read the exercise question and select one of the answers.

QUESTION: Consider the above piece of VHDL code . If the process is called when the value of EN is 0, what do you think happens to the value of Q.

A- Q is assigned the value of D. Wrong. B- Q is assigned 0; Wrong. C- Q is assigned the value of EN Wrong. D- Q retains its existing value Correct. Q retains its existing value, because when the process is called, no assignments are made to change the value of Q.

6.6 Exercise 2: Incomplete Assignments


So we have concluded that if this process is called when EN has the value of 0, then Q will not change value. What type of hardware should be synthesized to model this behavior?

A- an AND gate wrong. B- A transparent ( i.e. level sensitive) latch Wrong. Correct. A transparent latch is synthesized, as the value of q is the same as D when EN=1, but Q retains its last value when EN=0. C- An edge triggered flip flop Wrong.

D- A pair of cross coupled NAND Gates. Wrong.

6.7 Controlling Transparent Latches

Lets consider the implications of what we have seen in these two exercises.

Transparent Latches

The process shown in this example is the same as you have studied in the last exercise, and synthesize into a transparent latch.

Incomplete assignments build transparent latches


----------------------------------------------process ( A, B ) begin if CONDITION then X <= A; Y <= B; else X <= 0; ----Y<=1; easily missed. end if; end process; -----------------------------------------------

The more general description of what we have seen is where a signal is assigned to within some branches of code, but not in others. This is called an incomplete assignment. If this happens within a COMBINATIONAL process, then a transparent latch is build in the synthesized hardware.

How to suppress latches?


It is easy to accidentally have incomplete assignments within your code, and build unwanted latches. In a real design, while you could try to ensure that you make an assignment to every signal in every branch of your code, this can be very tedious.

Use default assignments

The most reliable methode is to makedefault assignments to signals at the very top of a combinational process. These assignments will be overridden by assignments made later in the process, but will ensure that transparent latches are not synthesized.

6.8 Definition of RTL


The definition of RTL is really very simple: all of your code must be partitioned between clocked and combinational processes.

Hence the way in which the design function is partitioned defines where each register is placed in the design, and how it is clocked and reset.

You control the registers

From this definition, we can see that you control how much logic is placed between registers. I f the synthesis tool cannot achieve your required clock speed, then you may need to re-write the code to place less logic between registers.

Clocked process rules

To summarize the rules for clocked processes: all combinational logic defined within the process must follow the rising edge of clock detection.

Combinational process rules


And for combinational processes: the process must have a complete sensitivity list, and default signal assignments to prevent transparent latches being build.

6.9 Exercise 3: Partitioning Between Processes


Please read the exercise question and select one of the answers.

which of these architectures represents the hardware described by VHDL code shown?

A- Answer A No.

B- Answer B No.

C- Answer C Correct. No. all signals which are assigned to within a clocked process have register s on their outputs so we have described two register pipelines, one for X and Y and anoter for Z.

D- Answer D No.

6.10Exercise 4: Find the Latches

Please read the exercise question and select one of the answers.

Which one of the four sections of code shown here will synthesize transparent latches?

A- Example A Correct. This example synthesizes transparent latches because Z is only assigned when X=0. B- Example B No. because the assignment to Z on the first line ensures that Z is always assigned a value. C- Example C No. because the else clause ensures that there will always be an assignment to Z.

D- Example D No. it is a clock process , which synthesizes edge trigger registers on the signal Z. In this case when X=1, then the value of Z is retained in its synthesized register.

6.11 Finite State Machines

Now we will look at how we describe finite state machines.

Our example design is part of a controller for a CPU (Central Processing Unit) based system. We will look at the general style of describing a state machine, rather then considering all of the functionality of this example.

FSM architecture

The general architecture of an FSM (Finite State Machine) consists of a combinational block of next state logic, state registers, and combinational output logic as shown here.

Enumerated type for the state vector

architecture RTL of FSM is Type T_STATE is (IDLE, RW_CYCLE, INT_CYCLE, DMA_CYCLE);

In this example, we will assume that the FSM has 4 states. These are described using user defined data type. In this code here we have defined a type called T_STATE which will be used to represent the 4 states named IDLE, RW_CYCLE, INT_CYCLE and DMA_CYCLE.

Declaration of state vector

architecture RTL of FSM is Type T_STATE is (IDLE, RW_CYCLE, INT_CYCLE, DMA_CYCLE); Signal NEXT_STATE, STATE : T_STATE; begin

we then declare the signals STATE and NEXT_STATE as the inputs and outputs of our state vector: as these signals define the state of our FSM, then they are declared to be of type T_STATE.

6.12 State Machine Code Next state logic

NS: process (STATE, RW, INT, INT_REQ, DMA_REQ) Begin Case STATE is When IDLE => --- statements When RW_CYCLE => --- statements When INT_CYCLE => --- statements When DMA_CYCLE => --- statements end case; end process NS;

The next state logic is defined within a combinational process which contains a large case statement with a branch for each state of the state machine. The process is sensitive to the control inputs, and to the signal STATE.

Next state function

NS: process (STATE, RW, INT, INT_REQ, DMA_REQ) Begin Case STATE is When IDLE =>

If ( INT_REQ = 1 ) then NEXT_STATE <= INT_CYCLE; elsif (DMA_REQ = 1 ) then NEXT_STATE <DMA_CYCLE; end if; When RW_CYCLE => --- statements When INT_CYCLE => --- statements When DMA_CYCLE => --- statements end case; end process NS;

Within each branch of the case statement, we have code which assigns to the NEXT_STATE signal to define the state transitions. In this example we will transition from state IDLE if INT_REQ or DMA is a 1.

Registers

REG : process (CLK , RST) Begin if RST = 1 then STATE <= IDLE;

else if CLK event and CLK =1 then STATE <= NEXT_STATE; end if; end process REG; The state vector is defined within a separate clocked process which defines only registers, and no combinational logic. We assign the value of NEXT_STATE to STATE only when there is a rising edge of clock.

Output logic

The output logic may be defined either within the same process as the next state logic, or within a new combinational process. If you wish to describe a Moore state machine where the outputs are only a function of the state vector, then a separate process is recommended.

6.13 Operation on Vectors


First, lets look at the problems associated with performing operations on vectors

Vectors do not represent numbers

A vector (such as std_logic_vector), is not considered to represent a number. VHDL considers a vector as just a collection of single bit values which have been associated together for

convenience.

Limited operations on vectors

Not OK

As a result of this, by default in the language it is not possible to perform arithmetic operations , such as addition and subtraction, on vectors. Relational operations such as testing for equality,only give a satisfactory result if the vectors are of the same length.

There is a solution
There is a solution to this issue, which is implemented via a capability known as operator overloading.

6.14 Overloading
First we will look at the concept of overloading, and consider a few examples.

Multiple functions with different data types

The concept of overloading is that VHDL allows multiple functions to be defined with the same name, but different types for their input and output.

This concepts extend to standard operators: for example , it is legal to define multiple functions called +, as long as they have different combinations of data types for their inputs and outputs.

Functions called in context

Signal A, B, Z: X; Z <= A + B;

The language defines that a VHDL simulator should be able to call the appropriate function automatically in the context in which it is used.

Some exercises for you:


The following exercise will help you to understand this concept. The exercises are based upon a more real world example where we have a package containing multiple functions called +, which can be overloaded to perform arithmetic vectors.

The package:
Package P_ARITHMETIC is Subtype slv is std_logic_vector; Function + (L:slv; R:slv) return integer; (1) Function + (L:slv; R:slv) return slv; (2) Function + (L:slv; R:integer) return slv; (3) Function + (L:integer; R:slv) return slv; (4) End P_ARITHMETIC;

The exercises use the package P_ARITHMETIC SHOWN HERE.The package contains four functions called +, each with a different combination of data types. We have defined slv as subtype of std_logic_vector, which makes slv effectively an alias for std_logic_vector.

entity:

use work.P_ARITHMETIC.all; entity OVERLOADED is port ( A_BUS, B_BUS: in slv (0 to 3); A_INT, B_INT: in integer; Y_BUS, Z_BUS: out slv (0 to 3); Y_INT, Z_INT: out integer); End OVERLOADED;

The ports of this entity, describes the signals that we will be trying to add together. Each signal is either a vector (signal named _BUS) or an integer (signal named _INT).

Architecture

Architecture A of OVERLOADED is Begin

Y_INT <= A_INT + B_INT; Z_BUS <= A_BUS + B_BUS; Y_BUS <= A_BUS+B_INT; End A;

In the architecture are the lines of VHDL code that we want to implement. In the following exercises, your task is to explain whether each line of VHDL code is legal by default in the language, legal because a function is overloaded, or illegal.

Please read the exercise question and select one of the answers.

6.15 Exercise 5: Operator Overloading (1)

Y_INT <= A_INT +B_INT;

How is this line of VHDL code implemented?

A- Overloading of function 1. No function number 1 cannot be overloaded, as the types of its input and output parameters do not match the types of signals in the line of VHDL code we are considering. B- Overloading of function number 4. No function number 4 cannot be overloaded, as the types of its input and output parameters do not match the types of signals in the line of VHDL code we are considering.

C- The code is legal VHDL without the need for overloading.

Correct . It is legal in the language to add together two integers and return an integer, so no overloaded functions are required.

D- The line of code is illegal. No, the code is definitely legal.

6.16 Exercise 6: Operator Overloading (2)

Z_BUS <= A_BUS + B_BUS;

How is this line of VHDL code implemented?

A- Overloading of function 1. No. function number 1 cannot be overloaded, as the types of its input and output parameters do not match the types of signals in the line of VHDL code we are considering. B- Overloading of function number 2. Correct. It is not legal to add together vectors by default in the language, but function number 2 has parameters with the same type and is overloaded to implement the addition.

C- The code is legal VHDL without the need for overloading.

No, it is not legal to add together two vectors by default in the language.

D- The line of code is illegal. No, the code is definitely legal when used in this context.

6.17 Exercise 7: Operator Overloading (3)

Y_BUS <= A_BUS + A_INT;

How is this line of VHDL code implemented?

A- Overloading of function 3. Correct. It is not legal to add together vectors by default in the language, but function number 3 has parameters with the same type and is overloaded to implement the addition. B- Overloading of function number 4. No. function number 4 cannot be overloaded, as the types of its input and output parameters do not match the types of signals in the line of VHDL code we are considering. C- The code is legal VHDL without the need for overloading. No, it is not legal to add together a vector and intiger by default in the language.

D- The line of code is illegal. No, the code is definitely legal when used in this context.

6.18 Exercise 8: Operator Overloading (4)


Z_INT <= A_BUS+ B_INT; How is this line of VHDL code implemented?

A- Overloading of function number 2. No.Function number 2 cannot be overloaded, as the types of its input and output parameters do not match the types of the signals in the line of VHDL code we are considering. B- No. Function number 3 cannot be overloaded, as the types of its input and output parameters do not match the types of the signals in the line of VHDL code we are considering. C- The code is legal VHDL without the need for overloading. No, it is not legal to add together a vector and integer by default in the language.

D- The line of code is illegal. Correct. The code is illegal because you cannot perform addition with a vector by default, and there is no function to overload with the correct combination of data types.

6.19 Vector Arithmetic Packages Package of overloaded functions:

As you can imagine, what is ideally required is a large VHDL package, with overloaded functions for all of the major arithmetic and relational operators, for all combinations of vectors and integers. The good news is that you dont have to write one yourself

Synthesis vendors supply the package:


Each synthesis vendor supplies such a package. They typically contain all of the arithmetic and relational operators for combination of vector and integers, along with useful functions for converting between integers and vectors.

Vendors used to supply different ones:


In the first half of the 1990s, there was an issue because each synthesis vendor supplied a different package with their tools. However engineers used to choose from one ore two packages that are commonly used on real projects.

Standard packages from and IEE:


The IEE defined official standard package called Numeric_std.

6.20 Synthesis of Operators


Finally in the synthesis section, we will spend some time considering how arithmetic and relational operators may be implemented through synthesis.

Code size versus gate count:

Z<= A+B;

Z <= A+B;

When we are dealing with these operators, we find that a small amount of code can easily relate to large amount of silicon area, so it is important to understand how the operators can be synthesized efficiently.

Gates versus micro-cells:

The first issue is whether the operator is build from discrete gates, or if an optimized macro-cell is chosen from your technology library. Some synthesis tools can choose macro-cells automatically, while others require you to make a technology specific instance of a cell within your VHDL code.

Architecture of operator:

With mathematical operators, it is important to consider whether the implementation is optimized for area or speed. Some synthesis tools can only synthesize one architecture, whiles others will allow you to specify what architecture should be used, or even make the choice automatically.

Z<=A+B Generate: ---- Ripple carry adder: SMALL - Carry Lookahead adder: FAST

Sharing of operators:

If SEL = 1 then Z <= A + B; Else

Z <= A + C; End if;

One adder or two?

In some situations operations are not being carried out at he same time, and a single operator can be shared. Again some synthesis tools are able to perform this automatically, while with others it is necessary to write the VHDL code in a different style to share the operator.

6.21 Resource Sharing


The concept of sharing operations that are not performed at the same time is known as Resource Sharing. Lets take a look at an example of this..

Example:

If SEL = 1 then Z <= A + B; Else Z < = A + C; End if;

The example code is shown here. This code literally represents two adders, because two + operators have been used. The architecture that this code represents is shown, with two adders, and a multiplexer.

Sharing the adder:

It is possible to implement this function with only one adder. We can multiplex either B or C Onto the single adder, as we have shown in this diagram. Some synthesis tools can perform this automatically while others cannot.

Manual Sharing:

If the synthesis tool cannot perform this optimization, the VHDL code can be re-written to achieve the same result.

the code is shown here, and you can see that an intermediate variable, X , has been defined to represent the output of the MUX, which is then input to a single adder.

7 Overview of Synthesis for Xilinx Devices


7.1 Introduction

In this chapter we will be setting scene and giving a very general overview of some of the issues involved in using VHDL for the design of Xilinx devices.

7.2 What we will cover


Before we begin this chapter, lets first look at the topics we will cover.

PLD technologies:

First we will discuss PLD architectures , how they differ from ASICs and how this effects design methodologies. Then we will architectures of two types of Xilinx PLD. These are FPGAs and CPLDs.

Xilinx PLDs:
Then will look at the architectures of the two types of Xilinx PLD. These are FPGAs and

CPLDs.

Xilinx Atchitectures:

Then we will look at how these characteristics impact on the style in which you write your code.

7.3 Terminology
We will start by clarifying some of the terminology that we will be using. Here are the definitions Xilinx uses:

PLDs:

The term PLD (Programmable Logic Device) covers all of the programmable devices that Xilinx offers. The two types of PLD that Xilinx offer are the FPGA (Field Programmable Gate Array), and the CPLD or Complex PLD.

FPGAs, CLDs:

The Xilinx FPGA technologies are SRAM-based, such as the XC4000e. The Xilinx CPLD architecture are EPROM or FLASH technology based, en example of which is the XC9000 series.

Implementation:

The term implementation is used to describe the process of turning the logic design into a physical design i.e. placing and routing the design and downloading into the target device.

7.4 PLD Synthesis Issues


Lets begin by looking into what we need to consider when using synthesis for the design of PLDs.

First synthesis users designed ASICs (Application Specific Integrated Circuits), where you can

only program the device once.

Then it moved into PLD-based technologies. Where, you can re- program the device many times.

Synthesizing to PLD technologies:

From a synthesis perspective, the tool needs to contain specific algorithms to map the logic into the most efficient combination of the large building blocks.

7.5 Xilinx Device Architectures


We will give you an overview of the Xilinx device architectures.

7.6 FPGA Technologies


Xilinx FPGA technologies are based on static RAM building blocks which need to be downloaded with their logical function each time the system is powered up.

Configurable Logic Blocks (CLB):

Each building block in a given Xilinx FPGA device is known as Configurable Logic Block (CLB) A CLB is a cell consisting of 8 or more inputs, 3 or more outputs, some combinational logic and

two or more registers.

Connection by programmable switches:

The CPLDs are arranged into a fixed matrix and are connected by programmable switches. These form the required signal nets between CLBs.

IOBs provide IO (Input/Output) connections:

The matrix of logic cells is surrounded by IO cells called IOBs (Input Output Blocks). These IO cells have different structure from the CLBs and can be configured to provide different types of IO interface.

7.7 CPLD Technologies

CPLD technologies are not based on static RAM building blocks and they dont need to be downloaded with their logical function each time the system is powered up. They have bigger physical size, and accommodate less function. CPLD technologies is mainly useful for smaller applications. CPLDs are based on a different type of building block than used in FPGAs. In a CPLD, each building block is referred to as a Function Block (FB). Each FB is comprised of macro cells, each capable of implementing a combinational or registered function. These function blocks are connected via a switch matrix.

7.8 Where PLD Specific Issues Occur


So, having looked at the architecture of PLD technologies, we can now move on to look at the

main areas of interest from the coding style and synthesis point of view.

Efficient mapping to PLD architecture


The synthesis tool must be able to map the VHDL Code into an efficient utilization of CLBs. However, the style in which you write your code can help the synthesis tool to obtain better results.

Good Coding Style


Good coding style means that the synthesis tool can identify constructs within your code that it can easily map to technology features.

7.9 How the PLD Specific Issues Are Handled


The key to using PLD resources efficiency is to write your VHDL so that it makes the best use of the architectures available within the target device.

Architecture independence
An important advantage of designing with VHDL is that the description can be independent of architecture, an can be re targeted to a new architecture if required. However the code that is purely generic may not make the most efficient use of architecture specific features.

Architecture independence versus efficiency


A trade off exists here. You might want to keep the code architecture independent, leaving the synthesis tool to infer the best resources for the target device, or you might use architecture specific constructs to exploit pre-optimized functions at he expense of architecture independence.

Inference can be difficult

In fact not all functions can be inferred by a synthesis tool. For instance, some tools do not infer RAM. Hence users are sometimes required to make specific reference to these parts in their code. This is known as instantiation.

7.10 Exercise 1: Inference


What does it mean if a feature is inferred? A- The feature may not be required. No. This is not the meaning of the term inferred. B- An instance of the feature must be explicitly placed in the design No. this is instantiation were the synthesis tool simply uses the library component. C- The code implies that the synthesis tool should use a certain feature. Correct. The code is not instantiated directly but the code directs the synthesizer to use feature in your design. D- The feature is removed in optimization.

the

7.11 Exercise 2: Instantiation


The disadvantage of instantiating special function is ..

A- The code cannot be synthesized. No. The code can be synthesized. The synthesis tool simply includes the instantiated function in the generated netlist. B- It will lead to inefficient usage of resources. No. On the contrary, a physical structure will already be defined for the function and it already have been optimized.

will

C- The code cannot be simulated.

No. providing the libraries contain definitions of the behaviour of the function then it can be simulated.

D- The code is no longer architecture independent.

Correct. Having instantiated an architecture specific function in your design the synthesis tool will not be able to infer an alternative structure in another architecture.

8 Coding Styles

Now we are going to look at some of the features available in XILINX architectures. We will look at the coding styles which will make best use of these resources.

8.1 Coding Styles Introduction


The terminology will be based on FPGAs however many of the issues are applicable to CPLDs. Where there are significant requirement differences we will point these out.

8.2 Using Modules


A very important factor for efficient resource usage is the question of utilizing modules. You will find that Xilinx have already identified the most commonly used complex functions and developed optimized modules that can perform these tasks. This has two advantages for designers: they do not need to describe the behavior of the function in their code, and they dont need to worry about implementation optimization as this has already been done by Xilinx. All they need to do is instantiate these modules into the code.

8.3 LogiBOX Facility


Xilix provides a tool called LogiBLOX, which is a graphical interactive tool for creating modules, such as counters, shift registers and multiplexers. LogiBLOX includes both a library of

generic modules and a set of tools for customizing them. This means that you can create your own library of functions that are optimized towards the architecture and technology of your choice. You can instantiate these functions in your code as and when you need them. LogiBLOX also generates simulateable VHDL modules, so you can simulate the function available in your target family series, and create architecture specific, optimized implementation of your chosen functions.

8.4 Synthesis of Arithmetic Operators


Sometimes small pieces of code can synthesize to large pieces of logic and this is particularly true of arithmetic functions. Ideally you should think carefully how to control the implementation of such functions. Arithmetic functions might be best generated as a logiBLOX module.

8.5 Exercise 1: LogiBox


LogiBox is a tool that

A- Synthesizes arithmetic function from your code No.

B- Enables you generate your own library modules Yes. You can instantiate these modules in your code

C- Generates code that the synthesis tool can easily synthesize No. LogiBLOX will generate behavioral code of the block that you create and it synthesizes the module on the fly but it does not generate code for synthesis.

D- Checks that the code you have written is efficient No. LogiBLOX will not do this for you. It is agraphical tool that enables you generate

your

own library of modules.

8.6 Exercise 2: Manual Resource Sharing


What is manual resource sharing? A- The process by which the user reduces the use of resources. Correct. The user can write the code that expensive arithmetic resources are shared.

B- The method by which the synthesis tool reduces the use of resources. No. this is known as automatic resource sharing.

C- The method by which the synthesis tool reduces the use of resources. No. This is known as automatic resource sharing.

D- A method of creating an arithmetic module. No. Manual resource sharing is a method of specifying how the module is utilized rather than created.

8.7 Encoding for State Machines


Having discussed how to access modules from a VHDL based design, we are now going to look at how state machines can be implemented in Xilinx devices from VHDL.

Use of enumerated types


Most state machines written in VHDL use an enumerated type to define the state signal, as shown in the code here.

Default encoding
By default in VHDL, an enumerated type is usually encoded as a binary sequence, mapping from the value 0 throug the sequence of values which are listed in the type definition. However in the XILINX synthesis tool, the default encoding is a one-hot style.

Binary encoding IDLE RW_CYCLE INT_CYCLE DMA_CYCLE 00 01 10 11

One-hot encoding IDLE RW_CYCLE INT_CYCLE 0001 0010 0100

DMA_CYCLE

1000

Changing the encoding Within the Xilix tools you can choose between binary or one hot encoding from the user interface or specify a different encoding from from within the VHDL code. En example of the VHDL syntax which can be used to change the encoding is shown here.

8.8 Use of One-Hot State Machines When to use one-hot


One hot encoding gives the best performance for a state machine, but it also uses the most registers. For the register rich architectures ( Spartan and Virtex) one hot encoding is recommended.

8.9 Safe State Machines


Consider a state machine which has three states. In hardware, this will be implemented in at least two registers, which themselves can represents four states.

Illegal states

This means that one of the possible states of the register is not legal, and the operation of the state machine is not defined if the registers enter this state.

Safe state machines


A safe state machine defines how the hardware should behave if it enters any undefined states. Lets look at the different options for making state machine safe.

Using the others clause

A quick way of doing this is to use the others clause in the case statement and define a legal next state in this clause. From this the Xilinx synthesis tool builds logic that will send the state machine into a known state from any illegal state.

Specifying illegal states

an alternative method is to specify all possible illegal states so that their action can be defined. This can be very tedious process.

VHDL for the target Architecture

Whenever you write VHDL for synthesis, it is essential to think Hardware, You need to be sure that you only code for features that are available.

8.10 Exercise 3: Safe state machine What is safe state machine?

Please read the exercise question and select one of the answers.

A One with an even number of states. No.

B- One which can never get into an illegal state No. A safe state machine could get into an illegal state.

C- One which will always go to a valid state from an illegal state. Correct. If the state machine gets into an illegal state then goes into a valid state.

D- One which always finish in a particular state. No.

8.11 I/O Features

We will look at some Xilinx IO Features that available, such as clock buffers and 3-states. We will start by looking at IO cells in Xilinx devices.

Input /Output blocks


IOBs ( or Input/Output blocks) are the blocks that provide the interface signals between the external package pins and the internal signal lines.

IOB configuration
Each IOB controls one package pin and can be configured to provide different types of buffers as input, output or bidirectional pins. In the next section of this chapter we will concentrate on how we can insert the different types of buffer into our design.

8.12 I/O Definitions


There are two steps involved in IO definition. The first step is IO buffer type definition ( input, output, tristate etc.). The second step is known as pin assignment, which is the process of assigning an IO signal to a particular pin. Lets look at IO buffer type definition first.

Type definition in the code


You can instantiate or imply the IO buffer types in your code. The Xilinx synthesis tool is capable of automatically inferring all of the different IO types. We will be looking at suitable code examples later in the tutorial.

Separate Hierarchy for IO

If your synthesis tool does not infer IOBs or if you have chosen to instantiate them in your code it is a good idea to treat the IO definition as a separate level of hierarchy. Using this method, the highest level of hierarcy instantiates the core logic as well as each of the IOBs.

Type definition in the synthesis tool

In some synthesis tools you can perform a separate step for IO definition. You will be allowed to select buffer types and assign them to ports of the core logic. Alternatively you may be able to make these definitions in a control file.

IO Pin assignment

And finally, lets consider pin assignment. When using the Xilinx tools, the pin assignment is specified within what is called the User Control File (.UCF). See Xilinx tools documentation for more details on how to specify this information.

8.13 Using 3-state and Bidirectional I/O


Many of the Xilinx device families support registered, 3-state or bidirectional I/O, or various combinations of these. Lets first look at how 3-state and bi-directional I/O elements are handled.

3-state outputs

Many synthesis tools, including Xilinx tools, have the ability to automatically infr both 3-state output and bi directional IO cells from the equivalent VHDL code.

Coding style for inferring 3-states

The appropriate coding style to infer a 3-state function in an IO cell uses statements as shown in this example. I t is the use of the assignment of Z that enables the synthesis tool to infer the 3state buffer.

Coding style for inferring bi-directional IOs

The code shown here will generate bi-directional IO blocks or cells. Note again the use of the assignment of the Z value.

8.14 Utilizing Registered I/Os


Finally in this look at accessing IO cells from VHDL, lets consider implementing registers on your input or output signals.

Registered IO

For Xilinx tools registered IO are automatically implemented using a register in the appropriate IO cell if it is available. But be careful here; make sure that the architecture supports your implied usage of clock enable and resets in IO cell.

Register insertion during MAP


In addition, the Xilix implementation tools do have a switch allows to pull registers into the IOB cells where appropriate.

Bi-directional & registered 3-state IO

if you want to make use of registers within a 3-state or bi-directional IO, then this function from your VHDL code by the Xilix tools.

Pull-ups

Xilinx device families have IO resources which allow pull-up/down resistors to be connected to IO pads: these can be instantiated or specified by a graphical methode.

8.15Exercise 5: IOB Definition


Please read the exercise question and select one of the answers.

How can IOBs be defined from the VHDL?

A- By inference only. No. You can imply IOBs but it is not the only method defining them.

B- By inference or instantiation No. Theses are two methods of IOB definition but there is another technique that you can use.

C- By inference, instantiation or via a tool driven method. That is right. You need to investigate which method fits in best with your design flow.

D- By schematic insertion only.

No. Schematic method is a method of doing this but it is not the only way of doing it.

8.16 Special Routing Requirements


Special routing resources are sometimes required by a PLD architecture on high fanout nets such as reset and clock signals, resulting in better speed and skew performance. To utilize these special routing resources you must identify the special nets to the place and route tool.

Global set/reset (GSR)

If your synthesis tool cannot infer the reset network from its connectivity, you can highlight it by instantiating the STARTUP component, whose input is connected to all of the RESET connections of the device, via a net called GSR.

Clock networks

Xilinx synthesis tool, examines the connectivity of design and instantiate global buffers automatically on clock networks. If your synthesis tool does not do this then you need to instantiate a global buffer cell to drive the clock net.

Use Generic clock buffer

Unless you require the use of a specific global buffer, it is the best to use the generic BUFG global routing resource. The place and route tools can substitute this buffer for the best available resources. Use of any other buffering schemes means the tool is not free to make the best choice.

Portability issues

Keep in mind that many Xilinx architectures have global buffers which are available only in that architecture, so using the BUFG allows for an easier transition between families. Also the number of clock buffers available varies, so check on how many you need and how many you

implying.

8.17Exercise 6: Clock Buffer


Please read the exercise question and select one of the answers.

How should you use a global clock buffer on a non-clock signal?

A- By naming the net CLOCK. No. This is not sufficient to indicate to the synthesis tool that it should use a clock buffer to drive the net. B- By instantiating the generic clock buffer Thats right. By instantiating the generic buffer the implementation tools are then free to allocate the best resources for the net.

C- By leave the tool to decide whether one is required No. while some tools do automatically assign clock buffers to signals with a high fanout, this not always the case so you will not be guaranteed a clock buffer.

D- By using a synthesis tool specific instruction.

No You must be able to insert a clock buffer using the synthesis tool but you would be better advised to instantiate a generic clock buffer BUFG instead.

8.18 Internal 3-state signals

Lets now consider the use of internal 3-state buffers, which can save a great deal of resources within your design. They are very useful for implementing muxes or wired functions. These 3state buffers can be configured in 3-state, wired and, or wired.

3-state inference

This code shows an alternative to the usual if description of a 3 to 1 decoder by using 3-state inference. It will yield an efficient implementation of 3 to 1 mux, utilizing 3 state buffers.

Wired logic

Wired logic can be a good way of reducing the area and complexity of some types of combinational function. Most tools are not capable of inferring wired logic from Boolean operators so you will need to use instantiating to create this structure of logic.

Wide decoders
A common function is that of an address decoder and many Xilix devices have dedicated circuitry around the edge of the device so the input signals can be decoded. These type of Wide Edge Decoders are usually implemented as a service of wired-and cells with a pull-up on the 3state signal.

Implementing wide decoders


To take advantage of the wide Edge Decoders, you simply need to instantiate the WAND library symbols. However, you should read the libraries manual for guidance on which type of decoders are available for your chosen family.

8.19 Exercise 7: 3-state Inference


Please read the exercise question and select one of the answers.

What must you do to infer a 3-state component?

A- Instantiate the 3-state component. No. This would indeed yield a 3-state component but the question is looking for how would you infer a 3-state component.

B- Use logiBLOX module. No. While it is possible to generate a bussed 3-state buffer symbol using LogiBLOX, this question does not relate to LogiBLOX usage.

C- Use either a sequential or concurrent assignment to Z. That is correct. This implies to the synthesis tool that the inferred component must be able to generate the Z state. D- Use a Synthesis tool specific question. No. using a synthesis tool specific instruction should not be necessary.

9 Design Flow and Control

9.1 Introduction

Generic design flow

In this chapter of the tutorial we are going to take a close look at the design for Xilinx devices. We will start by looking at a generic design flow, in other words the flow that applies to any HDL design.

The design flow in Xilix tools

Then we will look at how design flow maps into the Xilinx tools and technologies.

9.2 Generic Design Flow-Specification


So lets start by looking at the generic design flow thaqt applies to almost HDL route to any type of PLD technology.

Specifications

The design flow should always start with a specification, whether it is simply a few algorithms for input to output relationship, or a large document written in English or even VHDL.

Behavioral coding

Sometimes, VHDL design work will start by producing a behavioral VHDL description and then converting each functional block into RTL. This generally done for new development of large designs-100k gates or more.

Behavioral simulation for comparison


The advantage of writing a behavioral model first is that you can effectively simulate your specification to ensure it is correct, and then use the results for later comparition with the simulation of your synthesizable RTL model.

RTL for programmable logic As we have said, this type of approach is only used for large designs. For the typical programmable logic design, it is not generally necessary to use such a rigorous methodology. Coding directly at the register transfer level is sufficient.

9.3 Generic Design Flow-Simulation and Synthesis


The job of the synthesis tool is to translate the RTL description of the design into a logical description. In other words the synthesis tool takes an RTL description of the design and creates a gate level description from it.

Following the synthesis it is necessary to check that the synthesis tool has generated a logic description that has the same behavior as the RTL. This is done using the same testbench to simulate the gate level netlist as was used to simulate the RTL description, and comparing the simulation results.

9.4 Generic Design Flow-Implementation


Once we have a logical netlist then we can think about translating this into a physical description. This process is cold implementation. The implementation step first involves mapping, the placement and routing, and finally the programming of the target device.

Mapping
Mapping is the process of packing the logical description generated by the synthesis tool into the different resources of the device, such as Configurable Logif Blocs (CLBs) or functional Blocks (FBs);

Place And Route (PAR)

Placement involves allocation of mapped resources into specific locations on the device. Routing is then performed to connect between these building blocks. If timing requirements are supplied to the place and route tools, then the routing will be performed to rty to meet these timing constraints.

Post layout verification

Now that we have this physical description of the design, the timing will have been changed slightly. In order to check that this does not change the functionality of the dasign, we must verify that the designs timing is stiil within specification.

Programming
The final step is to program the device with the design files that you have created.

9.5

Exercise 1

What is the advantage of performing syntax checking within the code editor? A- You dont need to compile your code after checking the syntax. No. You still need to compile your code after you have used the syntax checker as part of the

separate simulation and synthesis steps. B- Syntax checking is usually faster than code compilation so errors are found quicker. Correct. It is a quicker way of finding syntax errors in your code, and can be performed within the editor you already working in. C- It will correct your code for you. No it will not correct your code for you, but it will find errors and usually indicate what the problem is. D- You will no longer need to perform simulation. No. Syntax checking will not check the functionality of your design for you, so simulation will still be required.

9.6

RTL Simulation

You may simulate your RTL as you write it on a block by block basis. This will require you to write a test bench for each piece of code.

Code iteration

You may need to iterate around the code entry and simulation loop several times before you satisfied with your code.

VHDL Simulation requirements


The Xilix toolset only contains a gate level simulator. Therefore you will need to use a third party simulator (e.g. Modelsim) to simulate your RTL and gate level designs with your VHDL testbench. You will also need VHDL models of the various Xilinx specific building blocks in your design.

9.7

Simulation Support from Xilinx

Now we are going to discuss the kinds of VHDL packages and libraries that Xilinx supply with the Xilinx tools to support the VHDL based design flow.

Standard VHDL packages


Your design will need to reference the IEEE standard packages STD and STD_LOGIC_1164. These packages are fully supported by the Xilinx tools for design capture and synthesis, and will be supported by your third party VHDL simulator for simulation.

Xilinx specific libraries


Later in the design flow, you will want to simulate the gate level VHDL description of your design, and to do this you will need a VHDL description of each gate level element.

VITAL support
Xilinx provides these gate level libraries that you require for the VHDL simulator. The libraries are written to conform to the industry standard VITAL format. Libraries are supplied for macro functions as well as lower level primitives.

9.8

Synthesis

Xilinx supports synthesis tools with technology libraries.

Manually setting constraints


If you need to achieve specific synthesis goals i.e. optimizing for either area or speed, or you need to limit a critical path length, you can set these constraints manually using menu driven options within the synthesis tool.

UCF- User Constraints Files


It is also possible to place these constraint specifications in a single control file that can be accessed consistently each time you perform synthesis on a specific design.

NCF- Netlist Constraint Files Once synthesis is complete, the synthesis tool will create a netlist and may optionally create a constraint file containing all the timing and constraint information during synthesis. This is known as the Netlist Constraint File, and it is used to pass constraints on to timing driven implementation tools.

NGDBuild
Finally, we take the netlist and constraint outputs from the synthesis tool along with descriptions of the macros referenced in the netlist and use a tool called NGDBuild to create a generic database representing the design entirely from low level Xilinx primitives. This database is known as the NGD Generic Database.

9.9

Gate Level Simulation

Following synthesis, you now have a design described in Xilinx primitives which can be simulated within your VHDL simulator.

Re-use testbebch
The same testbench may be used to simulate the gate level description as was used for the RTL. This ensures that no functional errors have been introduced by the synthesis process, and that the style of the RTL code allowed an equivalent gate level design to be created.

NGD2VHDL
Before you can perform this VHDL base gate level simulation, you need to use a netlist translator called NGD2VHDL which translates the NGD file into a VHDL netlist.

VITAL libraries setup


You will need to have the VITAL based libraries for the gate level cells setup in your VHDL simulator. Once this is ready, then you can perform the gate level simulation using your VHDL testbench to create the stimulus.

9.10 Implementation
So now you are at a point where you are satisfied with the synthesis results and you want to move towards implementing the design. Lets look at the steps involved in the implementation process.

NGD (Negative Generic Database) is family independent

The NGD file is a netlist of Xilinx primitives which at this point coul be mapped to any device family. Because the available resources differ among different Xilinx technologies, the MAP program chooses different implementations, depending upon which device is used.

Mapping
The mapping software distributes the synthesized design across the available technology building blocks, and Generates the Negative Circuit Description (NCD) file. It also generates a Physical Constraints (PCF) file which is used by the next step which is placement and routing (PAR).

Placement and Routing


PAR is performed as a single step. Placement involves assigning the CLBs to their physical locations and routing is the process of establishing the correct connectivity between them. Control of place and route can be done by specifying constraints during design entry.

9.11 Exercise2:

What is the meaning of the term implementation? A- Simulating the actual FPGA device in its board level environment. No. B- Simulating the gate level description of the design No. C- Synthesizing the design No. D- Translating the logical description of the design into a physical description. Correct.

9.12 Back Annotation


So now you have the design placed an routed you need to verify that the function has not been changed by the introduction of the real delays imposed by the physical implementation of the design.

Physical information
In order to verify the design at this stage we need a description where the physical implementation information is used to more accurately define the timing characteristics of the design. This process is called back annotation.

NGDAnno
Back annotation data is generated by a program called NGDAnno. It extracts timing information from the physical database and generates either an SDF (Standard Delay Format) file or annotates the delays directly on the netlist.

Delays in SDF file used during simulation


VITAL complaint VHDL simulators have a option to expand the design database using data from the SDF file. The delays specified in the SDF file are then used during simulation. If you are using the Foundation Gate-Level simulator, the delays are placed directly on the EDIF netlist.

Timing checks
Provided you have set up HDL simulator correctly, you should get warning and error messages whenever you have violations of timing checks such as those for checking setup and hold times.

9.13 Exercise 3:
What is the process of back annotation? A- Distributing implementation delays back into the logical design. Correct. It means that you can run simulations with real delays instead of estimated delays. B- Running a simulation of the logical design that includes the real delays in the description. No. C- Distributing implementation delays back into the RTL design. No D- Checking that the routing is correct. No.

9.14 Post Layout Verification

Re-use testbench
So now you are at the stage where you have a VHDL file that has all of the implementation delays included. There are a couple of ways of verifying that functionality is still within

specification.

Re-use testbench
As we have discussed, you could run the simulation with the same testbench as used for the RTL and pre-layout simulations and complete the results.

ITA (interactive timing Analyzer)


You could instead use a static timing analyzer and in the Xilinx tools this is called ITA, or simply timing analyzer. By using ITA you can determine all of the path delays as it provides this information for all of the signals in your design.

Timing report

ITA also generates an enumerated report on constraint violations. ITA can be run on unplaced designs, completely placed and routed designs, or designs that are placed and/or routed to any degree of completion.

9.15 Exercise 4:
How is post layout VHDL simulation performed? A- By simulating back-annotated RTL Code. No. Timing information cannot be back annoted onto RTL code, only onto a gate level VHDL netlist. B- By simulating back-annotated gate level code Correct. The simulation database contains the timing information passed back from the layout tool.

C- By simulating XNF netlist No. The XNF netlist is not in VHDL format. D- On a purely gate level simulator. No. You can run post layoput simulations on a VHDL simulator. You do not have to move to a different simulator provided you have the VITAL based VHDL technology libraries available.

9.16 Programming
The final stage in the design fow is to program the target device. At this step, you need to translate the design information into a format suitable for programming.

BitGen program
The BitGen program is used to perform this translation. It takes a fully routed NCD (Circuit Description ) file as its input, and produces a configuration bitsream which is binary file with a .bit extention.

Filename .bit

This .bit file contains all of the configuration information from the NCD file defining the internal logic and interconnections, plus device-specific information from the files associated with the target device.

Download
The binary data in the .bit file can then be downloaded to the device, or it can be passed through a program called PROMGEN which will translate it to the appropriate format for PROM programming.

CPLD programming
The flow for programming a CPLD is very similar to that of programming an FPGA which we have just described. The NGD file is passed to the PLD Fitter Program. This then generates a .JED (JEDEC file ) which can be downloaded directly to the device, or red into the programmer.

9.17 Summary The generic flow


In this chapter we started by looking at the generic flow for any design using any tools.

Xilinx tool set


Then we went on to look in a little more detail at how the steps are performed within the environment of the Xilix tools for FPGA devices.

Control and constraints


An finally, we talked about methods of controlling and constraining the design throughout the design flow.

10
10.1

Issues in Using VHDL for Programmable Logic Design

10.2 Why Use VHDL


First, lets look at some of the reasons to use VHDL in your design.

Implementation independent
One reason for using VHDL is to have a design description which is independent of its implementation technology.

Vendor independence
VHDL is now supported by all major tools vendors, and so a VHDL description is generally portable between different tools sets, giving greater choice and flexibility.

Productivity through synthesis


Todays logic synthesis tools allow a gate level design to be build and optimized automatically from a VHDL description. VHDL synthesis can increase overall productivity between two and 5 times for large designs.

VHDL can be simulated

A VHDL description can be simulated, which is not the case for language such as ABEL and PALASM. There are many advantages which this can bring: lets move on to look at these in more detail.

10.3 Advantages of Simulation

VHDL for stimulus

A VHDL based simulation typically uses the VHDL language to describe the stimulus, as well as the device which is being designed. The code that defines the stimulus is generally called the testbench, and having a portable stimulus description gives greater flexibility.

Testbench advantages

There are many advantages of the testbench. Very complex stimulus can be created, and it allows interaction between the testbench and the device model.

Testbench benefits

Through the testbench, the interaction between devices on the board can be simulated at an early stage in the design cycle, leading a fewer board level iterations, and a reduction in overall development time.

Modeling of a system

Some companies use VHDL to model their system, before they have partitioned it to implementation. This can help to clarify the specification at an early stage, provide a precise definition of the partitioning, and supply stimulus for the more detailed implementation models.

Design re-use
It is well known that 80% of design is re-design. There is the opportunity to make significant productivity increases on future projects through the re-use of VHDL code.

10.4 Medium Term Advantages of Using VHDL Increasing programmable logic densities

In the 1990s the programmable logic devices were available with tens and hundreds of thousand useable gates. The experience of early VHDL users has shown that it is at these design complexities where significant productivity gains can be achieved by using VHDL synthesis.

VHDL is a standard
VHDL is a standard language. An ever increasing number of engineers will have VHDL skills, and other design groups will use VHDL too.

Design re use
It is well known that 80% of the design is re-resign. By investing in a technology and tool independent standard language, there is the opportunity to make significant productivity increases on future projects through the re-use of VHDL code.

Summary

In summary, we have considered the advantages of implementation and tool independence, increased productivity when using synthesis with large designs, the ability to simulate at board and system levels, and a future-proof investment which can facilitate design re-use.

10.5 The Issues to watch for


What are the issues to watch out for? Here they are

RTL description for synthesis

It is necessary to write VHDL for synthesis in a style which describes each register in the design, and the function of the combinational logic between registers. This is known as a Register Transfer Level description (RTL), and is a subset of the complete language definition.

Coding style affects synthesis results

The style which VHDL code is written has a direct influence on the quality of the design resulting from synthesis. VHDL designers therefore need to understand both language syntax and how coding styles affect synthesis results.

Code may be technology specific


Programmable logic technologies usually have some specific features in their architecture which allow you to make a design smaller or faster. You may need to make some parts of your code technology specific in order to access these features.

Plan for these issues


In summary, consider these issues and plan before a project begins.

10.6 Quality of Result Issues


Probably the biggest issue with some of todays synthesis tools is their ability to synthesize an efficient programmable logic design which can be clocked at the highest possible speed. Let,s explore these issues in more detail.

Programmable logic architectures


Different programmable logic architectures are characterized by different styles of logic cells. To achieve an efficient implementation for specific technology family, the architecture ofthese logic cells must be taken into account by synthesis tool.

Large Logic Cells

These logic cells can be quite large and therefore more difficult for a synthesis tool to optimally place into a design. If the logic cells are not used efficiently, a slower and larger implementation may result. Different tools can give very different results, so evaluate this issues carefully.

Manual intervention at times

Even the most sophisticated synthesis tools are not always able to optimize a design as well as an experienced designer, and you should expect to carry out a smaal amount of manual intervention at times. In spite of this, synthesis can still offer significant productivity benefits for large designs.

10.7 Data path Issues

Other issues which can occur are associated with data path oriented designs. Lets look at these issues now.

Arithmetic and relational operators

Data path oriented portions of a design contain many regular structures such as arithmetic and comparison elements. Often silicon vendors libraries contain macrocells of these elements which can be build efficiently during device layout.

Macrocells may not be used correctly


The benefit of using VHDL is that operations such as addition can be described with a single statement (e.g Z<=A+B). You could find that your synthesis tool can only build a adder from

many primitive gates, or may not choose the most efficient macrocell.

Work arounds
These issues can be worked around by making instances of vendor specific macrocells in the VHDL code. However this makes the code vendor specific and more difficult to write.

10.8 Issues to watch: Conclusions Awareness


In conclusion, many of these issues we have discussed will not prevent a successful design being synthesized, and awareness of the issues from the start will enable you to choose the most appropriate tool set and to start a project with realistic expectatios.

Ask your programmable logic vendor

When you plan to buy a synthesis tool set then your programmable logic vendor may be able to give good advice about the issues you can expect to face with specific tools.

10.9 Fitting VHDL into Your Design Flow

It is not necessary to base all of a programmable logic design on VHDL. It is plssible to use VHDL on the parts of the design you consider most suitable. In this Scenario you can simulate the synthesized gate level netlist.

10.10

Use for a Complete Design

The second method of introducing VHDL is to describe a complete device with the language, and to simulate the VHDL code as well as synthesizing the gate level design.

10.11

Board Level Simulation

Finally, we will look at what is required to perform VHDL simulation at the board level in a design with multiple programmable logic or Application Specific (ASIC) devices.

Testbebch emulates part of board


One approach is to use a VHDL testbench to emulate the surrounding board components.

Standard parts models

Alternatively, some of the more powerful work station based simulators can mix non VHDL software and hardware models of standard parts with the VHDL code for the programmable logic and ASIC devices. As you may be aware, these simulators and models can be very expensive.

Running low level software


Some VHDL users are actually executing low level software programs on the CPU model within their VHDL simulation. New hardware/software co-verification tools are becoming available to assist this process. Software drivers can then be specified and debugged before the first prototype board is manufactured.

Potential Benefits
To summarize, VHDL brings the opportunity on complex designs to reduce the number of board

iterations, and decrease the design time through synthesis.

10.12

Conclusions

Finally, lets draw some conclusion from the topics we have covered.

Potential benefits

We have considered the benefits of VHDL in terms of implementation and tool independence, increased productivity when using synthesis with large designs, reduced iterations through board and system simulation. You can purchase a low cost synthesis tool and have one engineer use VHDL for parts of a device. You can invest more in using VHDL with simulation for your designes.

11 Examples
11.1Example for if statement
11.1.1 N-bit Comparator

VHDL CODE for n-bit comparator

---------------------------------------------------- n-bit Comparator --- this comparator has two n-bit inputs &

-- three 1-bit output

---------------------------------------------------

library ieee; use ieee.std_logic_1164.all;

---------------------------------------------------

entity Comp is

generic(n: natural :=2); port( A: B: less: equal: in std_logic_vector(n-1 downto 0); in std_logic_vector(n-1 downto 0); out std_logic; out std_logic;

greater: out std_logic ); end Comp;

---------------------------------------------------

architecture behv of Comp is

begin

process(A,B) begin if (A<B) then less <= '1'; equal <= '0'; greater <= '0'; elsif (A=B) then less <= '0'; equal <= '1'; greater <= '0'; else less <= '0'; equal <= '0'; greater <= '1'; end if; end process;

end behv;

---------------------------------------------------

VHDL TEST BENCH for n-bit comparator

-------------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL;

ENTITY comp_tb_vhd IS END comp_tb_vhd;

ARCHITECTURE behavior OF comp_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT) COMPONENT Comp PORT( A : IN std_logic_vector(1 downto 0); B : IN std_logic_vector(1 downto 0); less : OUT std_logic; equal : OUT std_logic; greater : OUT std_logic

); END COMPONENT;

--Inputs SIGNAL A : std_logic_vector(1 downto 0) := (others=>'0'); SIGNAL B : std_logic_vector(1 downto 0) := (others=>'0');

--Outputs SIGNAL less : std_logic; SIGNAL equal : std_logic; SIGNAL greater : std_logic;

BEGIN

-- Instantiate the Unit Under Test (UUT) uut: Comp PORT MAP( A => A, B => B, less => less, equal => equal, greater => greater );

tb : PROCESS BEGIN

-- Wait 100 ns for global reset to finish wait for 100 ns; A<= "01"; B<= "11"; wait for 100 ns; A<= "10"; B<= "00";

wait for 100 ns; A<= "11"; B<= "11";

-- Place stimulus here

wait; -- will wait forever END PROCESS;

END; ------------------------------------------------------------------------------------------------------------

--

SIMULATION

11.1.2 Shift Register (shift_reg)


-----------------------------------------------------------------------------------------------------------library ieee ; use ieee.std_logic_1164.all;

---------------------------------------------------

entity shift_reg is port( I: clock: shift: Q: ); end shift_reg; in std_logic; in std_logic; in std_logic; out std_logic

---------------------------------------------------

architecture behv of shift_reg is

-- initialize the declared signal signal S: std_logic_vector(2 downto 0):="111";

begin

process(I, clock, shift, S) begin

-- everything happens upon the clock changing if clock'event and clock='1' then

if shift = '1' then S <= I & S(2 downto 1); end if; end if;

end process;

-- concurrent assignment Q <= S(0);

end behv;

----------------------------------------------------

Testbench for Shift register

-------------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL;

ENTITY shifter_tb_vhd IS END shifter_tb_vhd;

ARCHITECTURE behavior OF shifter_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT) COMPONENT shift_reg PORT( I : IN std_logic; clock : IN std_logic; shift : IN std_logic; Q : OUT std_logic ); END COMPONENT;

--Inputs SIGNAL I : std_logic := '0'; SIGNAL clock : std_logic := '0'; SIGNAL shift : std_logic := '0';

--Outputs SIGNAL Q : std_logic;

BEGIN

-- Instantiate the Unit Under Test (UUT) uut: shift_reg PORT MAP( I => I, clock => clock, shift => shift, Q => Q );

clk_p: PROCESS begin CLOCK <= '0'; wait FOR 10 ns; clock <= '1'; wait for 10 ns; END PROCESS;

tb : PROCESS BEGIN

-- Wait 100 ns for global reset to finish wait for 100 ns;

I<= transport '1'; shift <= '1'; wait for 100 ns; I<= transport '0'; wait for 100 ns; I<= transport '1'; -- Place stimulus here

wait; -- will wait forever END PROCESS;

END;

Simulation Result for the Shift register

11.2Example for Array


11.2.1 Static Random Access Memory (SRAM)
VHDL CODE for the SRAM

--------------------------------------------------------------- 4*4 RAM module

--- KEYWORD: array, concurrent processes, generic, conv_integer --------------------------------------------------------------

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

--------------------------------------------------------------

entity SRAM is generic( width: integer:=4; depth: integer:=4; addr: integer:=2); port( Clock: Enable: Read: Write: Read_Addr: in std_logic; in std_logic; in std_logic; in std_logic; in std_logic_vector(addr-1 downto 0);

Write_Addr: Data_in: Data_out: ); end SRAM;

in std_logic_vector(addr-1 downto 0); in std_logic_vector(width-1 downto 0); out std_logic_vector(width-1 downto 0)

--------------------------------------------------------------

architecture behav of SRAM is

-- use array to define the bunch of internal temparary signals

type ram_type is array (0 to depth-1) of std_logic_vector(width-1 downto 0); signal tmp_ram: ram_type;

begin

-- Read Functional Section process(Clock, Read) begin if (Clock'event and Clock='1') then if Enable='1' then

if Read='1' then -- buildin function conv_integer change the type -- from std_logic_vector to integer Data_out <= tmp_ram(conv_integer(Read_Addr)); else Data_out <= (Data_out'range => 'Z'); end if; end if; end if; end process;

-- Write Functional Section process(Clock, Write) begin if (Clock'event and Clock='1') then if Enable='1' then if Write='1' then tmp_ram(conv_integer(Write_Addr)) <= Data_in; end if; end if; end if; end process;

end behav; ----------------------------------------------------------------

Test bench for the SRAM

--------------------------------------------------------------------- Test Bench for memory module --- use loop statement to test module completely --------------------------------------------------------------------

library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use ieee.std_logic_unsigned.all;

entity MEM_TB is end MEM_TB;

-- entity declaration

--------------------------------------------------------------------

architecture TB of MEM_TB is

component SRAM is port( Clock: Enable: Read: Write: Read_Addr: Write_Addr: Data_in: Data_out: ); end component; in std_logic; in std_logic; in std_logic; in std_logic; in std_logic_vector(1 downto 0); in std_logic_vector(1 downto 0); in std_logic_vector(3 downto 0); out std_logic_vector(3 downto 0)

signal T_Clock, T_Enable, T_Read, T_Write: std_logic; signal T_Data_in, T_Data_out: std_logic_vector(3 downto 0); signal T_Read_Addr: std_logic_vector(1 downto 0); signal T_Write_Addr: std_logic_vector(1 downto 0);

begin

U_CKT: SRAM port map (T_Clock, T_Enable, T_Read, T_Write, T_Read_Addr, T_Write_Addr, T_Data_in, T_Data_out);

Clk_sig: process begin T_Clock<='1'; wait for 5 ns; T_Clock<='0'; wait for 5 ns; end process; -- clock cycle 10 ns

process variable err_cnt: integer := 0; begin

T_Enable <= '1'; T_Read <= '0'; T_Write <= '0'; T_Write_Addr <= (T_Write_Addr'range => '0'); T_Read_Addr <= (T_Read_Addr'range => '0'); T_Data_in <= (T_Data_in'range => '0'); wait for 20 ns;

-- test write for i in 0 to 3 loop

T_Write_Addr <= T_Write_Addr + '1'; T_Data_in <= T_Data_in + "10"; T_Write <= '1'; wait for 10 ns; assert (T_Data_out="ZZZZ") report "Something wrong!" severity Error; if (T_Data_out /= "ZZZZ") then err_cnt := err_cnt + 1; end if; end loop;

-- test read for i in 0 to 2 loop T_Read_Addr <= T_Read_Addr + '1'; T_Read <= '1'; wait for 10 ns; assert (conv_integer(T_Data_out)=2*conv_integer(T_Read_Addr)) report "Something wrong!" severity Error; if (conv_integer(T_Data_out)/=2*conv_integer(T_Read_Addr)) then err_cnt := err_cnt + 1; end if; end loop;

-- summary of all the tests if (err_cnt=0) then assert false report "Testbench of ROM completed successfully!" severity note; else assert true report "Something wrong, try again" severity error; end if;

wait;

end process;

end TB;

-------------------------------------------------------------------------configuration CFG_TB of MEM_TB is for TB end for; end CFG_TB; --------------------------------------------------------------------------

Simulation result for SRAM.

11.2.2 Read Only Memory (ROM)

VHDL code for 32*8 ROM

--------------------------------------------------------------- 32*8 ROM module -- This examples shows how to use two dimensional ARRAY -- ROM model has predefined content for read only purpose --------------------------------------------------------------

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

entity ROM is port( Clock : in std_logic; Reset : in std_logic;

Enable : in std_logic; Read : in std_logic; : in std_logic_vector(4 downto 0);

Address

Data_out: out std_logic_vector(7 downto 0) ); end ROM;

--------------------------------------------------------------

architecture Behav of ROM is

type ROM_Array is array (0 to 31) of std_logic_vector(7 downto 0);

constant Content: ROM_Array := ( 0 => "00000001", 1 => "00000010", 2 => "00000011", 3 => "00000100", 4 => "00000101", 5 => "00000110", 6 => "00000111", 7 => "00001000", 8 => "00001001", 9 => "00001010", 10 => "00001011", 11 => "00001100", 12 => "00001101", 13 => "00001110", 14 => "00001111", OTHERS => "11111111" -- Suppose ROM has -- prestored value -- like this table --------------

);

begin process(Clock, Reset, Read, Address) begin if( Reset = '1' ) then Data_out <= "ZZZZZZZZ"; elsif( Clock'event and Clock = '1' ) then if Enable = '1' then if( Read = '1' ) then Data_out <= Content(conv_integer(Address)); else Data_out <= "ZZZZZZZZ"; end if; end if; end if; end process; end Behav;

--------------------------------------------------------------

Testbench for the ROM

---------------------------------------------------------------------------------File_name :ROM_TB --DESIGNED BY : A.K.G. --Date: 13-11-2006 -------------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL;

ENTITY rom_tb_vhd IS END rom_tb_vhd;

ARCHITECTURE behavior OF rom_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT) COMPONENT ROM PORT( Clock : IN std_logic; Reset : IN std_logic; Enable : IN std_logic; Read : IN std_logic;

Address : IN std_logic_vector(4 downto 0); Data_out : OUT std_logic_vector(7 downto 0) ); END COMPONENT;

--Inputs SIGNAL Clock : std_logic := '0'; SIGNAL Reset : std_logic := '0'; SIGNAL Enable : std_logic := '0'; SIGNAL Read : std_logic := '0'; SIGNAL Address : std_logic_vector(4 downto 0) := (others=>'0');

--Outputs SIGNAL Data_out : std_logic_vector(7 downto 0);

BEGIN

-- Instantiate the Unit Under Test (UUT) uut: ROM PORT MAP( Clock => Clock, Reset => Reset, Enable => Enable, Read => Read,

Address => Address, Data_out => Data_out );

CLK_PR: process begin

clock <='0'; wait for 10 ns; clock <='1'; wait for 10 ns;

end process;

tb : PROCESS BEGIN

RESET <= '1';

-- Wait 100 ns for global reset to finish wait for 100 ns; RESET <='0'; enable<='1';

address<="00001"; wait for 100 ns; address<="00010"; read<='1'; -- Place stimulus here

wait; -- will wait forever END PROCESS;

END;

Simulation Result for the ROM

11.3 Example for Decoder

11.3.1 Hex2led

VHDL Code for hex2led

-- Module Name:

hextoled - Behavioral

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all;

entity hex2led is Port ( HEX : in std_logic_vector(3 downto 0);--defines the input LED : out std_logic_vector(6 downto 0));

end hex2led;

architecture Behavioral of hex2led is

begin

--HEX-to-seven-segment decoder -- HEX: in STD_LOGIC_VECTOR (3 downto 0); -- LED: out STD_LOGIC_VECTOR (6 downto 0); --- segment encoding --0 ---

-- 5 | | 1 ---- <- 6

-- 4 | | 2 ----3

with HEX SELect LED<= "1111001" when "0001", --1

-- to generate 0 display turns on 1, 2

"0100100" when "0010", --2 -- to generate 1 display turns on 0,1,3,4,6

"0110000" when "0011", --3 -- to generate 2 display turns on 0,1,2,3,6

"0011001" when "0100", --4 -- to generate 3 display turns on 1,2,5,6

"0010010" when "0101", --5 "0000010" when "0110", --6 "1111000" when "0111", --7 "0000000" when "1000", --8 "0010000" when "1001", --9 "0001000" when "1010", --A "0000011" when "1011", --b "1000110" when "1100", --C "0100001" when "1101", --d "0000110" when "1110", --E "0001110" when "1111", --F "1000000" when others; --0

end Behavioral;

Testbench for the Hex2led


LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL;

ENTITY hextoled_tb_vhd IS END hextoled_tb_vhd;

ARCHITECTURE behavior OF hextoled_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT) COMPONENT hex2led PORT( HEX : IN std_logic_vector(3 downto 0); LED : OUT std_logic_vector(6 downto 0) ); END COMPONENT;

--Inputs SIGNAL HEX : std_logic_vector(3 downto 0) := (others=>'0');

--Outputs SIGNAL LED : std_logic_vector(6 downto 0);

BEGIN

-- Instantiate the Unit Under Test (UUT) uut: hex2led PORT MAP( HEX => HEX, LED => LED );

tb : PROCESS BEGIN

-- Wait 100 ns for global reset to finish wait for 100 ns; Hex<="0001"; wait for 100 ns; Hex<="0010"; wait for 100 ns;

Hex<="0011";

wait for 100 ns; Hex<="0100"; wait for 100 ns; Hex<="0101"; wait for 100 ns; Hex<="1000";

-- Place stimulus here

wait; -- will wait forever END PROCESS;

END;

Simulation result for hex2led

11.4 Example for case statement

11.4.1 Multiplexer (MUX)

VHDL code for MUX

---------------------------------------------------------------------------------library IEEE;

use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity mux4 is Port ( sel : in integer range 0 to 3; d0 : in STD_LOGIC; d1 : in STD_LOGIC; d2 : in STD_LOGIC; d3 : in STD_LOGIC; z : out STD_LOGIC); end mux4;

architecture Behavioral of mux4 is

begin output_selection: process (sel, d0, d1, d2, d3) begin case sel is

when 0 => z<= d0; when 1 => z<= d1; when 2 => z<= d2; when 3 => z<= d3; end case; end process output_selection;

end Behavioral; ---------------------------------------------------------------------------------------------------------------------

Testbench for the MUX

-------------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL;

ENTITY mux_tb_vhd IS END mux_tb_vhd;

ARCHITECTURE behavior OF mux_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT) COMPONENT mux4 PORT( sel : IN integer range 0 to 3; d0 : IN std_logic; d1 : IN std_logic; d2 : IN std_logic; d3 : IN std_logic; z : OUT std_logic ); END COMPONENT;

--Inputs SIGNAL d0 : std_logic := '0'; SIGNAL d1 : std_logic := '0'; SIGNAL d2 : std_logic := '0'; SIGNAL d3 : std_logic := '0'; SIGNAL sel : integer range 0 to 3;

--Outputs SIGNAL z : std_logic;

BEGIN

-- Instantiate the Unit Under Test (UUT) uut: mux4 PORT MAP( sel => sel, d0 => d0, d1 => d1, d2 => d2, d3 => d3, z => z );

tb : PROCESS BEGIN

-- Wait 100 ns for global reset to finish wait for 100 ns;

-- Place stimulus here

d0 <= transport '1'; d1 <= transport '0'; d2 <= transport '1'; d3 <= transport '0'; wait for 100 ns; sel <= transport 0; wait for 100 ns; sel <= transport 1; wait for 100 ns; sel <= transport 2; wait for 100 ns; sel <= transport 3; wait; -- will wait forever END PROCESS;

END; ----------------------------------------------------------------------------------------------------------------------

Simulation result for the MUX

11.5 Example for the for loop


11.5.1 Multiplier

VHDL code for the Multiplier

-- Example of doing multiplication showing -- (1) how to use variable with in process -- (2) how to use for loop statement -- (3) algorithm of multiplication ---------------------------------------------------------

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

-- two 4-bit inputs and one 8-bit outputs entity multip is port( num1, num2: product: ); end multip; in std_logic_vector(1 downto 0); out std_logic_vector(3 downto 0)

architecture behv of multip is

begin process(num1, num2)

variable num1_reg: std_logic_vector(2 downto 0); variable product_reg: std_logic_vector(5 downto 0);

begin

num1_reg := '0' & num1; product_reg := "0000" & num2;

-- use variables doing computation -- algorithm is to repeat shifting/adding

for i in 1 to 3 loop if product_reg(0)='1' then product_reg(5 downto 3) := product_reg(5 downto 3) + num1_reg(2 downto 0); end if; product_reg(5 downto 0) := '0' & product_reg(5 downto 1); end loop;

-- assign the result of computation back to output signal product <= product_reg(3 downto 0);

end process;

end behv;

----------------------------------------------------------------------------------------------------------------------

Testbench for the Multiplier

library ieee; use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

entity multip_tb is end multip_tb;

architecture TB of multip_tb is

component multip is port( num1, num2: in std_logic_vector(1 downto 0); product: ); end component; out std_logic_vector(3 downto 0)

signal T_num1, T_num2: std_logic_vector(1 downto 0); signal T_product: std_logic_vector(3 downto 0);

begin

U_UT: multip port map (T_num1, T_num2, T_product);

process begin

wait for 100 ns; T_num1 <= "11"; T_num2 <= "01"; wait for 100 ns; T_num1 <= "11"; T_num2 <= "11"; wait;

end process;

end TB;

----------------------------------------------------------configuration CFG_TB of multip_tb is for TB end for; end CFG_TB; --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Simulation Result for the Multiplier

GO TO TOP

Sponsored by

Potrebbero piacerti anche