Introduction to Digital Design Using Digilent FPGA Boards Block Diagram / VHDL Examples Richard E. Haskell Darrin M. Hanna Oakland University, Rochester, Michigan LBE Books Rochester Hills, MI Copyright 2009 by LBE Books, LLC. All rights reserved. ISBN 978-0-9801337-6-9 Online Version Published by LBE Books, LLC 1202 Walton Boulevard Suite 214 Rochester Hills, MI 48307 www.lbebooks.com ii Preface A major revolution in digital design has taken place over the past decade. Field programmable gate arrays (FPGAs) can now contain over a million equivalent logic gates and tens of thousands of flip-flops. This means that it is not possible to use traditional methods of logic design involving the drawing of logic diagrams when the digital circuit may contain thousands of gates. The reality is that today digital systems are designed by writing software in the form of hardware description languages (HDLs). The most common HDLs used today are VHDL and Verilog. Both are in widespread use. When using these hardware description languages the designer typically describes the behavior of the logic circuit rather than writing traditional Boolean logic equations. Computer-aided design tools are used to both simulate the VHDL or Verilog design and to synthesize the design to actual hardware. This book assumes no previous knowledge of digital design. We use 30 examples to show you how to get started designing digital circuits that you can implement on a Xilinx Spartan3E FPGA using either the Digilent BASYSTM system board that can be purchased from www.digilentinc.com for $59 or the Digilent Nexys-2 board that costs $99. We will use Active-HDL from Aldec to design, simulate, synthesize, and implement our digital designs. A free student edition of Active-HDL is available from Aldec, Inc. (www.aldec.com). To synthesize your designs to a Spartan3E FPGA you will need to download the free ISE WebPACK from Xilinx, Inc. (www.xilinx.com). The Xilinx synthesis tools are called from within the Aldec Active-HDL integrated GUI. We will use the ExPort utility to download your synthesized design to the Spartan3E FPGA. ExPort is part of the Adept software suite that you can download free from Digilent, Inc. (www.digilentinc.com). A more complete book called Digital Design Using Digilent FPGA Boards - VHDL / Active-HDL Edition is also available from Digilent or LBE Books (www.lbebooks.com). This more comprehensive book contains over 75 examples including examples of using the VGA and PS/2 ports. Similar books that use Verilog are also available from Digilent or LBE Books. Many colleagues and students have influenced the development of this book. Their stimulating discussions, probing questions, and critical comments are greatly appreciated. Richard E. Haskell Darrin M. Hanna iii Introduction to Digital Design Using Digilent FPGA Boards Block Diagram / VHDL Examples Table of Contents Introduction - Digital Design Using FPGAs 1 Example 1 - Switches and LEDs 6 Example 2 - 2-Input Gates 11 Example 3 - Multiple-Input Gates 16 Example 4 - Equality Detector 21 Example 5 - 2-to-1 Multiplexer 23 Example 6 - Quad 2-to-1 Multiplexer 27 Example 7 - 4-to-1 Multiplexer 34 Example 8 - Clocks and Counters 42 Example 9 - 7-Segment Decoder 48 Example 10 - 7-Segment Displays: x7seg and x7segb 54 Example 11 - 2's Complement 4-Bit Saturator 64 Example 12 - Full Adder 70 Example 13 - 4-Bit Adder 75 Example 14 - N-Bit Adder 79 Example 15 - N-Bit Comparator 82 Example 16 - Edge-Triggered D Flip-Flop Available only in print vesion Example 17 - D Flip-Flops in VHDL Example 18 - Divide-by-2 Counter Example 19 - Registers Example 20 - N-Bit Register in VHDL Example 21 - Shift Registers Example 22 - Ring Counters Example 23 - Johnson Counters Example 24 - Debounce Pushbuttons Example 25 - Clock Pulse Example 26 - Arbitrary Waveform Example 27 - Pulse-Width Modulation (PWM) Example 28 - Controlling the Position of a Servo Example 29 - Scrolling the 7-Segment Display Example 30 - Fibonacci Sequence iv Appendix A - Aldec Active-HDL Tutorial Part 1: Project Setup Part 2: Design Entry - sw2led.bde Part 3: Synthesis and Implementation Part 4: Program FPGA Board Part 5: Design Entry - gates2.bde Part 6: Simulation Part 7: Design Entry - HDE Part 8: Simulation - gates2 Appendix B - Number Systems B.1 Counting in Binary and Hexadecimal B.2 Positional Notation B.3 Fractional Numbers B.4 Number System Conversions B.5 Negative Numbers 123 123 127 130 134 136 142 146 149 Available only in print vesion Appendix C - Basic Logic Gates C.1 Truth Tables and Logic Equations C.2 Positive and Negative Logic: De Morgan's Theorem C.3 Sum of Products Design C.4 Product of Sums Design Appendix D - Boolean Algebra and Logic Equations D.1 Boolean Theorems D.2 Karnaugh Maps Appendix E - VHDL Quick Reference Guide v 189 Introduction 1 Introduction Digital Design Using FPGAs The first integrated circuits that were developed in the early 1960s contained less that 100 transistors on a chip and are called small-scale integrated (SSI) circuits. Medium-scale integrated (MSI) circuits, developed in the late 1960s, contain up to several hundreds of transistors on a chip. By the mid 1970s large-scale integrated (LSI) circuits containing several thousands of transistors had been developed. Very-large-scale integrated (VLSI) circuits containing over 100,000 transistors had been developed by the early 1980s. This trend has continued to the present day with 1,000,000 transistors on a chip by the late 1980s, 10,000,000 transistors on a chip by the mid-1990s, over 100,000,000 transistors by 2004, and up to 1,000,000,000 transistors on a chip today. This exponential growth in the amount of digital logic that can be packed into a single chip has produced serious problems for the digital designer. How can an engineer, or even a team of engineers, design a digital logic circuit that will end up containing millions of transistors? In Appendix C we show that any digital logic circuit can be made from only three types of basic gates: AND, OR, and NOT. In fact, we will see that any digital logic circuit can be made using only NAND gates (or only NOR gates), where each NAND or NOR gate contains four transistors. These basic gates were provided in SSI chips using various technologies, the most popular being transistor-transistor logic (TTL). These TTL chips were the mainstay of digital design throughout the 1960s and 1970s. Many MSI TTL chips became available for performing all types of digital logic functions such as decoders, adders, multiplexers, comparators, and many others. By the 1980s thousands of gates could fit on a single chip. Thus, several different varieties of programmable logic devices (PLDs) were developed in which arrays containing large numbers of AND, OR, and NOT gates were arranged in a single chip without any predetermined function. Rather, the designer could design any type of digital circuit and implement it by connecting the internal gates in a particular way. This is usually done by opening up fuse links within the chip using computer-aided tools. Eventually the equivalent of many PLDs on a single chip led to complex programmable logic devices (CPLDs). Field Programmable Gate Arrays (FPGAs) A completely different architecture was introduced in the mid-1980's that uses RAM-based lookup tables instead of AND-OR gates to implement combinational logic. These devices are called field programmable gate arrays (FPGAs). The device consists of an array of configurable logic blocks (CLBs) surrounded by an array of I/O blocks. The Spartan-3E from Xilinx also contains some blocks of RAM, 18 x 18 multipliers, as well as Digital Clock Manager (DCM) blocks. These DCMs are used to eliminate clock distribution delay and can also increase or decrease the frequency of the clock. 2 Introduction Each CLB in the Spartan-3E FPGA contains four slices, each of which contains two 16 x 1 RAM look-up tables (LUTs), which can implement any combinational logic function of four variables. In addition to two look-up tables, each slice contains two D flip-flops which act as storage devices for bits. The basic architecture of a Spartan-3E FPGA is shown in Fig. 1. CLB LUT FF CLB LUT Slice FF Slice LUT FF LUT FF LUT FF LUT FF Slice LUT Slice FF LUT CLB FF CLB IOBs Figure 1 Architecture of a Spartan-3E FPGA The BASYS board from Digilent contains a Xilinx Spartan3E-100 TQ144 FPGA. This chip contains 240 CLBs arranged as 22 rows and 16 columns. There are therefore 960 slices with a total of 1,920 LUTs and flip-flops. This part also contains 73,728 bits of block RAM. Half of the LUTs on the chip can be used for a maximum of 15,360 bits of distributed RAM. By contrast the Nexys-2 board from Digilent contains a Xilinx Spartan3E-500 FG320 FPGA. This chip contains 1,164 CLBs arranged as 46 rows and 34 columns. There are therefore 4,656 slices with a total of 9,312 LUTs and flip-flops. This part also contains 368,640 bits of block RAM. Half of the LUTs on the chip can be used for a maximum of 74,752 bits of distributed RAM. In general, FPGAs can implement much larger digital systems than CPLDs as illustrated in Table 1. The column labeled No. of Gates is really equivalent gates as we have seen that FPGAs really don't have AND and OR gates, but rather just RAM look-up tables. (Each slice does include two AND gates and two XOR gates as part of carry and arithmetic logic used when implementing arithmetic functions including addition and Introduction 3 multiplication.) Note from Table 1 that FPGAs can have the equivalent of millions of gates and tens of thousands of flip-flops. Xilinx Part CPLDs 9500 family FPGAs Spartan Spartan II Spartan IIE Spartan 3 Spartan-3E Virtex Virtex E Virtex-II Table 1 Comparing Xilinx CPLDs and FPGAs No. of Gates No. of I/Os No. of CLBs No. of Flip-flops 800 - 6,400 5,000 - 40,000 15,000 - 200,000 23,000 - 600,000 50,000 - 5,000,000 100,000 - 1,600,000 57,906 - 1,124,022 71,693 - 4,074,387 40,960 - 8,388,608 34 - 192 77 - 224 100 - 784 86 - 284 96 - 1,176 182 - 514 384 - 3,456 124 - 784 192 - 8,320 108 - 376 240 - 3,688 180 - 512 384 - 6,144 176 - 804 384 - 16,224 88 - 1,108 64 - 11,648 Block RAM (bits) 36 - 288 360 - 2,016 642 - 5,556 16,384 - 57,344 2,082 - 15,366 32,768 - 294,912 2,280 - 71,264 73,728 - 1,916,928 1,920 - 29,505 73,728 - 663,552 2,076 - 26,112 32,768 - 131,072 1,888 - 66,504 65,536 - 851,968 1,040 - 99,832 73,728 - 3,096,576 Modern Design of Digital Systems The traditional way of designing digital circuits is to draw logic diagrams containing SSI gates and MSI logic functions. However, by the late 1980s and early 1990s such a process was becoming problematic. How can you draw schematic diagrams containing hundreds of thousands or millions of gates? As programmable logic devices replaced TTL chips in new designs a new approach to digital design became necessary. Computer-aided tools are essential to designing digital circuits today. What has become clear over the last decade is that today's digital engineer designs digital systems by writing software! This is a major paradigm shift from the traditional method of designing digital systems. Many of the traditional design methods that were important when using TTL chips are less important when designing for programmable logic devices. Today digital designers use hardware description languages (HDLs) to design digital systems. The most widely used HDLs are VHDL and Verilog. Both of these hardware description languages allow the user to design digital systems by writing a program that describes the behavior of the digital circuit. The program can then be used to both simulate the operation of the circuit and synthesize an actual implementation of the circuit in a CPLD, an FPGA, or an application specific integrated circuit (ASIC). Another recent trend is to design digital circuits using block diagrams or graphic symbols that represent higher-level design constructs. These block diagrams can then be compiled to produce Verilog or VHDL code. We will illustrate this method in this book. We will use Active-HDL from Aldec for designing our digital circuits. This integrated tool allows you to enter your design using either a block diagram editor (BDE) or by writing Verilog or VHDL code using the hardware description editor (HDE). Once your hardware has been described you can use the functional simulator to produce waveforms that will verify your design. This hardware description can then be synthesized to logic equations and implemented or mapped to the FPGA architecture. 4 Introduction We include a tutorial for using Active-HDL in Appendix A. A free student version of Active-HDL is available on their website.1 We will use Xilinx ISE for synthesizing our VHDL designs. You can download a free version of ISETM WebPACKTM from the Xilinx website.2 This WebPACKTM synthesis tool can be run from within the Aldec Active-HDL development environment as shown in the tutorial in Appendix A. The implementation process creates a .bit file that is downloaded to a Xilinx FPGA on the BASYS board or Nexys-2 shown in Fig. 2. The BASYS board is available to students for $59 from Digilent, Inc.3 This board includes a 100k-gate equivalent Xilinx Spartan3E FPGA (250k-gate capacity is also available), 8 slide switches, 4 pushbutton switches, 8 LEDs, and four 7-segment displays. The frequency of an on-board clock can be set to 25 MHz, 50 MHz, or 100 MHz using a jumper. There are connectors that allow the board to be interfaced to external circuits. The board also includes a VGA port and a PS2 port. The use of these ports are described in a different book.4 Another more advanced board, the Nexys-2 board, is also available to students for $99 from Digilent. The Nexys-2 board is similar to the BASYS board except that it contains a 500k- or 1200k-gate equivalent Spartan 3E FPGA, a Hirose FX2 interface for additional add-on component boards, 16 MB of cellular RAM, 16 MB of flash memory, a 50 MHz clock and a socket for a second oscillator. The Nexys-2 is ideally suited for embedded processors. All of the examples in this book can be used on both the BASYS board and the Nexys-2 board. The only difference is that you would use the file basys2.ucf to define the pinouts on the BASYS board and you would use the file nexys2.ucf to define the pinouts on the Nexys-2 board. Both of these files are available to download from www.lbebooks.com. Table 2 shows the jumper settings you would use on the two boards. (a) (b) Figure 2 (a) BASYS board, (b) Nexys-2 Board 1 http://www.aldec.com/education/ 2 http://www.xilinx.com 3 http://www.digilentinc.com 4 Digital Design Using Digilent FPGA Boards - VHDL / Active-HDL Edition; available from www.lbebooks.com. Introduction 5 Table 1.2 Board Jumper Settings BASYS Board Nexys-2 Board Set the JP3 jumper to JTAG Set the POWER SELECT jumper to USB Remove the JP4 jumper to select a 50 MHz Set the MODE jumper to JTAG clock VHDL VHDL is based on the Ada software programming language but it is not Ada nor is it a software programming language. VHDL is a hardware description language that is designed to model digital logic circuits. It simply has syntax similar to the Ada programming language but the way it behaves is different. In this book you will learn VHDL by studying the examples we use to describe digital logic and then doing some of the VHDL problems at the end of each chapter. In this book we begin by using the Active-HDL block diagram editor to draw logic circuits using basic gates. When you compile these block diagrams Active-HDL will generate the corresponding VHDL code. The block diagram representing your logic circuit can then be used as a module in a higher-level digital design. This higher-level design can then be compiled to produce its corresponding VHDL code. This hierachical block diagram editor will make it easy to design top-level designs. Sometimes it will be easier to design a digital module by writing a VHDL program directly rather than drawing it using gates. When you do this you can still use the block diagram for this module in higher-level designs. We will illustrate this process in many of our examples. Just like any programming language, you can only learn VHDL by actually writing VHDL programs and simulating the designs using a VHDL simulator that will display the waveforms of the signals in your design. This is a good way to learn not only VHDL but digital logic as well. A companion book5 that uses Verilog instead of VHDL is available from www.digilentinc.com or www.lbebooks.com. More comprehensive Verilog and VHDL books are also available.6,7 5 Introduction to Digital Design Usign Digilent FPGA Boards - Block Diagram/Verilog Examples 6 Digital Design Using Digilent FPGA Boards - Verilog / Active-HDL Edition, LBE Books, 2009. 7 Digital Design Using Digilent FPGA Boards - VHDL / Active-HDL Edition, LBE Books, 2009. 6 Example 1 Example 1 Switches and LEDs In this example we will show the basic structure of a VHDL program and how to write logic equations for 2-input gates. Example 1a will show the simulation results using Aldec Active-HDL and Example 1b will show how to synthesize the program to a Xilinx FPGA on the BASYS or Nexys-2 board. Prerequisite knowledge: None Learned in this Example: Use of Aldec Active-HDL - Appendix A 1.1 Slide Switches The slide switches on the BASYS and Nexys-2 boards are connected to pins on the 3.3 V FPGA through a resistor R as shown in Fig. 1.1. R The value of R is 4.7 k on the BASYS board sw[i] and 10 k on the Nexys-2 board. When the slide switch is down it is connected to ground and the input sw(i) to the FPGA is read as a logic 0. When the slide switch is up it is connected to 3.3 Figure 1.1 Slide switch connection V and the input sw(i) to the FPGA is read as a logic 1. There are eight slide switches on the BASYS and Nexys-2 boards. The eight pin numbers on the FPGA corresponding to the eight slide switches are given in a .ucf file. The file basys2.ucf shown in Listing 1.1 defines the pin numbers for all I/O on the BASYS board. Note that we have named the slide switches sw(i), i = 0:7, which correspond to the switch labels on the board. We will always name the slide switches sw(i) in our top-level designs so that we can use the basys2.ucf file without change. Because the pin numbers on the Nexys-2 board are different from those on the BASYS board we will use a different file called nexys2.ucf to define the pin numbers on the Nexys-2 board. The names of the I/O ports, however, will be the same for both boards. Therefore, all of the examples in this book can be used with either board by simply using the proper .ucf file when implementing the design. Both of these .ucf files can be downloaded from www.lbebooks.com. 1.2 LEDs A light emitting diode (LED) emits light when current flows through it in the positive direction as shown in Fig. 1.2. Current flows through the LED when the voltage on the anode side (the wide side of the black triangle) is made higher than the voltage on Switches and LEDs 7 the cathode side (the straight line connected to the apex of the black triangle). When current flows through a lighted LED the forward voltage across the LED is typically between +1.5 and +2.0 volts. If voltage V2 in Fig. 1.2 is less than or equal to voltage V1 then no current can flow through the LED and therefore no light will be emitted. If voltage V2 is greater than voltage V1 then current will flow through the resistor R and the LED. The resistor is used to limit the amount of current that flows through the LED. Typical currents needed to light LEDs range from 2 to 15 milliamps. Listing 1.1 basys2.ucf # Pin assignment for LEDs NET "ld<7>" LOC = "p2" ; NET "ld<6>" LOC = "p3" ; NET "ld<5>" LOC = "p4" ; NET "ld<4>" LOC = "p5" ; NET "ld<3>" LOC = "p7" ; NET "ld<2>" LOC = "p8" ; NET "ld<1>" LOC = "p14" ; NET "ld<0>" LOC = "p15" ; # Pin assignment for slide switches NET "sw<7>" LOC = "p6"; NET "sw<6>" LOC = "p10"; NET "sw<5>" LOC = "p12"; NET "sw<4>" LOC = "p18"; NET "sw<3>" LOC = "p24"; NET "sw<2>" LOC = "p29"; NET "sw<1>" LOC = "p36"; NET "sw<0>" LOC = "p38"; # Pin assignment NET "btn<3>" LOC NET "btn<2>" LOC NET "btn<1>" LOC NET "btn<0>" LOC for pushbutton switches = "p41"; = "p47"; = "p48"; = "p69"; # Pin assignment for 7-segment displays NET "a_to_g<6>" LOC = "p25" ; NET "a_to_g<5>" LOC = "p16" ; NET "a_to_g<4>" LOC = "p23" ; NET "a_to_g<3>" LOC = "P21" ; NET "a_to_g<2>" LOC = "p20" ; NET "a_to_g<1>" LOC = "p17" ; NET "a_to_g<0>" LOC = "p83" ; NET "dp" LOC = "p22" ; NET NET NET NET "an<3>" "an<2>" "an<1>" "an<0>" LOC LOC LOC LOC = = = = "p26"; "p32"; "p33"; "p34"; # Pin assignment for clock NET "mclk" LOC = "p54"; 8 Example 1 There are two different ways that an I/O No current no light pin of an FPGA can be used to turn on an LED. V2 V1 > V2 The first is to connect the FPGA pin to V2 in Fig. R LED 1.2 and to connect V1 to ground. Bringing the pin (V2) high will then turn on the LED. To turn off light the LED the output pin would be brought low. Current This is the method used for the LEDs ld(7) - ld(0) on the BASYS and Nexys-2 boards. V2 V1 < V2 R The second method is to connect the LED FPGA pin to V1 in Fig. 1.2 and to connect V2 to Figure 1.2 Turning on an LED a constant voltage. Bringing the pin (V1) low will then turn on the LED. To turn off the LED the output pin would be brought high. This voltage should be equal to V2 to make sure no current flows through the LED. This second method is the method used for the 7segment displays on the BASYS and Nexys-2 boards. Examples 9 and 10 will show how to display hex digits on the 7-segment displays. 1.3 Connecting the Switches to the LEDs Part 1 of the tutorial in Appendix A shows how to connect the input switches to the output LEDs using the block diagram editor (BDE) in Active-HDL. The result is shown in Fig. 1.3. Figure 1.3 Connecting the eight switches to the eight LEDs Switches and LEDs 9 Compiling the file sw2led.bde generates the VHDL file sw2led.vhd shown in Listing 1.2. Alternatively, by selecting the hardware description editor (HDE) the entity and architecture declarations are automatically generated but you will need to write your own assignment statements. This can lead to the simpler VHDL program shown in Listing 1.3 where we can write a single assignment statement using the assignment operator, <=, to replace the two intermediate assignment statements in Listing 1.2. It is unnecessary to define the intermediate bus BUS23(7:0). Listing 1.2 sw2led.vhd library IEEE; use IEEE.std_logic_1164.all; entity sw2led is port( sw : in STD_LOGIC_VECTOR(7 downto 0); ld : out STD_LOGIC_VECTOR(7 downto 0) ); end sw2led; architecture sw2led of sw2led is ---- Signal declarations used on the diagram ---signal BUS23 : STD_LOGIC_VECTOR (7 downto 0); begin ---- Terminal assignment ----- Inputs terminals BUS23 <= sw; -- Output\buffer terminals ld <= BUS23 end sw2led; Listing 1.3 sw2led2.vhd library IEEE; use IEEE.std_logic_1164.all; entity sw2led2 is port( sw : in STD_LOGIC_VECTOR(7 downto 0); ld : out STD_LOGIC_VECTOR(7 downto 0) ); end sw2led2; architecture sw2led2 of sw2led2 is begin ld <= sw; end sw2led2; 10 Example 1 Note in the entity in Listing 1.3 that the input sw and the output ld are defined to be of type STD_LOGIC_VECTOR (7 downto 0). For simulation purposes this type is defined to have nine possible values. In addition to the usual 0 and 1 the other seven possible values are U (uninitialized), X (unknown), Z (high impedance), W (weak unknown), L (weak 0), H (weak 1), and - (don't care). In Parts 2 and 3 of the tutorial in Appendix A we show how to synthesize, implement, and download the design to the FPGA board. In summary, the steps you follow to implement a digital design on the BASYS or Nexys-2 board are the following: 1. 2. 3. 4. 5. Create a new project and design name. Using the BDE create a logic diagram. Save and compile the .bde file. Optionally simulate the design (see Example 2). Synthesize the design selecting the Spartan3E family and the 3s100etq144 device for the BASYS board and the 3s500efg320 device for the Nexys-2 board. 6. Implement the design using either basys2.ucf or nexys2.ucf as the custom constraint file. Check Allow Unmatched LOC Constraints under Translate and uncheck Do Not Run Bitgen under BitStream. Select JTAG Clock as the start-up clock under Startup Options. 7. Use ExPort to download the .bit file to the FPGA board. At this point the switches are connected to the LEDs. Turning on a switch will light up the corresponding LED. Problem 1.1 The four pushbuttons on the BASYS and Nexys-2 boards are connected to pins on the FPGA using the circuit shown in Fig. 1.4. The value of R is 4.7 k on the BASYS board and 10 k on the Nexys-2 board. When the pushbutton is up the two resistors pull the input down to ground and the input btn(i) to the FPGA is read as a logic 0. When the pushbutton is pressed the input is pulled up to 3.3 V and the input btn(i) to the FPGA is read as a logic 1. Create a .bde file using Active-HDL that will connect the four pushbuttons to the rightmost four LEDs. Compile and implement the program. Download the .bit file to the FPGA board and test it by pressing the pushbuttons. R 3.3 V btn(i) R Figure 1.4 Pushbutton connection 2-Input Gates 11 Example 2 2-Input Gates In this example we will design a circuit containing six different 2-input gates. Example 2a will show the simulation results using Aldec Active-HDL and Example 2b will show how to synthesize the program to a Xilinx FPGA on a Digilent board. Prerequisite knowledge: Appendix C - Basic Logic Gates Appendix A - Use of Aldec Active-HDL 2.1 Generating the Design File gates2.bde Part 4 of the tutorial in Appendix A shows how to connect two inputs a and b to the inputs of six different gates using the block diagram editor (BDE) in Active-HDL. The result is shown in Fig. 2.1. Note that we have named the outputs of the gates the name of the gate including an underscore. Identifier names in VHDL can contain any letter, digit, underscore _, or $. The identifier can not begin with a digit or be a VHDL keyword. VHDL is not case sensitive. The name of this file is gates2.bde. When you compile this file the VHDL program gates2.vhd shown in Listing 2.1 is generated. Figure 2.1 Circuit diagram for Example 2 12 Example 2 Listing 2.1 gates2.vhd -- Example 2a: gates2 library IEEE; use IEEE.std_logic_1164.all; entity gates2 is port( a : in STD_LOGIC; b : in STD_LOGIC; and_gate : out STD_LOGIC; nand_gate : out STD_LOGIC; nor_gate : out STD_LOGIC; or_gate : out STD_LOGIC; xnor_gate : out STD_LOGIC; xor_gate : out STD_LOGIC ); end gates2; architecture gates2 of gates2 is begin ---- Component instantiations ---and_gate <= b and a; nand_gate <= not(b and a); or_gate <= b or a; nor_gate <= not(b or a); xor_gate <= b xor a; xnor_gate <= not(b xor a); end gates2; The logic diagram in Fig. 2.1 contains six different gates. This logic circuit is described by the VHDL program shown in Listing 2.1. The first line in Listing 2.1 is a comment. Comments in VHDL follow the double dash --. All VHDL programs begin with an entity statement containing the name of the entity (gates2 in this case) followed by a list of all input and output signals together with their direction and type. We will generally use lower case names for signals. The direction of the input and output signals is given by the VHDL statements in, out, or inout (for a bi-directional signal). To describe the output of each gate in Fig. 2.1 we simply write the logic equation for that gate preceded by the assignment operator, <=. These are concurrent assignment statements which means that the statements can be written in any order. 2.2 Simulating the Design gates2.bde Part 4 of the tutorial in Appendix A shows how to simulate this VHDL program using Active-HDL. The simulation produced in Appendix A is shown in Fig. 2.2. Note that the waveforms shown in Fig. 2.2 verify the truth tables for the six gates. Also note that two clock stimulators were used for the inputs a and b. By making the period of the clock stimulator for the input a twice the period of the clock stimulator for the input b all four combinations of the inputs a and b will be generated in one period of the input a. 2-Input Gates 13 Figure 2.2 Simulation of logic circuit in Fig. 2.1 2.3 Generating a Top-Level Design Part 5 of the tutorial in Appendix A shows how to create a top-level design for the gates2 circuit. In order to use the constraint files basys2.ucf or nexys2.ucf described in Example 1 we must name the switch inputs sw(i) and the LED outputs ld(i). This toplevel design, as created in Part 5 of Appendix A is shown in Fig. 2.3. The module gates2 in Fig. 2.3 contains the logic circuit shown in Fig. 2.1. Note that each wire connected to a bus must be labeled to identify its connection to the bus lines. Figure 2.3 Top-level design for Example 2 14 Example 2 Compiling the top-level design shown in Fig. 2.3 will generate the VHDL program shown in Listing 2.2. The inputs are now the two rightmost slide switches, sw(1:0), and the outputs are the six right-most LEDs ld(5:0). To associate these inputs and outputs with the inputs a and b and the six output in the gates2 component in Fig. 2.1 and Listing 2.1 we use the VHDL port map statement U1 : gates2 port map( a => sw(1), b => sw(0), and_gate => ld(5), nand_gate => ld(4), nor_gate => ld(3), or_gate => ld(2), xnor_gate => ld(1), xor_gate => ld(0) ); Listing 2.2 gates2_top.vhd -- Example 2b: gates2_top library IEEE; use IEEE.std_logic_1164.all; library EXAMPLE2; entity gates2_top is port( sw : in STD_LOGIC_VECTOR(1 downto 0); ld : out STD_LOGIC_VECTOR(5 downto 0) ); end gates2_top; architecture gates2_top of gates2_top is component gates2 port ( a : in std_logic; and_gate : out std_logic; b : in std_logic; nand_gate : out std_logic; nor_gate : out std_logic; or_gate : out std_logic; xnor_gate : out std_logic; xor_gate : out std_logic ); end component; begin U1 : gates2 port map( a => sw(1), b => sw(0), and_gate => ld(5), nand_gate => ld(4), nor_gate => ld(3), or_gate => ld(2), xnor_gate => ld(1), xor_gate => ld(0) ); end gates2_top; 2-Input Gates 15 This VHDL port map statement begins with an arbitrary name for the component in the top-level design. Here we call it U1. This is followed by the name of the component being instantiated, in this case gates2 from Listing 2.1. Then using the port map statement enclosed in parentheses are the inputs and outputs from Listing 2.1 associated with corresponding inputs and outputs in the top-level design in Fig. 2.3. Note that we connect the input a in Listing 2.1 to the input sw(1) on the FPGA board. The input b in Listing 2.1 is connected to sw(0) and the outputs and_gate, nand_gate, or_gate, nor_gate, xor_gate, and xnor_gate are connected to the corresponding LED outputs ld(5:0). These associations can be made in this way in any order. The port map statement in Listing 2.2 generated from the top-level block diagram are associated in alphabetical order. Follow the steps in the tutorial in Appendix A and implement this design on the FPGA board. Note that when you change the settings of the two right-most slide switches the LEDs will indicate the outputs of the six gates. 16 Example 3 Example 3 Multiple-Input Gates In this example we will design a circuit containing multiple-input gates. We will create a logic circuit containing 4-input AND, OR, and XOR gates. We will leave it as a problem for you to create a logic circuit containing 4-input NAND, NOR, and XNOR gates. Prerequisite knowledge: Appendix C - Basic Logic Gates Appendix A - Use of Aldec Active-HDL 3.1 Behavior of Multiple-Input Gates The AND, OR, NAND, NOR, XOR, and XNOR gates we x(1) studied in Example 1 had two inputs. The basic definitions hold x(2) z AND for multiple inputs. A multiple-input AND gate is shown in Fig. x(n) 3.1. The output of an AND gate is HIGH only if all inputs are HIGH. To describe this multiple-input AND gate in VHDL we Figure 3.1 could simply write the logic equation as Multiple-input AND gate. . z <= x(1) and x(2) and ... and x(n); x(1) x(2) OR A multiple-input OR gate is shown in Fig. 3.2. The output of an OR gate is LOW only if all inputs are LOW. Just x(n) As with the AND gate we can write the logic equation as Figure 3.2 . Multiple-input OR gate. z z <= x(1) or x(2) or ... or x(n); A multiple-input NAND gate is shown in Fig. 3.3. The output of a NAND gate is LOW only if all inputs are HIGH. We can write the logic equation as . z <= not(x(1) and x(2) and ... and x(n)); x(1) x(2) NAND z x(n) Figure 3.3 Multiple-input NAND gate. . A multiple-input NOR gate is shown in Fig. 3.4. The output of a NOR gate is HIGH only if all inputs are LOW. We can write the logic equation as . z <= not(x(1) or x(2) or ... or x(n)); x(1) x(2) NOR x(n) Figure 3.4 Multiple-input NOR z Multiple-Input Gates A multiple-input XOR gate is shown in Fig. 3.5. What is the meaning of this multiple-input gate? Following the methods we used for the previous multiple-input gates we can write the logic equation as . z <= x(1) xor x(2) xor ... xor x(n); We will create a 4-input XOR gate in this example to determine its meaning but first consider the multiple-input XNOR gate shown in Fig. 3.6. What is the meaning of this multiple-input gate? (See Problem 3.1 at the end of this example for the answer.) Following the methods we used for the previous multiple-input gates we can write the logic equation as . x(1) x(2) x(3) x(4) XOR 17 z Figure 3.5 Multiple-input XOR gate. x(1) x(2) XNOR z x(n) Figure 3.6 Multiple-input XNOR gate. z <= not(x(1) xor x(2) xor ... xor x(n)); or we can use the following gate instantiation statement for an XNOR gate. z <= x(1) xnor x(2) xnor ... xnor x(n); 3.2 Generating the Design File gates4.bde Use the block diagram editor (BDE) in Active-HDL to create the logic circuit called gates4.bde shown in Fig. 3.7. A simulation of this circuit is shown in Fig. 3.8. From this simulation we see that the output of an XOR gate is HIGH only if the number of HIGH inputs is ODD. Figure 3.7 Block diagram for gates4.bde 18 Example 3 If you look at the file gates4.vhd that is generated when you compile gates4.bde you will see that Active-HDL defines separate components for the 4-input AND, OR, and XOR gates and then uses a VHDL instantiation and port map statement to "wire" them together. Alternatively, we could use the HDE editor to write the simpler VHDL program called gates4b.vhd shown in Listing 3.1 that uses standard VHDL logical operators to implement the three 4-input gates. This VHDL program will produce the same simulation as shown in Fig. 3.8. Figure 3.8 Simulation of the design gates4.bde shown in Fig. 3.7 Listing 3.1: gates4b.vhd --Example 3: 4-input gates library IEEE; use IEEE.STD_LOGIC_1164.all; entity gates4b is port( x : in STD_LOGIC_VECTOR(4 downto 1); and4_gate : out STD_LOGIC; or4_gate : out STD_LOGIC; xor4_gate : out STD_LOGIC ); end gates4b; architecture gates4b of gates4b is begin and4_gate <= x(1) and x(2) and x(3) and x(4); or4_gate <= x(1) or x(2) or x(3) or x(4); xor4_gate <= x(1) xnor x(2) xnor x(3) xnor x(4); end gates4; Multiple-Input Gates 19 3.3 Generating the Top-Level Design gates4_top.bde Fig. 3.9 shows the block diagram of the top-level design gates4_top.bde. The module gates4 shown in Fig. 3.9 contains the logic circuit shown in Fig. 3.4. If you compile gates4_top.bde the VHDL program gates4_top shown in Listing 3.2 will be generated. Compile, synthesize, implement, and download this design to the FPGA board. Figure 3.9 Block diagram for the top-level design gates4_top.bde Listing 3.2: gates4_top.v -- Example 2: 4-input gates - top level library IEEE; use IEEE.std_logic_1164.all; library EXAMPLE3; entity gates4_top is port( sw : in std_logic_vector(3 downto 0); ld : out STD_LOGIC_VECTOR(2 downto 0) ); end gates4_top; architecture gates4_top of gates4_top is component gates4 port ( x : in std_logic_vector(3 downto 0); and4_gate : out std_logic; or4_gate : out std_logic; xor4_gate : out std_logic ); end component; begin U1 : gates4 port map( and4_gate => ld(2), or4_gate => ld(1), x => sw, xor4_gate => ld(0) ); end gates4_top; Example 3 20 Problem 3.1 Use the BDE to create a logic circuit containing 4-input NAND, NOR, and XNOR gates. Simulate your design and verify that the output of an XNOR gate is HIGH only if the number of HIGH inputs is EVEN. Create a top-level design that connects the four inputs to the rightmost four slide switches and the three outputs to the three rightmost LEDs. Implement your design and download it to the FPGA board. 3.2 The circuit shown at the right is for a 2 x 4 decoder. Use the BDE to create this circuit and simulate it using Active-HDL. Choose a counter stimulator for x(1:0) that counts every 20 ns, set en to a forced value of 1, and simulate it for 100 ns. Make a truth table with (x(1), x(0)) as the inputs and y(0:3) as the outputs. What is the behavior of this decoder? x[1] x[0] y[0] y[1] y[2] y[3] en Equality Detector 21 Example 4 Equality Detector In this example we will design a 2-bit equality detector using two NAND gates and an AND gate. Prerequisite knowledge: Appendix C - Basic Logic Gates Appendix A - Use of Aldec Active-HDL 4.1 Generating the Design File eqdet2.bde The truth table for a 2-input XNOR gate is shown in Fig. 4.1. Note that the output z is 1 when the inputs x and y are equal. Thus, the XNOR gate can be used as a 1bit equality detector. XNOR x y z z = ~(x ^ y) x y z 0 0 1 1 0 1 0 1 1 0 0 1 Figure 4.1 The XNOR gate is a 1-bit equality detector By using two XNOR gates and an AND gate we can design a 2-bit equality detector as shown in Fig. 4.2. Use the BDE to create the file eqdet2.bde using ActiveHDL. Figure 4.2 Block diagram of a 2-bit equality detector, eqdet2.bde 22 Example 4 If you compile the file eqdet2.bde Active-HDL will generate the VHDL program eqdet2.vhd shown in Listing 4.1. A simulation of eqdet2.bde is shown in Fig. 4.3. Note that the output eq is 1 only if a(1:0) is equal to b(1:0). Listing 4.1: eqdet2.vhd -- Title : eqdet2 library IEEE; use IEEE.std_logic_1164.all; entity eqdet2 is port( a : in STD_LOGIC_VECTOR(1 downto 0); b : in STD_LOGIC_VECTOR(1 downto 0); eq : out STD_LOGIC ); end eqdet2; architecture eqdet2 of eqdet2 is signal eq1 : STD_LOGIC; signal eq2 : STD_LOGIC; begin eq1 <= not(b(1) xor a(1)); eq2 <= not(b(0) xor a(0)); eq <= eq2 and eq1; end eqdet2; Figure 4.3 Simulation of the 2-bit equality detector, eqdet2.bde Create a top-level design called eqdet2_top.bde that connects a(1:0) and b(1:0) to the rightmost four slide switches and connects the output eq to ld(0). Implement your design and download it to the FPGA board. 2-to-1 Multiplexer: if Statement 23 Example 5 2-to-1 Multiplexer: if Statement In this example we will show how to design a 2-to-1 multiplexer and will introduce the VHDL if statement. Section 5.1 will define a multiplexer and derive the logic equations for a 2-to-1 multiplexer. Section 5.2 will illustrate the use of two versions of the VHDL if statement. Prerequisite knowledge: Karnaugh Maps - Appendix D Use of Aldec Active-HDL - Appendix A 5.1 Multiplexers An n-input multiplexer (called a MUX) is an n-way digital switch that switches one of n inputs to the output. A 2-input multiplexer is shown in Fig. 5.1. The switch is controlled by the single control line s. This bit selects one of the two inputs to be "connected" to the output. This means that the logical value of the output y will be the same as the logical value of the selected input. From the truth table in Fig. 5.1 we see that y = a if s = 0 and y = b if s = 1. The Karnaugh map for the truth table in Fig. 5.1 is shown in Fig. 5.2. We see that the logic equation for y is y = ~s & a | s & b (5.1) Note that this logic equation describes the circuit diagram shown in Fig. 5.3. a ab s 00 01 0 1 1 11 10 1 1 1 y = ~s & a | s & b Figure 5.2 K-map for a 2-to-1 multiplexer b 2x1 MUX s y s 0 0 0 0 1 1 1 1 a 0 0 1 1 0 0 1 1 b 0 1 0 1 0 1 0 1 Figure 5.1 A 2-to-1 multiplexer y 0 0 1 1 0 1 0 1 24 Example 5 Use the BDE to create the block diagram mux21.bde shown in Fig. 5.3 that implements logic equation (5.1). Compiling mux21.bde will generate a VHDL file, mux21.vhd, that is equivalent to Listing 5.1. A simulation of mux21.bde is shown in Fig. 5.4. Note in the simulation that y = a if s = 0 and y = b if s = 1. Figure 5.3 Block diagram for a 2-to-1 multiplexer, mux21.bde Listing 5.1 Example5a.vhd -- Example 5a: 2-to-1 MUX using logic equations library IEEE; use IEEE.std_logic_1164.all; entity mux21 is port( a : in STD_LOGIC; b : in STD_LOGIC; s : in STD_LOGIC; y : out STD_LOGIC ); end mux21; architecture mux21 of mux21 is signal aout : STD_LOGIC; signal bout : STD_LOGIC; signal nots : STD_LOGIC; begin aout <= nots and a; bout <= s and b; nots <= not(s); y <= bout or aout; end mux21; 2-to-1 Multiplexer: if Statement 25 Figure 5.4 Simulation of the 2-to-1 MUX in Fig. 5.3 5.2 The VHDL if statement The behavior of the 2 x 1 multiplexer shown in Fig. 5.1 can be described by the VHDL statements if s = '0' then y <= a; else y <= b; We saw that the assignment statements in VHDL using the assignment operator <= are concurrent and execute in parallel. On the other hand the if statement is an example of a procedural, or sequential, statement. Procedural statements must be contained within a process and are executed in the order that they appear in the code. Thus, the VHDL if statement must be contained in a process as shown in Listing 5.2. The process begins with the statement