You are on page 1of 11

Digital Electronics and Electrical Machines

Digital Electronics Component

Finite State Machines: Verilog (DEEM-29)


Purpose: You are expected to make your own notes, read a textbook, attempt any student
exercises set and find your own problems to work through.

Introduction
This session introduces the use of the hardware description language Verilog, as required
for Digital Assignment 2 and Digital Assignment 3.
This material contains a very brief overview of a language. Like all languages it is best
learnt by practice in-the-field.
A very brief introduction to the history of Verilog
Verilog is traditionally assumed to be a United States hardware description language. An
alternative European language is VHDL.
Verilog was written by Prabhu Goel, Phil Moorby, Chi-Lai Huang, and Douglas Warmke in
1983/1984.
Verilog was transferred into the public domain and in 1995 was submitted to become IEEE
Standard 1364. This standard has been updated in 2001, 2005, 2009 and 2017.
It is now part of a language with broader systems modelling capabilities called
SystemVerilog standardized as IEEE 1800.
It is considered to be a C-like language, hence the reason for a brief second year
introduction.
Notes:
Verilog Modules
Verilog adopts the concept of a hierarchy of modules. Think of a printed circuit board
containing multiple integrated circuits, each containing many logic gates:

Module #1
Module #2 Module #3 Module #4

#5 #6 #7

Interfaces

Interfaces
Interfaces
Interfaces
Interfaces

Interfaces

Interfaces
Interfaces

#5 #5 #8

There tends to be fewer variations of the lower level modules (e.g. basic gates, counters,
arithmetic operations, etc.)

A key part of engineering design is to explicitly, rigorously and elegantly define the function
of each module and the associated interfaces. Generally, if you get this correct, the
implementation and through-life costs are reduced. This is good systems engineering
practice. There are international standards and many software tools to help you.

Notes:

 Spend ten minutes Googling international standards designed to help you with
documenting the functionality and interfaces of systems modules (don’t limit this to
software design techniques e.g. UML). You will find that this pays-back handsomely
at an interview.
Verilog Modules
A module is defined with a name and a list of interface signal names.
module DEEM_Source_1(sw_A,sw_B,sw_C,sw_D,led_A,led_B,led_C,led_D);
input sw_A;
input sw_B;
input sw_C;
input sw_D;
output led_A;
output led_B;
output led_C;
output led_D;
// Add the functional code here
endmodule
The direction of the interfaces is defined as ‘input’ or ‘output’. It can also be bi-
directional.
Many programmers will include the variable names within the module definition and then
define the direction separately, as shown above.
A module always finishes with ‘endmodule’.
Notes:

Verilog Modules
All commands are semicolon delimited.
module DEEM_Source_2(sw_A,led_A,led_B);
input sw_A;
output led_A;
output led_B;
// Add functional code here – this is outside a block in this example
assign led_A = sw_A; // Add a non-inverting buffer
assign led_B = ~sw_A; // Add an inverter
endmodule

Unlike the C-language which is classed as procedural, Verilog is classed as concurrent, or


dataflow. So it is possible that everything happens in parallel.
For combinatorial logic, use AND gates (&), OR gates (|) and inverters (~).
The ‘assign’ statement continuously assigns the value on the right hand side of the equate
to the signal name on the left.
Notes:
Verilog Modules
The C-language uses curly braces {} for the demarcation of procedural blocks. Verilog
uses ‘begin’ and ‘end’. Blocks are executed concurrently.
module DEEM_Source_3(sw_A,led_A,led_B);
input sw_A;
output led_A, led_B;
reg led_A, led_B; //Signals driven inside a block must be of type reg

initial
begin
led_A = sw_A; // Add a non-inverting buffer
led_B = ~sw_A; // Add an inverter
end

always @(sw_A) // sw_A changes state


begin
led_A = 1; // Set
led_B = 0; // Reset
end
endmodule

An ‘initial’ block runs only once.


An ‘always’ block is free-running. Usually, such a block is associated with a sensitivity
list, often sensitive to changes in signals.
You can have as many blocks as you like. The important concept is that all blocks will
start executing at the same time. Some may never finish, others will finish at different
times.
Notes:
Verilog Syntax Reminder
All Verilog commands are semicolon delimited.
Comments are delimited by ‘//’ symbols.
So what do the following two lines implement?
// Add some functional logic
assign led_A = sw_A; // Add a non-inverting buffer
assign led_B = ~sw_A; // Add an inverter

The ‘assign’ and the ‘=‘ character drops in combinatorial logic that continuously executes.
This is what we would use for ‘output logic’.
The ‘~’ is an inverter, the ‘&’ is an AND gate and the ‘|’ is an OR gate.

led_A
sw_A
sw_B led_B
led_C
sw_C
Black Box led_D
sw_D
or Verilog led_E
Inputs Module led_F
Outputs

