0% found this document useful (0 votes)
13 views28 pages

Lecture04 IntroVerilogI

This document serves as an introduction to Verilog, a Hardware Description Language (HDL) used for modeling digital systems. It covers various coding styles including structural, dataflow, and behavioral models, emphasizing the importance of abstraction in digital design. The document also discusses design strategies, simulation techniques, and the significance of synthesizable code in hardware implementation.

Uploaded by

prnjan
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)
13 views28 pages

Lecture04 IntroVerilogI

This document serves as an introduction to Verilog, a Hardware Description Language (HDL) used for modeling digital systems. It covers various coding styles including structural, dataflow, and behavioral models, emphasizing the importance of abstraction in digital design. The document also discusses design strategies, simulation techniques, and the significance of synthesizable code in hardware implementation.

Uploaded by

prnjan
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/ 28

Introduction to Verilog I

CMPE 415 Programmable Logic Devices

Prof. Ryan Robucci

DEPARTMENT OF COMPUTER SCIENCE AND ELECTRICAL ENGINEERING


References
† http://6004.csail.mit.edu/6.371/handouts/L0{2,3}.pdf
marked in Red Outline Shape
Why use an HDL?

Want an executable functional specification
– Document exact behavior of all the modules and their Interfaces
– Executable models can be tested & refined until they do what you want

Too much detail at the transistor and mask levels
– Can’t debug 1M transistors as individual analog components
– Abstract away “unnecessary” details
– Play by the rules: don’t break abstraction with clever hacks

HDL description is first step in a mostly automated process to
build an implementation directly from the behavioral model

http://6004.csail.mit.edu/6.371/L03.pdf
Abstraction

Abstraction is a cornerstone of digital design.

HDLs allow us to model hardware with varying
levels of abstraction. They allow us to flexibly
describe and represent not only functionality,
but also implementation and structure at
varying degrees. For the purpose of
simulation, the most significant difference
from functional modeling in software is the
level of support for representing timing
(delays) and concurrent execution.
A Tale of Two HDLs

http://6004.csail.mit.edu/6.371/L02.pdf
Important Verilog Coding Styles

Structural models: basically a hierarchical netlist starting with
“primitives” and modules built using other styles.

Dataflow models: combinational logic described using
expressions

Behavioral models: This level describes a system by
concurrent “algorithms” (Behavioral). Each algorithm itself is
sequential, that means it consists of a set of instructions that
are executed one after the other. There is no regard to the
structural realization of the design.

Register-Transfer Level (RTL) register-focused design.
– Registers are identified, and the movement of data
between them at specific specified timing events like clock
edges logic is described. Modern RTL code definition is
"Any code that is synthesizable is called RTL code".
Structural

Structural models: basically a hierarchical netlist with “primitives” (built-in
Verilog logic gates, or instances of library modules).

Instantiation of Modules

Use of Gate Level Primitives
– Within the logic level the characteristics of a system are described by
logical links and their timing properties. All signals are discrete signals.
They can only have definite logical values (`0', `1', `X', `Z`). The usable
operations are predefined logic primitives (AND, OR, NOT etc gates).
Using gate level modeling might not be a good idea for any level of logic
design. Gate level code is generated by tools like synthesis tools and this
netlist is used for gate level simulation and for backend. http://www.asic-world.com/verilog/intro1.html


Use of Switch Level Primitives
– Switch Level modeling allows you to construct transistor-level schematic
model of a design from transistor and supply primitives
– nmos, pmos, supply1, supply0, etc...
Structural Verilog
// 2-to-4 demultiplexer with active-low outputs
// structural model
module demux1(a,b,enable,z);
Remember that
input a,b,enable; statements “run”
output [3:0] z; concurrently so
order in code
wire abar,bbar; // local signals isn’t significant!

not v0(abar,a)
not v1(bbar,b);
nand n0(z[0],enable,abar,bbar);
nand n1(z[1],enable,a,bbar);
nand n2(z[2],enable,abar,b);
nand n3(z[3],enable,a,b);

endmodule

http://6004.csail.mit.edu/6.371/L02.pdf
Dataflow modeling

Dataflow models: combinational logic described using expressions
– assign target = expression http://6004.csail.mit.edu/6.371/handouts/L02.pdf
– Arithmetic operators: +, -, *, /, %, >>, <<
– Relational operators: <, <=, ==, !=, >=, >, ===, !==
– Logical operators: &&, ||, !, ?:
– Bit-wise operators: ~, &, |, ^, ~^, ^~
– Reduction operators: &, ~&, |, ~|, ^, ~^
– Concatenation, replication: {sigs…} {number{…}}
http://6004.csail.mit.edu/6.371/L02.pdf


