This edition first published 2017
Edition History
John Wiley & Sons, Inc. (1e, 2008)
All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, except as permitted by law. Advice on how to obtain permission to reuse material from this title is available at http://www.wiley.com/go/permissions.
The right of Pong P. Chu to be identified as the author of this work has been asserted in accordance with law.
Registered Office
John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, USA
Editorial Office
111 River Street, Hoboken, NJ 07030, USA
For details of our global editorial offices, customer services, and more information about Wiley products visit us at www.wiley.com.
Wiley also publishes its books in a variety of electronic formats and by print-on-demand. Some content that appears in standard print versions of this book may not be available in other formats.
Limit of Liability/Disclaimer of Warranty
While the publisher and authors have used their best efforts in preparing this work, they make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including without limitation any implied warranties of merchantability or fitness for a particular purpose. No warranty may be created or extended by sales representatives, written sales materials or promotional statements for this work. The fact that an organization, website, or product is referred to in this work as a citation and/or potential source of further information does not mean that the publisher and authors endorse the information or services the organization, website, or product may provide or recommendations it may make. This work is sold with the understanding that the publisher is not engaged in rendering professional services. The advice and strategies contained herein may not be suitable for your situation. You should consult with a specialist where appropriate. Further, readers should be aware that websites listed in this work may have changed or disappeared between when this work was written and when it is read. Neither the publisher nor authors shall be liable for any loss of profit or any other commercial damages, including but not limited to special, incidental, consequential, or other damages.
Library of Congress Cataloging-in-Publication Data
Names: Chu, Pong P., 1959- author.
Title: FPGA prototyping by VHDL examples : Xilinx MicroBlaze MCS SoC / by
Pong P. Chu, Cleveland State University.
Description: Second edition. | Hoboken, NJ, USA : Wiley, 2017. | Includes
bibliographical references and index. |
Identifiers: LCCN 2017015720 (print) | LCCN 2017016756 (ebook) | ISBN
9781119282754 (pdf) | ISBN 9781119282761 (epub) | ISBN 9781119282747
(cloth)
Subjects: LCSH: Field programmable gate arrays–Design and construction. |
Prototypes, Engineering. | VHDL (Computer hardware description language)
Classification: LCC TK7895.G36 (ebook) | LCC TK7895.G36 C485 2017 (print) |
DDC 621.39/5—dc23
LC record available at https://lccn.loc.gov/2017015720
Cover image: Olympic National Park, Courtesy of Pong P. Chu
Cover design by Wiley
To my mother, Chi-Te, my wife, Lee, and my daughter, Patricia
HDL (hardware description language) and FPGA (field-programmable gate array) devices allow designers to quickly develop and simulate a sophisticated digital circuit, realize it on a prototyping device, and verify operation of the physical implementation. As the capacity of FPGA devices continues to grow, a device can accommodate an SoC (system on a chip) design, which integrates a processor, memory modules, I/O peripherals, and custom hardware accelerators into a single chip. This book uses a “learning by doing” approach and illustrates the FPGA and HDL development and design process by a series of examples in the SoC context.
The examples start with simple gate-level circuits, progress gradually through the RT (register-transfer) level modules, and lead to a functional embedded system with custom I/O peripherals and hardware accelerators. A simple SoC framework, FPro (abbreviated from the book title “FPGA Prototyping”), is introduced as a platform to integrate all the design examples together. An FPro system contains a Xilinx MicroBlaze MCS soft-core processor, a video subsystem, and the MMIO (memory-mapped I/O) subsystem that can incorporate custom I/O cores. Except for the processor, all components are designed and coded from scratch. All the hardware and software examples can be synthesized, compiled, and physically tested on the prototyping board.
The primary focus of this book is on developing efficient and reliable digital systems and effectively using HDL as a tool to describe the intended hardware. The HDL language itself is not the main subject and its coverage is limited to a small synthesizable subset. The book uses about a dozen proven code templates to provide the skeletal structures of various types of circuits. These templates are general and can easily be integrated to construct a large, complex system. Although this approach limits the “freedom” of syntactic expression, it helps us steer our effort to develop an innovative and efficient hardware architecture.
After discussing the fundamentals in Part I, the book illustrates more complicated and sophisticated designs in the SoC context. Along the way, readers will learn many system-level concepts, including the derivation of a soft-core processor and IP (intellectual property) core based system, the partition and integration of software and hardware, and the development of custom I/O peripherals and hardware accelerators.
Although the book is intended for beginning designers, the examples follow strict design guidelines and prepare readers for future endeavors. The coding and design practice is “forward compatible,” which means that:
The intended audience is students in an advanced digital design course as well as practicing engineers who wish to learn about FPGA-and HDL-based development. Readers need to have a basic knowledge of digital systems, usually a required course in electrical engineering and computer engineering curricula, and a working knowledge of the C/C + + language. Prior exposure to computer architecture, embedded system, and operating system is not necessary but will be helpful.
This book is the successor edition of FPGA Prototyping by VHDL Examples: Xilinx Spartan 3 Version. The most significant change is that the new edition presents the hardware in the SoC context and covers many system-level concepts. Instead of treating each module as an isolated entity, the book integrates them into a single coherent SoC platform that allows readers to explore both hardware and software “programmability” and develop complex and interesting embedded system projects. The major revisions in this edition are:
This book is prepared to be used with the Nexys 4 DDR FPGA prototyping board manufactured by Digilent Inc. It contains an Artix FPGA device and the needed I/O peripherals. All HDL codes and discussions in the book can be applied to this board directly. The less expensive Basys 3 board can be used as well. This board incorporates fewer I/O peripherals and contains a smaller FPGA device.
Most peripherals discussed in the book are de facto industrial standards and the corresponding HDL codes can be used for other FPGA boards as long as they provide adequate analog interface circuits and connectors. Another option is to use stand-alone I/O peripheral modules or to construct the circuits on a breadboard.
The book uses the Xilinx Vivado WebPack edition for hardware development and the Xilinx SDK for software development. Both software packages are free and can be downloaded from Xilinx's website.
The design examples involve interfaces to several PC peripheral devices, including a USB keyboard, a USB mouse, a VGA compatible monitor, and a powered speaker. These accessories are widely available and probably can be obtained from an old PC.
The book is divided into four parts. Part I introduces the elementary HDL constructs and their hardware counterparts, and demonstrates the construction of a basic digital circuit with these constructs. It consists of six chapters:
Part II introduces the hardware construction of an FPro system and the development of embedded software. A basic “vanilla” FPro system, which contains a timer core, a UART (universal asynchronous receiver and transmitter) core, a GPI (general-purpose input) core, and a GPO (general-purpose output) core, is used to illustrate the key concepts of the process. It consists of four chapters:
Part III applies the techniques from Parts I and II to develop an array of I/O cores for the peripherals on the Nexys 4 DDR prototyping board. The I/O cores are constructed from scratch with custom hardware and device driver. Part III consists of nine chapters:
Part IV discusses the development of a stream-based video subsystem. The subsystem provides a framework to generate and mix multiple video sources into a single video data stream for display. It consists of four chapters:
The book also includes an Appendix with four tutorials. The tutorials consist of the following:
On an accompanying website (http://academic.csuohio.edu/chu_p), additional information is available, including the following materials:
The book contains a number of color figures. They are shown as grayscale in the printed version. These figures can be found on the website as well.
The book is self-prepared, which means that the author has produced all aspects of the text, including illustrations, tables, code listings, indexing, and formatting. As errors are always bound to happen, the accompanying website provides an updated errata sheet and a place to report errors.
P. P. Chu
Cleveland, Ohio
May, 2017
The author would like to thank Dr. R. James Duckworth and Dr. Jackie F. Wolder-ing for their suggestions and feedback. Part of this material is based upon work supported by the National Science Foundation under Grant No. 1504030. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author and do not necessarily reflect the views of the National Science Foundation.
All trademarks used or referred to in this book are the property of their respective owners.
P. P. Chu
HDL (hardware description language) is used to describe and model digital systems. VHDL is one of the two major HDLs. In this chapter, we use a simple comparator to illustrate the skeleton of a VHDL program. The description uses only logical operators and represents a gate-level combinational circuit, which is composed of simple logic gates.
VHDL stands for “VHSIC (very high-speed integrated circuit) hardware description language.” It was originally sponsored by the U.S. Department of Defense and later transferred to the IEEE (Institute of Electrical and Electronics Engineers). The language is formally defined by IEEE Standard 1076. The standard was first ratified in 1987 and revised several times. The main versions are referred to as VHDL-87, VHDL-93, VHDL-2000, and VHDL-2008. The synthesis subset does not change significantly after VHDL-93 and this book mainly follows VHDL-93.
VHDL is intended for describing and modeling a digital system at various levels and is an extremely complex language. The focus of this book is on hardware design rather than the language. Instead of covering every aspect of VHDL, we introduce the key VHDL synthesis constructs by examining a collection of examples. Detailed VHDL coverage may be explored through the sources listed in the Bibliographic Notes section.
In this chapter, we introduce the HDL concepts, basic VHDL language constructs, logical operators, and program structure. A simple gate-level combinational circuit is used for demonstration. In Chapter 3, we cover the more sophisticated VHDL operators and constructs and examine module-level combinational circuits, which are composed of intermediate-sized components, such as adders, comparators, and multiplexers.
Consider a 1-bit equality comparator with two inputs, i0
and i1
, and an output, eq
. The eq
signal is asserted when i0
and i1
are equal. The truth table of this circuit is shown in Table 1.1.
Table 1.1 Truth table of a 1-bit equality comparator
input i0 i1 |
output eq |
0 0 | 1 |
0 1 | 0 |
1 0 | 0 |
1 1 | 1 |
Assume that we want to use basic logic gates, which include not, and, or, and xor cells, to implement the circuit. One way to describe the circuit is to use a sum-of-products format. The logic expression is
One possible corresponding VHDL code is shown in Listing 1.1. We examine the language constructs and statements of this code in the following subsections.
Listing 1.1 Gate-level implementation of a 1-bit comparator
VHDL is case insensitive, which means that upper- and lowercase letters can be used interchangeably, and free formatting, which means that spaces and blank lines can be inserted freely. It is good practice to add proper spaces to make the code clear and to associate special meaning with cases. In this book, we reserve uppercase letters for constants.
An identifier
is the name of an object and is composed of 26 letters, digits, and the underscore (_), as in i0
, i1
, and data_bus1_enable. The identifier must start with a letter.
The comments start with –– and the text after it is ignored. In this book, the VHDL keywords are shown in boldface type, as in entity, and the comments are shown in italics type, as in
—— this is a comment
The first two lines,
invoke the std_logic_1164
package from the ieee
library. The package and library allow us to add additional types, operators, functions, etc., to VHDL. The two statements are needed because a special data type is used in the code.
The entity declaration
essentially outlines the I/O signals of the circuit. The first line indicates that the name of the circuit is eq1
, and the port section specifies the I/O signals. The basic format for an I/O port declaration is
signal_name1, signal_name2, …: mode data_type;
The mode
term can be in or out, which indicates that the corresponding signals flow “into” or “out of” of the circuit. It can also be inout, for bidirectional signals.
VHDL is a strongly typed language, which means that an object must have a data type and only the defined values and operations can be applied to the object. Although VHDL is rich in data types, our discussion is limited to a small set of predefined types that are suitable for synthesis, mainly the std_logic
type and its variants.
std_logic_type
The std_logic
type is defined in the std_logic_1164
package and consists of nine values. Three of the values, ’0’
, ’1’
, and ’Z’
, which stand for logical 0, logical 1, and high impedance, can be synthesized. Two values, ’U’
and ’X’
, which stand for “uninitialized” and “unknown” (e.g., when signals with ’0’
and ’1’
values are tied together), may be encountered in simulation. The other four values, ’-’,
’H’
, ’L’
, and ’W’
, are not used in this book.
A signal in a digital circuit frequently contains multiple bits, such as a data bus. The std_logic_vector
data type, which is defined as an array with elements of std_logic
, can be used for this purpose. For example, let a
be an 8-bit input port. It can be declared as
a: in std_logic_vector(7 downto 0);
We can use a term like a(7 downto 4)
to specify a desired range and a term like a(1)
to access a single element of the array. The array can also be declared in ascending order:
a: in std_logic_vector(0 to 7);
We generally avoid this format since it is more natural to associate the MSB with the leftmost position.
Logical operators
Several logical operators, including not, and, or, and xor, are defined over the std_logic_vector
and std_logic
data type. Bitwise operation is used when an operator is applied to an object with the std_logic_vector
data type. Note that the and, or, and xor operators have the same precedence and we need to use parentheses to specify the desired order of evaluation, as in
(a and b) or (c and d)
The architecture body,
describes operation of the circuit. VHDL allows multiple bodies associated with an entity, and thus the body is identified by the name sop_arch
(“sum-of-products architecture”).
The architecture body may include an optional declaration section, which specifies constants, internal signals, and so on. Two internal signals are declared in this program:
signal p0, p1: std_logic;
The main description, encompassed between begin and end, contains three concurrent statements. Unlike a program in a conventional language, such as C, in which the statements are executed sequentially, concurrent statements are like circuit parts that operate in parallel. The signal on the left-hand side of a statement can be considered as the output of that part, and the expression specifies the circuit function and corresponding input signals. For example, consider the statement
It is a circuit that performs the or operation. When p0
or p1
changes its value, this statement is activated and the expression is evaluated. The new value is assigned to eq
after the default propagation delay.
The graphical representation of this program is shown in Figure 1.1. The three circuit parts represent the three concurrent statements. The connections among these parts are implicitly specified by the signal and port names. The order of the concurrent statements is clearly irrelevant and the statements can be rearranged arbitrarily.
We can expand the comparator to 2-bit inputs. Let the input be a
and b
and the output be aeqb
. The aeqb
signal is asserted when both bits of a
and b
are equal. The code is shown in Listing 1.2.
Listing 1.2 Gate-level implementation of a 2-bit comparator
The a
and b
ports are now declared as a two-element std_logic_vector
. Derivation of the architecture body is similar to that of a 1-bit comparator. The p0, p1, p2
, and p3
signals represent the results of the four product terms, and the final result, aeqb
, is the logic expression in sum-of-products format.
A digital system is frequently composed of several smaller subsystems. This allows us to build a large system from simpler or predesigned components. VHDL provides a mechanism, known as component instantiation, to perform this task. This type of code is called a structural description.
An alternative to the design of the 2-bit comparator of Section 1.2.6 is to utilize the previously constructed 1-bit comparators as the building blocks. The diagram is shown in Figure 1.2, in which two 1-bit comparators are used to check the two individual bits and their results are fed to an and cell. The aeqb signal is asserted only when the two bits are equal.
The corresponding code is shown in Listing 1.3. Note that the entity declaration is the same and thus is not included.
Listing 1.3 Structural description of a 2-bit comparator
The code includes two component instantiation statements, whose syntax is
The first portion of the statement specifies which component is used. The unit_label
term gives a unique id for an instance, the lib_name
term indicates where (i.e., in which library) the component resides, and the entity_name
and arch_name
terms indicate the names of the entity and architecture. The arch_name
term is optional. If it is omitted, the last compiled architecture body will be used. The second portion is port mapping, which indicates the connection between formal signals, which are I/O ports declared in a component's entity declaration, and actual signals, which are the signals used in the architecture body.
The first component instantiation statement is
The work
library is the default library in which the compiled entity and architecture units are stored, and eq1
and sop_arch
are the names of the entity and architecture defined in Listing 1.1. The port mapping reflects the connections shown in Figure 1.2. The component instantiation statement is also a concurrent statement and represents a circuit that is encompassed in a “black box” whose function is defined in another module.
This example demonstrates the close relationship between a block diagram and code. The code is essentially a textual description of a schematic. Although it is a clumsy way for humans to comprehend a diagram, it puts all representations in a single HDL framework.
The component instantiation statement is added in VHDL 93. Older codes may use the mechanism in VHDL 87, in which a component must first be declared (i.e., made known) and then used. The code in this format is shown in Listing 1.4.
Listing 1.4 Structural description with VHDL-87
Note that the original clause
is replaced by a clause with the declared component name
When an HDL program is targeted to a physical device of a prototyping board, the design is subject to a variety of constraints. One constraint is the locations of the I/O pins. For example, the switches and LEDs of the board are “pre-wired” to specific I/O pins of the FPGA device and they cannot be altered. The pin assignment is defined in a constraint file, which is processed in conjunction with HDL files.
The designs of this book use a constraint file that specifies the pin assignment for all the I/O signals on the Nexys 4 DDR prototyping board. To use this file, the top-level HDL module must have the same predefined I/O signal names. This can be achieved by creating an HDL file to “wrap” the original design and map its original I/O signals to the prototyping board's I/O signals. For example, we name the I/O pins connected to the slide switches and LEDs as sw
and led
and specify their pin assignment in the constraint file. For a physical implementation, the a
and b
signals of the previous comparator circuit can be connected to the four switches and the output, aeqb
, can be connected to an LED. The corresponding wrapping code is shown in Listing 1.5.
Listing 1.5 Top-level wrapping circuit
The code essentially maps the “logical” port names of the comparator to the physical signals on the prototyping board. Note that the output led
signal is defined as a one-element vector to accommodate future expansion. The procedure to include the constraint file is demonstrated in Appendix A.2.
After code is developed, it can be simulated
in a host computer to verify the correctness of the circuit operation and can be synthesized
to a physical device. Simulation is usually performed within the same HDL framework. We create a special program, known as a testbench, to mimic a physical lab bench. The sketch of a 2-bit comparator testbench program is shown in Figure 1.3. The uut
block is the unit under test, the test vector generator
block generates testing input patterns, and the monitor block examines the output responses.
A simple testbench for the 2-bit comparator is shown in Listing 1.6.
Listing 1.6 Testbench for a 2-bit comparator
The code consists of a component instantiation statement, which creates an instance of a 2-bit comparator, and a process statement, which generates a sequence of test patterns.
The process statement is a special VHDL construct in which the operations are performed sequentially. Each test pattern is generated by three statements. For example,
The first two statements specify the values for the test_in0
and test_in1
signals, and the third indicates that the two values will last for 200 ns.
The code has no monitor. We can observe the input and output waveforms on a simulator's display, which can be treated as a “virtual logic analyzer.” The simulated timing diagram of this testbench is shown in Figure 1.4. Writing code for a comprehensive test vector generator and a monitor requires detailed knowledge of VHDL and is beyond the scope of this book. This listing can serve as a testbench template for other combinational circuits. We can substitute the uut instance and modify the test patterns according to the new circuit.
A short bibliographic section appears at the end of each chapter to provide some of the most relevant references for further exploration. A comprehensive bibliography is included at the end of the book.
VHDL is a complex language. The Designer's Guide to VHDL by P. J. Ashenden provides detailed coverage of the language's syntax and constructs. The author's RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability provides a comprehensive discussion on developing effective, synthesizable codes. The derivation of the testbench for a large digital system is a difficult task. Writing Testbenches: Functional Verification of HDL Models, 2nd edition, by J. Bergeron focuses on this topic.
At the end of each chapter, some experiments are suggested as exercises. The experiments help us better understand the concepts and provide a hands-on opportunity to design and debug actual circuits.
Develop the HDL codes in Experiment 2.6.1. The code can be simulated and synthesized after we complete Chapter 2.
Develop the HDL codes in Experiment 2.6.2. The code can be simulated and synthesized after we complete