0% found this document useful (0 votes)
17 views

Ss6.Verilog Comb Logic

Uploaded by

ryujindance
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Ss6.Verilog Comb Logic

Uploaded by

ryujindance
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 134

CPEN 211: Introduction to Microcomputers

Slide Set 6: Verilog for Combinational


Logic

Prof. Tor Aamodt


[ Background image: Logic gate diagram for a portion of the PDP 11 data path; The PDP 11 was a famous “minicomputer” from the 1970s.
Copyright © DEC. Source: http://www.psych.usyd.edu.au/pdp-11/Images/11_20_dp.gif ]
Apple A8 die photo
(application processor
used in iPhone 6)

[http://vlsiarch.eecs.harvard.edu/accelerators/die-photo-analysis]

Slide Set #6 2
Learning Objectives
After this slide set you should be able to:
1. Write Verilog for combinational logic
2. Write Verilog for comb. logic testbenches
3. List important style guidelines that help avoid
common errors when working with
combinational logic

Slide Set #6 3
Scaling logic design

~1M logic gates and 742 SRAMs

How to scale to more complex designs?


Hardware design languages to the rescue

designing hardware with KMAPs

designing hardware with an HDL


Why Use Verilog?
• Verilog can be used as an input to:
– Synthesis – implement hardware with gates, cells,
or FPGAs
– Simulation – see what your hardware will do
before you build it

Slide Set #6 6
Text: Dally §1.5
What is Verilog?
• It is NOT a programming language!
• It is a hardware description language (HDL)
• Why do we need a new method to describe
hardware?
– What is wrong with schematics?
• With Verilog, you can specify hardware in two ways:
– Structurally: what the hardware looks like (like schematics)
– Behaviourally: what the hardware does
• But the real power of Verilog is that it lets you
combine structural and behavioural descriptions in
the same design!
Slide Set #6 7
Tools and design flow

RTL description testbench


(e.g., RTL Verilog) (e.g., Verilog, C, etc.)
synthesis
(Quartus tech mapper) compilation
gate-level netlist (Modelsim vlog)
simulator
place & route
(Quartus fitter) binary
FPGA config
simulation
(bitstream)
(Modelsim vsim)
FPGA programming
(Quartus programmer)
signal traces
circuit on FPGA (waveforms)
Verilog infelicities

• designed for simulation,


not hardware design (!)
• only small subset
is “synthesizable” full Verilog
(testbenches)
• you need to learn
hardware  RTL description
patterns and stick to them synthesizable
Verilog
• but also (some of) the rest (hardware)
to write testbenches
The most important thing to remember:

There are many things that we can describe, but can not build

Therefore, we should not expect all Verilog code to be


“synthesizable”

Slide Set #6 10
Verilog Modules
• The basic construct for modeling a digital system in
Verilog is called a module. Each hardware block is
described in one module.

• Modules have
– Module declaration
– Input and output declarations
– Internal signal declarations
– Logic definition; describes either what the block does
and/or what it is composed of
• Assign statements
• Case statements
• Module instantiations

Slide Set #6 11
Running example…
• Input: 3 bits
• Output: 1 if more inputs are 1 than are 0
abc out
a
000 0 ba
001 0 c 00 01 11 10 a
b
010 0 0 0 1 0
0

0 1 3 2
b v c
011 1 out
f
0 1 1 1
c

100 0
1

4 5 7 6

101 1 b c
110 1 a c a b
v v
111 1

Slide Set #6 12
Structure module name ports

a
module Majority(input a, input b, input c, output out);
b n1

n2 f out
endmodule
ports specify direction
n3
c

module Majority( input [2:0] val, output out ) ;

endmodule
bus width (here 3 bits: 2, 1, 0)

important: modules are not functions


Slide Set #6 13
Structure
a
module Majority(input a, input b, input c, output out);
b n1
wire n1, n2, n3 ;
n2 f out and foo(n1, a, b) ;
and bar(n2, a, c) ;
and baz(n3, b, c) ;
n3
c or glurph(out, n1, n2, n3) ;
endmodule

instance name
modules to
instantiate*

*actually, not and and are Verilog primitives, but you can instantiate them like modules

Slide Set #6 14
Text: Dally §3.6
Modules + instance hierarchy = structure

instance of instance of
a 7404 module a 7400 module

instance of a 1kΩ resistor


module two more instances of a 1kΩ resistor module

again: modules are not functions

Think about module instances as chips on a breadboard. Think


about input/output ports as pins on chips. We use wires to get
value from one chip output to another chip input.
Okay, but when does “stuff happen”?
a
module Majority(input a, input b, input c, output out);
b n1
wire n1, n2, n3 ;
n2 f out and foo(n1, a, b) ;
and bar(n2, a, c) ;
and baz(n3, b, c) ;
n3
c or glurph(out, n1, n2, n3) ;
endmodule

test inputs
and outputs

wires inside
our design

time
Slide Set #6 16
Text: Dally §3.6
Primer on Verilog Syntax

Slide Set #6 17
File types
.v is extension for Verilog
.sv is extension for SystemVerilog <- use this

SystemVerilog is a superset of Verilog and as we


will learn a few helpful keywords that are only
supported by SystemVerilog, it will make your
life easier if you use .sv for your files.

Slide Set #6 18
Boolean Expressions in Verilog
• Verilog uses &, |, and ~ to represent AND, OR,
and NOT, respectively.
• Verilog uses ^ for exclusive-OR.

• Avoid using ! for NOT (we’ll see why later).

Slide Set #6 19
Text: Dally §3.6
Continuous assignment
We can instantiate logic and connect it together
with a type of statement called a continuous
assignment. As the name suggests, it is always
active (always happening):

assign <wire> = <expression (with wires or regs)>;

Slide Set #6 20
Example: Verilog description of an AND gate (older K&R style):

Module declaration I/O list

module AND_GATE(a, b, c);


input a, b;
Declare I/Os
output c;

assign c = a & b;

endmodule An assign statement defines a signal with


an equation

Slide Set #6 Slide Set 2, Page 21


Same thing, but with the ANSI style I/O declaration syntax we saw earlier:

module AND_GATE(input a, input b, output c);


assign c = a & b;
endmodule

Slide Set #6 Slide Set 2, Page 22


Majority Circuit in Verilog
a
b n1

n2 fout

n3
c

Note: all assignments performed


concurrently. module Majority(a, b, c, out) ;
input a, b, c ;
output out ;
wire n1, n2, n3 ;

assign n1 ==an1
out & b
| ; | n3 ;
n2
assign n1 = a &
n2 b
c ;
assign n2 = b
n3 a & c ;
assign n3 ==bn1
out & c
| n2
; | n3 ;
endmodule

Slide Set #6 23
Text: Dally §3.6
Majority Circuit in Verilog
a
b n1

n2 fout

n3
c

We can combine a wire declaration and assign statement…


module Majority(a, b, c, out) ;
input a, b, c ;
output out ;

wire n1 = a & b ;
wire n2 = a & c ;
wire n3 = b & c ;
assign out = n1 | n2 | n3 ;
endmodule

Slide Set #6 24
Text: Dally §3.6
Majority Circuit in Verilog
a
b

fout

A single assign statement can include multiple Boolean operators….

module Majority(a, b, c, out) ;


input a, b, c ;
output out ;
assign out = (a & b)|(a & c)|(b & c) ;
endmodule

Slide Set #6 25
Text: Dally §3.6
So a recipe for specifying combinational logic in VHDL:

1. Write a boolean expression for each output

2. Include each boolean expression as a signal assignment


within a module.

This will work, and you can use it. But, there are more
efficient and easier ways to do it.

Slide Set #6 Slide Set 2, Page 26


Verilog Literal Numbers
Verilog numbers can be expressed using:
<size>’[<signed>]<radix>value

<size> Number of bits.


<signed> Signed: s (if omitted unsigned)
<radix> Radix of the number:
b – binary
d – decimal
o – octal
h – hexidecimal
value Digits depend upon radix; Underscores ignored.

Examples: 8’b0001_1101 (8-bits, value is 29 in decimal)


8’d29 (same value)
Slide Set #6 27
Describing Buses in Verilog

In the prior example all signals were a


single bit. This maps nicely to one wire.

We can also have a signal that represents a set of parallel wires:


wire [2:0] X;
This defines X as a bus with 3 parallel wires. This is like an array in
a programming language. Each element of the array is a single bit.
Busses can also be used as input/output signals of design entities.

Slide Set #6 28
Describing Buses in Verilog
The size of a bus and the element numbers are assigned when the signal is
defined:

[0:7] // 8 elements addressable with indices 0 to 7


[3:11] // 8 elements addressable with indices 3 to 11
[33:23] // 11 elements addressable with indices 33 to 23

You can do lots of cool things with busses:

1. You can assign values to all elements in the array at once


assign x = 8’b00011101;

2. You can copy one bus to another:


assign out_bus = in_bus;

Slide Set #6 29
Cool things™, continued…
3. You can access individual elements (“wires”):

wire STATUS;
wire [15:0] MAIN_BUS;

assign STATUS = MAIN_BUS[15];

4. You can access subranges of busses:

wire [31:0] MAIN_BUS;


wire [3:0] OPCODE;

assign OPCODE = MAIN_BUS[31:28];

Slide Set #6 30
Examples of Copying Busses
// Example 1
wire [7:0] out_bus;
wire [7:0] in_bus;

assign out_bus = in_bus;

// Example 2
wire [7:0] out_bus;
wire [15:8] in_bus;

assign out_bus = in_bus; // OK: out_bus(7) connected to in_bus(15)

// Example 3
wire [7:0] out_bus;
wire [0:7] in_bus;

assign out_bus = in_bus; // OK: out_bus(7) connected to in_bus(0)

// Example 4
wire [7:0] out_bus;
wire [15:0] in_bus;

assign out_bus = in_bus; // Same as assign out_bus[7:0] = in_bus[7:0];
Slide Set #6 31
Examples of Copying Busses

// Example 5
module bus_test(a,b);
input [7:0] a;
output [7:0] b;

assign t = a;
assign b = t;
endmodule

Moral? Verilog does not consider it an error if you use a signal without
declaring it first! (Verilog treats signals without declarations like a wire).

Slide Set #6 32
Cool things™, continued…
5. Concatenate short vectors to produce longer ones using { }

Example: if the following two signals are defined

wire [3:0] ERROR_CODE;


wire [7:0] MAIN_BUS;
Then the following assignments are legal:
assign MAIN_BUS = {4'b0000, 4'b1111};
assign MAIN_BUS = {4'b0000, ERROR_CODE};
assign MAIN_BUS = {1'b1, 7'b0000000};
assign MAIN_BUS = {1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0};
assign MAIN_BUS = {1'b0, ERROR_CODE, 3b'111};

assign {ERROR_CODE,MAIN_BUS} = 12b’111110101010;

Slide Set #6 33
Cool things™, continued…
6. You can make copies of one or more bits using the replication operator, {k{n}}

wire [1:0] x = 2’b10;


wire [7:0] y = {4{x}}; // y = 8’b10101010; {k{n}} makes k copies of n
wire [8:0] z = {3{x,1’b0}}; // z = 9’b100100100; combined w/ concat.

7. You can make two-dimensional arrays:

reg [3:0] data [7:0]; // data contains 8 elements of 4-bits each

We could have used “wire” instead of “reg” – but we will use reg because
assignments to memory are made in an “always” block. Inside an always block
you could write:

data [7] = 4’b0011;

8. You can write bitwise Boolean expressions:

wire [3:0] result = A & B;


// result[0] = A[0] & B[0]; result[1] = A[1] & B[1]; …
Slide Set #6 34
Boolean Expressions Revisited
• When applied to two operands &, |, ^ are
“bit-wise”
• Bitwise means the operators operate
individually on each bit in a bus.
• Also ~ is bitwise.

Slide Set #6 35
Text: Dally §3.6
Busses and Booleans
wire [3:0] result = A & B;

X(3)
A[0]
Z(3)
result[0]
Y(3)
B[0]
X(2)
A[1]
4
B[1] Z(2)
result[1]
Y(2) XA
Z
result
X(1)
A[2] YB 4
Z(1)
result[2] 4
Y(1)
B[2]
X(0)
A[3]
Z(0)
result[3]
Y(0)
B[3]

Slide Set #6 36
Cool things™, continued…
9. You can OR or AND together bits using:

wire result = |A; // result = (A[0] | A[1] | A[2] | … A[n-1])


wire foo = &A; // foo = (A[0] & A[1} & A[2] & …. A[n-1])

Slide Set #6 37
Thermostat Revisited

[http://www.clipartpanda.com/categories/cute-house-clipart]

[http://blogs.plos.org/obesitypanacea/2011/02/25/turn-down-your-thermostat-to-lose-weight-suggests-new-study-dripping-with-sarcasm/]

Slide Set #6 38
Design Step

presetTemp

fanOn
Thermostat
currentTemp

Slide Set #6 39
Example, Verilog for Thermostat

module Thermostat(presetTemp, currentTemp, fanOn) ;


input [2:0] presetTemp, currentTemp ; // temperature inputs, 3 bits each
output fanOn ; // true when current > preset

wire fanOn ; // don’t really need this line as outputs are “wire” by default
assign fanOn = (currentTemp > presetTemp) ;
endmodule

Slide Set #6 40
Text: Dally §1.5
Example: Majority Gate

module Majority( input [2:0] val, output out ) ;


assign out = (val==3'b111) | (val==3'b110) | (val==3’b101) | (val==3'b011);
endmodule

val

3 =
3'b111

=
3'b110
out

=
3'b101

=
3'b011

Slide Set #6 41
Verilog “define”
Very similar to “#define” in C:

`define <macro_name> <macro_text>

Example:
No Semicolon!

`define Sa 2'b00

means “Sa” has the value 2'b00

To use a define value you put backtick ` before it: `Sa

Slide Set #5 42
Verilog Conditional Operator

<cond_expr> ? <true_expr> : <false_expr>

Meaning: If <cond_expr> is true, then the value of


entire expression is the value given by <true_expr>
otherwise the value is given by <false_expr>.

Examples:
If “in” is 1, then value of (in ? `Sb : `Sa) is `Sb
If “in” is 0, then value of (in ? `Sb : `Sa) is `Sa

Slide Set #5 43
Verilog Description of a Multiplexer

A0
2'b00 1
2
b
next_state_reset
2
A1
next_state 0
2

reset
select

wire [1:0] b = select ? A0 : A1;

NOTE: This is combinational logic.


Slide Set #5 44
Example: Majority Gate
`define Unanimous 3'b111

module Majority( input [2:0] val, output out ) ;


assign out = (val==`Unanimous) ? 1'b1 :
(val==3'b110) ? 1'b1 :
(val==3’b101) ? 1'b1 :
(val==3'b011) ? 1'b1 : 1'b0 ;
endmodule
0
val 1 1 out
3 =
3'b111
0
1 1

=
3'b110
0
1 1

=
3'b101
0 0
1 1

=
3'b011
Slide Set #6 45
The Always Block
Two important things to know:

1. What an always block is (syntax and meaning)


2. Rules to ensure your always block Verilog code
is synthesizable by CAD tools.

We will also talk about SystemVerilog variants that


can help avoiding bugs: always_comb, always_ff

Slide Set #6 46
The always block allows us to describe the function or behaviour
of a circuit or subcircuit without describing the actual hardware

We have already seen some sorts of behavioural descriptions:

assign fanOn = (currentTemp > presetTemp) ;

This describes the behaviour of the circuit driving “fanOn”


without necessarily specifying the actual hardware
implementation

But we are going to take this MUCH further and describe circuits
at a much higher level.

Slide Set #6 47
How can we describe behaviour?
If we could write an English description, that would be nice
- but English gives too much room for ambiguity

A better way: describe the behaviour using something that has


a notion of order between statements – somewhat like
software
- writing software is easy
- no room for ambiguity

Verilog provides always block syntax which makes describing


behavior easier.

Slide Set #6 48
Always Block Syntax and Semantics

always @(<sensitivity_list>) begin


<sequence of statements in which order matters>
end

- Each always block describes the function of one block of hardware.


- When a signal in the sensitivity list changes, statements inside the always
block are immediately & instantaneously evaluated one after the other in
order starting from the beginning of the always block.
- Sensitivity list is a list of signals separated by commas (“,”) or “or” or an
asterisk (“*”), which means the list of all signals read inside the always block.
Individual signals may include event “posedge” or “negedge” modifier.
- The sensitivity list is NOT the same thing as the input parameters to
a function (in a language like “C” or Java, or C++). It does NOT pass
values into the always block. The sensitivity list determines when the
sequence of statements inside the always block will be evaluated.
- If only one statement inside always block, we can omit “begin” and “end”

NOTE: The “description” inside the always block may have little resemblance to the
actual hardware implementation. However, provided you follow certain rules
(described later) the hardware will implement the same behavior.

Slide Set #6 49
A Great (But Silly) Harry Potter Analogy
Hardware

[Source: http://www.davidbordwell.net/blog/wp-content/uploads/HPatPoA-paintings.jpg]

Software

[Source: http://ichef.bbci.co.uk/news/640/cpsprodpb/EDED/production/_83890906_83890905.jpg]
Slide Set #6 50
What goes inside an Always Block?
• For CPEN 211: “if”, “case”, “casex” statements! DO
NOT USE LOOPS IN ALWAYS BLOCKS.
• Use “begin” and “end” to group statements (like {} in C)
• Signals modified in an always block MUST be declared
as “reg” instead of “wire”. (This is a syntax rule, says
nothing about the hardware that will be synthesized.)
• Always block outputs modified using “=” or “<=” (will
talk about difference a bit later).
• Can read either “wire” or “reg” inside an always block
• Do NOT use assign statements inside an always block.

Slide Set #6 51
If Statement
if (<condition expression>)
<statement>
[ else <statement> ]

NOTES:
1. Need to wrap <statement> in begin/end if you
want multiple statements.
2. When describing combinational logic using if
statement need to include “else” (Why? See
synthesis rules later in slide set).

Slide Set #6 52
Case Statement

case (<selector>)
{ <label list> : <statement> }+
[ default: <statement> ]
endcase

NOTES:
1. Need to wrap <statement> part in begin/end pair if you want
multiple statements.
2. When describing combinational logic with case statement need
to include default (Why? See synthesis rules later in slide set).

Slide Set #6 53
Example: Days in Month Function

month days
DaysInMonth

Slide Set #6 54
Example, Days in Month Function

Slide Set #6 55
Example: Days in Month Function
module DaysInMonth(month,
Reg definesdays)
a signal ;set in an
always
input [3:0] month ; block.// Itmonth
does NOTof define
the year 1 = Jan, 12 = Dec
a register.
output [4:0] days ; // number of days in month

Always block evaluates each time


reg [4:0] days ;
activity list changes. In this case each
time month changes
always @(month) begin // evaluate whenever month changes
case(month)
Case statement selects statement
2: days = 5'd28 ; //depending
Februaryonhasvalue28
of argument. Like a
4,6,9,11: days = 5'd30 ; //truth
30 days
table. have September ...
default: days = 5'd31 ; // all the rest have 31...
endcase
end Can have multiple values
endmodule Default covers values not per statement
listed.
Slide Set #6 56
Text: Dally §7.1.2, 9.2
Some Common Syntax Errors
** Error: <file name>(<line number>): LHS in procedural continuous assignment may
not be a net: t.

Error (10043): Verilog HDL unsupported feature error at <file name>(<line number>):
Procedural Continuous Assignment to register is not supported

Do NOT use “assign” inside of an always block.

** Error: <file name>(<line number>): (vlog-2110) Illegal reference to net ”<name>".

Do NOT update a “wire” inside an always block (output of always block must be reg)

57
Writing a truth table in Verilog
Example: Prime number function
No dcba q
Truth table: 0 0000 0
1 0001 1
2 0010 1
3 0011 1
4 0100 0
5 0101 1
6 0110 0
7 0111 1
8 1000 0
9 1001 0
10 1010 0
11 1011 1
12 1100 0
13 1101 1
14 1110 0
15 1111 0
Slide Set #6 58
Text: Dally §7.1.2
4-bit Prime Number Function in
Verilog Code – Using case
module prime(in, isprime) ;
input [3:0] in ; // 4-bit input
output isprime ; // true if input is prime
reg isprime ;
always @(in) begin
case(in)
1,2,3,5,7,11,13: isprime = 1'b1 ;
default: isprime = 1'b0 ;
endcase
end
endmodule

Slide Set #6 59
Text: Dally §7.1.2
Q: When do you need begin / end?
If you want more than one statement to be “evaluated”
based upon same condition, then you group those
statements in ”begin” and “end”:
We do NOT need
always @(sel or A or B)
“begin” here because
if (sel == 1'b0) “if/else” is a single
begin We DO need “begin/end” statement
Y = A; here because we want
Z = B; two statements “Y=A;”
end and “Z=B;” to be
evaluated if sel == 1’b0.
else
begin
Y = B;
Z = A;
end
Slide Set #6 60
Q: When do you need begin / end?
Example of using begin/end inside case to allow
multiple statements for a given case label:

always @(*)
case(in)
4’b0000: begin
out1 = 1'b1;
out2 = |in2;
end
4'b0001: begin
out1 = 1'b0;
out2 = 1'bx;
end

Slide Set #6 61
always_comb
• Using sensitivity list or @(*) is error prone as
“always” is too powerful (too general).
• SystemVerilog introduced versions that specify
design intent: always_comb, always_ff
• For combinational logic use “always_comb”
always_comb
case(month)
2: days = 5'd28 ;
4,6,9,11: days = 5'd30 ;
default: days = 5'd31 ;
endcase

Slide Set #6 62
Multiple updates

always_comb begin
Y = 2'b11;
if (A == 1'b1) begin
Y = 2'b00;
end
end

Slide Set #6 63
Beware the Ambiguous ELSE!
always_comb begin always_comb begin
Y = 2'b00; Y = 2'b00;
if (A == 1'b0) if (A == 1'b0)
if (B == 1'b1) if (B == 1'b1)
Y = 2'b01; Y = 2'b01;
else else
Y = 2'b10; Y = 2'b10;
end end

Source of confusion? Without more information it is ambiguous


which of the two if statements the “else” belongs to. ModelSim
and Quartus pick the “closest if” -- indentation does NOT matter!
Slide Set #6 64
Use begin/end to get intended behavior

always_comb begin
Y = 2'b11;
if (A == 1'b1) begin
if (B == 1'b1)
Y = 2'b00;
end else
Y = 2'b01;
end

Slide Set #6 65
Combinational Logic Building Blocks
in Verilog

Slide Set #6 66
Verilog implementation of a 2:4 decoder
a1 a0 b3 b2 b1 b0

Decoder
0 0 0 0 0 1
0 1 0 0 1 0 a b
1 0 0 1 0 0 n2 m
4
1 1 1 0 0 0
n
m≤2
“X << Y“ means a[1]
a[0]
shift X to the
left by Y bit
module Dec24(a, b) ; positions. b[3]

input [1:0] a ; b[2]


output [3:0] b ;
wire [3:0] b = 1 << a ; b[1]

endmodule
b[0]

Slide Set #6 67
Text: Dally §8.2
Encoder
a3 a2 a1 a0 b1 b0

a3

a2

a1

a0
0 0 0 1 0 0
0 0 1 0 0 1 b1
0 1 0 0 1 0
1 0 0 0 1 1
b0

b0 = a3 ∨ a1
// 4:2 encoder
b1 = a3 ∨ a2
module Enc42(a, b) ;
input [3:0] a ;
output [1:0] b ;
assign b = {a[3] | a[2], a[3] | a[1]} ;
endmodule

Slide Set #6 68
Text: Dally §8.4
1-bit, 2-input One-Hot Select Mux
Symbol: Implementation with
AND and OR gates:
a0
Mux b a0
a1
s[0]
b
a1
s s[1]
2

// 1-bit 2-input mux with one-hot select


module Mux2a(a1, a0, s, b) ;
input a0, a1; // inputs
input [1:0] s; // one-hot select
output b ;
assign b = (s[0] & a0) | (s[1] & a1);
endmodule
Slide Set #6 69
2-bit, 3-input Mux a0[0]
a0[1]

a1[0]
b[0]
a1[1]

a2[0]
a0 a2[1]

2
a1 b
Mux
2 2
a2
b[1]
2

s s[0]
3 s[1]
s[2]

// 2-bit, 3-input mux with one-hot select


module Mux3_2(a2, a1, a0, s, b) ;
input [1:0] a0, a1, a2; // inputs
input [2:0] s ; // one-hot select
output[1:0] b ;
assign b = ({s[0],s[0]} & a0) |
({s[1],s[1]} & a1) |
({s[2],s[2]} & a2) ;
endmodule
Slide Set #6 70
module Mux3a(a2, a1, a0, s, b) ;
input [7:0] a0, a1, a2 ; // inputs
input [2:0] s ; // one-hot select
output[7:0] b ;
This makes 8 copies of 1’bx. Here ‘x’ means
reg [7:0] b ; “don’t care”. So, the default statement says
we “don’t care” what any of the bits of b are
always @(*) begin if s does not match 3’b001, 3’b010 or
case(s) 3’b100. Quartus can use these don’t cares
to optimize the implementation. Just like
3'b001: b = a0 ;
you did with a KMAP.
3'b010: b = a1 ;
3'b100: b = a2 ;
default: b = {8{1'bx}} ;
endcase
end
endmodule

Slide Set #6 71
Verilog Syntax Module Instantiation

Slide Set #6 72
Module Instantiation

Instantiate

Tic-tac-toe example (Dally §9.4)…


oin
ain
//Figure 9.13

TwoInArray
9
win
cout
module TwoInArray(ain, bin, cout) ; bin
9

input [8:0] ain, bin ; win


output [8:0] cout ; xin
ain a

TwoInArray
9

Select3
block oout
cout b out
9 9

2x bin

don't lose
c

module TicTacToe(xin, oin, oout) ; empty

Empty
9

TwoInArray winx(oin, xin, win) ; first open square
73
TwoInArray blockx(xin, oin, block) ;
Consider a REALLY simple example
Consider the following example:

We can express each gate as a module:

module NAND_GATE(A,B,Z); module INV_GATE(A,Z );


input A, B ; input A;
output Z ; output Z;
assign Z = ~(A & B); assign Z = ~A;
endmodule endmodule

Slide Set #6 74
Instantiation Syntax

<module name> <instance name>(<port list>) ;

<module name> name of the module.


<instance name> name of this instance of the module.
<port list> list of signals connected to inputs and outputs of module.

Module output ports must be connected to wire where instantiated.


Module input ports can be connected to either a reg or wire.

Slide Set #6 75
module NAND_GATE(A,B,Z);
A Z
input A, B ; A Z
output Z ; B
assign Z = ~(A & B);
NAND_GATE INV_GATE
endmodule

module INV_GATE(A,Z); Modules can be in separate “.v” files


input A; (compiled in any order)
output Z;
assign Z = ~A;
endmodule

module AND_GATE (IN1, IN2, OUT1);


input IN1, IN2;
output OUT1;
wire X;
NAND_GATE U0 (IN1, IN2, X);
INV_GATE U1 (X, OUT1);
endmodule

Module instantiation is NOT the same as a function call in a programming


language like C/C++/Java. A closer “analogy” is plugging chips into a
breadboard and connecting wires to the pins on the chip, which is something you 76
do BEFORE powering up and using circuit (instantiate before power is “on”).
module AND_GATE (IN1, IN2, OUT1);
input IN1, IN2;
output OUT1;
wire X;
NAND_GATE U0 (IN1, IN2, X); Module
INV_GATE U1 (X, OUT1); instantiations
endmodule

Verilog syntax for module instantiation:


<module name> <instance name>(<port list>) ;
IMPORTANT! Semantics of module instantiation is NOT same
as for function call in a programming language like C/C++/Java.

Module outputs must be connected to “wire” where instantiated.


(Module inputs can be either “reg” or “wire” where instantiated.)
77
Module outputs must be connected to
“wire” where instantiated
Suppose we want to use “always” to define Z inside NAND_GATE…
module NAND_GATE(A,B,Z); 112: module AND_GATE (IN1, IN2, OUT1);
input A, B ; 113: input IN1, IN2;
output reg Z ; 114: output OUT1;
always @(A, B) 115: reg X;
wire X;
Z = ~(A & B); 116: NAND_GATE U0 (IN1, IN2, X);
endmodule 117: INV_GATE U1 (X, OUT1);
118: endmodule

Moral: Use “wire” for outputs where module is instantiated.


Again, module inputs can be connected to either reg or
wire at the location where the module is instantiated. 78
Very Common Instantiation Bug
Mismatch in input/output port width between declaration and
instantiation:
module Bad(a,b);
input [7:0] a;
output [7:0] b;
reg b; // bug: should be “reg [7:0] b;”
always @*
b = a;
endmodule

module OtherModule;
wire [7:0] x;
wire [7:0] y;
Bad U0(x,y);

In ModelSim, no compile error, but you do get a warning when starting simulation:
** Warning: (vsim-3015) <file1>(<line1>): [PCDPC] - Port size (1) does not
match connection size (8) for port 'b'. The port definition is at:
<filename2>(<line2>).
Slide Set #6 79
Module Instantiation “LEGO Analogy”

Verilog can be viewed as a description for how to build hardware. You may
want to think of module instantiation, assign statements, always blocks in
Verilog as instructions saying how to build a LEGO toy (picture above).

After you build a LEGO toy, you can play with it, which is similar in this
analogy to changing slide switches and/or pressing push buttons on your
DE1-SoC after downloading compiled design (e.g., LEGO wheels turning).
Slide Set #6 80
[figure source: http://lego.brickinstructions.com/lego_instructions/set/9324/Micro_Building_Set]
Implicit vs. Named Port Association
In the NAND+NOT gate example, order to connect wires was implicit

NAND_GATE U0 (IN1, IN2, X);

means that IN1 is connected to the first port in the module definition
and IN2 is connected to the second port in the module definition, etc.

We can also use named association:

NAND_GATE U0( .A(IN1), .B(IN2), .Z(X) );

means that IN1 is connected to A in the module def’n, etc.


NOTE: When using named notation, order does not matter: Could
use “NAND_GATE U0(.Z(X), .B(IN2), .A(IN1))” above instead.
Slide Set #6 81
Named Port Association: Syntax
<port list> ::= <named assoc> [, <port list> ]
<named assoc> ::= { .<port name>(<signal name>) }+
<port name> name of the input/output port in module declaration.
<signal name> name of signal connected to port in module instantiation.

module AND_GATE (IN1, IN2, OUT1);


module NAND_GATE(A,B,Z); input IN1, IN2;
input A, B ; output OUT1;
output Z ; wire X;
assign Z = ~(A & B); NAND_GATE U0( .A(IN1), .B(IN2),.Z(X));
endmodule INV_GATE U1 (X, OUT1);
endmodule

Slide Set #6 82
Example of Named Association
module Dec24(a, b) ;
input [1:0] a ;
output [3:0] b ;
wire [3:0] b = 1 << a ;
endmodule
NO210, INV110 are modules
Using “Synopsys” above decoder Verilog synthesizes to: defining NOR and NOT gates in
the “technology library” or
module Dec_Synthesized ( in, out ); “cell library” provided by the
input [1:0] in; chip manufacturing company.
output [3:0] out;
wire n2, n3;
NO210 U2 ( .A(n2), .B(n3), .Y(out[3]) );
NO210 U3 ( .A(in[0]), .B(n2), .Y(out[2]) );
NO210 U4 ( .A(in[1]), .B(n3), .Y(out[1]) );
NO210 U5 ( .A(in[0]), .B(in[1]), .Y(out[0]) );
IV110 U6 ( .A(in[1]), .Y(n2) );
IV110 U7 ( .A(in[0]), .Y(n3) );
endmodule
Slide Set #6 83
Module Parameters
Another silly analogy…
When buying a car typically need to pick a
color… color doesn’t change once you pick
up your car (not without a lot of work).

Slide Set #2 84
Module Parameters
• Often want to change width of signals when instantiating a module
in different parts of our design (or in different designs) and often
the rest of the design should change in a predictable way.
• Verilog parameter syntax allows us to specify properties of a
module that stay fixed for any given module instance:

Syntax of module declaration with parameter(s):


module <module_name>( <port list> ) ;
{ parameter <parameter name> [ = <default value> ] ; } *

Syntax of module instantiation with default parameters overridden:


<module name> #(<parameter list>) <instance name>(<port list>) ;
Slide Set #2 85
Verilog implementation of a n:m decoder

// a - binary input (n bits wide)


// b - one hot output (m bits wide)
module Dec(a, b) ;
parameter n=2 ;
parameter m=4 ;

Decoder
input [n-1:0] a ;
output [m-1:0] b ; a b
n m
wire [m-1:0] b = 1 << a ;
endmodule n
m≤2

What if we want a 3->8 decoder?


Instantiate a 3->8 decoder using:
Dec #(3,8) U1(a, b) ;
Slide Set #6 86
Text: Dally §8.2
Example: Implement an arbitrary logic function
with a decoder -- e.g., prime number function
in[2 :0] b [7:0]

3:8
3 8 b [7 ]
b [5 ]
b [3 ] i sp rime

b [2 ]
b [1 ]

module Primed(in, isprime) ;


input [2:0] in ;
output isprime ;
wire [7:0] b ;
// compute the output as the OR of the required minterms
wire isprime = b[1] | b[2] | b[3] | b[5] | b[7] ;
// instantiate a 3->8 decoder
Dec #(3,8) d(in,b) ;
endmodule Slide Set #6 87
Text: Dally §8.2
Parameterized Multiplexer (v1)
a0 module Mux3a(a2, a1, a0, s, b) ;
2k parameter k = 1 ;
a1 b input [k-1:0] a0, a1, a2 ; // inputs
Mux
2k 2k input [2:0] s ; // one-hot select
a2
2k output[k-1:0] b ;
reg [k-1:0] b ;

s always_comb begin
3k case(s)
3'b001: b = a0 ;
3'b010: b = a1 ;
3'b100: b = a2 ;
default: b = {k{1'bx}} ;
endcase
end
endmodule

Slide Set #6 88
Parameterized Multiplexer (v2)
// 4-input, k-bit mux with one-hot select
module Mux4(a3, a2, a1, a0, s, b) ;
parameter k = 1 ;
input [k-1:0] a0, a1, a2, a3 ; // inputs
input [3:0] s ; // one-hot select
output[k-1:0] b ;
wire [k-1:0] b = ({k{s[0]}} & a0) |
({k{s[1]}} & a1) |
({k{s[2]}} & a2) |
({k{s[3]}} & a3) ;
endmodule

Mux4 #(2) mx(2'd3, 2'd2, 2'd1, 2'd0, f, h) ;

f h
# 0001 00
k=1 k=2
# 0010 01
# 0100 10
# 1000 11

Slide Set #6 89
// 4:1 multiplexer with binary select (arbitrary width)
module Mux4b(a3,a2, a1, a0, sb, b) ;
parameter k = 1 ;
input [k-1:0] a0, a1, a2, a3 ; // inputs
input [1:0] sb ; // binary select
output[k-1:0] b ;
wire [k-1:0] t0, t1 ;

assign t0 = sb[0] ? a1 : a0;


assign t1 = sb[0] ? a3 : a2;
assign b = sb[1] ? t0 : t1;
endmodule
t0

t1

Slide Set #6 90
Text: Dally §8.3
Always Block Synthesis Rules for
Combinational Logic

Slide Set #6 91
Most important few slides in this course!

If write all your Verilog in one big always


block your code probably will not work!

Why?

Next slides will tell you and explain what


you need to do to ensure your Verilog
works.

Slide Set #6 92
VHDL Code
Verilog

The synthesis tool


Synthesis Tool “compiles” the Verilog into
(eg. Quartus II) gates. Makes hardware out
of Verilog.

Gates and Registers

Slide Set #6 93
VHDL Code
Verilog

What do you think happens


Synthesis Tool if the synthesis tool can not
(eg. Quartus II) make hardware for your
Verilog?

Gates and Registers The gates will not implement the


behaviour you specified…
If you are lucky, you get an error
message (or warning)
Your circuit won’t implement the
behaviour you specified

Slide Set #6 94
“Synthesizable” Verilog

Not all Verilog code can be synthesized by current tools.


- This isn’t limited to our tools (Quartus)

Synthesizable Verilog is a subset of Verilog that can be synthesized


by current tools.

If you write Verilog that is not synthesizable:


- Tools will not be able to create hardware
- Sometimes it will try, but end up with something that is
“not quite right”
- Sometimes you get an error message, sometimes you don’t!

Moral: if you are going to synthesize, always write Synthesizable Verilog!

Slide Set #6 95
But what sort of Verilog is Synthesizable?
In general, it depends a bit on the tools.

RTL-level Synthesis Tools: can handle a fairly small subset.


There is even an industry standard: “1364.1-2002 - IEEE
Standard for Verilog Register Transfer Level Synthesis”

Behavioural Synthesis Tools: larger subset


To make sure your Verilog is synthesizable, every always block must be one
of four types. The first type is “purely combinational” (we’ll see other
types later).

In the next three slides, I am going to explain rules to ensure your Verilog
for combinational logic is synthesizable by all tools.

Slide Set #6 96
Type 1: Purely Combinational: All outputs are a function
only of the present inputs (outputs do not depend upon
previous inputs).

always @(sel or A or B) begin


if (sel == 1'b0)
Y = A;
else always_comb begin
Y = B; if (sel == 1'b0)
end Y = A;
else
always @(*) begin Y = B;
if (sel == 1'b0) end
Y = A;
else
Y = B;
end

Slide Set #6 97
For purely combinational always blocks:

Rule 1: Every input that can affect the output(s) must be


in the sensitivity list or use the wildcard @(*) or use
SystemVerilog “always_comb” instead of “always”

Rule 2: Every output must be assigned a value for every


possible combination of the inputs

WARNING: Everyone remembers Rule 1 but many forget Rule 2.

Forgetting Rule 2 will cost you HOURS or even DAYS of extra debugging
due to “inferred latches” (see HDL Tools Tutorial). If you use
always_comb, you’ll get an error if you forget Rule 2.

Slide Set #6 98
This would not be synthesizable This would not be synthesizable
(violates Rule 1): (violates Rule 2):

always @(A or B) begin always @(SEL or A)


if (SEL == 1'b0) if (SEL == 1'b0)
Y = A; Y = A;
else
Y = B;
end

Warning (10235): Verilog HDL Warning (10240): Verilog HDL Always


Always Construct warning at Construct warning at ss6.v(164):
ss6.v(152): variable "SEL" is read inferring latch(es) for variable "Y",
inside the Always Construct but which holds its previous value in one
isn't in the Always Construct's or more paths through the always
Event Control construct
Slide Set #6 99
Check Synthesis results using
“RTL Viewer” in Quartus

Use RTL viewer for labs and while studying for midterm.
Helps you develop better intuition for Verilog; catch
design errors. Slide Set #6 100
IMPORTANT: If you write Verilog that connects
output of combinational logic back to input (possibly
through some other combinational logic block) you’ll
get warnings in Quartus about “combinational loops”
and/or inferred latches. ModelSim will not give you
any warnings and may (or may not) hit an “iteration
limit” error. Synthesize with Quartus and check
warnings!

Check synthesis warnings for warnings about


combinational loops. Almost always a bug.

always @(*) begin


if (sel == 1'b0)
Y = Y; // DO NOT DO THIS!!!
else
Y = B;
end
Slide Set #6 101
Synthesis Rules – Summary (for now)
• We just introduced our first ”synthesis rule”.
Use it when you want to design combinational
logic with an always block.
• After we talk about sequential logic we will
introduce a few more synthesis rules.
• However we will see the final and most
important rule will be: Every use of an always
block must match one of the synthesis rules.

Slide Set #6 102


Preview: Flip-flops and registers?
• Verilog has no built-in way to describe flip-flops
– because it’s secretly a simulator construction language
– but has syntax that looks like it does, presumably to confuse everyone

• registers are inferred from


– declaration syntax, and
– how you use them

• example: reg [3:0]  maybe a four-bit register, maybe not

(yes, this is as insane as it sounds)


A flip-flop: the simulator view

D-flip-flop rules:
– at the rising edge of clk, D copied to Q
– Q retains value until next rising edge of clk
module dff(input clk, input D, output Q);
variable to retain value reg r;
(you can think of this as the reg) assign Q = r; rising edge of clk
always_ff @(posedge clk) begin
block executed whenever r <= D;
nonblocking assignment
event posedge clk happens end
endmodule: dff for register updates
(more on this a bit later)

Advice: don’t think about the simulator view


Synthesis rules for inferring flip-flops
• remember: reg may or may not create a register

• synthesis tools infer a register when:


– a variable is declared as reg
– variable is written in exactly one always_ff @(posedge somesignal)
block
• somesignal becomes the register’s clock
– and is not written or assigned elsewhere in any way

• this pattern ensures DFF behaves the same way


in simulation and in real hardware
A flip-flop: the synthesis tool view

module dff(input clk, input D, output reg Q);


always_ff @(posedge clk) begin
Q <= D;
end
endmodule: dff
infer flip-flop
pattern matches

Advice: just memorize the patterns and don’t think about it


source: Disney
Testing and Testbenches

Slide Set #6 108


Slide Set #6 109
Testbench Scripts in Verilog

• Goal: Test if our design works before building


hardware.
• If design does not work (as it frequently won’t,
at least initially) our testbench makes it easier
to identify bugs during simulation.
• Important: Test script Verilog is not meant to
be synthesized into hardware (i.e., gates). Test
script Verilog is only used for simulation. In
example we will identify syntax/styles that
should NOT be used in synthesizable Verilog.
Slide Set #6 110
Text: Dally §3.6
ModelSim vs Quartus
• ModelSim: Used for simulation. Why
simulate? To verify our design is correct
BEFORE either building custom hardware
(expensive) or “programming” FPGA (harder
to debug). Does NOT perform synthesis.
• Quartus: Used for implementation. Performs
synthesis (use algorithms like KMAP to
determine which gates implement the same
behavior you seen in simulation).

Slide Set #6 111


Terminology
“Test Script”
Q1. Draw a logic
diagram for an XOR
gate using only NAND
“Device Under Test”
and NOT gates.

Output from “DUT”

Slide Set #6 112


The Initial Block (used in testbenches ONLY)

initial begin
<sequence of statements in which order matters; delays allowed>
end

- Initial blocks are not synthesizable – use ONLY for test bench ”scripts”
- Each initial block describes a sequence of operations
- Delays allowed
Syntax: #<number of time units> ;

Example:

#10;

The line above means the enclosing initial block should wait
10 “time units” before executing the next statement.

Slide Set #6 113


Test benches use a very different style
of Verilog
• Initial statements
• $display
• Repeat and other looping constructs
• #delay

• Don’t use these constructs in synthesizable


modules

Slide Set #6 114


Test Bench (test_maj)

in
Test Script DUT
(process) out (majority)

[http://www.servicenoodle.com/lighthouse-auto-sales-and-repair-p-552966]

module Majority(a, b, c, out) ;


input a, b, c ;
output out ;
assign out = (a & b)|(a & c)|(b & c) ;
endmodule

Slide Set #6 115


Text: Dally §3.6
We must use
Testbenches wire
have NOforinputs
module test_maj ; or”out” because
outputs! Thisittest_maj
is is
We must use reg reg [2:0] in ; // input -
driven
used three bit
by the
as the counter
top module
level
here because “count” wire out ; // output of majority
instantiation
module for
when simulating
is driven (i.e., written Majority.
// instantiate the gate design under test Majority.
to) from inside the
Repeat the block of Majority m(in[0],in[1],in[2],out) ;
“initial” block.
code 8 times.
// generate all eight input patterns
initial begin Instantiate an instance of Majority to
#100 means wait 100
in = 3'b000 ;
time steps before use as a “design under test” (DUT).
repeat (8) begin
going to the next line. #100 ;
$display("in = %b, out = %b",in,out) ;
$display is similar to in = in + 3'b001 ;
“printf” in C. end
end The initial block operates in parallel
endmodule with the module instance “m” of
Majority. Starts at time=0.

This Verilog is NOT synthesizable. It is a testbench


used ONLY for testing and debugging.
Slide Set #6 116
Text: Dally §3.6
Testbench Output (ModelSim)
in = 000, out = 0
in = 001, out = 0
in = 010, out = 0
in = 011, out = 1
in = 100, out = 0
in = 101, out = 1
in = 110, out = 1
in = 111, out = 1

Slide Set #6 117


Text: Dally §3.6
How to write test scripts?
• First: Think of waveform you want as input. How? Consider
“corner cases” – ask yourself “what might break?”
• Second: Write the script.
• Example: Suppose want inputs “A” and “B” to look like this:
1
A
0

1
B
0

0 5 10 15 20 25 30 35 40 45 50

Time

Slide Set #6 118


module AB_test ;
reg A, B; // input
wire out ; // output of DUT

// instantiate design under test 1


A
Foo DUT(A,B,out); 0

1
// generate input patterns here B
initial begin 0

// t=0 (time elapsed so far) 0 5 10 15 20 25 30 35 40 45 50


A = 1'b0; B = 1'b0;
Time
#10 ;
// t=10
A = 1'b1;
#5 ;
// t=15
B = 1'b1;
#5 ;
// t=20
A = 1'b0;
#20 ;
// t=40
B = 1'b0;
#10 ;
// t=50
$stop(0);
end Slide Set #6 119
endmodule
What to test?
• If feasible: everything! Only smaller designs.
• For larger designs testing “everything” is not feasible.
In that case, you focus on “corner cases” and things
“that could go wrong”.
• At a minimum, each line of your synthesizable Verilog
code should be “exercised” by at least one test in your
testbench. That means that line does something for
that test. This is not a guarantee you are testing
everything, but a good start.
• No complete algorithm / recipe. “Formal verification”
is one approach but currently “blows up” for large
designs. One can speculate machine learning could be
used to lower human effort—likely won’t be foolproof.
Slide Set #6 120
Strategies for Designing Tests
• Start simple and built up:
– Test functionality of single blocks (unit testing).
– Test combinations of blocks (full system testing).
• Test both what should happen does happen AND
what should NOT happen does NOT happen.
– If an output should be 0 for this input, is it?
• Use regularity to cut down the number of tests:
– If 32-bit adder correctly adds 0+0, 0+1, ... 19+19, and
23244501+7984, it very likely works for all positive
integers.

Slide Set #6 121


Debugging
• Two issues students face:
– Syntax errors
– Simulation (design) errors

• Video walk through of debugging techniques


using HDL tutorial as an example.
https://youtu.be/2c3CZouKJKs

Slide Set #6 122


Simulation (Design) Errors
?
?
Hardware defined
by Verilog
Inputs Outputs
statement (e.g.,
always block) 

1. Use ModelSim waveform viewer to identify error symptom.


2. Trace to cause by finding the block that is the signal’s driver.
3. First check inputs to block in waveform viewer to verify they
look OK.
4. If (a) all inputs to this block look OK,
lab1_top DUT (then problem is the
.not_LEFT_pushbutton(~sim_LEFT_button),
Verilog for that block (examine Verilog for THIS BLOCK ONLY,
.not_RIGHT_pushbutton(~sim_RIGHT_button),
until you understand why output.A(sim_A), is different than expected
.B(sim_B),
when inputs look OK). If (b).result(sim_result)
an input to this block is not OK
trace backward to source);block
Slide Set #6
and go to 3. 123
Possibility (a) Input Looks Correct

Inputs

✔ Hardware defined
✔ by Verilog
Outputs
statement (e.g.,
✔ always block) 

Examine Verilog for THIS block carefully


(most likely THIS is where the root cause of the bug is)
Video with more details: https://youtu.be/2c3CZouKJKs
Slide Set #6 124
Example
pb_top DUT (
.not_LEFT_pushbutton(~sim_LEFT_button),
.not_RIGHT_pushbutton(~sim_RIGHT_button),
.A(sim_A),
.B(sim_B),
.result(sim_result)
);

module pb_top (
input not_LEFT_pushbutton,
input not_RIGHT_pushbutton,
input [3:0] A,
input [3:0] B,
output reg [3:0] result );
...
always @* begin
case( {LEFT_pushbutton, RIGHT_pushbutton} )
2’b01: result = ADDed_result;
2’b10: result = ANDed_result;
2’b11: result = ADDed_result; // Right push button takes precedence
endcase
end
Slide Set #6 125
Possibility (b) Input Looks Wrong

Inputs

✔ Hardware defined

 by Verilog
statement (e.g.,
Outputs

✔ always block) 

“Garbage In, Garbage Out”

Slide Set #6 126


Hardware defined
by “2nd” Verilog 
statement (e.g.,
always block)

Hardware defined
by “1st” Verilog 

statement (e.g.,
always block)

Repeat process starting from this block

Slide Set #6 127


Example

module NAND_GATE(A,B,Z); A Z
input A, B ;
A Z
B
output Z ;
assign Z = (A & B); NAND_GATE INV_GATE
endmodule

module INV_GATE(A,Z);
input A;
output Z;
assign Z = ~A;
endmodule

module AND_GATE (IN1, IN2, OUT1);


input IN1, IN2;
output OUT1;
wire X;
NAND_GATE U0 (IN1, IN2, X);
INV_GATE U1 (X, OUT1);
endmodule
Slide Set #6 128
Add Internal Signals to ModelSim
Waveform Viewer
A Z A Z
B
NAND_GATE INV_GATE

Slide Set #6 129


9 Rules of Debugging (D. Agans)
https://goo.gl/MgvFRc
Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and
Hardware Problems

1. Understand the system


2. Make it fail
3. Quit thinking and look
4. Divide and conquer
5. Change one thing at a time
6. Keep an audit trail
7. Check the plug
8. Get a fresh view
9. If you didn’t fix it, it ain’t fixed
Slide Set #6 130
The “Top Level” Module
• In “C” a program starts with “main()”.
• What is the equivalent to “main()” in Verilog?
• In Verilog you must specify a “top level module”. It can
be called anything you want, and it can instantiate
other modules. The name of the top level module
does NOT need to match the file name, etc…
• You specify the top level module to use when starting a
simulation in ModelSim transcript window as follows:
vsim <top_level_module_name>
• In Quartus you specify the top level module when
setting up the project and can change it by going to:
Assignments >Settings… > General > Top-level entity.

Slide Set #6 131


Top Level Module vs. Pin Assignments

• Only the top-level module connects to pins on the FPGA


inside your DE1-SoC.
• The mapping between I/O names in the top level module and
pins on the FPGA is specified using the pin assignments file.
Slide Set #6 132
Relevant CPEN 211 Style Guidelines
• Combinational modules use only
1. Assign statements
2. Case or Casex statements (with default)
3. If statements – only if all signals have a default assignment
4. Instantiations of other combinational modules
• Do not use
1. Loops
2. Always blocks except for case, casex, or if
• Logic is organized into small modules
1. Leaf modules not more than 40 lines
2. If it could be made two modules, it should be
• Activation lists (sensitivity list) for case statements include ALL inputs (or use *)

Slide Set #6 133


Summary
• Learned how to convert Boolean expressions into logic
gates
• Learned some Synthesizable Verilog
– Module instantiation (implicit vs. named)
– Bus notation
– Module parameters
– Arbiter example combining above
– Always block: syntax, semantics and rules for describing
combinational logic behavior
• Learned how to write simple Verilog testbenches
– How to write a test script
– Strategies for designing tests
– Recommended “debugging strategy” to isolate simulation
(i.e., design) errors in Verilog
Slide Set #6 134

You might also like