Verilog HDL

Download as pdf or txt
Download as pdf or txt
You are on page 1of 180

Verilog HDL

Workshop Goal

Introduction to Verilog as a simulation


language/environment as well as a description language
for RTL Synthesis.

2
Workshop Prerequisites

You should have knowledge of the following:


l Digital Logic design
l Linux/UNIX and X-Windows
l A Unix based text editor

3
The Verilog® Language

Throughout the class, as new language constructs etc


are introduced they are marked with one of the
following icons depending upon whether they are
synthesizable or not or simply ignored:

Synthesizes Synthesizes Ignored

Focus in on the Verilog language, NOT the tools!

4
Course Outline
Day 1
• Lexical Conventions
• Module anatomy
• Port declarations
• Module instances
• Data types
• Nets, registers, parameter
• Procedural blocks
• Timing
• controls, event queue
• Blocking/Non blocking Proc.
• Operators

Day 2
• Programming statements
• Task & Functions
• Verilog for Test
• X & Tri-State Buffers
• Gate-level Modeling
• Finite State machines
5
Day 1
What is a Hardware Description Language?

Two things distinguish an HDL from a linear language like “C” :

• Concurrency:
– The ability to do several things simultaneously
• i.e. different code-blocks can run concurrently
• Timing:
– Ability to represent the passing of time and sequence events
accordingly

A powerful feature of the Verilog HDL is that you can use the same
language for:
• Describing Design (RTL/Behavioral)
• DescribingTestbench
• Simulation
• Synthesis
• Netlist Output

7
Synthesize or Simulate?

At the RT Level, language issues blur somewhat:


– Are you modeling a design for simulation?
– Are you describing the design to a synthesis tool?

Compromise, because both apply:


– Must simulate the design & the target system
– Do not need a simulator for successful synthesis
– Synthesis uses a subset of the Verilog language
– Good code for synthesis may not be fastest to simulate
– Synthesis tools require partitioning/structure, not useful
in simulation

8
Simulation Environment

control
commands

INPUT OUTPUT

models.v Textual messages

test vectors Simulator Tabular output

libraries Graphical waveform

Assembly/ Visual drawings


Microcode

Feedback

9
What is Synthesis?

Verilog code:
Generic
always @ (A or B or C) Translation Boolean
begin (& syntax-check)
case (1’b1) (GTECH)
A: result = 2’b00; netlist
B: result = 2’b01;
C: result = 2’b10;
default: result = 2’b00;
endcase
end Optimization
Constraints & Target Library
Mapping

Target
Synopsys Technology
HDL-synthesis
Toolset
Netlist

10
Basic Modeling Structure

Module gate, block, chip,


board, system ...

Ports Pins, Interface


Levels of
abstractions
Body always @ (posedge clk)....
Instances assign #3 out=(sel)?in0:in1; Multilevel
Concurrent blocks

11
An Example

12
VCS
VCS stands for Verilog Compiled Simulator

There are two different types of Verilog event based simulators:


• Interpreted
• Compiled
VCS compiles the Verilog source,and links the object files to the
simulation engine to create an executable.

Verilog Object Link


Source files simv
(mem.v (mem.o (executable)
cpu.v) cpu.o)

13
Running the Simulator - VCS
vcs -help lists compile options, runtime options, environment variables
Basic invocation:
vcs file1.v file2.v file3.v … fileN.v
simv Verilog executable generated by VCS

Command line options (commonly used):


-gui Compile for interactive simulation
-R Run after compilation (shell)
-R -gui Run interactively with GUI after compilation
-debug_all Enable full debugging capabilities
-f <filename> Read host command arguments from file
-l<filename> Set log file name
+v2k Compile with support for Verilog 2001 extensions
-sverilog Compile with support for SystemVerilog

14
LEXICAL CONVENTIONS

Basic Verilog rules …

15
White Space
White space is used to separate words and to enhance readability:
• Verilog is a free format language
• White space characters are spaces, tabs, carriage returns, etc
• Verilog ignores these characters except when they separate language
tokens

input a,b,c;

input a, b, c;

input a, b,
c;

c=a;
c=b;

16
Comments
Single line comments:
• Begin with "//" and end with a carriage return
• May begin anywhere on the line
Multiple line comments:
• Begin with "/*" and end with a "*/"
• May begin and end anywhere on the line
• Everything in between is commented out

module pound_one;
reg [7:0] a,a$b,b,c; // register declarations
reg clk;

initial
begin
clk=0; // initialize the clock
c = 1;
forever #25 clk = !clk;
end Coding style tip - Use single
/* This section of code implements line comments for comments.
a pipeline */ Reserve multi-line comments
always @ (posedge clk)
begin for commenting out a section
a = b; of code.
b = c;
end
endmodule
17
Strings