Notes:
Verilog ‘always’ Statement
Positive edge-triggered flip-flops are implemented by using an ‘always’ block. This
always executes and is delimited by ‘begin’ and ‘end’ statements.
An always block should have a sensitive list which tells the always block when to execute
the code. The @ symbol after the reserved word 'always', indicates that the block will be
triggered ‘at’ the condition in parenthesis after symbol @.
always @(posedge Clk_Q)
begin
Q0 <= (~Q2 & ~Q1) | (~Q3 & ~Q1) | (~Q0);
Q1 <= (~Q2 & ~Q1 & Q0) | (~Q3 & ~Q1 & Q0);
Q2 <= // Relevant statements
Q3 <= // Relevant statements
end

In this code the ‘always’ executes the following code block on the positive edge of the
signal ‘Clk_Q’.
This time the assignment uses ‘<=‘ to execute code in parallel at the ‘end’ of a block. This
is called a non-blocking operation. It is helpful when implementing finite state machines
where all transition equations could be functions of all other transition equations. If
implemented in a procedural language such as MATLAB or C, a set of intermediate
(temporary) variables would be required to obtain the desired result. Verilog can
implement such functionality using up to half the number of statements.
A ‘=‘ executes code sequentially in a begin-end loop. This is called a blocking operation
as each statement might be assumed to be completed before starting the next statement.
Notes:
Verilog Finite State Machine Example
When implementing a synchronous finite state machine, we need to define that the outputs
to contain flip-flops using the ‘reg’ command. Using a previous stepper motor controller
design example:
DIR
0 0 0

S0 S1 S2 S3
11 10 00 01
1 1 1
Q2 Q1
0
1

module DEEM_Source_4(DIR,Clk_Q,Q1,Q2,Q3,Q4);
input DIR;
input Clk_Q;
output reg Q1, Q2, Q3, Q4;
always @(posedge Clk_Q) // FSM active on positive edge
begin
Q1 <= (~Dir & ~Q2) | (Dir & Q2); // D-type flip-flop register Q1
Q2 <= (~Dir & Q1) | (Dir & ~Q1); // D-type flip-flop register Q2
Q3 <= ~Q1; // Output logic, inverted version of Q1
Q4 <= ~Q2; // Output logic, inverted version of Q2
end
endmodule

Notes:
Verilog Simulation
Our design will probably consist of a nested hierarchy of modules.
To verify the performance we surround our design with an even higher level of ‘wrapper’
module.

Highest-Level Verilog Module ()

led_A
sw_A
sw_B led_B
led_C
sw_C
led_D
sw_D Verilog
led_E
Module
led_F
Inputs to Module
defined as reg at Outputs from module defines
highest-level as wire at highest level

At this very highest level the ‘outputs’ driving the ‘inputs’ of our design must be classed as
‘reg’. This does not necessarily mean these outputs are associated with flip-flops, just
that the data will be stored and stable in some manner.
Similarly, at this very highest level the ‘inputs’ driven from the ‘outputs’ of our design must
be classed as ‘wire’.
Notes:
Verilog Simulation Code
Often we simulate timing waveforms and so only need a simple ‘initial’ block.
module Typical_Test_Bench(); // At highest level no parameters are passed
wire out_A,out_B,out_C,out_D; // Outputs from other modules appear as wires
reg Signal_1,Signal_2; // Inputs to other modules appear as registers

initial
begin // Most of your code could appear within an ‘initial’ block
//Initialize clock
Signal_1 = 0;
Signal_2 = 0;
#10 Signal_1 = 0;
#10 Signal_1 = 1;
#10 Signal_1 = 0;
#10 Signal_2 = 1;
#10 Signal_1 = 1;
$finish;
end

// Instantiate your lower-level modules (drop-in your deign to be tested)


YourDesignName AnyRandomName(Signal_1,Signal_2,out_A,out_B,out_C,out_D);
endmodule

Time delays may be inserted using the ‘#10’, where the number represents a multiple of
the basic timing rate.
Simple, linear, procedural code is often preferred for verification purposes.
Note that here ‘YourDesignName’ is the file that contains your source code that will be
loaded onto the board and ‘AnyRandomName’ is any random name to keep the software
happy.
Notes:
Verilog Simulation Code
The simulation process produces pretty timing waveforms.

These diagrams need to be automatically converted into a rigorous verification result that a
lawyer can understand. This is often a far more challenging task than designing the
system in the first place.
Notes:
External Resources
There are many good resources available about Verilog.
Examples include:
https://en.wikipedia.org/wiki/Verilog#:~:text=Verilog%2C%20standardized%20as%20IEEE
%201364,register-transfer%20level%20of%20abstraction.
http://www.asic-world.com/verilog/veritut.html
https://www.chipverify.com/verilog/verilog-tutorial
The ISO/IEC 15288 is a systems engineering standard covering processes and lifecycle
stages.

You might also like