Structural Verilog may include many of the dataflow operations that map directly to
built-in logic primitives and specifications of net connections.
– The following are the same in many contexts

x = a & b & c;

nand n0(x,a,b,c);
– The exact implementation and structure implied in the following is less certain unless we
explicitly know the exact module that addition would map to with our synthesizer and library

x = a+b
Dataflow Verilog
// 2-to-4 demultiplexer with active-low outputs
// dataflow model
module demux2(a,b,enable,z);
input a,b,enable;
output [3:0] z;

assign z[0] = | {~enable,a,b}; //reduction operator


assign z[1] = ~(enable & a & ~b);
assign z[2] = ~(enable & ~a & b);
assign z[3] = enable ? ~(a & b) : 1’b1; //conditional
// expression like C
endmodule

http://6004.csail.mit.edu/6.371/L02.pdf
Behavioral Code and RTL Code

Behavioral code is implemented in procedural blocks that include one or several statements that describe
an algorithm to define the behavior of a block of logic in a simulation or in hardware

A procedural block may include sequential statements from which the algorithm may be understood by
beginning interpretation of statements one at a time (similar to traditional software coding languages) or
parallel statements intended to be interpreted in parallel.
– begin...end block include code with sequential statements
– fork...join blocks include code with parallel statements

The creation of behavioral code is sometimes characterized by a lack of regard for hardware realization

Synthesizable Behavioral Code is code that a given synthesizer can map to a hardware implementation
– The definition of synthesizable is synthesizer dependant- some simple prodecural code constructs are universally
synthesizable by every synthesizer, while more complex code blocks and certain operators are not considered
synthesizable by many

Example:
– x = myUINT8 >> 2;

This is a shift by a constant implemented by a simple routing of bits. It is generally regarded as synthesizable
– x = myUINT8 >> varShift;

This is a variable shift with many possible implementations. It will simulate just fine, but at the synthesis step many synthesizers will throw an error
saying that this is not synthesizable though it is ex
– Behavioral code may indeed describe behavior in such a way that is not directly synthesizable by almost any
synthesizer (such as reading waveforms from a .txt file) – though what is “synthesizable” is always defined by the
synthesizer tool being used

Procedural code implemented with regard for hardware implementation, from which the registers, the
combinatorial logic between, and control signals like clocks may be inferred is called Register Transfer
Level (RTL) code
– Sometimes the terms “behavioral code” and “RTL code” are used in proximity to refer to synthesizable and non-
synthesizable code, though even this separation is dependent on the synthesizer tool being used
Initial and Always Blocks

Initial and Always blocks will be the first two types of blocks we will
discuss (tasks and functions will be discussed later)

Initial blocks are triggered once at the start of a simulation or in the
case of some synthesis tools may be used to describe the power-up
state of registers or may be used to describe the initial default value
of an intermediate variable

Always blocks are triggered with every change in one or more signals
as provided in a sensitivity list.
– When describing combinatorial logic the sensitivity list should include
every input to the logic
– For coding sequential logic the sensitivity list should include only the
control signals that trigger updates to sequential logic

Example Control signals to include in a sensitivity list for seq. logic blocks:
– enable for latches
– clock for more traditional registers or flip-flops
– any additional asynchronous controls like an asynchronous set and asynchronous reset
Behavioral
reg “register”
Verilog
// 2-to-4 demultiplexer with active-low outputs
// behavioral model Beginner's note
module demux3(a,b,enable,y); Here is something to be cleared up
input a,b,enable; right away when learning Verilog
“reg” is just a variable. In fact it is
output [3:0] y; called a “variable” as of
reg y; // not really a register! Verilog 2000 because the name is
so confusing.
always @(a, b, enable) So, don't be confused by it, “reg” is
case ({enable,a,b}) not necessarily register,
They are used in behavioral
default: y = 4'b1111; descriptions as variables that may
3'b100: y = 4'b1110; end up being
implemented with if sequential
3'b110: y = 4'b1101; logic is generated and are just
3'b101: y = 4'b1011; represent the output net
of combinatorial logic otherwise.
3'b111: y = 4'b0111; Wires on the other hand are for
structural connections (nets/wires)
endcase between modules
endmodule or outputs of combinatorial
expressions.
http://6004.csail.mit.edu/6.371/L02.pdf
Thus we shall always refer to a statement
“reg y;”
as “reg why” not “register why”
Behavioral
Verilog
// 2-to-4 demultiplexer with active-low
outputs
// behavioral model
module demux3(a,b,enable,y);
input a,b,enable;
output [3:0] y;
reg y; // not really a register!
always @(a, b, enable)
case ({enable,a,b}) Contents of “sensitivity list”
default: y = 4'b1111; needs careful attention. A bug
here is a most common cause
3'b100: y = 4'b1110; for differences between Verilog
3'b110: y = 4'b1101; simulation and synthesized
3'b101: y = 4'b1011; hardware.
3'b111: y = 4'b0111;
Since y is always assigned a value in the
endcase body of the always block, it’s value
endmodule doesn’t have to be remembered
between executions.
Therefore no state needs to be saved,
http://6004.csail.mit.edu/6.371/L02.pdf i.e., no register needs to be created.
Sequential vs Combinatorial Logic in hardware synthesis
using always begin...end blocks (Rules of Thumb)