• Strings are enclosed in double quotes and are specified on one line
• Verilog recognizes normal C escape Characters (\t, \n, \\, \",%%).
(prints: tab, new line, \ , “ , %)

Examples:
“String”

"Scott's module is working just great!“

"This format is spaced with a tab \t followed with this“

"\n This puts a newline before this string“

"Address = %h at time %d"


18
Identifiers
Identifiers are names assigned by the user to Verilog objects such as modules,
variables, tasks etc:
• Identifiers must begin with an alphabetical or underscore character
(a-z A- Z _ )
• Identifiers may contain alphabetical characters, numeric, underscores
and dollar signs (a-z A- Z 0-9 _ $)
module pound_one;
reg [7:0] a,a$b,b,c; // register declarations
reg clk;
initial
begin
clk=0; // initialize the clock Identifiers in this module:
c = 1;
forever #25 clk = !clk;
end
/* This section of code implements
a pipeline */ pound_one, a, a$b, b, c, clk,
always @ (posedge clk)
begin
a = b;
b = c;
end
endmodule

19
Escaped Identifiers

The use of escaped identifiers allow any character to be used in an


identifier:
• Escaped identifiers start with a backslash (\) and end with
white space
• Gate level netlist generated by EDA tools often have
escaped identifiers

Examples
\ab#~*this=or=that
\5-6
\bus_a[0]
\bus_a[1]

20
Case Sensitivity

Verilog is case sensitive (so are Synopsys synthesis tools):


• Identifiers that do not match in case are considered unique
• All Verilog key words are in lower case

Examples
module // keyword
Module // unique identifier but not keyword
MODULE // unique identifier but not keyword

Silly example:
module MoDule (mODULE, modulE); //terrifying, but legal J
input mODULE;
output modulE…
...
endmodule

21
Logic values

Verilog has 4 logic Values:

0 zero, low, false, not asserted


1 one, high, true, asserted
z or Z high impedance
x or X unknown

22
Integers & Real Numbers (1/2)
• Verilog numbers may be integers or real numbers
• Integers may be sized or unsized:
Syntax: <size>'<base><value>
where:
<size> is the number of bits
<base is b or B (binary), o or O (octal), d or D (decimal), h or H (hex)
<value> is 0-9 a-f A-F x X z Z ? _
Examples: 2'b01, 6'o243, 78, 4'ha,
• Default radix is decimal:
1 32'd1
• underscores ( _ ) are ignored (use them as you would commas):
836_234_408_566_343
• a "?" is interpreted as Z (high impedance):
2'b?? 2'bzz
• When <size> is less than <value> - the upper bits are truncated:
2'b101 2'b01, 4'hfcba 4'ha

23
Integers & Real Numbers (2/2)

• When <size> is greater than <value>, and the left-most bit of <value> is 0 or 1, then
zero's are extended to <size> bits:
4'b01 4'b0001, 16'h0 16'h0000
4'b11 4'b0011, 16'h1 16'h0001

• When <size> is greater than <value>, and the left-most bit of <value> is an x then the
x value is extended to <size> bits:
4'bx1 4'bxxx1, 16'hx 16'hxxxx

• When <size> is greater than <value>, and the left-most bit of <value> is a z then the z
value is extended to <size> bits:
4'bz1 4'bzzz1, 16'hz 16'hzzzz

• Real numbers may be either in decimal or scientific notation:


• Syntax: <value>.<value> or <mantissa>e<exp>
6.439 or 5.3e6

24
Integers & Real Numbers Examples

3.14 decimal notation


6.4e3 scientific notation for 6400.0
16'bz 16 bit z (z is extended to 16 bits)
83 un-sized decimal
8'h0 8 bits with 0 extended to 8 bits
2'ha5 2 bits with upper 6 bits truncated (binary equivalent = 01)
2_000_000 2 million
16'h0x0z 16'b0000xxxx0000zzzz

25
System tasks & functions Ignored

Specific tasks and functions may be defined by EDA vendors and users to be
used as part of the simulator:
• Begin with the dollar sign ( $ )
• The Verilog standard has a number of standard $ defined
• Users may define their own built in tasks using the Programming
Language Interface (PLI)

List of most commonly used built in tasks and functions:


$monitor Continuously monitors listed signals
$display Prints message to the screen
$time function that returns the current simulation time (64-bits)
$stime like above, but returns truncated lower 32-bits
$stop Halts execution but does not exit
$finish Halts execution and exits the simulation

26
MODULE
module name (port_names);

module port declarations

data type declarations

procedural blocks

continuous assignments

user defined tasks & functions

primitive instances

module instances

specify blocks

endmodule

27
Verilog Module
module name (port_names);

module is a basic building block in Verilog module port declarations

data type declarations


Can be an element or a collection of lower
level design blocks procedural blocks

continuous assignments

module contain: user defined tasks & functions

• Declarations primitive instances

• Functionality module instances

Example: specify blocks

endmodule
module COUNTER (cout, clk, rst) ;



endmodule

28
Module Port Declarations
Scalar (1bit) port declarations:
port_direction port_name, port_name ... ;

Vector (Multiple bit) port declarations:


port_direction [port_size] port_name, port_name ... ;

port_direction : input, inout (bi-directional) or output


port_name : legal identifier
port_size : is a range from [msb:lsb]
Big endian or little endian may be used.
Literal integers or parameters may be used.

input a, into_here, george; // scalar ports


input [7:0] in_bus, data; //vectored ports
output [8:31] out_bus; //vectored port
inout [maxsize-1:0] a_bus; //parameterized port

29
Module Instances
Synthesizes
• A module may be instantiated within another module
• There may be multiple instances of the same module
TOP
• Ports are either by order or by name
• Use by order unless there are lots of ports
• Use by name for libraries and other peoples code (may A A
change)
• Cannot mix the two syntax's in one instantiation
B

syntax for instantiation with port order:


module_name instance_name (signal, signal...);

syntax for instantiation with port name:


module_name instance_name (.port_name(signal), .port_name (signal)… );

30
Example: Module Instances
module half_adder (sum, a, b); module register (data_out, data_in, clk, resetn);
output [8:0] sum; output [8:0] data_out;
input [8:0] a,b; input [8:0] data_in;
input clk,resetn;
assign
sum=a+b; reg [8:0] data_out;
endmodule
always @(posedge clk or negedge resetn)
if (!resetn) out<=0;
else out<=in;
endmodule

module integrator (out, in1, in2, myclk, clr_n);


output [8:0] out;
input [8:0] in1, in2;
input myclk, clr_n;
wire [8:0] a1;

register U1 (out, a1, myclk, clr_n) By port order


half_adder U2 ( .sum(a1), .b(in1), .a(in2) );
By port name
endmodule
31
Module Header Format

Traditional header format Newer header format


module count(Cout,Cin,clk); module count(output Cout,
input Cin, clk);
input Cin, clk;
reg CoutR;
output Cout;
assign Cout=CoutR;
reg Cout;
………
…….
endmodule
endmodule

32
Exercise

n Write a module description for a block with the name


COUNTER
n Input ports: clk, reset, load, data
n Output ports: count
n Note: data and count are 4 bits wide

33
Answer

module COUNTER (clk, reset, load, data, cout) ;

input clk, reset, load;


input [3:0] data;
output [3:0] cout;

endmodule

34
Data Types

Three data type classes:


Nets:
• Physical connections between devices
Registers:
• Storage devices, variables
Parameters:
• Constants

syntax:
data_type identifier, identifier... ;
or
data_type [msb:lsb] identifier, identifier ... ;

35
Nets
• Connect devices
• Are continuously driven by the device that drives them
• New values are propagated automatically when the driver changes

wire, tri standard basic interconnect


wor, trior Synthesizes
wired-OR outputs
wand, triand Synthesizes wired-AND outputs
tri0 Synthesizes
pulls down when tri-stated
tri1 Synthesizes
pulls up when tri-stated
trireg Synthesizes
stores last value when tri-stated
supply0, supply1 constant 0 or 1

Examples
wire a,b; // scalar wires
wor [7:0] in_bus; // wired-OR bus
wand [8:31] out_bus; // wired and bus

36
Registers
• Variables in Verilog
• Represents storage devices
• Not necessarily represents flip-flop or latches

reg unsigned variable of any size


integer signed 32-bit variable
time unsigned 64 bit variable Synthesizes

real signed floating point variable of double precision Synthesizes

reg a; // scalar reg variable


reg [7:0] in_bus; // vectored reg variable
integer i, j; //32 bit signed variables
time t; // unsigned 64 bit variable
real b,c; // signed floating point variables

reg [3:0] status = 4’b0; // Combined declaration and initialization


Synthesizes

Equivalent to:
reg [3:0] status;
initial status = 4’b0;

37
Memories

Memories are declared as two-dimensional arrays of registers.

syntax:
reg [msb:lsb] identifier [first_addr:last_addr] ;
where
msb:lsb determine the width (word size) of the memory
first_addr:last_addr determine the depth (address range) of the
memory
mem
255
reg [15:0] mem [0:255]; // 256x16 memory
reg [0:31] mem_a [1023:0]; //1kx32 memory
0
15 0

38
Accessing Memories

Memory locations are accessed using an index.

data_reg = mem[33]; // data_reg gets data at addr 33

Prior to Verilog 2001 a bit or subrange of a location in the array could not
be accessed directly, a temporary variable had to be used.
temp = mem[33]; // data_reg gets data at addr 33
3_bit_reg = temp[8:6]; //get three bits of addr 33
mem
255
temp 3_bit_reg
8 6 2 0

8 6
33
0
15 0
Verilog 2001 finally corrects this: 3_bit_reg = mem[33][8:6];
“address”
dimensions “data”
first (in order) dimensions
(slicing) last
39
Memories – Any-dimension Remember “ +v2k ” at invocation.

Verilog 2001 supports any-dimensional arrays of registers AND nets…


syntax:
reg/net [msb:lsb] identifier [first_addr:last_addr], [first_addr:last_addr] , [… ;
where
msb:lsb determine the width (word size) of the memory
first_addr:last_addr determine each dimension (address range) of the array

reg [15:0] array [0:255] [0:9]; // 256x10x16 memory


wire [0:31] array2 [1023:0] [15:0] [7:0] [2:0]; //1kx16x8x3x32 array

“address”
Addressing Multi-dim arrays: dimensions
first (in order)
reg [15:0] D3 [1023:1020] [15:8] [7:3] [2:0]; // 4x8x5x3 array of 16-bit reg’s
initial begin
D3 [1023] [15] [7] [2] = 16’hFFFF; // store: ffff
D3 [1023] [15] [7] [2] = D3 [1023] [15] [7] [2] –1; // decrement: fffe
$display(“%h”, D3 [1023] [15] [7] [2] [7:0] ); // print: fe
end
“data”
dimensions
(slicing) last

40
Indexed vector part-selects
Bit-selects in verilog expressions may use variables:
reg [63:0] data;
reg data_bit;
reg [7:0] data_byte;
integer bit_sel;

initial begin
data = 32;
bit_sel = 5;
data_bit = data[bit_sel];

// Prior to Verilog 2001, variables may NOT be used for part-selects.


data_byte = data[bit_sel:0]; // Unsupported in any verilog version!

// Verilog 2001 introduces a new syntax…


data_byte = data[bit_sel -: 6]; // Defines a 6-bit slice ( i.e. data[5:0] )
end

New Syntax

base_expr -: offset // neg. offset from base_expr (inclusive)


base_expr +: offset // pos. offset from base_expr (inclusive)

41
parameters Synthesizes

Parameters:
• Run-time constant
• Used anywhere a literal may be used
• For synthesis, must be defined before being used
• Size [msb:lsb] is finally supported by Verilog 2001

syntax:
parameter <[msb:lsb]> identifier = value <, identifier = value ...> ;

examples:
parameter [2:0] a = 1; // 3-bit
parameter // default 32-bit
depth = 32,
width = 8;

42
Parameter redefinition

Currently, Verilog supports two styles of parameter redefinition:

Explicit: defparam hierarchy_path.parameter_name = value;


Implicit: module_name # (value) instance_name (signals);

The Verilog 2001 Standard adds a third style:

In-Line explicit:
module_name # (.parameter_name(value)) instance_name (signals);

43
Explicit Redefinition example
module fifo (d_in, d_out, write, read, full, empty); //module definition
. . .
parameter depth = 32; //parameter. set default depth of 32
. . .
endmodule

module top; // top level module


. . .
fifo fifo_64(d_in_64,d_out_64,write_64,read_64,full_64,empty_64);
// instance of fifo with depth of 64
defparam fifo_64.depth = 64; //override of parameter depth, set to 64

fifo fifo_128(d_in_128 ,d_out_128 ,write_128 ,read_128 ,full_128 ,empty_128);


// instance of fifo with depth of 128
defparam fifo_128.depth = 128; //override of parameter depth, set to 128
. .
endmodule
top

fifo_64 fifo_128

44
Redefinition example (inline-explicit)
module fifo (d_in, d_out, write, read, full, empty); //module definition
. . .
parameter depth = 32; //parameter. set default depth of 32
. . .
endmodule

module top; // top level module


. . .
fifo # (.depth(64)) fifo_64(d_in_64,d_out_64,write_64,read_64,full_64,empty_64);
// instance of fifo with override of parameter depth, set to 64

fifo #(.depth(128)) fifo_128(d_in_128 ,d_out_128 ,write_128 ,read_128 ,full_128 ,empty_128);


// instance of fifo with override of parameter depth, set to 128
. .
endmodule

top

fifo_64 fifo_128

45
Exercise

n Write the register declaration for the following


signals from the module COUNTER:
l Single bit: clk, reset, load
l 4 bits: data, cout
l use parameters instead of literals

46
Answer

module COUNTER (clk, reset, load, data, cout) ;

parameter width = 4;

input clk, reset, load;


input [ width-1:0] data;
output [width-1:0] cout;

endmodule

47
Using the ports of a module Synthesizes

go
clk out out
rst

module incrementer(go, out, clk, rst);


input go,clk,rst; Driving an output port
output [11:0] out; If an output port and a reg variable
share the same name, Verilog infers
reg[11:0] out; a wire of that name connecting the two.
This is called an implicit wire.
So, the port reflects all
always @ (posedge clk or negedge rst) changes in the reg value...
if (!rst)
out = 12’b0;
else if (go)
out = out +1; Reading an input port
An input port can be used directly in
endmodule the code as Verilog infers a wire
by that name also.

48
Port Connection Rules
module
reg
reg -or- net
net
-or- net
net tri tri

Inputs:
• Internally must be of net data type (e.g. wire)
• Externally the inputs may be connected to a reg or net data type
Outputs:
• Internally may be of net or reg data type
• Externally must be connected to a net data type
Inouts:
• Internally must be of net data type (tri recommended)
• Externally must be connected to a net data type (tri recommended)

49
Combined port/type declarations

Verilog 2001 supports co-declaration of a port AND its related variable:


port_direction port_type port_name, port_name ... ;

Vector (Multiple bit) port declarations:


port_direction port_type [port_size] port_name, port_name ... ;

port_direction : input, inout (bi-directional) or output


port_type : is a data type (reg, wire)
port_name : legal identifier
port_size : is a range from [msb:lsb]

input wire a, into_here, george; // scalar ports and nets


input wire [7:0] in_bus, data; // vectored ports and nets
output reg [8:31] out_bus; // vectored port and driving reg
inout wire [maxsize-1:0] a_bus; // parameterized port and net

50
ANSI style port declarations

Port declarations can also be made within the parentheses of the module declaration.

module module_name (port_direction port_type [port_width] port_name,


port_direction port_type [port_width] port_name,
etc ...
);

module MUX2 (output reg [1:0] out,


input wire [1:0] sel,
input wire [1:0] in_a,
input wire [1:0] in_b ) ;

Throughout the rest of this class we will mix ANSI/non-ANSI for illustration.

51
Exercise

What (if anything) is wrong with the following lines of


code?

input parity, data_bus [7:0];


output bit, BIT;
inout [variable +2 : variable] port;
module top;
test test_inst_a(into,reg_a,.outof(outof));
test test_inst_b(into,,outof);

52
PROCEDURAL BLOCKS

53
Procedural Blocks

• There are two types of procedural blocks:


• initial blocks - executes only once Synthesizes
• always blocks - executes in a loop

• Multiple Procedural blocks may be used, if so the multiple blocks are


concurrent

• Execution order of procedural blocks is indeterminate

• Procedural blocks may have:


• Timing controls - which delays when a statement may be executed
• Procedural assignments
• Programming statements

54
Sequential Blocks

n Sequential Blocks
l Statements in a sequential block are processed in the
order they are specified
l A statement is executed only after its preceding statement
completes execution (except for non-blocking
assignments)
l If delay or event control is specified it is relative to the
simulation time, i.e. execution of the previous statement

55
Parallel Blocks

n Parallel Blocks
l Statements in a parallel block are executed concurrently
l Ordering of statements is controlled by the delay or event
control assigned to each statement
l If delay or event control is specified, it is relative to the
time the block was entered

56
Comparison of Sequential & Parallel Blocks

n Fundamental difference between sequential and


parallel blocks:
l All statements in a parallel block start at the time when the
block was entered
l Thus, the order in which the statements are written in the
block is not important

57
initial Statement
• initial block starts at time 0, executes exactly once during a simulation,
and then does not execute again
• In case of multiple initial blocks, each block starts to execute concurrently
at time 0
• Each block finishes execution independently from other blocks

module stimulus;
reg x,a,b;

initial
begin
#5 a = 1'b1; //multiple statements; need to be grouped
#25 b = 1'b0;
end

time statement executed


initial
begin
5 a = 1'b1;
#10 x = 1'b0; 10 x = 1'b0;
end 30 b = 1'b0;
50 $finish;
initial #50 $finish;

endmodule
58
always Statement
• always statement starts at time 0 and executes the statements in the
always block continuously in a looping fashion
• This statement is used to model a block of activity that is repeated
continuously
• An example is a clock generator module that toggles the clock signal
every half cycle

module clock_gen (clock);


output clock;
reg clock;

//Initialize clock at time zero


initial clock = 1'b0;

//Toggle clock every half-cycle (time period = 20)


always #10 clock = ~clock;

initial #1000 $finish;

endmodule

59
Fork-Join Statements Synthesizes

reg x, y;
reg [1:0] z, w;
initial
fork
x = 1'b0; x completes at simulation time 0
#5 y = 1'b1; y completes at simulation time 5
#10 z = {x, y}; z completes at simulation time 10
#20 w = {y, x};
join w completes at simulation time 20

60
Procedural statement groups
When there is more than one statement within a
procedural block the statements must be grouped.

Sequential grouping: Parallel grouping:


always @(posedge clk) initial Synthesizes
begin begin
a = 5; Synthesizes
fork // example of nesting
c = 4; a = 5;
wake_up = 1; c = 4;
end Synthesizes
wake_up = 1;
join
d = 8;
always @(posedge clk) end
a = b;
Synthesizes NOTE: Inside a fork-join
• Statements are executed concurrently.
• Flow does not continue until all statements execute.
NOTE:
• Statements are executed sequentially.

61
Timing Controls (procedural delays)

#delay - simple delay:


Ignored
Delays execution for a specific number of time steps.

#5 reg_a = reg_b;
Synthesizes
@ (edge signal) - edge-triggered timing control:
Delays execution until a transition on signal occurs.
edge is optional and can be specified as either posedge or negedge.
Several signal arguments can be specified using the keyword or.

always @ (posedge clk) reg_a = reg_b;

wait (expression) - level-sensitive timing control:


Delays execution until expression evaluates true.
Synthesizes

wait (cond_is_true) reg_a = reg_b;

62
Simulation Time & Event Queues

Event Queues time


t

t+1

t+2

t+3

• Time can only advance forward


• Time advances when every event scheduled at that time step is executed
• Simulation completes when all event queues are empty
• An event at time t may schedule another event at time t or any other time t+n

63
Zero time loops

A zero time loop is encountered when events are continuously scheduled at


a time step without advancing time.
• Characterized by the simulator appearing to "hang"
Example
always a = b;

This causes the event a <-- b to be continuously scheduled and executed at


time t. Time can not advance beyond the start time t.

a<-b a<-b a<-b a<-b a<-b t

t+1

64
"Deadlocks"

A "deadlock" is encountered when a portion of the code is waiting for


events to occur and no events are being scheduled.

• Characterized by simulation finishing apparently in a


premature fashion

• Simulation finishes because no events are scheduled

65
Procedural assignments Synthesizes

Assignments made within procedural blocks are called procedural assignments:


• Value of the RHS of the equal sign is transferred to the LHS
• LHS must be a register data type (reg, integer, real or time). NO NETS!
• RHS may be any valid expression or signal
• Two types of procedural assignments:
• Blocking
• Non blocking

always @ (posedge clk)


begin
a = 5; // procedural assignment
c = 4*32/6; // procedural assignment
wake_up =$time; // procedural assignment
end

66
Blocking Assignments Synthesizes

• RHS expression evaluated


• Assignment is scheduled
• Flow blocks until assignment is executed

initial Time
begin
a = b; a<-b(t) t
Event Queues c<-d(t) t’ t
c = d;
e = f; e<-f(t) t’’
end t+1
t+2
t+3
<-- Execution order

67
Delayed Blocking assignments

• Evaluation of the assignment is delayed by the timing control


• RHS expression evaluated
• Assignment is scheduled
• Flow blocks until assignment is executed

initial Event Queues Time


begin
t
#1 a = b;
end a<-b(t+1) t+1
t+2
equivalent to...
begin t+3
#1; <-- Execution order
a= b;
end

68
Delayed Blocking assignments

initial Event Queues Time


begin
t
#1 a = b;
#1 c = d; a<-b(t+1) t+1
#1 e = f; c<-d(t+2) t+2
end
e<-f(t+3) t+3
equivalent to… <-- Execution order
begin
#1;
a= b; LHS delays are additive with blocking assignment.
#1;
c=d;
#1;
e=f;
end

69
Blocking Intra-procedural delayed assignment

• RHS expression evaluated


• Assignment is scheduled but delayed by the timing control
• Flow blocks until assignment is executed

Event Queues Time


t
a<-b(t) t+1
initial
begin t+2
a = #1 b; t+3
end
<-- Execution order

- This construct is completely useless


70
Blocking Intra-procedural delayed assignment

initial Event Queues Time


begin t
a = #1 b;
a<-b(t) t+1
c = #1 d;
e = #1 f; c<-d(t+1) t+2
end t+3
e<-f(t+2)
<-- Execution order

RHS delays accumulate with blocking assignment.

71
Quiz

always @ (posedge clk)


a = b;

always @ (posedge clk)


b = c;

Assume b = 3 and c = 5
After the first @ (posedge clk)
what is the value of a?

72
Quiz

always @ (posedge clk)


begin
a = b;
b = a;
end

After the first @ (posedge clk),


does this do a swap?

73
Non-blocking Assignments Synthesizes

• RHS expression evaluated


• Assignment is scheduled at the end of the queue
• Flow continues on
• Assignment is made at end of the time step

initial Event Queues Time


begin
a<-b(t) t
a <= b;
end t+1
t+2
t+3
<-- Execution order

74
Race solved!

always @ (posedge clk)


a <= b;

always @ (posedge clk)


b <= c;

a always gets the value in b


Event Queues Time
a<-b(t) b<-c(t) t
t+1
t+2
t+3
<-- Execution order

75
Swap Accomplished!

always @ (posedge clk)


begin
a <= b;
b <= a;
end

a always gets b, b always gets a

Event Queues Time


b<-a(t) a<-b(t) t
t+1
t+2
t+3
<-- Execution order

76
Mixed Blocking and Non-blocking
Synthesizes

initial
begin Event Queues Time
a = b; c<-d(t) c<-f(t) a<-b(t) t
c <= d; t+1
c = f;
end t+2
t+3
DON’T DO!! <-- Execution order

Synthesis Tip!
The mixing of blocking and non-blocking assignments in a
procedural block is not allowed for synthesis.

Each reg variable may be assigned by only one type of


assignment (blocking/non-blocking) per module.

77
Delayed Non-blocking Assignments

initial • Evaluation of the assignment is delayed by the timing


begin control
#1 a <= b; • RHS expression evaluated
end
• Assignment is scheduled at the end of the queue
• Flow continues on
• Assignment is made at end of the time step

Event Queues Time


t
a<-b(t+1) t+1
t+2
t+3
<-- Execution order

78
Non-blocking Intra-procedural delayed
Assignments

initial • RHS expression evaluated


begin • Assignment is delayed by the timing control and is
a <= #1 b; scheduled at the end of the queue
end • Flow continues on
• Assignment is made at end of the time step

Event Queues Time


t
a<-b(t) t+1
t+2
t+3
<-- Execution order

79
Non-blocking Intra-procedural delayed Assignments

initial
begin
a <= #1 b; Event Queues Time
c <= #1 d;
e <= #1 f; t
end e<-f(t) c<-d(t) a<-b(t) t+1
t+2
t+3
<-- Execution order

RHS delays do not accumulate with non-blocking


-but-
LHS delays would accumulate same as in blocking case.

80
Procedural blocks Synthesis Tips!

An always block can be used to describe logic which is...


sequential -or- combinational
always @ (posedge clk or negedge rst)
if (!rst)
begin always @ (a or b or d)
a <= 0;
c <= 0;
c = a & b & d;
e <= 0;
end
else
begin
a <= b;
c <= d; Because no edge is specified:
e <= f;
end
• Usually synthesizes into combinational
logic but...

Because an edge is specified: • Look out for accidentally inferred


• variables on LHS will be registered (a,c latches (described later in course!)
and e above)
For multi-variable sensitivity lists(like here):
• If any specify an edge, they all must
For asynchronous signals like reset or set:
• Must specify an edge of asynchronous
signal in the sensitivity list.
• The asynchronous signal should be the
first one checked in the if.
81
Rules of Thumb - 1

Synthesis Tip!
Use blocking assignments for combinational always blocks
and do not use delays...

Example
always @(dat)
i_dat = ~dat;

For Testbenches & other non-synthesizable Verilog:

• When the RHS is a fixed value, use a blocking assignment


• Any procedural delay should appear on the LHS

• Do not use non-blocking assignments, which tend to be


confusing this type of situation
a= #5 b;
Examples

#5 a = `FALSE; #5 a= b;
#5 b = 42;
#5 c = c+1; // inc/decrement of values

82
Quiz

Consider the following code:


`define FALSE 0
`define TRUE 1
initial
begin
a = `FALSE;
a <= `TRUE;
if (a == `TRUE)
$display ("True");
else
$display ("False");
end

What will print out? True or False?

83
Rules of Thumb - 2
Synthesis Tip!
Use non-blocking assignments exclusively for sequential always blocks.
Adding a RHS delay, produces an ‘intuitive’ transport delay in simulation
and makes waveforms easier to read.
Example
always @(posedge CLK)
Q <= #1 D;

For Testbenches & other non-synthesizable Verilog:

When the RHS is a "sampled" value, use a non blocking assignment.


Any procedural delay should appear on the RHS.
Do not use a simple procedural delay. a <= #5 b;
Examples of "sampled” values would be registers and wires
driven by another concurrent block.

Examples #5 a <= b;
a <= #5 b; // where b is a register
c <= #5 d; // where d is a wire

The procedural delay (#) on the RHS best models propagation delay as an
engineer understands it.

84
Event Control

n The @ symbol is used to specify an event control


n Statements can be executed on changes in signal value or at a positive
or negative transition of the signal value
n The keyword posedge is used for a positive transition and negedge for
negetive transition

@(clock) q = d; //q = d is executed whenever signal clock changes value


@(posedge clock) q = d; //q = d is executed whenever signal clock does
//a positive transition ( 0 to 1,x or z,
// x to 1, z to 1 )
@(negedge clock) q = d; //q = d is executed whenever signal clock does
//a negative transition ( 1 to 0,x or z,
//x to 0, z to 0)
q = @(posedge clock) d; //d is evaluated immediately and assigned
//to q at the positive edge of clock

85
Assignments and Synthesis (1) Synthesis Tip!

module two_stage(Q, D, CLK);


input D, CLK; P
output Q;
Q1. Does this simulate a pipe ? D Q
reg Q, P; A1. _____
CLK
always @ (posedge CLK)
begin
Q = P;
Q2. Which does it synthesize into?
P = D; A2. ___________
is_a_pipe
end
Forbidden
by R.O.T. #2

module two_stage(Q, D, CLK);


input D, CLK;
output Q;
Q3. Does this simulate a pipe ? D P
A3. _____
Q
reg Q, P; CLK

always @ (posedge CLK) Q4. Which does it synthesize into?


begin A4. ___________
P = D; not_a_pipe
Q = P;
end
Conclusion: Blocking assignments are order
dependent (for both simulation and synthesis)

86
Assignments and Synthesis (2) Synthesis Tip!

module two_stage(Q, D, CLK);


input D, CLK; P
output Q;
D Q
reg Q, P; Synthesizes into this...
CLK
always @ (posedge CLK)
begin
Q <= P;
P <= D;
end
R.O.T. #2

module two_stage(Q, D, CLK);


input D, CLK;
output Q; P

reg Q, P; Synthesizes into this... D Q

always @ (posedge CLK) CLK


begin
P <= D;
Q <= P;
end

Conclusion: Non-blocking assignments are order independent!

87
OPERATORS

88
Lexical Conventions: Operators

n Operators
l Unary operators
u stand before the operand
l Binary operators
u stand between two operands
l Ternary operators
u have two separate operators that separate three operands

89
Operators
Arithmetic +,-,*
Other arithmetic /,% Synthesizes
HDLC 2000+
Verilog 2001
Power **
Synthesizes
Presto 2000+

Bitwise ~, &,|,^,~^
Unary reduction &,~&,|,~|,^,~^
Logical !,&&,||
Equality ==,!= (0,1)
Identity ===,!== (0,1,x,z) Synthesizes

Relational <,>,<=,>=
Logical shift <<,>>
Conditional ?:
Concatenate {}
Replicate {{}}

90
Examples of Operators
reg [3:0] r1, r2, r3;
reg aa, bb;
initial begin
r1 = 4'b0101;
r2 = 4'b1100;
end
// Bitwise operators:
r3 = r1 & r2; // AND each bit of r1 with r2 (4'b0100)
r3 = r1 ^ r2; // Excl-OR each bit of r1 with r2 (4'b1001)
// Note: hi-impedance (z) bits are treated as if they were unknown (x)

// Logical operators: ‘0’ if all bits are zero, ‘1’ if any bits are non-zero
aa = r1 && r2; // 1-bit result of AND’ing logical values (1 or true)
bb = ! r2; // 1-bit result, the invert of logical r2 (0 or false)

// Reduction operators: think of a wide gate


aa = ~& r2; // 1-bit result of NAND’ing all bits of r2 (1'b1)

91
Examples of Operators (cont’d)

reg [3:0] r1, r2, r3, r4;


reg aa, bb ;
initial begin
r1 = 4'b0101;
r2 = 4'b1100;
r3 = 4'b0011;
aa = 1;
bb = 0;
end

Concatenation & Replication:


r1 = { 4 { aa } }; // Replicate a single-bit four times (r1 == 4'b1111)

{r2 , r1} = { {6 { aa }} , {2 { bb }} }; // Concatenate on LHS, Replicate on RHS


// (r2 == 4'b1111, r1 == 4'b1100 )

{aa, bb, r1} = { { 2 { 1’b0 }}, r2 >> 2 }; // Replicate, right-shift & concatenate
// left / right shift zero fills
// ( aa == 0, bb == 0, r1 == 0011 )

92
Examples of Operators (cont’d)
reg [3:0] r1, r2, r3, r4, r5;
reg aa, bb, gate ;

Conditional:
r1 = gate ? r2 : r3; // gate selects between r2 or r3
// syntax: LHS = sel ? (sel == true) : (sel == false);
// synthesizes into MUX logic

Nested Conditional:
r1 = (aa == 0 ) ? ( (bb == 0) ? r2 : r3) : r4;
or
r1 = {aa,bb} == 0 ? r2 :
aa bb one
{aa,bb} == 1 ? r3 :
0 0 r2
{aa,bb} == 2 ? r4 : r4; 3:1 0 1 r3
1 0 r4 4:1

1 1 r5
QUIZ: Convert this 3:1 MUX to a 4:1 MUX (see table)

93
Signed Arithmetic
Synthesizes

In Verilog, the result of an arithmetic expression is determined from the type


of the operands. If either operand is unsigned, unsigned results are returned.
Also, integers are signed 32-bit variables (preventing non 32-bit arith. logic).

Verilog 2001 provides 5 new features:


• Reg and net datatypes can be declared as signed (new keyword signed )
• Function return values may be declared as signed
• Integer numbers in any radix can be declared as signed (new specifier “s” )
• Operands can be converted between unsigned & signed ($signed, $unsigned)
• Arithmetic shift operators have been added

reg signed [11:0] dat; // 12-bit signed reg


output signed [11:0] dat; // 12-bit signed output port
function signed [127:0] calc; // 128-bit signed function

dat = 12’sh cad; // ‘s’ signifies a signed value

94
Bit lengths resulting from expressions

In general, the bit-length result of an expression is determined from the length of


the operand(s).

In most cases this length is the length of the longer operand:

reg[3:0] A,B;
reg[2:0] C;

A – C, A & C, A^C, A%C, A/C 4-bit result


B?A:C also a 4-bit result (Length of B unimportant)

There are some obvious exceptions:

A*C 7-bit result (Sum of operand lengths)


A << C 4-bit result (shift-count doesn’t affect length)

Unary & Reduction operators always yield single-bit results.

95
Operator Precedence

Operators Operator Symbols Highest Precedence


Unary +-!~
Multiply, Divide, */%
Modulus
Add, Subtract +-
Shift << >>
Relational < <= > >=
Equality == != === !==
Reduction &, ~&
^, ^~
|, ~|
Logical &&
||
Conditional ?: Lowest Precedence

96
Example: Putting it all together
ADDER
16
in_1

+
16
add_out
16
in_2

module ADDER (add_out, in_1, in_2) ;

parameter width = 16;

output [width : 0] add_out;


input [width – 1: 0] in_1, in_2;
reg [width : 0] add_out;

always @( in_1 or in_2)


add_out = in_1 + in_2;

endmodule

97
Day 2
Rules Of Thumb

Yesterday, we developed two Rules of Thumb for Procedural code.

R.O.T #1

Use blocking assignments for combinational always blocks


and do not use any delays...

Example
always @(a) a b
b = a;

R.O.T #2

Use non-blocking assignments exclusively for sequential always blocks.


Adding a RHS delay, produces an ‘intuitive’ transport delay in simulation
and makes waveforms easier to read.
Example
always @(posedge CLK) d q
q <= #1 d;
CLK

99
Rules of Thumb - 0

• Be Consistent!

• Apply the ROT’s uniformly!

100
PROGRAMMING STATEMENTS

101
Programming Statements

• Two types of programming statements:


• Conditional
• Looping
• Programming statements only used in procedural
blocks (always or initial)

102
if and if-else Synthesizes

syntax:
if(expression) statement
If the expression evaluates to true then execute the statement (or
statement group).
if(expression) statement1
else statement2
If the expression evaluates to true then execute statement1,
if false, then execute statement2 (or corresponding statement groups).

if (sel) if (sel) if (sel)


out = A; out = A; begin
else out1 = A;
if (sel) out = B; out2 = B;
begin end
out 1= A; else
out2 = B; begin
end “begin end” needed
around multiple
out1 = C;
sequential statements. out2 = D;
end

103
Nested if-else-if

module if_ex( input wire


clk,red,blue,pink,yellow,orange,green,
output reg color);

always @ (posedge clk)


if (red || (blue && pink))
begin Nested if else’s are often
used to
$display ("color is mixed up");
synthesize priority
color <= 0; // reset the color encoding or
end cascading logic.
else if (blue && yellow)
$display ("color is greenish");
else if (yellow && (green || orange))
$display ("not sure what color is");
else $display ("color is black");
endmodule

104
case Synthesizes

syntax:
case (expression)
case_item_1: statement or statement_group
case_item_2,
case_item_3: statement or statement_group Priority encoding
case_item_n: statement or statement_group
default: statement or statement_group
endcase
• Does an identity comparison (but only simulation will match x, z)
• Compares expression with each case_item_(n) in turn
• If none match, the default code is executed
• Default clause is ideal to catch unknown/unspecified values
reg [2:0] reg_a, reg_b;
always @ (posedge clk)
case (reg_a)
3'b000: begin
reg_b <= 0; Begin end needed around
reg_c <= 0; multiple sequential
end statements.
3'b001: reg_b <= 1;
3'b010, // this branch does reg_b <= 3;
3'b011: reg_b <= 3; Comma means OR
default: reg_b <= 5;
endcase
105
casez, casex
Synthesizes

• casez - special version of case that allows the Z logic value in the
case-items (z or ? treated as a don’t care).

• casex - special version of case that allows the Z or X logic value in


the case-items (x or z or ? treated as don’t cares).

reg [2:0] reg_a, reg_b;


always @ (posedge clk)
casex (reg_a) QUIZ:
3'b000: reg_b <= 0;
3'b001: reg_b <= 1; 1. What happens for 3’b011?
3'b01?: reg_b <= 2;
3'b011: reg_b <= 3; 2. Case-items here are not mutually
3'b1x0: reg_b <= 4; exclusive, therefore will you get
default: reg_b <= 5; priority encoding HW or multiplexing
endcase
type HW?

Coding style tip - to save confusion use " ? " as the don't care indicator.

106
Understanding case - 1

Given: reg [2:0] reg_a, reg_b;


always @ (posedge clk)
case (reg_a)
3'b000: reg_b <= 0;
3'b001: reg_b <= 1;
3'b011: reg_b <= 2;
3'b01z: reg_b <= 3;
3'b1x0: reg_b <= 4;
default: reg_b <= 5;
endcase

What branch would be taken if:


reg_a is 3'bxxx
reg_a is 3'b01z
reg_a is 3'b1x0

107
Understanding case - 2

Given: reg [2:0] reg_a, reg_b; QUIZ:


always @ (posedge clk) What branch would be taken if:
casex (reg_a) reg_a is 3'bxxx
3'b000: reg_b <= 0; reg_a is 3'b01z
3'b001: reg_b <= 1; reg_a is 3'b01x
3'b011: reg_b <= 2; What branch would be taken for casez:
3'b01z: reg_b <= 3; reg_a is 3'bxxx
3'b1x0: reg_b <= 4; reg_a is 3'b01z
reg_a is 3'b01x
default: reg_b <= 5;
endcase

108
x’s in Synthesis
Remember: Simulation & Synthesis interpret “X” differently:
Simulation - unknown, Synthesis - don’t care.

Using x in a case_item of a case statement (not casex or casez) may


cause a mismatch. You may get a warning.

case (a)
2'bxx: c = 3; // This branch won't occur in synthesis
default: c = 4;
endcase

Be aware, when assigning X’s they may propagate throughout your


design under simulation:
– Try to limit assignments of X to internal variables, not the output
nodes of your module

109
‘case’ and Synthesis
• In Simulation, case (and if-else) statements are priority encoded

• Priority-encoded hardware is rarely needed and can cost you time/gates

HDL Compiler will yield NON priority encoded logic if:


1. The case statement is exhaustive (all cases are specified).
2. All cases are mutually exclusive.

• You can affect the decision by embedding compiler directives in your code
(comments appearing after the case declaration)

Example:
NOT RECOMENDED case (reg_a) // synopsys full_case parallel_case
4’h0: b = c;
...

// synopsys full_case - All possible clauses have been coded. No default clause necessary
This is similar to (but not as good as) using a default clause.
- Because it is not Verilog compatible, use default instead.

// synopsys parallel_case - Do not produce priority encoded logic (and so save some gates).

- Be aware, this may cause mismatches between RTL/gate sims.

110
Which to use: case or if-else?
Synthesis Tip!

Some general rules to remember:

• Use if-else where you MUST have priority


encoded logic

• Use case for non-priority encoded logic and


make sure
• All case items are mutually exclusive
• Every case statement has a default clause

111
Inferred Storage Device Report Synthesis Tip!

When sequential logic is inferred by HDL Compiler, an inference report is produced:

• Each inferred memory element is identified


• Sequential characteristics are listed

===============================================================
| Register name | Type | Width | Bus | AR | AS | SR | SS | ST |
===============================================================
| out | latch | 8| - | - | - | - | - | - |
===============================================================

For more information consult:

HDL Compiler for Verilog Reference Manual


Always check for accidental latches!!

112
Inferred latches in Synthesis
Synthesis Tip!
Latches can be accidentally inferred from Verilog RTL code.
An example:
When using if - else and case all possible “logic paths” must be specified or else storage
devices are inferred.

The following generates a mux:


reg out, sel, a, b;
always @ (sel or a or b)
if(sel)
out = a;
else out = b;

The following infers a latch:


always @ (sel or a or b)
if(sel)
out = a;

Can you see why?

113
Avoiding Inferred latches
Synthesis Tip!
Specify all case/if structures thoroughly!:
• Every if has an else, every case has a default
• All output signals must be assigned in every branch

- OR -

Assign a default value to all outputs before the if/case structure:

module default (input wire sel, a,


output reg out);

always @(sel or a)
begin
out = 1’b1;
if(sel) // no else is no problem now!
out = a;
end
endmodule

114
Example: D Flip-flop
module FF (Q, CLK, RST, D); module FF (Q, CLK, RST, D);

output Q; output Q;
input CLK, RST, D; input CLK, RST, D;

reg Q; reg Q;

always @(posedge CLK) always @(posedge CLK or negedge rst)


begin begin
if (!RST) if (!RST)
Q = 0; Q = 0;
else else
Q = D; Q = D;
end end

endmodule endmodule

Synchronous reset Asynchronous reset

115
forever Not recommended
for synthesis

syntax:
forever statement or statement_group
• statement or statement_group is continuously executed
• An infinite loop
• Make sure time advances, or zero-time loops will happen!
• In synthesis, make sure the loop contains an edge-triggered timing
control i.e. @(posedge clk) or @ (negedge clk)

module clock_gen;
reg clk;
initial
begin
clk = 0;
forever #25 clk = !clk; //50 time step clock
end
endmodule

116
repeat Synthesizes

syntax:
repeat (expression) statement or
statement_group
• statement or statement_group is executed expression number of times

module reset_ex (input wire clk);


reg reset;

initial // generate reset pulse


begin
reset = 0;
repeat (4) @ (posedge clk);
reset = 1;
repeat (2) @ (posedge clk);
reset = 0;
end
endmodule

117
while Synthesizes

syntax:
while (expression) statement or
statement_group module while_ex (input wire clk,
input [1:0] wire a,b,
output [1:0] reg c);
• statement or statement_group is
continuously executed as long as always
expression evaluates true (or non zero) begin
@ (posedge clk)
• Beware of zero-time loops! They can while (c < b)
occur if both time is not advancing and @ (posedge clk)
expression never goes false c = c + a;
end
endmodule
• In synthesis, the loop must contain an
edge-triggered timing control, i.e.
@(posedge clk) or @ (negedge clk)

118
for Synthesizes

syntax:
for (assignment_init; expression; assignment)
statement or statement_group

• The assignment_init is executed once at the start of the loop


• Loop executes as long as expression is true
• The assignment is executed at the completion of each loop
• If time is not advancing in the loop, it will complete in one time step

module for_ex1 (input wire clk);


reg [31:0] mem [0:9]; // 9x32 memory
integer i;
always @ (posedge clk)
for (i = 9; i >= 0; i = i-1)
mem[i] = 0; // init the memory to zeros
endmodule

119
Ever see a hardware for? Synthesis Tip!

Design Compiler® simply unrolls the loop... module for_ex3(input wire start_cnt,
output reg [7:0] cnt);
module for_ex2(input wire start_cnt, integer i;
output reg [7:0] cnt); reg [7:0] vec;
unrolls
integer i; into
reg [7:0] vec; always @ (start_cnt)
this
begin
always @ (start_cnt) if (vec[0] == 1'b0)
for (i = 0; i <= 3; i = i+1) cnt = cnt + 1;
if (vec[i] == 1'b0) if (vec[1] == 1'b0)
cnt = cnt + 1; cnt = cnt + 1;
endmodule if (vec[2] == 1'b0)
cnt = cnt + 1;
if (vec[3] == 1'b0)
cnt = cnt + 1;
You can not re-assign the loop variable from end
within the for loop. It’s supposed to be a constant! endmodule

Beware of using complex functions inside a for-loop, they


can easily be replicated unnecessarily by the unrolling.
(The example here generates 4 adders!)
For synthesis you cannot embed edge-triggered timing controls in for loops.
Must use constants in expression limit.

120
Naming Statement Groups Synthesizes

:group_name

Statement groups may be given a name:


• Allows for disabling of the named block
• Defines the block as a new scope level, with local
variables if desired

always
begin :mikes_block // group_name
a = 1;
b = b + 1;
end

121
disable Synthesizes

syntax:
disable group_name
• Execution of the named group of statements is stopped and all
associated scheduled events are removed from the event queues

always
begin: do_stuff
forever @(posedge clk) For synthesis, it must be in the
begin same named block that it disables.
if (done) // is it done?
begin
$display($time,,"disabling block");
disable do_stuff; // stop doing it
end
#5 a = !a; // stuff to do
end
end

122
Sensitivity lists
• A sensitivity list allows you to monitor any change in the inputs for a procedural
block
• Procedural blocks with sensitivity lists can model combinational logic
• Beware of incomplete sensitivity lists

Synthesis Tip!
module sense_list_ex(b,c,d); Design Compiler derives it’s own sensitivity
input b,c,d; lists and issues a warning message if this
does not match your code:
reg a;
always @ (b or c or d) “Signal being used but not in timing control”
if (b) Warning!
a = c && d;
else if (c) If you don’t update/correct your RTL source,
a = d; this will cause your RTL and gate level
simulation results to mismatch!
endmodule
RULES:
Combinational sensitivity lists should include:
Quiz: 1) Any signal on right hand side of an assignment.
Why will this code infer a latch for "a" 2) Any signal in an “if” or “case” expression.

123
Sensitivity lists and Verilog 2001

module comma_sens(b,c,d); Two new features of Verilog 2001


input b,c,d; • Comma separated sensitivity lists
reg a;
Verilog 2001 adds a second style for listing signals:
always @ (b , c , d)
if (b) always @(b, c) // comma separated sens
a = c && d;
else
list
a = d;
endmodule Verilog 2001 adds a wildcard capability:

always @* // combinational sens list only


module wild_sens(b,c,d);
input b,c,d; No space

reg a;
always @ // NOTE: no space after @ • Wildcard sensitivity lists
*
if (b)
a = c && d;
else
a = d;
endmodule

124
Continuous Assignments Synthesizes

• The main use for continuous assignments is to model


combinatorial logic
• Done without gates and the interconnecting nets
• Continuous assignments drive a net that has been previously
declared
• Any change in the RHS of a continuous assignment cause the
entire RHS to be evaluated and the LHS to be updated accordingly

syntax: Explicit continuous assignment:


assign net_name = expression;
where net_name is a net that has been previously declared

Examples
wire a;
wire [7:0] c;
assign a = (c_state == `IDLE ) && (sig2 || sig1);
assign c = bus_valid ? d : 8'hz; // tri state bus

125
Implicit Continuous Assignments

Synthesizes

syntax: Implicit continuous assignment


combines net declaration and assignment:
net_type net_name = expression;

Examples
reg [7:0] d;
wire [7:0] e = d & 8'b00001111;
wire b = d; // what happens here?

126
Example: Adder
ADDER
16
in_1

+
16
add_out
16
in_2

module ADDER (add_out, in_1, in_2) ;

parameter width = 16;

output [width : 0] add_out;


input [width – 1: 0] in_1, in_2;

assign add_out = in_1 + in_2;

endmodule

127
Transport Delay (Glitch Catcher) module glitch_catcher;
reg [3:0] a,b;
always @ (b)
a <= #3 b;
initial
begin
b = 0;
#4 b = 1;
#2 b = 2;
#2 b = 3;
#2 b = 4;
#10 $stop;
end
endmodule

a XXX 0 1 2 3 4

b 0 1 2 3 4

time
1 2 3 4 5 6 7 8 9 10 11 12 13

Coding style tip - The best way to model combinational logic with transport delay is with
an always block with a sensitivity list and non-blocking assignments as shown above.

128
Inertial Delay (Glitch Swallower) module glitch_swallow;
wire [3:0] a;
reg [3:0] b;
initial
begin
b = 0;
#4 b = 1;
#2 b = 2;
#2 b = 3;
1. Change on RHS #2 b = 4;
2. Delay #10 $stop;
end
3. Evaluate RHS & update LHS assign #3 a = b;

endmodule

a XXX 0 4

b 0 1 2 3 4

time 1 2 3 4 5 6 7 8 9 10 11 12 13

Coding style tip - The best way to model combinational logic with inertial delay is with
net data type and a continuous assignment as shown above.

129
TASK & FUNCTION

130
User Defined Tasks
Synthesizes

• Analogous to procedure in programming languages


• Allow modules to be broken into more manageable parts
• For simulation: Tasks may contain timing constructs
• For synthesis: @ ’s are not allowed in tasks

syntax:
task name_of_task;
input, inout, and output declarations
local variable declarations
statement or statement_group
endtask

131
Example Task & Call
module call_task;
reg [31:0] into, add, dat;
Task reg sel;
Definition // clk logic not shown

task write_wd;
input [31:0] addr, data;
output sel;
begin
into = {4'b0010,28'h0};
@ (posedge clk) #5 into = addr;
@ (posedge clk) #5 into = data;
sel = 0; // clear sel call_task
end into
endtask write_wd
add addr
initial dat data
begin sel sel
add = 100;
Example dat = 123;
task call sel = 1; clk

write_wd(add,dat,sel); // same as write_wd (100,123,sel);


end
endmodule

132
Example Test fixture - test_pipe.v
module test_pipe;
reg clk;
reg [7:0] d_in;
wire [7:0] d_out;
integer i; /*** module instantiation ***/
initial pipe pipe_1 (
begin d_in,
clk = 0; // init clk
d_in = 0; // init d_in d_out,
forever #20 clk = ~clk; // 40 time step clock clk
end );
task single; // send a single word through the pipe endmodule
input [7:0] data;
begin
d_in = data;
@ (negedge clk) d_in = 0; // clear the pipe
end
endtask
task burst; // send n words through the pipe

endtask
initial //testing sequence
begin
#10 // get clear of time=0
@ (negedge clk) single(4); // send one word through
repeat (4) @ (negedge clk); // wait to clear
burst(10); // send through 10
repeat (4) @ (negedge clk); // wait to clear
burst (3); // send through a partial burst Note: For clarity, some testbench code has
repeat (4) @ (negedge clk); // wait to clear been omitted from this slide.
for (i=1; i<9; i=i+1)
@ (negedge clk) // skip one clock
single (i); //send a word
#500 $stop; // wait to clear then stop
end

133
User-Defined Functions Synthesizes

Analogous to functions in other programming languages:

syntax:
function <[ signed ][ size or type ]> name_of_function;
input declarations
local variable declarations
statement or statement_group
endfunction

• signed is optional and indicates returned value is 2’s compliment (signed) value
• size is optional and is of form [msb:lsb]
• type is optional and is either integer or real
• Returns the value assigned to the name of the function
• Functions may not contain timing controls (incl. non-blocking procedural assignments)
• Functions must have at least one input
• Looks local first then global to module for referenced variables
• Functions may be called:
– within a continuous assignment e.g. assign b = func(a);
– indirectly within an instantiation e.g. mod U1 (one, func (a, b) );
– nested within another function

134
Function - Example
`define FALSE 0
`define TRUE 1
module function_ex (clk);
input clk;
reg r1,r2,r3;

function error; // the function definition


input[7:0] a,b,c;
if ((a !=b) && (a !=c))
error = `FALSE; // assign value to the name of the function
else error = `TRUE;
endfunction

always @ (posedge clk)


if (error(r1,r2,r3) ) // call of the function
$display ("error in reg compare");

// another example call below


reg d; A function can be called where a
always @ (posedge clk) value may be placed in your code.
d <= error(r1,r2,r3) ;
endmodule

135
Functions in Synthesis Synthesis Tip!

• Used to describe combinational logic


• Functions may call other functions
• Functions have only one output which can be a vector
For multiple outputs from a function, use the concatenate operator to bundle
several return values:
module function_ex2 (busA,busB);
input [7:0] busA,busB;
function [9:0] signed_add;
input [7:0] a, b;
reg [7:0] sum;
reg carry, overflow;
begin
...
signed_add = {carry, overflow, sum};
end
endfunction
wire C,V;
wire [7:0] result_bus;
assign {C, V, result_bus} = signed_add(busA, busB);
endmodule

136
VERILOG FOR TEST

137
System Task & Functions

Specific tasks and functions may be defined by EDA vendors and users to be
used as part of the simulator:
• Begin with the dollar sign ( $ )
• The Verilog standard has a number of standard $ defined
• Users may define their own built in tasks using the Programming
Language Interface (PLI)

List of most commonly used built in tasks and functions:


$monitor Continuously monitors listed signals
$display Prints message to the screen
$time function that returns the current simulation time (64-bits)
$stime like above, but returns truncated lower 32-bits
$stop Halts execution but does not exit
$finish Halts execution and exits the simulation

138
$display, $monitor & $strobe
$display();
TIP: You can print your instance name as part of a message
$display ($time,“%m Out_reg = %b”, out_reg);

$monitor();
– outputs whenever a (non-$time) variable it references changes
– Note: only one $monitor can be active at a time
$monitor ($time,“Out_reg = %b”, out_reg);

$strobe();
– like $display, but waits until end of time step

always wait (valid)


@ (posedge clk)
$strobe (“On active clk edge, Data[31:0] = %0h”, data);

139
$stop and $finish

module testbench module testbench


… …

initial initial
begin begin
a = 0; a = 0;
b = 1; b = 1;
… …
… …
#1000 $stop; #1000 $finish;
end end
endmodule endmodule

140
Compiler directives

Compiler directives cause the Verilog compiler to take special actions:


• Indicated by the grave accent character ( ` )
• Directive remains in effect until it is overridden or modified; it is active
across modules and files
• `timescale, `define, `ifdef, `include

`define macro text_string


text substitution of text_string for macro

Example: `define tpd 5

`define tpd 5
module test_designA;
. . .
initial
#`tpd c = 0;

designA DUT (...);


. . .
endmodule

141
`timescale Compiler directive
Time scales establish the delay time base and precision in Verilog models.

`timescale time_unit base / time_precision base

time_unit base: sets the time unit for 1 time step i.e.. What a delay
of 1 means
time_precision base: sets the precision i.e. how to round delays

Example
`timescale 1 ns / 100 ps time unit is 1 ns and round to the nearest .1ns

• By default a time step is unit-less


• Once you set a time scale for any one module you must have a time scale set
for all modules

Specify a timescale directive for each module in your design

142
Compiler directives example: `include
module A ( ); module B ( ); module C ( );
parameter parameter parameter
Width = 5, Width = 5, Width = 5,
Depth = 10, Depth = 10, Depth = 10,
Height = 20; Height = 20; Height = 20;
… … …
… … …
endmodule endmodule endmodule

param.inc
parameter module A ( ); module B ( ); module C ( );
Width = 5, `include param.inc; `include param.inc; `include param.inc;
Depth = 10, … … …
Height = 20; … … …
endmodule endmodule endmodule

143
“`define” and “`ifdef” for code modification
File: test_choices
`define TRUE 1
`define DISPLAY_ERRORS 0
`define FULL_CHECK `TRUE
`define RANDOM

File: testbench.v

`include “test_choices” // load testbench configuration from a file


module testbench;
reg [7:0] addr;
integer seed;

if (`DISPLAY_ERRORS) $display ("had an error here");

if (`FULL_CHECK) do_all_tests;

`ifdef RANDOM
initial addr = $random(seed) * 43;
`else
initial addr = addr +1;
`endif

144
Options for (re)defining a text macro

Define
Text macros may be defined from the command line. The following invocation line defines the
text macro TRUE.
vcs -R my_module.v +define+TRUE=1+
This would be equivalent to having the statement
`define TRUE 1
in the module my_module in the file my_module.v

Redefine
`define directives within a module can be overridden from the command line
Given the following line of code was in the module my_module in the file my_module.v:
`define TRUE 1
The following invocation line overrides the value of 1 for TRUE with 0 for this simulation:
vcs -R my_module.v +define+TRUE=0+

145
Initializing Memories Synthesizes

Memories may be initialized sequentially within Verilog:


reg [15:0] mem [0:255];
integer i;
initial
for (i=0; i<256; i = i+1) mem[i] = 0; //initialize each location with 0

Or they may be initialized with a file using built-in system tasks: $readmemb / $readmemh which
read ASCII text files specifying data in binary/hex representation.

syntax:
$readmem<base>("file_name",memory_name );
$readmem<base>("file_name",memory_name,<start_address>,<finish_address> );

reg [15:0] mem [0:255], mem1[0:255];


initial begin
$readmemh("mem_h.dat", mem); // read file mem_h.dat into memory mem
$readmemh("mem_h.dat", mem1, 16, 0); // read file starting at 16, down to 0

// there is also a corresponding command for dumping the contents of a memory to a file
$writememh("hex.dat", mem); // write file hex.dat from memory mem
$writememh(“hex2.dat", mem1, 16, 0); // write file hex2.dat starting at address 16, down to 0
end

146
Memory Image Files Synthesizes

ab
ae File is read sequentially
af starting at left address in
memory declaration.
00

- OR -
ab
ae Hex addresses may be specified
af so that the file is still read
00 sequentially.
@1ff
ab - BUT -
ae starts loading at address 1ff.
af - AND THEN -
@2ab jumps to address 2ab etc... Note:
00
03 • Comments are allowed!
00 • Use hex addresses only
af • Uninitialized locations are left “X”

147
Scoping
instance names module name
top
instance names
b c d
mega

h
e f g
giga i
module flop
.... module names
reg float; // local register k
flop
....
endmodule

path is in form of: module_name.instance_name.instance_name


example - path to reg float : top.d.h.i.k.float
module giga
....
k.float = 1; // write register “float” from instance i of module giga
....
flop k (...portlist...);
endmodule
148
force & release Synthesizes

• force Overrides all other logic forcing a value to a data type


• release Removes the effect of a force

syntax:
force net_or_register = expression;
release net_or_register;

• On the release of a register data type the register retains its "forced
value" until it is over written
• On the release of a net data type the net immediately takes on the
value of its driver

149
force & release example
module test_force;
reg clk;
reg [7:0] d,q;
wire [7:0] w;
initial begin // generate a clock
clk = 0;
forever #25 clk = !clk;
end
initial
for(d = 0;d < 256;d=d+1) @ (negedge clk); //create incrementing value for d
always @ (posedge clk)
q <= d; // normal operation for q
assign w = d; // normal operation for w
initial
begin
#100 force q = 8'hff; // force to all 1's
$display ("%0d force applied to q",$time);
#200 release q; // release the force, q stays 8'ff until the next assignment to q is made
$display ("%0d release of q",$time);
#100 force w = 8'hff; // force to all 1's
$display ("%0d force applied to w",$time);
#200 release w; //release the force, w changes value immediately to the current value of d;
$display ("%0d release of w",$time);
#100 $finish;
end
initial $monitor ("%0d d = %h, q = %h, w = %h",$time,d,q,w);
endmodule
150
Uses of force & release

• Fast initialization of system registers


• In testbench code for temporary patches
• In testbench code to inject errors
• From the command line during interactive debugging

Note:
A force statement in the model itself is more efficient than
one entered at the command line and doesn’t need the +cli switch

151
Bus Monitor tasks

• Part of test fixture not stimulus

• Protocol specific tasks whose purpose is to


catch low level bus protocol errors

• Really should not be written by HW designer

• Should be conditionally enabled in/out of


simulation

152
Simple Bus Monitor Example

CPU Memory IO

System Bus

bus_check.v
Bus always @ (posedge clock)
Check
if (arb[1] && idle && not_ready)
// error!

153
Writing to a file

• Instead of the screen you may write to a file


• Standard System tasks:
• $fopen
• $fclose
• $fmonitor
• $fdisplay
• $fwrite // like $fdisplay, without an automatic CR at EOL
• $fstrobe

154
Write to a file example

module dcm(clk,bus_error_flag,stat_var);
input clk,bus_error_flag,stat_var;
integer errfile;
initial
errfile = $fopen("error_output");

always @ (posedge clk)


if (bus_error_flag)
$fdisplay(errfile,"Bus error at time %0d: in DCM, status = %d", $stime, stat_var);

endmodule

155
X & TRI-STATE BUFFERS

156
z’s in Synthesis

• z is used to generate tri-state logic


• Assignment must occur in conditional statement (if or case) or with
the conditional operator (?:)
• Using z in a case_item of a case statement (not casex or casez)
may cause a mismatch

reg [1:0] a;

case (a)
2’b01: c = 2;
2'bzz: c = 3; // This branch won't occur in synthesis
default: c = 4;
endcase

157
Tri-state buffer inference

Assigning “z” to a net implies tri-state logic.

module bidir_ex2(sel1, sel2, A, B, C);


input sel1, sel2, B, A;
output C; sel1
tri C; A C

assign C = (sel1) ? A : 1'bz; sel2


assign C = (sel2) ? B : 1'bz; B

endmodule

Remember to make sure sel1 and sel2 never happen at the same time.

158
Tri-state buffer on the output of a flip-flop

module bidir_ex3 (clock,enable,in,out); When a variable is registered (or latched)


in the same always block in which it is
input clock,enable,in; tri-stated, the tri-state controller is also
output out; registered (or latched).
reg out;

always @ ( posedge clock ) enable


if ( enable )
out <= in;
else
out <= 1'bz; in out

clk
endmodule

159
Tri-state buffer on the Output of a flip-flop

module bidir_ex4
(clock,enable,in,out); enable
input clock,enable,in;
output out; in tmp out
reg tmp;
tri out; clk

always @ ( posedge clock )


tmp <= in;
Separate the flop inference from the
assign out = enable ? tmp : 1'bz; tri-state buffer inference.
endmodule

160
Bi-directional ports & tri-state buses

Test_bidir
bidir
!( en_a || en_b )

en_a
data data
out_stuff
data_a

combinational sequential
tri-state
en_b
Remember: Model these separately.

data_b
in_stuff

161
Bi-directional ports & tri-state buses

• test_bidir instantiates bidir.


module test_bidir; • “data” is the bi-directional module bidir (en_a, en_b, data,reset);
bus. input en_a, en_b,reset;
reg [7:0] data_a, data_b; inout [7:0] data;
reg en_a, en_b, reset;
tri [7:0] data; • Both ends must talk & listen reg [7:0] in_stuff,out_stuff;
in turn with only one driver tri [7:0] data;
assign data = en_a ? data_a : 8'bz; active at a time.
assign data = en_b ? data_b : 8'bz; assign data = (en_a || en_b) ?
• data is driven to bidir by 8'bz: out_stuff;
initial
begin either en_a or en_b asserted. always @ (data)
# 1 reset = 1; if (en_a || en_b)
#6 reset = 0; • data is driven from bidir by in_stuff <= data;
en_a = 0; both en_a or en_b not
en_b = 0; asserted. always @ (reset or data)
data_a = 5; if (reset) out_stuff <= 0;
data_b = 8; else
# 10 en_a = 1; • Continuous assignments at out_stuff <= out_stuff + 1;
#10 en_a = 0; each end handle the
en_b = 1; switching between talk &
end listen. In this case based on endmodule
en_a and en_b.
bidir dut (en_a, en_b, data, reset);

endmodule

162
GATE-LEVEL MODELING

163
Verilog RTL & Gate-Level Netlist Example
module counter ( clk, rst, en, load, cout );
input [7:0] load;
module counter (clk, rst, en, load, output [7:0] cout;
cout) ; input clk, rst, en;
wire N5, N6, N7, N8, N9, N10, N11, N12, n10, n11, n12, n13, n14, n15, n16,
n17, n18, n19, n20, n21, n22, n23, n24, n25, n26;
input clk, rst, en;
DFFRHQX1 cout_reg_7_ ( .D(n18), .CK(clk), .RN(rst), .Q(cout[7]) );
input [7:0] load; DFFRHQX1 cout_reg_3_ ( .D(n22), .CK(clk), .RN(rst), .Q(cout[3]) );
DFFRHQX1 cout_reg_4_ ( .D(n21), .CK(clk), .RN(rst), .Q(cout[4]) );
output [7:0] cout; DFFRHQX1 cout_reg_5_ ( .D(n20), .CK(clk), .RN(rst), .Q(cout[5]) );
reg [7:0] cout; DFFRHQX1 cout_reg_6_ ( .D(n19), .CK(clk), .RN(rst), .Q(cout[6]) );
DFFRHQX1 cout_reg_1_ ( .D(n24), .CK(clk), .RN(rst), .Q(cout[1]) );
DFFRHQX1 cout_reg_2_ ( .D(n23), .CK(clk), .RN(rst), .Q(cout[2]) );
always @(posedge clk or negedge DFFRHQX1 cout_reg_0_ ( .D(n25), .CK(clk), .RN(rst), .Q(cout[0]) );
INVX1 U20 ( .A(n10), .Y(n18) );
rst) AOI22X1 U21 ( .A0(N12), .A1(n26), .B0(load[7]), .B1(en), .Y(n10) );
INVX1 U22 ( .A(n11), .Y(n19) );
if (!rst) AOI22X1 U23 ( .A0(N11), .A1(n26), .B0(load[6]), .B1(en), .Y(n11) );
cout = 0; INVX1 U24 ( .A(n12), .Y(n20) );
AOI22X1 U25 ( .A0(N10), .A1(n26), .B0(load[5]), .B1(en), .Y(n12) );
else if (en) INVX1 U26 ( .A(n13), .Y(n21) );
cout = load; AOI22X1 U27 ( .A0(N9), .A1(n26), .B0(load[4]), .B1(en), .Y(n13) );
INVX1 U28 ( .A(n14), .Y(n22) );
else AOI22X1 U29 ( .A0(N8), .A1(n26), .B0(load[3]), .B1(en), .Y(n14) );
INVX1 U30 ( .A(n15), .Y(n23) );
cout = cout + 1; AOI22X1 U31 ( .A0(N7), .A1(n26), .B0(load[2]), .B1(en), .Y(n15) );
INVX1 U32 ( .A(n16), .Y(n24) );
AOI22X1 U33 ( .A0(N6), .A1(n26), .B0(load[1]), .B1(en), .Y(n16) );
endmodule INVX1 U34 ( .A(n17), .Y(n25) );
AOI22X1 U35 ( .A0(N5), .A1(n26), .B0(load[0]), .B1(en), .Y(n17) );
INVX1 U36 ( .A(en), .Y(n26) );
counter_DW01_inc_0 add_16 ( .A(cout), .SUM({N12, N11, N10, N9, N8, N7, N6,
N5}) );
endmodule

164
Using libraries - 1

• Organize your code into libraries according to abstraction


level

• A library is usually organized as either:


• library file
• One file containing all the Verilog modules in that
library
• library directory
• A single directory per library
• A separate file for each module in the library

Let’s look at how to specify a library …

165
Using Libraries - 2

module TOP(out,in,clock); n If IP library is a single file, lib.v located in directory


/EDA/vendor/lib:
input in,clock;
l vcs source.v -v /EDA/vendor/lib/lib.v
output out;
wire a_in, b_in, clkin; n If IP library is a directory with multiple files located
in /EDA/vendor/lib:
vcs source.v –y /EDA/vendor/lib +libext+.v
PADINX1 U1 (in, a_in); l

PADINX1 U2 (clock, clkin); n Both option can be used with other VCS
PADOUTX1 U2 (b_in, out); compile-time option
...
...

endmodule

From IP Library

166
Timing Accuracy
• Pre Synthesis: Least Accurate
• RTL level
• Simple delay (#)

• Post Synthesis: More Accurate


• Gate level
• Specify blocks
• Statistical information in gate level library
• SDF

• Post Layout: Most Accurate


• Gate level
• RC/Parasitic data (SPEF)
• Used by STA tools and not simulators
• SDF

167
Pre-Synthesis

At the pre synthesis level (RTL) your timing accuracy for delays is only
as good as the simple delays you put into the code.

Example
Modeling propagation delay through the flip flops:

always @ (posedge clk)


d_out <= #5 d_3; // prop delay of 5 time steps

With `timescale 1ns/10ps the delay is 5 ns.

This delay was never intended to accurately represent the propagation


delay of real hardware.

168
Post-Synthesis: specify blocks

• Specify blocks may be used to add timing information to a module


• Typically used for gate level primitive models - ASIC cells etc

syntax:
specify
specparam_declarations
simple_pin-to-pin_path_delay
edge-sensitive_pin-to-pin_path_delay
state-dependent_pin-to-pin_path_delay
timing_constraint checks
endspecify

module FD1 (D,CP,Q,QN);


input D,CP;
output Q,QN;
. . . . // logic for flop
specify
(posedge CP => ( Q +: D )) = (3.4:3.5:3.6,2.8:2.9:3.0);
(posedge CP => (QN -: D )) = (2.8:2.9:3.0,3.4:3.5:3.6);
endspecify
endmodule

169
Standard Delay Format (SDF)

Standard Delay Format (SDF) is a standard format defined by Open Verilog


International which provides a way to store delay information for many tools
including simulation.
$sdf_annotate system task back annotates an SDF file to your design.
Back annotation is done dynamically, while running a simulation.

syntax:
$sdf_annotate ("sdf_file", module_instance);
(CELL
(CELLTYPE "FD1")
(INSTANCE d_out_reg\[0\])
module testbench;
(DELAY …
(ABSOLUTE
(IOPATH (posedge CP) Q (1.147:1.147:1.147) (1.390:1.390:1.390))
(IOPATH (posedge CP) QN (1.590:1.590:1.590) (1.370:1.370:1.370)) top DUT ( …);
)
) …
(TIMINGCHECK
(SETUP D (posedge CP) (0.800:0.800:0.800))
initial
(HOLD D (posedge CP) (0.400:0.400:0.400)) $sdf_annotate (“top.sdf”, testbench.DUT);
)

Example endmodule
SDF file

170
Finite State Machines

FSM styles

• Embedded signals
• Separate signals
• One-hot
• Mealy / Moore
FSM types

Inputs Output
Next state Logic Outputs
logic cloud State cloud
Vector
clk

• Mealy machine: Outputs derived from present state & inputs


• Moore machine: Outputs derived from present state
• For readability, use parameters for state names

172
FSM style #1
(next-state and output logic combined)

• Described with two always blocks:

• Sequential:
• Steps the state machine

• Combinational:
• A case statement, one state per branch
• State register is the case selector
• Next state assignments are explicit in each branch
• Outputs are assigned in each branch

173
Example 1
module example_a(input wire clk, rst, input_sig_1, input_sig_2,
output reg a, b);

parameter S0 = 2’h0, S1 = 2’h1, S2 = 2’h2;


reg [1:0] state, next_state;
Sequential always @ (posedge clk)
if (rst) // Fully synchronous reset
state <= #1 S0;
else
state <= #1 next_state;
always @ (state or input_sig_1 or input_sig_2 ) // sensitive to all state and all inputs
case (state)
S0: begin
b = `FALSE;
if (input_sig_1 || input_sig_2 )
a = `TRUE;
else
a = `FALSE;
if(input_sig_1 == `TRUE)
next_state = S1;
else

Combinational: end
next_state = S0; S0
S1: begin
Next State and b = `TRUE;
Output a = `FALSE;
Logic if(input_sig_2 == `TRUE)
next_state = S2;
else
next_state = S0;
end
S2: begin
S1
b = `FALSE;
a = `FALSE;
next_state = S0;
end
default: begin S2
a = 1’bx;
b = 1’bx;
next_state = S0;
end

174
endcase
endmodule
FSM style #2
(separate next-state and output logic)

• Same as previous example (A) except:

• Combinational logic is separated from the next state


register assignments

• Reduced FSM code-size, synthesis efficiency

175
Example 2
module example_c(input wire clk, rst, input_sig_1, input_sig_2,
output wire a, b);
parameter[1:0]
S0 = 2’b00, S1 = 2’b01, S2 = 2’b10;
Combinational: reg [1:0] state, next_state;
Output
logic
assign a = (state == S0) && (input_sig_1 || input_sig_2);
assign b = (state == S1);

always @ (posedge clk)


if (rst) // Fully synchronous reset
state <= #1 S0;
Sequential else
state <= #1 next_state;
S0
always @ (state or input_sig_1 or input_sig_2 )
case (state)
S0: if(input_sig_1)
next_state = S1;
else
next_state = S0; S1
Combinational:
Next State S1: if(input_sig_2)
next_state = S2;
logic else S2
next_state = S0;

S2:
next_state = S0;
default:
next_state = S0;
endcase
endmodule

176
One-Hot Encoding

• Only one bit of the state vector is asserted for any given state
• n states require n flops to implement
• State decode is simplified with the following benefits:
– Typically faster logic
– Modifications are simple
– Easily synthesized
– Do not have to worry about finding “optimal” state encoding
• Disadvantages:
– Area penalty because of extra flops

177
Example 3: One-Hot, Synch. Reset
module example_d (input wire clk, rst, input_sig_1, input_sig_2,
output wire a, b);
parameter S0 = 3'b001, S1 = 3'b010, S2 = 3'b100;
reg [2:0] state, next_state;

assign a = (state == S0) && (input_sig_1 || input_sig_2);


assign b = (state == S1);

always @ (posedge clk)


if (rst)
state <= #1 S0;
else
state <= #1 next_state;

always @ (state or input_sig_1 or input_sig_2)


S0
begin
next_state = S0; // set to initial state by default
case (state )
S0:
if(input_sig_1)
next_state = S1; S1
else
next_state = S0;
S1 :
if(input_sig_2)
next_state = S2; S2
else
next_state = S0;
S2 :
next_state = S0;
default:
next_state = S0;
endcase
end
endmodule
178
Example E: (One-Hot, Asynch. Reset)
module example_d (input wire clk, rst, input_sig_1, input_sig_2,
output wire a, b);
reg [2:0] state, next_state;
parameter S0 = 0, S1 = 1, S2 = 2;

assign a = (state[S0]) && (input_sig_1 || input_sig_2);


Can U
assign b = (state[S1]); Spot a deliberate
error in this code?
always @ (posedge clk or negedge rst )
if (rst)
state <= #1 3'b001; // S0 the initial state
else
state <= #1 next_state;
always @ (state or input_sig_1 or input_sig_2)
begin
next_state = 3’b000; S0
case (1’b1)
state [S0]:
if(input_sig_1)
next_state [S1] = 1’b1;
else
next_state [S0] = 1’b1;
state [S1]: S1
if(input_sig_2)
next_state [S2] = 1’b1;
else
next_state [S0] = 1’b1;
state [S2]: S2
next_state [S0] = 1’b1;
default:
next_state [S0] = 1’b1;
endcase
end

179
Exercise

n Write the Verilog code for 8 bit counter


n Module name is COUNTER
n Input ports: clk, reset
n Output port (8 bits): cout

180

You might also like