Phillip Stanley-Marbell
Foundations of
Embedded Systems
Physical Constraints, Sensor Uncertainty, Error Propagation,
Low-Level C on RISC-V, and Open-Source FPGA Tools
Draft Version of Michaelmas 2020
6
Digital Logic Design and Verilog
Figure 6.1: Programmable
logic devices provide a
mechanism to implement
computation by multiplex-
ing hardware resources in
space rather than in time.
Debugging is like alien abduction. Large blocks of time disappear, for
which you have no explanation.
Unknown source.
This chapter will explore a range of methods for using the state of signals
in hardware to achieve computation, including:
Specifying a digital logic circuit to implement the computational task, us-
2 phillip stanley-marbell
ing only primitive gates such as nand gates, not gates, and wires.
Describing the computational task, using some formal machine-readable
specification language, in terms of the desired behavior (referred to as
behavioral modeling) and having tools convert that behavioral specification
into primitive gates such as nand gates, not gates, and wires.
Describing the computational task, using some formal machine-readable
specification language, in terms of the structure rather than the behav-
ior, (referred to as structural modeling) and having tools convert that struc-
tural specification into primitive gates such as nand gates, not gates, and
wires.
6.1 Intended Learning Outcomes
By the end of this chapter, you should be able to:
1. Read and write hardware descriptions in the Verilog hardware description
language.
2. Master the basics of the Verilog syntax (modules, wires, types, ‘include,
etc.).
3. Design hardware in Verilog at the transistor, gate / hard IP, or behavioral
levels of abstraction.
4. Use electronic design automation (EDA) tools such as Yosys, Iverilog, Vvp,
and GTKWave to simulate your Verilog design.
5. Implement and test designs (D-type flip flop and 1 Hz LED blinker) in
multiple Verilog design styles.
6. Identify some different methods to use circuits to achieve computation.
7. Enumerate differences between a programmable processor and programmable
logic.
8. Enumerate the differences between PALs, PLAs/CPLDs, and FPGAs.
6.1.1 Learning outcomes pre-assessment
Complete the following
quiz to evaluate your prior knowledge of the material
for this chapter.
6.1.2 Things to think about
Complete the following
thinking exercise to stimulate your thoughts about
the contents of this chapter before proceeding with the material.
foundations of embedded systems 3
6.1.3 Things to look out for
Concepts people sometimes get confused by in this chapter include:
1. The difference between programming languages and hardware descrip-
tion languages.
2. The difference between configuring an FPGA (with a configuration bit-
stream comprising LUT configurations and a wiring configuration) and
programming a microcontroller (with a binary containing a sequence of
instructions).
3. The concept of programming a microcontroller that is in turn implemented
with an FPGA configuration bitstream.
6.1.4 The muddiest point
As you go through the material in this chapter, think about the following two
questions and note your responses for yourself or using the annotation tools
of the online version of the chapter. You will have the opportunity to submit
your responses to these questions at the end of the chapter:
1. What is least c lear to you in this chapter? (You can simply list the section
numbers or write a few words.)
2. What is most clear to you in this chapter? (You can simply list the section
numbers or write a few words.)
6.2 From Logic Gates to Processors
Chapter
5 introduced the concept of different methods for achieving digi-
tal computation. Given different computation tasks, the methods introduced
in Chapter
5 range from implementing each computation directly using a
collection of logic gates (often referred to as custom logic), to using a collec-
tion of logic gates to implement a fixed design such as a microprocessor and
then using different sequences of instructions for the processor to implement
different target applications. This chapter explores the approach of imple-
menting computation directly using digital logic. Broadly speaking, while
microprocessors multiplex digital logic in time to achieve computation, the
approach this chapter describes multiplexes digital logic in space.
The running example of a computational task which this Chapter will use,
will be the computational task of toggling a signal (connected to an LED).
The state of signals in hardware that define this task are the state of the LED.
4 phillip stanley-marbell
6.2.1 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding some basic ter-
minology from computer architecture which recurs in this chapter and later
in this course.
6.3 Digital hardware designs
Digital designs are invariably constructed from a collection of interconnected
modules. We will design digital hardware to achieve a given computational
task using modules to implement pieces of functionality. Figure
6.2 shows a
module with N inputs (labeled in1 to inN) on its left, and M outputs (labeled
out1 to outM) on its right.
Figure 6.2: Digital hard-
ware designs often use
modules to structure a
computational task.
The modules might be purely combinational, where inputs appear at out-
puts after the time taken for signals to propagate. The modules might also
contain both combinational and sequential logic (which contain state elements
such as clocked flip flops and unclocked latches).
Traditionally, all 1-bit (bi-stable) sequential digital circuit elements were
called flip flops. Today, however, the general convention is to refer to sequen-
tial elements that are clocked as flip flops and to those that are level-sensitive
as latches. When enabled, latches behave like combinational logic: changes in
their input are visible at their outputs after a propagation delay of the latch’s
internal circuitry. The term latch is also sometimes used to refer to a multi-bit
level-sensitive sequential element (e.g., pipeline latches); when such multi-bit
elements are clocked, they are usually referred to as registers. In this chap-
ter, we are concerned primarily with flip flops and latches in the context
of FPGAs. FPGAs generally contain lookup tables (LUTs) for implementing
generic combinational logic, and D-type flip flops. When your Verilog design
requires a latch in order to be implemented in hardware therefore, the syn-
thesis tools must use multiple LUTs (with feedback loops) to emulate each of
the gates in a latch.
6.4 Programmable Logic Devices
Programmable logic devices (PLDs) implement different digital logic circuits by
wiring together a collection of generic digital logic primitives such as and
gates, or gates, not gates, or coarser-grained digital logic structures such as
foundations of embedded systems 5
elements that implement an arbitrary truth table. Some people misinterpret
the term programmable in the context of PLDs: the term programmable in this
context means configurable (e.g., configurable choices of the wiring between
digital logic primitives). In that sense, you don’t really program a PLD in the
same way you program a microprocessor. Rather, you configure a PLD with a
choice of connections of the component inside it. You can however use a PLD
to implement a microprocessor: Appendix
E presents a hands-on project to
implement a RISC-V processor using a small-footprint programmable logic
device (the iCE40 FPGA).
6.4.1 PALs
The earliest programmable logic devices were one-time mask-programmable,
not reprogrammable. One of the earliest reprogrammable logic array devices
was the Altera EP300, introduced by Altera in 1984.
PAL devices consist of a programmable and array and fixed or array.
Each design is broken up into macrocells, where each macrocell is a sum of
products. The product terms of the sum of products make up the and array
of the PAL. In a typical PAL, any of the macrocell’s inputs or its logical com-
plement can be routed to any and gate in the and array and all the outputs
of the and gates in the and array of each macrocell are summed by the PAL
in a single or gate for each macrocell. The output of the or gate of each
macrocell can usually optionally be routed through a flip flop. Configuring a
PAL IC determines which of the IC’s input signals (or their complement) are
connected to which inputs of the and array and whether the output of the
or of each macrocell is routed to a flip flop, and so on.
Although they have a constrained internal structure (signals go through
and array, followed by or gate, then flip flop) PALs are a good match for
designs that are mostly combinational logic.
6.4.2 PLAs
PLAs, like PALs, have a programmable (i.e., configurable) and array. Unlike
PALs which have a fixed or array, PLAs usually have a configurable or
array and the PLA configuration determines which product ter m outputs get
routed into which or gates to generate the output of each macrocell.
6.4.3 FPGAs
Both PALs and PLAs/CPLDs have few sequential logic elements and do not
scale to large designs. Field-programmable gate arrays (FPGAs) are a fur-
ther evolution of PLDs beyond PALs and PLAs. Rather than employing con-
6 phillip stanley-marbell
figurable sum-of-product macrocells with configurable and and or planes
which feed into flip flops, FPGAs consist of fine-grained configurable lookup
tables (LUTs) which feed into flip flops. Each pair of LUT and flip flop is
typically referred to as a logic cell (LC). Configuring an n-input FPGA LUT
specifies the complete truth table for the LUT, permitting the LUT to be con-
figured to any n-input logic function. The LUTs in FPGAs typically have
a small number of inputs: For example, the iCE40 FPGA (Section
6.5) uses
4-input LUTs, permitting each input to the flip flops to be configured to be
any 4-input logic function. In many FPGA architectures, logic cells are fur-
ther grouped into collections, named programmable logic blocks (PLBs) on the
iCE40 (Section
6.5).
FPGAs almost always require an additional static random-access memory
(SRAM) IC to store their configurations, in contrast to most PALs, PLAs,
and CPLDs, which store configuration information within the IC itself. The
Lattice iCE40 FPGA, which Section
6.5 introduces, is thus uncommon in hav-
ing the ability to store configuration data directly in the FPGA, albeit in a
one-time-programmable memory. This is partly possible since the iCE40 is
specifically targeted at resource-constrained embedded systems and thus has
a smaller number of LUTs (fewer than 10 000), fewer than most FPGAs which
are targeted at high-performance computing systems and contain millions of
LUTs.
6.4.4 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding of PLAs, PALs,
FPGAs, and the iCE40 FPGA.
6.5 The Lattice iCE40 Low-Power Field-Programmable Gate Arrays
The iCE40 FPGA from Lattice Semiconductor is an IC with up to two SPI in-
terfaces, up to two I2C interfaces, and (depending on the variant) a few thou-
sand 4-input lookup tables and D-type flip flops, approximately 20 config-
urable I/O buffers, and differential amplifiers, which you can wire together
in any topology of your choosing. The iCE40 contains fixed-functionality
hardware elements that you can wire together with your configured digital
logic. Such fixed-functionality hardware elements in FPGAs are usually re-
ferred to as intellectual property blocks (IP blocks). The iCE40 contains IP blocks
for 8- and 16-bit multipliers and adders, buffers conforming to several differ-
ent I/O standards, and IP blocks that implement the functionality of the I2C,
I3C, and SPI serial I/O communication protocols.
Although you can in principle implement memories by wiring together
the flip flops in an FPGA, doing so would consume a large number of flip
foundations of embedded systems 7
flops. Most FPGAs therefore provide a number of fixed-function memory
elements. The iCE40 Ultra Plus, the variant of the iCE40 FPGA used in the
design project of Appendix
E, provides two kinds of fixed-function memory
elements: dual-port embedded block RAMs which have separate read and write
ports and single-port RAMs (SPRAMs).
6.5.1 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding of the differ-
ent methods to use circuits to achieve computation, the differences between
a programmable processor and programmable logic, and the differences be-
tween PALs, PLAs/CPLDs, and FPGAs.
6.6 Hardware Description Languages (HDLs)
Hardware description languages (HDLs) are human-readable notations for
describing the functionality of circuits. Although HDLs are most commonly
for describing digital logic, there are also a few HDLs for describing analog
circuits. The very high speed integrated circuit (VHSIC) hardware description lan-
guage (VHDL) is one example of a hardware description language which you
might have encountered previously. This chapter will use Verilog as the HDL.
You might already be familiar with another HDL such as VHDL. Knowing
one more HDL will make you a more versatile engineer: Many engineers and
researchers use both Verilog and VHDL. And, at the time of writing, the only
available completely-open-source FPGA tools only support Verilog.
6.6.1 The Verilog Hardware Description Language
Section
6.3 introduced the concept of structuring a hardware design into a
collection of interconnected modules. Every Verilog design has one module
called the toplevel which connects together the rest of the design
1
.
1
The yosys tool (Ap-
pendix
F) assumes the last
Verilog file in its arguments
is the toplevel.
6.6.2 Verilog syntax
Verilog uses C-style comments. The definition of a hardware module begins
with the keyword module, followed by the module name, and followed by a
list of identifiers in parenthesis. These identifiers in parenthesis are called the
ports list:
1 /
*
2
*
Verilog uses C-style comments
3
*
/
4 module simple(
5 /
*
6
*
The identifiers listed here are known
8 phillip stanley-marbell
7
*
as the "ports" of the Verilog module
8
*
and this part of the module (in parenthesis)
9
*
is known as the "port list".
10
*
11
*
We will follow a number of conventions
12
*
for the stylistic layout of Verilog code.
13
*
You can find the list of conventions here:
14
*
15
*
github.com/physical-computation/conventions/README-RTLCodingConvention.md
16
*
/
17 inSignal,
18 outSignal
19 );
20 /
*
21
*
The first component in the module is typically the input/output (I/O) declarations.
22
*
/
23 input inSignal;
24 output outSignal;
25
26 /
*
27
*
And finally the module’s implementation.
28
*
/
29 assign outSignal = inSignal;
30 endmodule
In the module simple of the example above, the ports are two signals,
inSignal and outSignal. The first component of a module is its I/O decla-
rations. These specify which of the ports are inputs and which are outputs.
The I/O declarations are typically followed by wire and register definitions.
In the example above, there are no additional wires or registers in the design
and the module I/O declarations are followed immediately by the module
implementation. In the example, the module simply connects its output to
its input.
An alternative more compact syntax for module definition is to merge the
I/O definitions with the ports list:
1 /
*
2
*
Verilog uses C-style comments
3
*
/
4 module simple(
5 /
*
6
*
The identifiers listed here are known
7
*
as the "ports" of the Verilog module
8
*
and this part of the module (in parenthesis)
9
*
is known as the "port list".
10
*
11
*
We will follow a number of conventions
12
*
for the stylistic layout of Verilog code.
13
*
You can find the list of conventions here:
14
*
15
*
github.com/physical-computation/conventions/README-RTLCodingConvention.md
16
*
/
17 input inSignal,
18 output outSignal
19 );
foundations of embedded systems 9
20
21 /
*
22
*
And finally the module’s implementation.
23
*
/
24 assign outSignal = inSignal;
25 endmodule
In the example above, the Verilog description states directly in the ports
list that inSignal is an input and that outSignal is an output. The body of
the module is just the implementation, which again, in this simple example,
simply connects the input with the output.
6.6.3 Instantiating modules
Verilog allows a design to be structured by using previously-defined modules
within other modules. Creating an instance of one module within another
module in Verilog is referred to as instantiating a module.
A module instantiation statement comprises the type of the module being
instantiated, followed by the name to be assigned to the instance, and fol-
lowed by the parameters of the module being instantiated. For example, the
following statement creates an instance of a native Verilog module type for a
nand gate, with the instance name nand0:
nand nand0 (net1, D, net0);
In the case of the nand module, the parameters are the output signal fol-
lowed by the input signals. There is a more failsafe method of assigning the
parameters that does not depend on the order, which we will refer to as “dot
notation”. Later sections of this chapter with larger examples will introduce
dot notation.
6.6.4 Logic values in Verilog
Signals in Verilog can take on one of four values: 0, 1, Z, and X. The logic
values 0 and 1 are the eponymous Boolean logic values (logic low and logic
high, respectively). The logic value Z is a high-impedance or floating value
(synonymous with ? in Verilog) and X is a logical don’t-care.
Verilog makes it easy to express constants in any radix. The notation is
simple: the number of bits that the value occupies followed by a tick character
() and then followed by a character denoting the radix or base (b for binary,
h for hexadecimal, and so on), followed in turn by a number in the given
radix. So, for example, a 1-bit binary number with value 0 is 1’b0, an 8-
bit binary constant with value 20 is 8’b00010100, and an 8-bit hexadecimal
constant with value 255 is notated as 8’hff. If a notated constant does not
include the word length, tick, and base, Verilog tools assume the constant is
in base 10.
10 phillip stanley-marbell
6.6.5 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding of Verilog syn-
tax, signal values in Verilog, and instantiating modules in Verilog.
6.6.6 Declaring wires, registers, and memories
In addition to gates or modules and constants, designs inevitably require
wires and registers. The syntax for a 1-bit wire is the keyword wire followed
by the wire name. An 8-bit wire or bus is named wireName is notated using
the syntax:
wire [7:0] wireName;
The specifier [7:0] is a notational convention: It is semantically equivalent to
[1:8] or [8:1] or [0:7]. The Verilog tools simply look at [index1:index2]
and allocate a width of size abs (index1 index2) + 1.
The syntax for a 1-bit register is:
reg someRegister;
Similarly, a design can declare a multi-bit register, as in this example of an
8-bit register:
reg [7:0] someRegister;
And we can have arrays of registers that is, memories. The syntax for declar-
ing a memory is:
reg [7:0] someMemory[0:31];
The example above declares a 32-byte memory. When a Verilog design is
synthesized for an FPGA target, memories declared in this way will typically
be synthesized to embedded block RAMs (if possible and if the target FPGA
has available block RAMs) and will otherwise be synthesized to flip flops.
6.6.7 Operators in Verilog
Hardware designs invariably need to perform operations on signals in a
given module. The three primary classes of operators in Verilog are bitwise
infix operators, logical infix operators, and unary reduction operators.
The bitwise operators are bitwise not (~), bitwise and (&), bitwise or (|),
and bitwise xor i.e., exclusive or (^). A Verilog design can apply these op-
erators to single bits or to multi-bit buses. The logical operators are logical
not (!), logical and (&&), and logical or (||). Unary reduction operators in
Verilog apply an operation across all the bits of a multi-bit signal. The unary
reduction operators are unary and reduction (&), unary nand reduction (~&),
unary or reduction (|), unary nor reduction (~|), unary xor reduction (^),
foundations of embedded systems 11
and unary xnor reduction (~^). For example, the following statement com-
putes the parity of a multi-bit signal:
assign parity = ^result[31:0];
6.6.8 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding of the material
on Verilog operators.
6.6.9 ‘include, ‘define, ‘ifdef, ‘else, ‘endif, and Verilog hygiene
The statement
‘include "path/to/file"
textually substitutes the contents of the file at the specified path into the
current file at the position of the ‘include statement. The statement
‘define macroName macroValue
defines a macro named macroName with value macroValue. One example from
the RISC-V processor design project in Appendix
E is
‘define kRV32I
_
INSTRUCTION
_
OPCODE
_
LUI 7’b0110111
Once a macro is defined, a Verilog design can use the macro (i.e., macro
expansion) by prefixing the macro name with a . For example, the follow-
ing snippet from the RISC-V processor design project implementation (Ap-
pendix E) uses the macro defined in the last example above:
case (Opcode)
/
*
*
LUI, U-Type
*
/
‘kRV32I
_
INSTRUCTION
_
OPCODE
_
LUI:
Verilog also allows a design to conditionally activate a collection of state-
ments in the design based on the value of a condition (e.g., a previously-
defined macro constant):
‘ifdef conditionA
blockA
‘else
blockB
‘endif
The example above conditionally compiles blockA if conditionA is true, oth-
erwise compiles blockB .
12 phillip stanley-marbell
6.6.10 Tools for debugging: Testbenches, iverilog, and gtkwave
A testbench is a test harnesses to test a Verilog design. The contents of a
testbench are statements that will not be translated into the final hardware
design, but which provide test stimuli or input to test a design and which
collect or monitor signals in a design for subsequent analysis and debugging.
Recall the example from Section
6.6.2:
1 /
*
2
*
Verilog uses C-style comments
3
*
/
4 module simple(
5 /
*
6
*
The identifiers listed here are known
7
*
as the "ports" of the Verilog module
8
*
and this part of the module (in parenthesis)
9
*
is known as the "port list".
10
*
11
*
We will follow a number of conventions
12
*
for the stylistic layout of Verilog code.
13
*
You can find the list of conventions here:
14
*
15
*
github.com/physical-computation/conventions/README-RTLCodingConvention.md
16
*
/
17 inSignal,
18 outSignal
19 );
20 /
*
21
*
The first component in the module is typically the input/output (I/O) declarations.
22
*
/
23 input inSignal;
24 output outSignal;
25
26 /
*
27
*
And finally the module’s implementation.
28
*
/
29 assign outSignal = inSignal;
30 endmodule
A simple testbench to generate signals for the module’s input and to monitor
the module’s outputs, is:
1 ‘timescale 1ns/1ns
2
3 module simpleTestbench;
4 reg signalIn, signalOut;
5
6 simple simpleInstance(.inSignal(signalIn), .outSignal(singnalOut));
7
8 initial begin
9 /
*
10
*
Delay for one time unit (1ns, as defined above), then set singalIn to 0
11
*
/
12 #1 signalIn = 0;
13
14 /
*
15
*
Delay for one time unit (1ns, as defined above), then set singalIn to 1
foundations of embedded systems 13
16
*
/
17 #1 signalIn = 1;
18
19 /
*
20
*
Delay for 10 time units (10ns, as defined above), then set singalIn to 0
21
*
/
22 #10 signalIn = 0;
23
24 /
*
25
*
Delay for one time unit (1ns, as defined above), then set singalIn to 1
26
*
/
27 #1 signalIn = 1;
28 end
29 initial begin
30 $dumpfile("simpleTestbench.vcd");
31 $dumpvars;
32 end
33 endmodule
The tool Icarus Verilog or iverilog provides a mechanism to simulate a
Verilog design with its associated testbench. The tool iverilog compiles a
Verilog design into an executable which implements a custom simulator for
the design. The following invocation from the command line will invoke
iverilog to generate a simulator for the example above and its testbench,
placing the generated simulator in the binary
simpleTestbench.
$ iverilog -o simpleTestbench simple.v simpleTestbench.v
Invoking the generated
simpleTestbench will generate the file simpleTestbench.vcd
2
2
The suffix and abbrevia-
tion vcd stands for “value
change dump”.
based on line 30 of the testbench above.
The program
gtkwave is one of many programs that can visualize the
generated timing diagram. When using the command-line FPGA tools of
Appendix
E and Appendix F, you can copy the generated .vcd file to your
workstation and run a local installation of gtkwave to visualize the simulation
output.
6.6.11 Transistor-, Gate-, Dataflow-, and Behavioral-Modeling in Verilog
Verilog permits implementation of designs at the transistor level and gate
level as well as using dataflow versus behavioral modeling approaches.
The following example shows how to implement a CMOS inverter using
primitives for NMOS and PMOS transistors in Verilog:
1 module cmosInverter(inSignal, outSignal);
2 input inSignal;
3 output outSignal;
4
5 supply1 vdd;
6 supply0 gnd;
7
8 pmos p1 (outSignal, vdd, inSignal);
9 nmos n1 (outSignal, gnd, inSignal);
14 phillip stanley-marbell
10 endmodule
The following example shows how to implement a D-type flip flop using
primitives fornand gates and not gates in Verilog:
1 module dff(
2 input D,
3 input clk,
4 input rst,
5 output Q,
6 );
7
8 wire net0;
9 wire net1;
10 wire net2;
11 wire net3;
12 wire net4;
13 wire net5;
14 wire net6;
15 wire net7;
16 wire net8;
17
18 nand nand0 (net1, D, net0);
19 nand nand1 (net2, net1, net0);
20 nand nand2 (net5, net1, net4);
21 nand nand3 (net4, net5, net2);
22 nand nand4 (net6, net5, net3);
23 nand nand5 (net7, net6, net3);
24 nand nand6 (Q, net6, net8);
25 nand nand7 (net8, Q, net7);
26 not not0 (net0, clk);
27 not not1 (net3, net0);
28 endmodule
6.6.12 Self-Assessment Quiz
Complete the following
quiz to evaluate your understanding of the material
on modeling hardware at different abstraction levels in Verilog.
foundations of embedded systems 15
6.7 The Muddiest Point
Think about the following two questions and submit your responses through
this
link.
1. What was least clear to you in this chapter? (You can simply list the section
numbers or write a few words.)
2. What was most clear to you in this chapter? (You can simply list the
section numbers or write a few words.)
16 phillip stanley-marbell
6.8 Further Reading
The following resources will be useful in exploring the concepts of this chap-
ter further:
1. Digital Design: An Embedded Systems Approach Using Verilog, ISBN: 978-
0123695277. This book is a detailed reference on the Verilog hardware
description language and will be valuable as you investigate methods to
reduce resource usage.
foundations of embedded systems 17