Digital Design Using Verilog HDL PDF
Digital Design Using Verilog HDL PDF
Digital Design Using Verilog HDL PDF
in JNTU World
Table of Contents
ld
Introduction – Digital Design Using FPGAs 1
Example 1 – Switches and LEDs 6
Example 2 – 2-Input Gates 11
Example 3 – Multiple-Input Gates 15
or
Example 4 – Equality Detector 20
Example 5 – 2-to-1 Multiplexer 22
Example 6 – Quad 2-to-1 Multiplexer 25
Example 7 – 4-to-1 Multiplexer 30
Example 8 – Clocks and Counters 37
Example 9 – 7-Segment Decoder 42
W
Example 10 – 7-Segment Displays: x7seg and x7segb 47
Example 11 – 2's Complement 4-Bit Saturator 55
Example 12 – Full Adder 60
Example 13 – 4-Bit Adder 65
Example 14 – N-Bit Adder 68
Example 15 – N-Bit Comparator 70
Example 16 – Edge-Triggered D Flip-Flop Available only in print vesion
Example 17 – D Flip-Flops in Verilog
TU
iv
ld
Appendix B – Number Systems Available only in print vesion
B.1 Counting in Binary and Hexadecimal
B.2 Positional Notation
B.3 Fractional Numbers
B.4 Number System Conversions
or
B.5 Negative Numbers
ld
or
W
TU
JN
Introduction 1
Introduction
The first integrated circuits that were developed in the early 1960s contained less
ld
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
or
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?
W
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.
TU
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).
JN
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.
ld
CLB CLB
LUT FF LUT FF
or
Slice Slice
LUT FF LUT FF
LUT FF LUT FF
W Slice Slice
LUT FF LUT FF
CLB CLB
IOBs
TU
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
JN
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.
ld
FPGAs
Spartan 5,000 – 40,000 77 – 224 100 – 784 360 – 2,016
Spartan II 15,000 – 200,000 86 – 284 96 – 1,176 642 – 5,556 16,384 – 57,344
Spartan IIE 23,000 – 600,000 182 – 514 384 – 3,456 2,082 – 15,366 32,768 – 294,912
Spartan 3 50,000 – 5,000,000 124 – 784 192 – 8,320 2,280 – 71,264 73,728 – 1,916,928
Spartan-3E 100,000 – 1,600,000 108 – 376 240 – 3,688 1,920 – 29,505 73,728 – 663,552
or
Virtex 57,906 – 1,124,022 180 – 512 384 – 6,144 2,076 – 26,112 32,768 – 131,072
Virtex E 71,693 – 4,074,387 176 – 804 384 – 16,224 1,888 – 66,504 65,536 – 851,968
Virtex-II 40,960 – 8,388,608
W 88 – 1,108 64 – 11,648 1,040 – 99,832 73,728 – 3,096,576
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
JN
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
ld
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
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
W
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.
TU
JN
(a) (b)
1 http://www.aldec.com/education/
2 http://www.xilinx.com
3 http://www.digilentinc.com
4 Digital Design Using Digilent FPGA Boards – Verilog / Active-HDL Edition; available
from www.lbebooks.com.
Introduction 5
Verilog
ld
Verilog is based on the C programming language but it is not C. Verilog is a
hardware description language that is designed to model digital logic circuits. It simply
has the same syntax as the C programming language but the way it behaves is different.
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 Verilog code. The block diagram representing your logic
or
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 Verilog 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 Verilog
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
W
in many of our examples.
Just like any programming language, you can only learn Verilog by actually
writing Verilog programs and simulating the designs using a Verilog simulator that will
display the waveforms of the signals in your design. This is a good way to learn not only
Verilog but digital logic as well.
A companion book5 that uses VHDL instead of Verilog is available from Digilent
or www.lbebooks.com. More comprehensive Verilog and VHDL books are also
available.6,7
TU
JN
5 Introduction to Digital Design Using Digilent FPGA Boards – Block Diagram / VHDL Examples, LBE
Books, 2009.
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
ld
In this example we will show the basic structure of a Verilog 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:
or
None
Learned in this Example:
Use of Aldec Active-HDL – Appendix A
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.
JN
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
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.
ld
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" ;
or
NET "ld<3>" LOC = "p7" ;
NET "ld<2>" LOC = "p8" ;
NET "ld<1>" LOC = "p14" ;
NET "ld<0>" LOC = "p15" ;
8 Example 1
ld
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 7-
segment displays on the BASYS and Nexys-2 boards. Examples 9 and 10 will show how
or
to display hex digits on the 7-segment displays.
Compiling the file sw2led.bde generates the Verilog file sw2led.v shown in
Listing 1.2. Alternatively, by selecting the hardware description editor (HDE) the
module statement and port declarations are automatically generated but you will need to
write your own assign statement. This can lead to the simpler Verilog program shown in
Listing 1.3 where we have combined the module statement and port declarations in a
single module statement that conforms to the 2001 Verilog standard. This format makes
it easier to see the input and output signals. We can also write a single assign statement
to replace the two assign statements in Listing 1.2. It is unnecessary to define the
intermediate bus BUS7[7:0] and because sw and ld are the same size we don't need to
ld
include the [7:0] in the assign statement.
or
// ------------ Port declarations --------- //
input [7:0] sw;
wire [7:0] sw;
output [7:0] ld;
wire [7:0] ld;
endmodule
TU
) ;
assign ld = sw;
endmodule
10 Example 1
ld
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.
or
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
W
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
TU
3.3 V btn(i)
R
2-Input Gates 11
Example 2
2-Input Gates
In this example we will design a circuit containing six different 2-input gates.
ld
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
or
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
W
name of the gate followed by an underscore. Identifier names in Verilog can contain any
letter, digit, underscore _, or $. The identifier can not begin with a digit or be a keyword.
Verilog is case sensitive.
The name of this file is gates2.bde. When you compile this file the Verilog
program gates2.v shown in Listing 2.1 is generated. We have modified the module
statement to conform to the 2001 Verilog standard as described in Example 1.
TU
JN
12 Example 2
ld
) ;
or
assign xnor_ = ~(b ^ a);
endmodule
The logic diagram in Fig. 2.1 contains six different gates. This logic circuit is
described by the Verilog program shown in Listing 2.1. The first line in Listing 2.1 is a
W
comment. Comments in Verilog follow the double slash //. All Verilog programs begin
with a module statement containing the name of the module (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 Verilog statements input, output, or inout (for a bi-directional signal).
The type of the signal can be either wire or reg. In Listing 2.1 all of the signals are of
type wire which you can think of as a wire in the circuit in Fig. 2.1 where actual voltages
TU
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
ld
or
Figure 2.2 Simulation of logic circuit in Fig. 2.1
W
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 top-
level 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
TU
14 Example 2
Compiling the top-level design shown in Fig. 2.3 will generate the Verilog
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 module in Fig. 2.1
and Listing 2.1 we use the Verilog instantiation statement
gates2 U1
( .a(sw[1]),
.and_(ld[5]),
.b(sw[0]),
ld
.nand_(ld[4]),
.nor_(ld[3]),
.or_(ld[2]),
.xnor_(ld[1]),
.xor_(ld[0])
);
or
This Verilog instantiation statement begins with the name of the module being
instantiated, in this case gates2 from Listing 2.1. This is followed by an arbitrary name
for this module in the top-level design. Here we call it U1. Then in parentheses the
inputs and outputs in Listing 2.1 are 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_, nand_, or_, nor_, xor_, and xnor_ are connected to the corresponding LED
outputs ld[5:0].
W
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.
gates2 U1
( .a(sw[1]),
.and_(ld[5]),
.b(sw[0]),
.nand_(ld[4]),
.nor_(ld[3]),
JN
.or_(ld[2]),
.xnor_(ld[1]),
.xor_(ld[0])
);
Multiple-Input Gates 15
Example 3
Multiple-Input Gates
ld
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
or
Appendix A – Use of Aldec Active-HDL
2.19. The output of an AND gate is HIGH only if all inputs are
HIGH. There are three ways we could describe this multiple- Figure 3.1
input AND gate in Verilog. First we could simply write the Multiple-input AND gate.
logic equation as
.
assign z = x[1] & x[2] & ... & x[n]; (3.1)
TU
This produces the same result as the statement (3.1) with much less writing.
Finally, we could use the following gate instantiation statement for an AND gate.
and(z,x[1],x[2],...,x[n]); (3.3)
JN
In this statement the first parameter in the parentheses is the name of the output port.
This is followed by a list of all input signals.
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 as with the AND gate there are
three ways we can describe this multiple-input OR gate in x[1]
Verilog. We can write the logic equation as x[2]
OR z
. x[n]
assign z = x[1] | x[2] | ... | x[n];
Figure 3.2
or we can use the | symbol as a reduction operator by writing Multiple-input OR gate.
assign z = |x;
16 Example 3
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 x[1]
. x[2]
NAND z
assign z = ~(x[1] & x[2] & ... & x[n]);
ld
x[n]
or
nand(z,x[1],x[2],...,x[n]);
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 x[1]
x[2]
. NOR z
W
assign z = ~(x[1] | x[2] | ... | x[n]); x[n]
nor(z,x[1],x[2],...,x[n]);
.
assign z = x[1] ^ x[2] ^ ... ^ x[n]; Figure 3.5
Multiple-input XOR gate.
JN
Multiple-Input Gates 17
example for the answer.) Following the methods we used for the previous multiple-input
gates we can write the logic equation as
.
assign z = ~(x[1] ^ x[2] ^ ... ^ x[n]);
or we can use the following gate instantiation statement for an XOR gate.
ld
xnor(z,x[1],x[2],...,x[n]);
or
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.
W
TU
JN
If you look at the file gates4.v that is generated when you compile gates4.bde you
will see that Active-HDL defines separate modules for the 4-input AND, OR, and XOR
gates and then uses a Verilog instantiation statement to "wire" them together.
Alternatively, we could use the HDE editor to write the simpler Verilog program
called gates4b.v shown in Listing 3.1 that uses reduction operators to implement the
three 4-input gates. This Verilog program will produce the same simulation as shown in
Fig. 3.8.
18 Example 3
ld
Figure 3.8 Simulation of the design gates4.bde shown in Fig. 3.7
or
Listing 3.1: gates4b.v
// Example 2: 4-input gates
module gates4b (
input wire [3:0] x ,
output wire and4_ ,
W
output wire or4_ ,
output wire xor4_
);
endmodule
TU
Multiple-Input Gates 19
gates4 U1
(
.and4_(ld[2]),
ld
.or4_(ld[1]),
.x(sw),
.xor4_(ld[0])
);
endmodule
or
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
W
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. x[1] x[0]
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
y[0]
value of 1, and simulate it for 100 ns. Make a truth
TU
y[3]
en
JN
20 Example 4
Example 4
Equality Detector
In this example we will design a 2-bit equality detector using two NAND gates
ld
and an AND gate.
Prerequisite knowledge:
Appendix C – Basic Logic Gates
Appendix A – Use of Aldec Active-HDL
or
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
1-bit equality detector.
W
XNOR
x y z
x z
0 0 1
y 0 1 0
1 0 0
z = ~(x ^ y) 1 1 1
z = x ~^ y
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 Active-
HDL.
JN
Equality Detector 21
If you compile the file eqdet2.bde Active-HDL will generate the Verilog program
eqdet2.v 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].
ld
output wire eq
) ;
wire eq1;
wire eq2;
or
assign eq2 = ~(b[0] ^ a[0]);
assign eq = eq2 & eq1;
endmodule
W
TU
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.
22 Example 5
Example 5
ld
logic equations for a 2-to-1 multiplexer. Section 5.2 will illustrate the use of two
versions of the Verilog if statement.
Prerequisite knowledge:
Karnaugh Maps – Appendix D
Use of Aldec Active-HDL – Appendix A
or
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
W
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
TU
1 1 0 0
1 1 1 s 1 1 1 1
Figure 5.2
K-map for a 2-to-1 multiplexer
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 Verilog file,
mux21.v, 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.
ld
Figure 5.3 Block diagram for a 2-to-1 multiplexer, mux21.bde
or
Listing 5.1 Example5a.v
// Example 5a: 2-to-1 MUX using logic equations
module mux21a (
input wire a ,
W
input wire b ,
input wire s ,
output wire y
);
endmodule
TU
JN
24 Example 5
The Verilog if statement must be cont ained in an always block as shown in Listing 5.2.
ld
Note that y must be declared to be of type reg because it is assigned a value within the
always block. The notation @(*) in the always statement is equivalent to @(a,b,s) where
a, b, s is called the sensitivity list. Any time any of these input values change the if
statement within the always block is executed. The use of the * notation is a convenience
that prevents you from omitting any of the signals or inputs used in the always block. A
Verilog program can contain more than one always blocks, and these always blocks are
or
executed concurrently. The Verilog code in Listing 5.2 will be compiled to produce the
logic circuit shown in Fig. 5.3. A simulation of the Verilog code in Listing 5.2 will
produce the same waveform as shown in Fig. 5.4.
always @(*)
TU
if(s == 0)
y = a;
else
y = b;
endmodule
Implement your design and download it to the FPGA board. Test the operation of the
multiplexer by changing the position of the toggle switches and pressing pushbutton
btn[0].
Example 6
ld
2-to-1 multiplexer can be designed using a single Verilog if statement. Finally, in
Section 6.3 we will show how to use a Verilog parameter to define a generic 2-to-1
multiplexer with arbitrary bus sizes.
Prerequisite knowledge:
Example 5 – 2-to-1 Multiplexer
or
6.1 Generating the Design File mux42.bde
By using four instances of the 2-to-1 MUX, mux21.bde, that we designed in
Example 5, we can design a quad 2-to-1 multiplexer as shown in Fig. 6.1. Use the BDE
to create the file mux24.bde using Active-HDL. Note that you will need to add the file
W
mux21.bde to your project.
TU
JN
Figure 6.1 The quad 2-to-1 MUX, mux24.bde, contains four 2-to-1 MUXs
26 Example 6
If you compile the file mux24.bde Active-HDL will generate the Verilog program
mux24.v shown in Listing 6.1. A simulation of mux24.bde is shown in Fig. 6.2. Note
that the output y[3:0] will be either a[3:0] or b[3:0] depending on the value of s.
ld
output wire [3:0] y;
) ;
mux21 U1
( .a(a[3]),
.b(b[3]),
.s(s),
or
.y(y[3])
);
mux21 U2
( .a(a[2]),
.b(b[2]),
.s(s),
.y(y[2])
);
mux21 U3
W
( .a(a[1]),
.b(b[1]),
.s(s),
.y(y[1])
);
mux21 U4
TU
( .a(a[0]),
.b(b[0]),
.s(s),
.y(y[0])
);
endmodule
JN
Use the BDE to create the top-level design called mux21_top.bde shown in Fig.
6.3. Note that a[3:0] are connected to the four leftmost slide switches, b[3:0] are
connected to the rightmost four slide switches, and y[3:0] are connected to the rightmost
LEDs. Also note that s is connected to btn[0], and the input btn[0:0] must be declared as
an array, even though there is only one element, so that we can use the constraint file
basys2.ucf or nexys2.ucf without change. Implement your design and download it to the
FPGA board. Test the operation of the quad 2-to-1 multiplexer by setting the switch
values and pressing pushbutton btn[0].
If you compile the file mux24_top.bde Active-HDL will generate the Verilog
ld
program mux24_top.v shown in Listing 6.2. A simulation of mux24_top.bde is shown in
Fig. 6.4.
or
Figure 6.3 Top-level design for testing the quad 2-to-1 MUX
W
Listing 6.2 Example6b.v
// Example 6b: mux24_top
module mux24_top (
input wire [0:0] btn;
input wire [7:0] sw;
output wire [3:0] ld;
) ;
TU
mux24 U1
( .a(sw[7:4]),
.b(sw[3:0]),
.s(btn[0]),
.y(ld)
);
endmodule
JN
28 Example 6
ld
Listing 6.3 mux24b.v
// Example 6c: Quad 2-to-1 mux using if statement
module mux24b(
input wire [3:0] a,
input wire [3:0] b,
input wire s,
or
output reg [3:0] y
);
always @(*)
if(s == 0)
y = a;
else
y = b;
W
endmodule
multiplexer with input and output bus widths of arbitrary size. Listing 6.4 shows a
Verilog program for a generic 2-to-1 MUX.
Note the use of the parameter statement that defines the bus width N to have a
default value of 4. This value can be overridden when the multiplexer is instantiated as
shown in Listing 6.5 for an 8-line 2-to-1 multiplexer called M8. The parameter override
clause is automatically included in the module instantiation statement when you copy it
in Active-HDL as shown in Listing 6.5. We will always use upper-case names for
parameters. The simulation of Listing 6.5 is shown in Fig. 6.5.
JN
If you compile the Verilog program mux2g.v shown in Listing 6.4 it will generate
a block diagram for this module when you go to BDE. If you right-click on the symbol
for mux2g and select Properties, you can change the default value of the parameter N by
selecting the Parameters tab and entering an actual value for N.
always @(*)
ld
if(s == 0)
y = a;
else
y = b;
endmodule
or
Listing 6.5 mux28.v
// Example 6e: 8-line 2-to-1 MUX using a parameter
module mux28(
input wire [7:0] a,
input wire [7:0] b,
input wire s,
W
output wire [7:0] y
);
mux2g #(
.N(8))
M8 (.a(a),
.b(b),
.s(s),
.y(y)
TU
);
endmodule
JN
Figure 6.5 Simulation result from the Verilog program in Listing 6.5
30 Example 7
Example 7
4-to-1 Multiplexer
In this example we will show how to design a 4-to-1 multiplexer. In Section 7.1
we will make a 4-to-1 multiplexer by wiring together three of the 2-to-1 multiplexers that
we designed in Example 5. In Section 7.2 we will derive the logic equation for a 4-to-1
ld
MUX. In Section 7.3 we will show how a 4-to-1 multiplexer can be designed using a
single Verilog case statement and in Section 7.4 we design a quad 4-to-1 multiplexer.
Prerequisite knowledge:
Example 5 – 2-to-1 Multiplexer
or
7.1 Designing a 4-to-1 MUX Using 2-to-1 Modules
Figure 7.2 The 4-to-1 MUX, mux41.bde, contains four 2-to-1 MUXs
4-to-1 Multiplexer 31
In Fig. 7.2 when s[1] = 0 it is v, the output of U2 that gets through to z. If s[0] = 0
in U2 then it is c[0] that gets through to v and therefore to z. If s[0] = 1 in U2 then it is
c[1] that gets through to v and therefore to z.
If, on the other hand, s[1] = 1 in U1 then it is w, the output of U3 that gets through
to z. If s[0] = 0 in U3 then it is c[2] that gets through to w and therefore to z. If s[0] = 1
in U3 then it is c[3] that gets through to w and therefore to z. Thus you can see that the
circuit in Fig. 7.2 will implement the truth table in Fig. 7.1.
When you compile the file mux41.bde Active-HDL will generate the Verilog
program mux41.v shown in Listing 7.1. A simulation of mux41.bde is shown in Fig. 7.3.
ld
Note that the output z will be one of the four inputs c[3:0] depending on the value of
s[1:0].
or
input wire [3:0] c ,
input wire [1:0] s ,
output wire z
);
// Internal signals
wire v; // output of mux M1
wire w; // output of mux M2
W
// Module instantiations
mux21 U1
( .a(v),
.b(w),
.s(s[1]),
.y(z)
);
TU
mux21 U2
( .a(c[0]),
.b(c[1]),
.s(s[0]),
.y(v)
);
mux21 U3
( .a(c[2]),
.b(c[3]),
.s(s[0]),
JN
.y(w)
);
endmodule
If you were going to create this top-level design using HDE instead of BDE you
would begin by defining the inputs c[3:0] and s[1:0] and the output z and the two wires v
and w. You would then “wire” the three modules together using the three module
instantiation statements shown in Listing 7.1.
The easiest way to generate this module instantiation statement is to first compile
the file mux21.v from Example 5 using Active-HDL, expand the library icon (click the
32 Example 7
plus sign), right click on mux21, and select Copy Verilog Instantiation as shown in Fig.
7.4. Paste this into your top-level mux41.v file.
ld
or
Figure 7.3 Simulation of the Verilog program in Listing 7.1
W
TU
JN
4-to-1 Multiplexer 33
Make three copies of this prototype and change the name of Label1 to U1, U2,
and U3 in the three statements. Now you just “wire up” each input and output variable
by changing the values in the parentheses to the signal that it is connected to. For
ld
example, the mux U1 input a is connected to the wire v so we would write .a(v). In a
similar way the mux input b is connected to wire w and the mux input s is connected to
input s[1]. The mux output y is connected to the output z in Fig. 7.2. Thus, the final
version of this module instantiation statement would be
mux21 U1 (.a(v),
or
.b(w]),
.s(s[1]),
.y(z)
);
The other two modules, U2 and U3, are “wired up” using similar module
instantiation statements.
W
7.2 The Logic Equation for a 4-to-1 MUX
The 4-to-1 MUX designed in Fig. 7.2 can be represented by the logic symbol
shown in Fig. 7.5. This multiplexer acts like a digital switch in which one of the inputs
c[3:0] gets connected to the output z. The switch is controlled by the two control lines
s[1:0]. The two bits on these control lines select one of the four inputs to be "connected"
TU
to the output. Note that we constructed this 4-to-1 multiplexer using three 2-to-1
multiplexers in a tree fashion as shown in Fig. 7.2.
JN
Recall from Eq. (5.1) in Example 5 that the logic equation for a 2-to-1 MUX is
given by
34 Example 7
Applying this equation to the three 2-to-1 MUXs in Fig. 7.2 we can write the
equations for that 4 x 1 MUX as follows.
v = ~s0 & c0 | s0 & c1
z = ~s1 & (~s0 & c0 | s0 & c1) | s1 & (~s0 & c2 | s0 & c3)
ld
or
z = ~s1 & ~s0 & c0
| ~s1 & s0 & c1 (7.2)
| s1 & ~s0 & c2
| s1 & s0 & c3
or
Equation (7.2) for z also follows from the truth table in Fig. 7.1. Note that the
tree structure in Fig. 7.2 can be expanded to implement an 8-to-1 multiplexer and a 16-to-
1 multiplexer.
A Verilog program that implements a 4-to-1 MUX using the logic equation (7.2)
is given in Listing 7.2. A simulation of this program will produce the same result as in
Fig. 7.3 (without the wire signals v and w).
W
Listing 7.2 mux41b.v
// Example 7b: 4-to-1 MUX using logic equation
module mux41b (
input wire [3:0] c ,
input wire [1:0] s ,
output wire z
);
TU
endmodule
The same 4-to-1 multiplexer defined by the Verilog program in Listing 7.2 can be
implemented using a Verilog case statement. The Verilog program shown in Listing 7.3
does this. The case statement in Listing 7.3 directly implements the definition of a 4-to-1
MUX given by the truth table in Fig. 7.1. The case statement is an example of a
procedural statement that must be within an always block. A typical line in the case
statement, such as
2: z = c[2];
4-to-1 Multiplexer 35
will assign the value of c[2] to the output z when the input value s[1:0] is equal to 2
(binary 10). Note that the output z must be of type reg because its value is assigned
within an always clause.
In the case statement the alternative value preceding the colon in each line
represents the value of the case parameter, in this case the 2-bit input s. These values are
decimal values by default. If you want to write a hex value you precede the number with
‘h as in ‘hA which is a hex value A. Similarly, a binary number is preceded with a ‘b as
in ‘b1010 which has the same value (10) as ‘hA. Normally, binary numbers are preceded
with the number of bits in the number such as 4’b107. Using this notation, the number
ld
8’b110011 will be the binary number 00110011.
or
output reg z
);
always @(*)
case(s)
0: z = c[0];
1: z = c[1];
2: z = c[2];
W 3: z = c[3];
default: z = c[0];
endcase
endmodule
All case statements should include a default line as shown in Listing 7.3. This is
because all cases need to be covered and while it looks as if we covered all cases in
TU
Listing 7.3, Verilog actually defines four possible values for each bit, namely 0 (logic
value 0), 1 (logic value 1), Z (high impedance), and X (unkown value).
A simulation of the program in Listing 7.3 will produce the same result as in Fig.
7.3 (without the wire signals v and w).
36 Example 7
always @(*)
ld
case(s)
0: z = x[3:0];
1: z = x[7:4];
2: z = x[11:8];
3: z = x[15:12];
default: z = x[3:0];
endcase
or
endmodule
W
TU
Example 8
ld
examples in this book will assume an input clock frequency of 50 MHz. If you are using
the BASYS board you should remove the clock jumper, which will set the clock
frequency to 50 MHz. This 50 MHz clock signal is a square wave with a period of 20 ns.
The FPGA pin associated with this clock signal is defined in the constraints file
basys2.ucf or nexys2.ucf with the name mclk.
In this example we will show how to design an N-bit counter in Verilog and how
or
to use a counter to generate clock signals of lower frequencies.
Prerequisite knowledge:
Appendix A – Use of Aldec Active-HDL
The Verilog program shown in Listing 8.1 was used to generate the symbol
shown in Fig. 8.1. Note that the sensitivity list of the always statement contains the
phrase
posedge clk or posedge clr
This means that the if statement within the always block will execute whenever either clr
or clk goes high. If clr goes high then the output q[N-1:0] will go to zero. On the other
hand if clr = 0 and clk goes high then the output q[N-1:0] will be incremented by 1.
The default value of the parameter N in Listing 8.1 is 4. A simulation of this 4-bit
counter is shown in Fig. 8.2. Note that this counter counts from 0 to F and then wraps
38 Example 8
around to 0. To instantiate an 8-bit counter from Listing 8.1 that would count from 0 –
255 (or 00 – FF hex) you would use an instantiation statement something like
counter #(
.N(8))
cnt16 (.clr(clr),
.clk(clk),
.q(q)
);
You can also set the value of the parameter N from the block diagram editor (BDE) by
ld
right-clicking on the symbol in Fig. 8.1 and selecting Properties and then the Parameters
tab.
or
#(parameter N = 4)
(input wire clr ,
input wire clk ,
output reg [N-1:0] q
);
// N-bit counter
always @(posedge clk or posedge clr)
begin
W
if(clr == 1)
q <= 0;
else
q <= q + 1;
end
endmodule
TU
JN
In the simulation in Fig. 8.2 note that the output q[0] is a square wave at half the
frequency of the input clk. Similarly, the output q[1] is a square wave at half the
frequency of the input q[0], the output q[2] is a square wave at half the frequency of the
input q[1], and the output q[3] is a square wave at half the frequency of the input q[2].
Note how the binary numbers q[3:0] in Fig. 8.2 count from 0000 to 1111.
The simulation shown in Fig. 8.2 shows how we can obtain a lower clock
frequency by simply using one of the outputs q[i]. We will use this feature to produce a
24-bit clock divider in the next section.
ld
8.2 Clock Divider
The simulation in Fig. 8.2 shows that the outputs q[i] of a counter are square
waves where the output q[0] has a frequency half of the clock frequency, the output q[1]
has a frequency half of q[0], etc. Thus, a counter can be used to divide the frequency f of
or
a clock, where the frequency of the output q(i) is fi = f 2i +1 . The frequencies and
periods of the outputs of a 24-bit counter driven by a 50 MHz clock are shown in Table
8.1. Note in Table 8.1 that the output q[0] has a frequency of 25 MHz, the output q[17]
has a frequency of 190.73 Hz, and the output q[23] has a frequency of 2.98 Hz.
W Table 8.1 Clock divide frequencies
q[i] Frequency (Hz) Period (ms)
i 50000000.00 0.00002
0 25000000.00 0.00004
1 12500000.00 0.00008
2 6250000.00 0.00016
3 3125000.00 0.00032
4 1562500.00 0.00064
TU
5 781250.00 0.00128
6 390625.00 0.00256
7 195312.50 0.00512
8 97656.25 0.01024
9 48828.13 0.02048
10 24414.06 0.04096
11 12207.03 0.08192
12 6103.52 0.16384
JN
13 3051.76 0.32768
14 1525.88 0.65536
15 762.94 1.31072
16 381.47 2.62144
17 190.73 5.24288
18 95.37 10.48576
19 47.68 20.97152
20 23.84 41.94304
21 11.92 83.88608
22 5.96 167.77216
23 2.98 335.54432
40 Example 8
The Verilog program shown in Listing 8.2 is a 24-bit counter that has three
outputs, a 25 MHz clock (clk25), a 190 Hz clock (clk190), and a 3 Hz clock (clk3). You
can modify this clkdiv module to produce any output frequency given in Table 8.1. We
will use such a clock divider module in many of our top-level designs.
ld
input wire clk ,
input wire clr ,
output wire clk190 ,
output wire clk25 ,
output wire clk3
);
reg [23:0] q;
or
// 24-bit counter
always @(posedge clk or posedge clr)
begin
if(clr == 1)
q <= 0;
else
q <= q + 1;
end
W
assign clk190 = q[17]; // 190 Hz
assign clk25 = q[0]; // 25 MHz
assign clk3 = q[23]; // 3 Hz
endmodule
TU
Note in Listing 8.2 that we define the internal signal q[23:0] of type reg. It must
be of type reg because its value is assigned within an always block. The BDE symbol
generated by compiling Listing 8.2 is shown in Fig. 8.3. You can edit either Listing 8.2
or the block diagram shown in Fig. 8.3 to bring out only the clock frequencies you need
in a particular design. For example, the top-level design shown in Fig. 8.4 will cause the
eight LEDs on the FPGA board to count in binary at a rate of about three counts per
second. The corresponding top-level Verilog program is shown in Listing 8.3.
JN
ld
Figure 8.4 Counting in binary on the eight LEDs
or
Listing 8.3 count8_top.v
// Example 8c: count8_top
module count8_top (
input wire mclk;
input wire [3:3] btn;
output wire [7:0] ld;
) ;
wire clk3;
W
clkdiv U1
( .clk3(clk3),
.clr(btn[3]),
.mclk(mclk)
);
TU
counter
#( .N(8))
U2
( .clk(clk3),
.clr(btn[3]),
.q(ld[7:0])
);
endmodule
JN
42 Example 9
Example 9
7-Segment Decoder
In this section we will show how to design a 7-segment decoder using Karnaugh
maps and write a Verilog program to implement the resulting logic equations. We will
ld
also solve the same problem using a Verilog case statement.
Prerequisite knowledge:
Karnaugh maps – Appendix D
case statement – Example 7
LEDs – Example 1
or
9.1 7-Segment Displays
Seven LEDs can be arranged in a pattern to form different digits as shown in Fig.
9.1. Digital watches use similar 7-segment displays using liquid crystals rather than
LEDs. The red digits on digital clocks are LEDs. Seven segment displays come in two
W
flavors: common anode and common cathode. A common anode 7-segment display has
all of the anodes tied together while a common cathode 7-segment display has all the
cathodes tied together as shown in Fig. 9.1.
+3.3V
a
TU
Common
Anode
f b
a b c d e f g
g
a b c d e f g
e c
Common
Cathode
JN
Figure 9.1 A 7-segment display contains seven light emitting diodes (LEDs)
The BASYS and Nexys2 boards have four common-anode 7-segment displays.
This means that all the anodes are tied together and connected through a pnp transistor to
+3.3V. A different FPGA output pin is connected through a 100Ω current-limiting
resistor to each of the cathodes, a – g, plus the decimal point. In the common-anode case,
an output 0 will turn on a segment and an output 1 will turn it off. The table shown in
7-Segment Decoder 43
Fig. 9.2 shows output cathode values for each segment a – g needed to display all hex
values from 0 – F.
x a b c d e f g
0 0 0 0 0 0 0 1 a
1 1 0 0 1 1 1 1
2 0 0 1 0 0 1 0
3 0 0 0 0 1 1 0 1 = off f b
ld
4 1 0 0 1 1 0 0
5 0 1 0 0 1 0 0 0 = on g
6 0 1 0 0 0 0 0
7 0 0 0 1 1 1 1
8 0 0 0 0 0 0 0 e c
9 0 0 0 0 1 0 0
A 0 0 0 1 0 0 0
or
b 1 1 0 0 0 0 0
C 0 1 1 0 0 0 1 d
d 1 0 0 0 0 1 0
E 0 1 1 0 0 0 0
F 0 1 1 1 0 0 0
e = ~x3 & x0 | ~x3 & x2 & ~x1 | ~x2 & ~x1 & x0
JN
x1 x0
x3 x2 00 01 11 10
00 1 1
~x3 & x0
01 1 1 1
11
~x3 & x2 & ~x1
10 1
44 Example 9
You can write the Karnaugh maps for the other six segments and then write the
Verilog program for the 7-segment decoder shown in Listing 9.1. A simulation of this
program is shown in Fig. 9.5. Note that the simulation agrees with the truth table in Fig.
9.2.
ld
output wire [6:0] a_to_g
);
or
assign a_to_g[5] = x[2] & x[1] & ~x[0] // b
| x[3] & x[1] & x[0]
| ~x[3] & x[2] & ~x[1] & x[0]
| x[3] & x[2] & ~x[1] & ~x[0];
assign a_to_g[4] = ~x[3] & ~x[2] & x[1] & ~x[0] // c
| x[3] & x[2] & x[1]
| x[3] & x[2] & ~x[0];
assign a_to_g[3] = ~x[3] & ~x[2] & ~x[1] & x[0] // d
W
| ~x[3] & x[2] & ~x[1] & ~x[0]
| x[3] & ~x[2] & x[1] & ~x[0]
| x[2] & x[1] & x[0];
assign a_to_g[2] = ~x[3] & x[0] // e
| ~x[3] & x[2] & ~x[1]
| ~x[2] & ~x[1] & x[0];
assign a_to_g[1] = ~x[3] & ~x[2] & x[0] // f
| ~x[3] & ~x[2] & x[1]
| ~x[3] & x[1] & x[0]
| x[3] & x[2] & ~x[1] & x[0];
TU
7-Segment Decoder 45
ld
3: a_to_g = 7'b0000110;
will assign the 7-bit binary value, 0000110, to the 7-bit array, a_to_g, when the input
hex value x[3:0] is equal to 3 (0011). In the array a_to_g the value a_to_g[6]
corresponds to segment a and the value a_to_g[0] corresponds to segment g. Recall that
in Verilog a string of binary bits is preceded by n’b, where n is the number of binary bits
in the string.
or
In the case statement the value preceding the colon in each line represents the
value of the case parameter, in this case the 4-bit input x. Also note that hex values such
as A are written as ‘hA.
Recall that all case statements should include a default line as shown in Listing
9.2. This is because all cases need to be covered and while it looks as if we covered all
cases in Listing 6.2, Verilog actually defines four possible values for each bit, namely 0
W
(logic value 0), 1 (logic value 1), Z (high impedance), and X (unkown value).
A simulation of Listing 9.2 will produce the same results as shown in Fig. 9.5. It
should be clear from this example that using the Verilog case statement is often easier
than solving for the logic equations using Karnaugh maps.
To test the 7-segment displays on the FPGA board you could create the design
hex7seg_top.bde shown in Fig. 9.6. This design uses the Verilog program hex7seg.v
from Listing 9.2 and produces a top-level Verilog program hex7seg_top.v equivalent to
Listing 9.3. Each of the four digits on the 7-segment display is enabled by one of the
TU
active low signals an[3:0] and all digits share the same a_to_g[6:0] signals. If an[3:0] =
0000 then all digits are enabled and display the same hex digit. This is what we do in
Fig. 9.6 and Listing 9.3. Making the output dp = 1 will cause the decimal points to be
off. You should be able to display all of the hex digits from 0 – F by changing the four
rightmost switches.
JN
46 Example 9
always @(*)
case(x)
0: a_to_g = 7'b0000001;
ld
1: a_to_g = 7'b1001111;
2: a_to_g = 7'b0010010;
3: a_to_g = 7'b0000110;
4: a_to_g = 7'b1001100;
5: a_to_g = 7'b0100100;
6: a_to_g = 7'b0100000;
7: a_to_g = 7'b0001111;
or
8: a_to_g = 7'b0000000;
9: a_to_g = 7'b0000100;
'hA: a_to_g = 7'b0001000;
'hb: a_to_g = 7'b1100000;
'hC: a_to_g = 7'b0110001;
'hd: a_to_g = 7'b1000010;
'hE: a_to_g = 7'b0110000;
'hF: a_to_g = 7'b0111000;
endcase
W
default: a_to_g = 7'b0000001; // 0
endmodule
module hex7seg_top (
input wire [3:0] sw ,
output wire [6:0] a_to_g ,
output wire [3:0] an ,
output wire dp
);
hex7seg D4 (.x(sw),
.a_to_g(a_to_g)
);
endmodule
Example 10
7-Segment Displays:
x7seg and x7segb
ld
In this example we will show how to display different hex values on the four 7-
segment displays.
Prerequisite knowledge:
Karnaugh maps – Appendix D
case statement – Example 7
or
LEDs – Example 1
if the control signal s[1:0] is 00 then x[3:0] becomes the input to the hex7seg module and
the value of x[3:0] will be displayed on digit 0. Similarly if you press btn[1] and the
control signal s[1:0] is 01 then x[7:4] becomes the input to the hex7seg module and the
value of x[7:4] will be displayed on digit 1. We can make the value of s[1:0] depend on
the value of btn[3:0] using the truth table in Fig. 10.1. From this truth table we can write
the following logic equations for s[1] and s[0].
The two OR gates in Fig. 10.2 will implement these logic equations for s[1:0].
48 Example 10
ld
or
Figure 10.2 BDE circuit mux7seg.bde for multiplexing the four 7-segment displays
module mux7seg (
input wire [3:0] btn,
output wire [6:0] a_to_g,
output wire [3:0] an
);
assign x = 'h1234;
hex7seg U1
( .a_to_g(a_to_g), .x(digit));
mux44 U2
( .s(s), .x(x), .z(digit));
endmodule
ld
of the outputs an[3:0] must be synchronized with s[1:0] so as to enable the proper digit at
the proper time. A circuit for doing this is shown in Fig. 10.3. The outputs an[3:0] will
satisfy the truth table in Fig. 10.4. Note that each output an[i] is just the maxterm M[i] of
q[1:0].
or
W
TU
Figure 10.3 BDE circuit x7seg.bde for displaying x[15:0] on the four 7-segment displays
1 1 0 1 1 1
Figure 10.4 Truth table for generating an[3:0] in Fig. 10.3
A simulation of x7seg.bde is shown in Fig. 10.5. Note how the an[3:0] output
selects one digit at a time to display the value 1234 on the 7-segment displays. When
x7seg.bde is compiled it creates a Verilog program that is equivalent to Listing 10.2. The
top-level design shown in Fig. 10.6 can be used to test the x7seg module on the FPGA
board. The Verilog program corresponding to this top-level design is given in Listing
10.3. Note that the x7seg module requires a 190 Hz clock generated by the clock divider
module clkdiv from Example 8.
50 Example 10
ld
or
Figure 10.5 Simulation of the x7segb.bde circuit in Fig. 10.3
wire nq1;
wire [3:0] digit;
wire [1:0] q;
assign nq1 = ~(q[1]);
assign nq0 = ~(q[0]);
assign an[0] = q[0] | q[1];
assign an[1] = nq0 | q[1];
assign an[2] = q[0] | nq1;
assign an[3] = nq0 | nq1;
JN
hex7seg U1
( .a_to_g(a_to_g),.x(digit));
mux44 U2
( .s({q[1:0]}),.x(x),.z(digit));
counter
#( .N(2)) U3
( .clk(cclk),.clr(clr),.q(q[1:0]));
endmodule
ld
Figure 10.6 Top-level design for testing x7seg
or
Listing 10.3 x7seg_top.v
// Example 10c: x7seg_top
module x7seg_top (
input wire mclk,
input wire [3:3] btn,
output wire dp,
output wire [6:0] a_to_g,
W
output wire [3:0] an
);
wire clk190;
wire [15:0] x;
assign x = 'h1234;
assign dp = 1;
TU
clkdiv U1
( .clk190(clk190),
.clr(btn[3]),
.mclk(mclk)
);
x7seg U3
( .a_to_g(a_to_g),
.an(an),
.cclk(clk190),
.clr(btn[3]),
JN
.x(x)
);
endmodule
52 Example 10
called x7segb, that displays leading zeros as blanks is shown in Listing 10.4. This is
done by writing logic equations for aen[3:0] that depend on the values of x[15:0]. For
example, aen[3] will be 1 (and thus digit 3 will not be blank) if any one of the top four
bits of x[15:0] is 1. Similarly, aen[2] will be 1 if any one of the top eight bits of x[15:0]
is 1, and aen[1] will be 1 if any one of the top twelve bits of x[15:0] is 1. Note that
aen[0] is always 1 so that digit 1 will always be displayed even if it is zero.
To test the module x7segb you can run the top-level design shown in Listing 10.4
that will display the value of x on the 7-segment displays where x is defined by the
following statement:
ld
assign x = {sw,btn[2:0],5'b01010}; // digit 0 = A
The curly brackets {--,--} are used for concatenation in Verilog. In this case we form the
16-bit value of x by concatenating the eight switches, the three right-most pushbuttons,
and the five bits 01010. Note that if all switches are off an A will be displayed on digit 0
or
with three leading blanks. Turning on the switches and pushing the three right-most
pushbuttons will display various hex numbers – always with leading blanks.
reg [1:0] s;
reg [3:0] digit;
wire [3:0] aen;
assign dp = 1;
// set aen[3:0] for leading blanks
assign aen[3] = x[15] | x[14] | x[13] | x[12];
assign aen[2] = x[15] | x[14] | x[13] | x[12]
| x[11] | x[10] | x[9] | x[8];
assign aen[1] = x[15] | x[14] | x[13] | x[12]
JN
ld
6: a_to_g = 7'b0100000;
7: a_to_g = 7'b0001111;
8: a_to_g = 7'b0000000;
9: a_to_g = 7'b0000100;
'hA: a_to_g = 7'b0001000;
'hb: a_to_g = 7'b1100000;
'hC: a_to_g = 7'b0110001;
or
'hd: a_to_g = 7'b1000010;
'hE: a_to_g = 7'b0110000;
'hF: a_to_g = 7'b0111000;
default: a_to_g = 7'b0000001; // 0
endcase
// Digit select
always @(*)
W
begin
an = 4'b1111;
if(aen[s] == 1)
an[s] = 0;
end
// 2-bit counter
always @(posedge cclk or posedge clr)
begin
if(clr == 1)
TU
s <= 0;
else
s <= s + 1;
end
endmodule
JN
54 Example 10
ld
);
wire [15:0] x;
x7segb X2 (.x(x),
or
.clk(clk),
.clr(btn[3]),
.a_to_g(a_to_g),
.an(an),
.dp(dp)
);
endmodule
W
TU
JN
Example 11
ld
Prerequisite knowledge:
Basic Gates – Appendix C
Equality Detector – Example 6
Quad 2-to-1 Multiplexer – Example 6
7-Segment Displays – Example 10
or
11.1 Creating the Design sat4bit.bde
Figure 11.1 shows a circuit called sat4bit.bde that was described in the November
2001 issue of NASA Tech Briefs. The circuit will take a 6-bit two’s complement number
W
with a signed value between –32 and +31 and convert it to a 4-bit two’s complement
number with a signed value between –8 and +7. Negative input values less than –8 will
be saturated at –8. Positive input values greater than +7 will be saturated at +7.
Note that the two XNOR gates and the AND gate form an equality detector whose
output s is 1 when x[3], x[4], and x[5] are all equal (see Example 4). This will be the case
when the 6-bit input number x[5:0] is between -8 and +7. In this case output y[3:0] of the
quad 2-to-1 MUX will be connected to the input x[3:0]. If the top three bits of x[5:0] are
not equal and x[5] is 1 then the input value will be less than -8 and the output y[3:0] of
TU
the quad 2-to-1 MUX will be saturated at -8. On the other hand if the top three bits of
x[5:0] are not equal and x[5] is 0 then the input value will be greater than +7 and the
output y[3:0] of the quad 2-to-1 MUX will be saturated at +7.
JN
56 Example 11
wire c0;
wire c1;
s;
ld
wire
wire xi;
or
mux24 U1
( .a({x[5],xi,xi,xi}),
.b(x[3:0]),
.s(s),
.y(y)
);
endmodule
W
A top-level design that can be used to test sat4bit is shown in Fig. 11.2. The
module x7segb11 is a modification of Listing 10.4 that will display only values between
-8 and +7 on the 7-segment display. Listing 11.2 shows the Verilog program for the
module x7segb11. The input to x7segb11 is the 4-bit output y[3:0] from sat4bit. Note
that only the two rightmost 7-segment display are enabled. The two leftmost displays are
TU
always blank. The hex7seg always block in Listing 11.2 has been modified to display the
magnitude of the signed value of y[3:0] – 0 to 8. The preceding 7-segment display will
either be blank or display a minus sign. The quad 4-to-1 MUX and the new 2-to-1 MUX
are used to display the minus sign when aen[1] is enabled if y[3] is 1; i.e., if y is negative.
JN
ld
reg msel;
reg [6:0] a_g0;
wire [6:0] a_g1;
reg [1:0] s;
reg [3:0] digit;
wire [3:0] aen;
or
assign a_g1 = 7'b1111110; // minus sign
assign dp = 1;
assign aen[3] = 0; // digit 3 always off
assign aen[2] = 0; // digit 2 always off
assign aen[1] = y[3]; // digit 1 on if negative
assign aen[0] = 1; // digit 0 always on
7: a_g0 = 7'b0001111;
8: a_g0 = 7'b0000000; // -8
9: a_g0 = 7'b0001111; // -7
'hA: a_g0 = 7'b0100000; // -6
'hb: a_g0 = 7'b0100100; // -5
'hC: a_g0 = 7'b1001100; // -4
'hd: a_g0 = 7'b0000110; // -3
'hE: a_g0 = 7'b0010010; // -2
'hF: a_g0 = 7'b1001111; // -1
default: a_g0 = 7'b0000001; // 0
endcase
58 Example 11
// Digit select
ld
always @(*)
begin
an = 4'b1111;
if(aen[s] == 1)
an[s] = 0;
end
or
// 2-bit counter
always @(posedge cclk or posedge clr)
begin
if(clr == 1)
s <= 0;
else
s <= s + 1;
end
endmodule
W
The Verilog program corresponding to the top-level design in Fig. 11.2 is given in
Listing 11.3. Download this top-level design to the FPGA board and observe the output
on the 7-segment display for different 6-bit switch inputs.
TU
JN
ld
output wire [5:0] ld
);
wire clk190;
wire [3:0] y;
assign ld = sw;
or
sat4bit U1
( .x(sw),
.y(y)
);
x7segb11 U2
( .a_to_g(a_to_g),
.an(an),
W
.cclk(clk190),
.clr(btn[3]),
.dp(dp),
.y(y)
);
clkdiv U3
( .clk190(clk190),
.clr(btn[3]),
TU
.mclk(mclk)
);
endmodule
JN
60 Example 12
Example 12
Full Adder
In this example we will design a full adder circuit.
ld
Prerequisite knowledge:
Basic Gates – Appendix C
Karnaugh Maps – Appendix D
7-Segment Displays – Example 10
or
12.1 Half Adder
The truth table for a half adder is shown in Fig. 12.1. In this table bit a is added
to bit b to produce the sum bit s and the carry bit c. Note that if you add 1 to 1 you get 2,
which in binary is 10 or 0 with a carry bit. The BDE logic diagram, halfadd.bde, for a
half adder is also shown in Fig. 12.1. Note that the sum s is just the exclusive-or of a and
b and the carry c is just a & b. The Verilog program corresponding to the circuit in Fig.
W
12.1 is shown in Listing 12.1. A simulation of halfadd.bde is shown in Fig. 12.2.
a b s c
0 0 0 0
0 1 1 0
1 0 1 0
TU
1 1 0 1
Figure 12.1 Truth table and logic diagram halfadd.bde for a half-adder
assign s = b ^ a;
assign c = b & a;
endmodule
Full Adder 61
ld
Figure 12.2 Simulation of the half-adder in Fig. 12.1
or
12.2 Full Adder
When adding binary numbers we need to consider the carry from one bit to the
next. Thus, at any bit position we will be adding three bits: ai, bi and the carry-in ci from
W
the addition of the two bits to the right of the current bit position. The sum of these three
bits will produce a sum bit, si, and a carry-out, ci+1, which will
be the carry-in to the next bit position to the left. This is called a c a b s c
i i i i i+1
full adder and its truth table is shown in Fig. 12.3. The results of
the first seven rows in this truth table can be inferred from the 0 0 0 0 0
0 0 1 1 0
truth table for the half adder given in Fig. 12.1. In all of these 0 1 0 1 0
rows only two 1's are ever added together. The last row in Fig. 0 1 1 0 1
12.3 adds three 1's. The result is 3, which in binary is 11, or 1 1 0 0 1 0
TU
plus a carry. 1 0 1 0 1
From the truth table in Fig. 12.3 we can write a sum of 1 1 0 0 1
products expression for si as 1 1 1 1 1
We can use the distributive law to factor out ~ci from the first two product terms and ci
from the last two product terms in Eq. (12.1) to obtain
62 Example 12
Fig. 12.4 shows the K-map for ci+1 from the truth table in Fig. 12.3. The map
shown in Fig. 12.4a leads to the reduced form for ci+1 given by
While this is the reduced form, a more convenient form can be written from Fig. 12.4b as
follows:
ld
ci+1 = ai & bi | ci & ~ai & bi | ci & ai & ~bi
= ai & bi | ci & (~ai & bi | ai & ~bi)
= ai & bi | ci & (ai ^ bi) (12.6)
bi bi
a ib i a ib i
00 01 11 10 00 01 11 10
or
ci ci
0 1 0 1
1 1 1 1 ci 1 1 1 1 ci
ai ai
W (a) (b)
Figure 12.4 K-maps for ci+1 for full adder in Fig. 6.2
From Eqs. (12.4) and (12.6) we can draw the logic diagram for a full adder as shown in
Fig. 12.5. Comparing this diagram to that for a half adder in Fig. 12.1 it is clear that a
full adder can be made from two half adders plus an OR gate as shown in Fig. 12.6.
TU
ci
ai si
bi
c i+1
ci s
si
ai s c
half-adder
c c i+1
bi half-adder
Figure 12.6 A full adder can be made from two half adders plus an OR gate
Full Adder 63
From Fig. 12.6 we can create a BDE design, fulladd.bde, as shown in Fig. 12.7.
The Verilog program resulting from compiling this design is equivalent to that shown in
Listing 12.2. A simulation of this full adder is shown in Fig. 12.8. Note that the outputs
agree with the truth table in Fig. 12.3.
ld
or
Figure 12.7 Block diagram fulladd.bde for a full adder
wire c1;
wire c2;
TU
wire s1;
halfadd U1
( .a(a),
.b(b),
.c(c1),
.s(s1)
);
JN
halfadd U2
( .a(s1),
.b(cin),
.c(c2),
.s(s)
);
endmodule
64 Example 12
ld
or
Figure 12.8 Simulation of the full adder in Fig. 12.7 and Listing 12.2
W
TU
JN
4-Bit Adder 65
Example 13
4-Bit Adder
In this example we will design a 4-bit adder.
ld
Prerequisite knowledge:
Basic Gates – Appendix C
Karnaugh Maps – Appendix D
Full Adder – Example 12
or
13.1 4-Bit Adder
Four of the full adders in Fig. 12.7 can be combined to form a 4-bit adder as
shown in Fig. 13.1. Note that the full adder for the least significant bit will have a carry-
in of zero while the remaining bits get their carry-in from the carry-out of the previous
bit. The final carry-out, is the cout for the 4-bit addition. The Verilog program
corresponding to the 4-bit adder in Fig. 13.1 is given in Listing 13.1.
W
TU
JN
66 Example 13
ld
wire c1;
wire c2;
wire c3;
fulladd U1
( .a(a[2]),
.b(b[2]),
or
.cin(c2),
.cout(c3),
.s(s[2])
);
fulladd U2
( .a(a[3]),
.b(b[3]),
.cin(c3),
W
.cout(cout),
.s(s[3])
);
fulladd U3
( .a(a[1]),
.b(b[1]),
.cin(c1),
.cout(c2),
TU
.s(s[1])
);
fulladd U4
( .a(a[0]),
.b(b[0]),
.cin(cin),
.cout(c1),
.s(s[0])
);
JN
endmodule
A simulation of the 4-bit adder in Fig. 13.1 and Listing 13.1 is shown in Fig. 13.2.
The value of a is incremented from 0 to F and is added to the hex value B. The sum s is
always equal to a + b. Note that the carry flag, cout, is equal to 1 when the correct
unsigned answer exceeds 15 (or F).
We can test the adder4 module from Fig. 13.1 and Listing 13.1 on the FPGA
board by combining it with the x7segb module from Listing 10.4 in Example 10 and the
clkdiv module from Listing 8.2 from Example 8 to produce the top-level design shown in
Listing 13.2. The 4-bit number sw[7:4] will be displayed on the first (left-most) 7-
4-Bit Adder 67
segment display. The 4-bit number sw[3:0] will be displayed on the second 7-segment
display. These two numbers will be added and the 4-bit sum will be displayed on the
fourth (right-most) 7-segment display and the carry bit will be displayed on the third 7-
segment display. Try it.
ld
or
Figure 13.2 Simulation of the 4-bit adder in Fig. 13.1 and Listing 13.1
W
Listing 13.2 adder4_top.v
// Example 13b: adder4_top
module adder4_top (
input wire mclk ,
input wire [3:3] btn ,
input wire [7:0] sw ,
output wire [6:0] a_to_g ,
output wire [3:0] an ,
TU
output wire dp ,
output wire [7:0] ld
);
assign cin = 0;
assign x = {sw,3'b000,c4,sum};
JN
adder4 U1 (.cin(cin),.a(sw[7:4]),.b(sw[3:0]),
.cout(c4),.s(sum));
clkdiv U2 (.mclk(mclk),.clr(clr),.clk190(clk190));
x7segb U3 (.x(x),.cclk(clk190),.clr(clr),
.a_to_g(a_to_g),.an(an),.dp(dp));
endmodule
68 Example 14
Example 14
N-Bit Adder
In this example we will design a N-bit adder.
Prerequisite knowledge:
ld
4-Bit Adder – Example 13
or
program the compiler will produce a full adder of the type we designed in Example 12.
The only question is how to create the output carry bit. The trick is to add a leading 0 to
a and b and then make a 5-bit temporary variable to hold the sum as shown in Listing
14.1. The most-significant bit of this 5-bit sum will be the carry flag.
A simulation of this program is shown in Fig. 14.1. Compare this with Fig. 13.2.
W
Listing 14.1 adder4b.v
// Example 14a: 4-bit behavioral adder
module adder4b (
input wire [3:0] a ,
input wire [3:0] b ,
output reg [3:0] s ,
output reg cf
);
reg [4:0] temp;
TU
always @(*)
begin
temp = {1'b0,a} + {1'b0,b};
s = temp[3:0];
cf = temp[4];
end
endmodule
JN
N-Bit Adder 69
ld
module adder
#(parameter N = 8)
(input wire [N-1:0] a,
input wire [N-1:0] b,
output reg [N-1:0] y
);
or
always @(*)
begin
y = a + b;
end
endmodule
W
TU
The top-level design shown in Fig. 14.3 can be used to test this N-bit adder on the
FPGA board. In this case we are adding two 4-bit switch settings and observing the sum
on the 7-segment display. To set the parameter N to 4 right-click on the adder symbol,
select Properties and click on the Parameter tab. Set the actual value of N to 4.
JN
Figure 14.3 Top-level design for testing the N-bit adder on the FPGA board
70 Example 15
Example 15
N-Bit Comparator
In this example we will design a N-bit comparator.
ld
Prerequisite knowledge:
N-Bit Adder – Example 14
or
logical operators shown in Table 15.1. An example of using these to implement an N-bit
comparator is shown in Listing 15.1. A simulation of this program for the default value
of N = 8 is shown in Fig. 15.1.
Note in the always block in Listing 15.1 we set the values of gt, eq, and lt to zero
before the if statements. This is important to make sure that each output has a value
assigned to it. If you don’t do this then Verilog will assume you don’t want the value to
W
change and will include a latch in your system. Your circuit will then not be a
combinational circuit.
N-Bit Comparator 71
ld
always @(*)
begin
gt = 0;
eq = 0;
lt = 0;
if(x > y)
gt = 1;
or
if(x == y)
eq = 1;
if(x < y)
lt = 1;
end
endmodule
W
You can test this comparator on the FPGA board by creating the BDE block
diagram comp4_top.bde shown in Fig. 15.2. To make this a 4-bit comparator right-click
on the comp symbol, select Properties, click on the Parameters tab, and set the actual
value of N to 4. You will be comparing the 4-bit number x[3:0] on the left four switches
with the 4-bit number y[3:0] on the right four switches. The three LEDs ld[4:2] will
TU
detect the outputs gt, eq, and lt. We selected these three LEDs because on the BASYS
board they are three different colors. Compile the design comp4_top.bde, implement it,
and download the .bit file to the FPGA board. Test the comparator by changing the
switch settings.
JN
72 Example 15
ld
or
W
TU
JN
Appendix A
ld
Select Create new workspace and click OK.
or
W
TU
Browse to the directory where you want the project saved, type Example1 for the
workspace name and click OK.
JN
110 Appendix A
Select Create an Empty Design with Design Flow and click Next.
ld
or
Click Flow Settings
W
TU
Select Xilinx
ISE/WebPack 8.1 XST VHDL/Verilog
JN
Press Select
Select Implementation
ld
or
Choose Xilinx
ISE/WebPack 8.1
Press Select
W
TU
Click Ok
112 Appendix A
ld
Click Next
or
W
and click Next.
TU
Click Finish.
JN
Click on BDE.
ld
or
Click Next.
W
TU
Select Verilog
JN
114 Appendix A
Type sw2led
and click Next.
ld
Click New.
or Type sw
W Set array
indexes to 7:0
TU
Type ld
Click New.
Set array
indexes to 7:0
JN
Click out.
Click Finish.
This will generate a block diagram (schematic) template with the input and output ports
displayed.
ld
You will need to select the output port by dragging the mouse with
the left mouse button down and move the output port to the left.
or
W
Select the bus icon and connect the input sw[7:0] to the output ld[7:0] as shown.
TU
Click Save
JN
116 Appendix A
Right-click on sw2led.bde
and select Compile
ld
or
W
Part 3: Synthesis and Implementation
Click
synthesis options
JN
ld
Check Verilog
BASYS Board:
Select 3s100etq144 for Device from pull down list.
or
Nexys2 Board:
Select 3s500efg320 for Device from pull down list.
Click Ok.
W
Click synthesis
TU
JN
118 Appendix A
Click implementation
options
ld
or
W
Select
TU
ld
Shift for more options…. Select BitStream and
uncheck Do Not Run Bitgen.
or
W
TU
Click Ok
120 Appendix A
Click
implementation
ld
or
W
When implementation is complete click Close.
To program the Spartan3E on the BASYS or Nexys-2 boards we will use the
ExPort tool that is part of the the Adept Suite available free from Digilent at
TU
http://www.digilentinc.com/Software/Adept.cfm?Nav1=Software&Nav2=Adept
Double-click the ExPort icon on the desktop.
ld
or
Your program is now running on the board. Change the switches and watch the LEDs.
W
TU
JN
122 Appendix A
Click on BDE.
ld
or
Click Next. W
TU
JN
Select Verilog
and Click Next
Type gates2
and click Next.
ld
Click New.
or Type a.
W
TU
Click New.
Type b.
JN
124 Appendix A
Click New.
Type and_.
Click out.
ld
or
Continue to click New and add the outputs nand_, or_, nor_, xor_, and xnor_.
W
TU
JN
Click Finish.
This will generate a block diagram (schematic) template with the input and output ports
displayed.
ld
or
W
Select the output ports by dragging the mouse with the left
mouse button down and move the output ports to the left.
Click + on
Built-in symbols
JN
126 Appendix A
Grab the and2 symbol with the mouse and drag it to the output port and_
ld
or
W
Grab the symbols for nand2, or2, nor2, xor2, and xnor2 and drag them to the
appropriate output port, moving the output ports down as necessary.
TU
JN
Select the wire icon and connect the gate inputs to a and b as shown.
ld
Click Save
or
W
TU
Right-click on gates2.bde
and select Compile
JN
128 Appendix A
Part 6: Simulation
ld
Select gates2.bde
Click > and Click OK
or
Click here to select
design files W
Click Choose, select gates2 as the top-level design, and click Add.
TU
Click OK
JN
ld
or
Click OK
130 Appendix A
The waveform window will automatically come up with the simulation already
initialized. Make sure the order is a, b, and_, nand_, or_, nor_, xor_, xnor (grab and
drag if necessary). Right-click on a and select Stimulators.
ld
or
W
Select Clock and set Frequency to 25 MHz
TU
JN
Click Apply
ld
Click Apply
Click Close
or
W Set simulation time to 200 ns
Click here to run simulation
TU
JN
132 Appendix A
Click on HDE.
Select Verilog
and Click OK.
ld
or
Click Next. W
TU
Type gates2
and click Next.
JN
ld
or
Click New.
Type b.
W
TU
Click New.
Type z.
JN
Click out.
Click Finish.
134 Appendix A
This will generate a Verilog template with the input and output signals filled in. Delete
all the comments and replace them with the single comment
// Example 1: 2-input gates
ld
Delete these
statements.
or
W
Edit the module, input, output, and wire statements to conform to the 2001 Verilog
standard as shown (see Listing 2.1 in Example 1).
TU
Delete these
comments.
JN
2
Click Save
1
Type in these six
assign statements
3 (see Listing 2.1 of
ld
Example 1)
Click on + and then
Right-click on
gates2.v and select
Compile
or
W
Click design flow and then Click functional simulation options
TU
Select gates2.v,
JN
136 Appendix A
Click Choose, select gates2 as the top-level design, and click Add.
ld
Click Ok
or
W
Click Use Default Waveform
TU
JN
Click Ok
ld
The waveform window will automatically come up with the simulation already
initialized. Make sure the order is a, b, z (grab and drag if necessary).
or
Right-click on a and select Stimulators.
W
TU
JN
138 Appendix A
ld
or
Click Apply
W
Click on b, select Clock and set Frequency to 50 MHz
TU
JN
Click Apply
Click Close
ld
or
W
Click + sign to show all elements of z.
Study the waveforms for various magnifications.
To print out this waveform you can detach it by clicking >> here and then
press Alt Prnt Scrn to copy it to the clipboard. Then paste it in a .doc file and print.
TU
JN
Appendix E
ld
1 = logic value 1
z or Z = high impedance
x or X = unknown value
Numbers d = decimal 35 (default decimal)
b = binary 4‘b1001
h = hexadecimal 8’a5 = 8’b10100101
o = octal
or
Parameters Associates an identifer name with a value that #(parameter N = 8)
can be overridden with the defparam statement
Local parameters Associates an identifer name with a constant that localparam [1:0] s0 = 2’b00,
cannot be directly overridden s1 = 2’b01, s2 = 2’b10;
Nets and Variables wire (used to connect one logic element to wire [3:0] d;
Types another) wire led;
reg (variables assigned values in always block) reg [7:0] q;
integer (useful for loop control variables) integer k;
Module
W
module module_name module register
#(parameter N = 8)
[#(parameter_port_list)] (input wire load ,
(port_dir_type_name,{ port_dir_type_name } input wire clk ,
); input wire clr ,
[wire declarations] input wire [N-1:0] d ,
output reg [N-1:0] q
[reg declarations] );
[assign assignments]
[always blocks] always @(posedge clk or posedge clr)
if(clr == 1)
TU
q <= 0;
endmodule else if(load)
q <= d;
endmodule
Logic operators ~ (NOT) assign z = ~y;
& (AND) assign c = a & b;
| (OR) assign z = x | y;
~(&) (NAND) assign w = ~(u & v);
~(|) (NOR) assign r = ~(s | t);
^ (XOR) assign z = x ^ y;
~^ (XNOR assign d = a ~^ b;
JN
ld
if statement if(expression1) if(s == 0)
begin y = a;
statement; else
end y = b;
else if (expression2)
begin
statement;
or
end
else
begin
statement;
end
case statement case(expression) case(s)
alternative1: begin 0: y = a;
statement; 1: y = b;
W end 2: y = c;
alternative2: begin 3: y = d;
statement; default: y = a;
end endcase
[default: begin
statement;
end
endcase
for loop for(initial_index; terminal_index; increment)
TU