if you could ignore the sensitivity list and reevaluate the procedural block at any and every instant of time
and there would be no change the overall interpretation of the algorithm then combinatorial hardware is
described meaning it can be mapped to a set of output input relationships described by a combinatorial truth
table and no memory of the past is required

if the restriction of only allowing revaluation of the block contents when specific changes occur according to
the sensitivity list would cause a difference in behavior at any point in time then sequential logic is described

If results from any execution of the block directly rely on signals/results generated from a previous execution
of the block then sequential logic is describe. This does not include the case when results are saved using
external sequential logic.

Draw the truth table for each block with and without considering the sensitivity list, it should include a row
for every possible input combination and the output variables should should never occur in the output
columns:
always @ (a,b,c) begin always @ (a,c) begin
x = (c & a) | (~c & b); x = (c & a) | (~c & x);
end end
always @ (a,b,c) begin always @ (c) begin
if c x = a; if c x = a;
else x = b; else x = b;
end end
always @ (a,b,c) begin
if c x = a;
end
Viewing results
module main; Dump variables in
reg a,b,enable; module main. First arg is
wire [3:0] s_z,d_z,b_z; # of levels to dump, eg,
“2” would include
demux1 structural(a,b,enable,s_z); variables from modules
demux2 dataflow(a,b,enable,d_z); instantiated by main.
demux3 behavioral(a,b,enable,b_z); $dumpvars with no args
initial begin will dump everything.
$dumpfile("demux.vcd"); //Specify file for
//Value Change Dump (VCD) info
$dumpvars(1,main);
enable = 0; a = 0; b = 0; //Force one last change
//at final time for better display
#10 enable = 1;
#10 a = 1;
#10 a = 0; b = 1;
#10 a = 1;
#10 enable = 0;
$finish;
end Code from the demux examples can
endmodule be found in /mit/6.371/examples/demux.vl
http://6004.csail.mit.edu/6.371/L02.pdf
Simulating

The stimulus (input)
– Designs can be instantiated and driven by other HDL code,
typically called a testbench, that drives test signals
– Alternatively, some simulators support a scripting language
to drive input signals

The output
– Use $display $monitor or $strobe statements to print result
to screen or file
– Create a value change dump file (VCD)

Can be read and displayed by many tools
– May Directly use a GUI to select and display signals
Design Strategies

For a beginner, treat Verilog as Hardware Description
Language, not a software coding language. Start off
learning Verilog by describing hardware for which
you can design and draw a schematic; then translate
this to HDL.

Plan by partitioning the design into sections and
modules and coding styles that should be used.

Identify existing modules, memory components
needed, and data-path logic, as well as the control
signals required to make those operate as desired.

Simulate each part with a testbench before putting
system together. Update testbenches and resimulate
them as your design evolves.

Large memory blocks are often provided by the
manufacturer to be instantiated. Smaller memory
elements may be coded or embedded into other
descriptions of the design

Data-path logic can be embedded coded with data-
flow, structural elements, or complex synthesizable
behavioral descriptions.

Some styles explicitly separate Comb. Logic and Seq
Logic, but this is up to you.

Best practice is to develop a consistent approach
to design, as well as a consistent coding style. It
makes designing, coding, and debugging easier
for you with time. An inconsistent hack-it-
together and hack-until-it-works approach is not
conducive to becoming more efficient.

Typically, complex control is implemented by a
synthesizable behavioral case-statement-
based state-machine, while simpler control
could be implemented with any combinatorial
description style. Data-path logic (comb. and
sequential) can be integrated into the overall
state machine or separated out (better for
incremental simulation).

Possible Blueprint:
Control status
input
(state machine)
data,status
control status
output
A datapath
Datapath modules
Components of a modeling/description language

Wires and registers with specified precision and sign

Arithmetic and bitwise operations

Comparison Operations

Bitvector Operations (selecting multiple bits from a vector,
concatenation)

Logical Operators

Selection (muxes)

Indexed Storage (arrays)

Organizational syntax elements and Precedence

Modules (Hardware) Definition and Instantiation
Modules and Ports *code from http://www.verilogtutorial.info/chapter_2.htm

port list: ports must be


keyword module begins a module
declared to be
`timescale 1ns / 1ps
input, output, or inout
//create a NAND gate out of an AND and an Inverter
module some_logic_component (c, a, b);
// declare port signals
output c;
input a, b; Additional internal nets
// declare internal wire
may be declared using the
wire d; wire or reg word
//instantiate structural logic gates
and a1(d, a, b); //d is output, a and b are inputs
not n1(c, d); //c is output, d is input
endmodule

keyword endmodule nodes can be connected


begins a module to nested modules or primitives
or interact with procedural code
Verilog 2000: New Port Decl. Options
Verilog 95 code
module memory( read, write, data_in, addr, data_out);
input read; After the port list, port direction must be
input write;
input [7:0] data_in; declared to be input, output, or inout
input [3:0] addr; as well as the width if more than one bit
output [7:0] data_out;
Type declaration: type is by default a
reg [7:0] data_out; wire unless another type is provided

Verilog 2k with direction and Verilog 2k with no type in


data type listed port list
module memory( module memory( declared
input wire read, input read, as wire by
input wire write, input write,
default
input [7:0] data_in,
input wire [7:0] data_in,
input wire [3:0] addr, input [3:0] addr,
output reg [7:0] data_out output reg [7:0] data_out
); );
Disadvantage to exposing type in port declaration
Verilog 2000 – port y as reg Verilog 2000 – port y as wire

module dff2y(output reg qA, module dff2y(output reg qA,
output reg qB, output reg qB,
output reg y, output wire y,
input dA, input dA,
input dB, input dB,
input en_n, input en_n,
input clk) input clk)
yy is
is not
not the
always@(posedge clk) output
output of a register always@(posedge clk)
if (~en_n) begin though
though declared as if (~en_n) begin
qA <= dA; reg
reg along
along with qA qA <= dA;
qB <= dB; and
and qB in in the left qB <= dB;
end module
module declaration end
It
It is
is arguable
arguable
always @(qA,aB) begin that
that such
such an assign y = qA&qB;
y = 1’b0; internal
internal coding
coding end
if (a&b) begin implementation
implementation
y = 1; detail
detail does not not
end belong
belong in in
end the
the presentation
presentation of anan
end “external”
“external” interface
interface
Disadvantage to exposing type in port declaration
Verilog 2000 -- hiding reg while exposing port direction
module dff2y( output qA, always@(posedge clk)
output qB, if (~en_n) begin
output y, qA_int <= dA;
input dA,
qB_int <= dB;
input dB,
end
input en_n,
input clk)
always @(qA,aB) begin
reg qA_int,qB_int,y_int; y_int = 1’b0;
if (a&b) begin
assign qA = qB_int; y_int = a&b;
assign qB= qA_int; end
assign y= y_int; end
end
Disadvantage to exposing type in port declaration
Verilog 95

With V’95, module dff2y(qA,qB, //dff out A B
y, //and of qA&qB
dA,dB, //dff inputs
the type is not en_n, //input clk en
clk) //clk

externally output reg qA;


output reg qB;
output reg qA;
output reg qB;

exposed in the
output reg y; output y;
input dA; input dA;
input dB; input dB;

port definition input en_n;


input en_n;
input en_n;
input clk;
always@(posedge clk) begin
always@(posedge clk)
if (~en_n) begin
qA <= dA; begin
qB <= dB; if (~en_n) begin
end qA <= dA;
end qB <= dB;
end
always @(qA,aB) begin end
y = 1’b0;
if (a&b) begin assign y = a&b;
y = a&b;
end end
end
end
Hierarchy and Instantiation

Implicit port mapping uses the order of the
ports in the definition to imply connections to
local nets
Instantiation with Implicit Port Mapping
module dff2y_en( output qA, qB,
output y,
input dA, dB, At this level
input en, of the
input clk)
hierarchy y
wire en_n;
wire en_n = ~en;
assign en_n = ~en; is a wire
dff2y dff2yInstance( regardless
qA,qB, //dff out A B
y, //and of qA&qB of the internal
dA,dB, //dff inputs code
en_n, //input clk en
clk); //clk implementation
endmodule of y in dff2y
Hierarchy and Instantiation

Explicit port mapping uses the port names
prefixed with . and allows reordering, no-
connect, and omission of ports
Instantiation with Explicit Port Mapping
module dff2y_en( output y,
input dA, dB,
input en,
input clk)

dff2y dff2yInstance(
.dA(dA),
.dB(dB),
.qA(), //qA not used (no-connect)
//qB omitted
.y(y),
.en_n(~en), Implicit net declaration of a
.clk(clk)); //clk net holding the result ~en.
endmodule This is NOT allowed if default
net declaration is disabled. ie using
`default net_type none

You might also like