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

The Verilog Language

The document describes the Verilog language, which was originally developed as a modeling language for digital logic simulation but is now commonly used for logic synthesis and digital hardware design. It discusses how Verilog is used for behavioral and structural modeling, simulation, synthesis, and timing analysis of digital designs. The document also covers various Verilog language concepts like modules, ports, primitives, continuous assignments, user-defined primitives, and four-valued logic.

Uploaded by

Himanshu Gupta
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

The Verilog Language

The document describes the Verilog language, which was originally developed as a modeling language for digital logic simulation but is now commonly used for logic synthesis and digital hardware design. It discusses how Verilog is used for behavioral and structural modeling, simulation, synthesis, and timing analysis of digital designs. The document also covers various Verilog language concepts like modules, ports, primitives, continuous assignments, user-defined primitives, and four-valued logic.

Uploaded by

Himanshu Gupta
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 83

The Verilog Language

Originally a modeling language for a very efficient


event-driven digital logic simulator
Later pushed into use as a specification language
for logic synthesis
Now, one of the two most commonly-used
languages in digital hardware design (VHDL is the
other)
Virtually every chip (FPGA, ASIC, etc.) is
designed in part using one of these two languages
Combines structural and behavioral modeling
styles

How Verilog Is Used

Virtually every ASIC is designed using either


Verilog or VHDL (a similar language)
Behavioral modeling with some structural
elements
Synthesis subset

Can be translated using Synopsys Design Compiler


or others into a netlist

Design written in Verilog


Simulated to death to check functionality
Synthesized (netlist generated)
Static timing analysis to check timing

Structural Modeling

When Verilog was first developed (1984) most


logic simulators operated on netlists
Netlist: list of gates and how theyre connected
A natural representation of a digital logic circuit
Not the most convenient way to express test
benches

Comparison
STRUCTURAL

Structural: Logic is
described in terms of
Verilog gate primitives

Example:
not n1(sel_n, sel);
and a1(sel_b, b,
sel_b);
and a2(sel_a, a, sel);
or o1(out, sel_b,
sel_a);

DATAFLOW

Dataflow: Specify
output signals in
terms of input
signals

Example:
assign out = (sel &
a) | (~sel & b);

Structural modelling

Dataflow modelling
b

b
sel

n1

a1

sel_b

sel

sel_n
o1

a
a2

out

sel_b
sel_n

out
sel_a

sel_a

Behavioral Modeling

A much easier way to write testbenches


Also good for more abstract models of circuits
Easier to write
Simulates faster

More flexible
Provides sequencing
Verilog succeeded in part because it allowed both
the model and the testbench to be described
together

Behavioral contd..

Behavioral: Algorithmically specify the behavior of


the design

Example:
if (select == 0) begin
out = b;
end
else if (select == 1) begin
out = a;
end

a
b

Black Box

2x1 MUX

sel

out

Dataflow modelling

Uses continuous assignment statement


Format:

assign [ delay ] net = expression;


Example: assign sum = a ^ b;

Delay: Time duration between assignment


from RHS to LHS

All continuous assignment statements execute


concurrently

Order of the statement does not impact the


design

Data flow modelling contd..

Example:
`timescale 1ns/100ps
module HalfAdder (A, B, Sum, Carry);
input A, B; output Sum, Carry;
assign #3 Sum = A ^ B;
assign #6 Carry = A & B;
endmodule

Contd..

Delay can be introduced

Associate time-unit with physical time

Example: assign #2 sum = a ^ b;


#2 indicates 2 time-units
No delay specified : 0 (default)
`timescale time-unit/time-precision
Example: `timescale 1ns/100 ps

Timescale
`timescale 1ns/100ps

1 Time unit = 1 ns
Time precision is 100ps (0.1 ns)
10.512ns is interpreted as 10.5ns

Two Main Components of


Verilog

Concurrent, event-triggered processes


(behavioral)
Initial and Always blocks
Imperative code that can perform standard data
manipulation tasks (assignment, if-then, case)
Processes run until they delay for a period of time or
wait for a triggering event

Structure (Plumbing)
Verilog program build from modules with I/O
interfaces
Modules may contain instances of other modules
Modules contain local signals, etc.
Module configuration is static and all run concurrently

Data types

Net Types: Physical Connection between


structural elements

Register Type: Represents an abstract storage


element.

Default Values
Net Types : z
Register Type : x

Net Types: wire, tri, wor, trior, wand, triand,


supply0, supply1

Register Types : reg, integer, time, real, realtime

Two Main Data Types

Nets represent connections between things

Do not hold their value


Take their value from a driver such as a gate or other
module
Cannot be assigned in an initial or always block

Regs represent data storage

Behave exactly like memory in a computer


Hold their value until explicitly assigned in an initial or
always block
Never connected to something
Can be used to model latches, flip-flops, etc., but do not
correspond exactly
Shared variables with all their attendant problems

Data types contd..

Net Type: Wire


wire [ msb : lsb ] wire1, wire2,

Example
wire Reset; // A 1-bit wire
wire [6:0] Clear; // A 7-bit wire

Register Type: Reg


reg [ msb : lsb ] reg1, reg2,

Example
reg [ 3: 0 ] cla; // A 4-bit register
reg cla; // A 1-bit register

Restricted data types

Data Flow and Structural Modeling


Can

use only wire data type


Cannot use reg data type

Behavioral Modeling
Can

use only reg data type (within initial and


always constructs)
Cannot use wire data type

Memories

An array of registers
reg [ msb : lsb ] memory1 [ upper : lower ];

Example
reg [ 0 : 3 ] mem [ 0 : 63 ];
// An array of 64 4-bit registers
reg mem [ 0 : 4 ];
// An array of 5 1-bit registers

Compiler directives

`define (Similar to #define in C) used to define


global parameter

Example:
`define BUS_WIDTH 16
reg [ `BUS_WIDTH - 1 : 0 ] System_Bus;

`undef Removes the previously defined directive

Example:
`define BUS_WIDTH 16

reg [ `BUS_WIDTH - 1 : 0 ] System_Bus;

`undef BUS_WIDTH

Contd..

`include used to include another file

Example
`include ./fulladder.v

Four-valued Data

Verilogs nets and registers hold four-valued data

0, 1

Obvious

Output of an undriven tri-state driver


Models case where nothing is setting a wires value

Models when the simulator cant decide the value


Initial state of registers
When a wire is being driven to 0 and 1 simultaneously
Output of a gate with Z inputs

Four-valued Logic

Logical operators work on three-valued logic

Z
Output 0 if one input is 0

0
1
X
Z

0
0
0
0

0
1
X
X

0
X
X
X

0
X
X
X

Output X if both inputs are


gibberish

Operators

Arithmetic(Unary )
Relational
Bitwise
Logical
Equality

STRUCTURAL
MODELING

Nets and Registers

Wires and registers can be bits, vectors, and


arrays

wire a;
// Simple wire
tri [15:0] dbus;
// 16-bit tristate bus
tri #(5,4,8) b;
// Wire with delay
reg [-1:4] vec;
// Six-bit register
trireg (small) q;
// Wire stores a small
charge
integer imem[0:1023]; // Array of 1024 integers
reg [31:0] dcache[0:63]; // A 32-bit memory

Modules and Instances

Basic structure of a Verilog module:

module mymod(output1, output2, input1, input2);


output output1;
output [3:0] output2;
Verilog convention lists
outputs first
input input1;
input [2:0] input2;

endmodule

Instantiating a Module

Instances of

module mymod(y, a, b);

look like

mymod mm1(y1, a1, b1);


// Connect-by-position
mymod (y2, a1, b1),
(y3, a2, b2);
// Instance names
omitted
mymod mm2(.a(a2), .b(b2), .y(c2)); // Connect-by-name

Gate-level Primitives

Verilog provides the following:

and
or
xor
buf
bufif0
bifif1

nand
nor
xnor
not
notif0
notif1

logical AND/NAND
logical OR/NOR
logical XOR/XNOR
buffer/inverter
Tristate with low enable
Tristate with high enable

Delays on Primitive Instances

Instances of primitives may include delays

buf
b1(a, b);
buf #3
b2(c, d);
buf #(4,5) b3(e, f);
buf #(3:4:5)
b4(g, h);

// Zero delay
// Delay of 3
// Rise=4, fall=5
// Min-typ-max

User-Defined Primitives

Way to define gates and sequential elements


using a truth table
Often simulate faster than using expressions,
collections of primitive gates, etc.
Gives more control over behavior with X inputs
Most often used for specifying custom gate
libraries

An UDP can contain only one output and up to 10


inputs.
Output port should be the first port followed by
one or more input ports.
All UDP ports are scalar, i.e. Vector ports are not
allowed.
UDPs can not have bidirectional ports.
The output terminal of a sequential UDP requires
an additional declaration as type reg.
It is illegal to declare a reg for the output terminal
of a combinational UDP

A Carry Primitive
primitive carry(out, a, b, c);
Always have exactly one
output out;
output
input a, b, c;
table
00? : 0;
Truth table may include
0?0 : 0;
dont-care (?) entries
?00 : 0;
11? : 1;
1?1 : 1;
?11 : 1;
endtable
endprimitive

A Sequential Primitive
Primitive dff( q, clk, data);
output q; reg q;
input clk, data;
table
// clk data q new-q
(01) 0 : ? : 0;
// Latch a 0
(01) 1 : ? : 1;
// Latch a 1
(0x) 1 : 1 : 1;
// Hold when d and q both 1
(0x) 0 : 0 : 0;
// Hold when d and q both 0
(?0) ? : ? : -;
// Hold when clk falls
? (??) : ? : -;
// Hold when clk stable
endtable
endprimitive

Continuous Assignment

Another way to describe combinational function


Convenient for logical or datapath specifications
Define bus widths

wire [8:0] sum;


wire [7:0] a, b;
wire carryin;
assign sum = a + b + carryin;

Continuous assignment:
permanently sets the
value of sum to be
a+b+carryin
Recomputed when a, b, or
carryin changes

primitive udp_body ( a, b,c);


output a;
input b,c;
// UDP function code here 11
// A = B | C;
table
// B C : A
? 1 : 1;
1 ? : 1;
0 0 : 0;
endtable
endprimitive

tb

`include "udp_body.v"
module udp_body_tb();
reg b,c;
wire a;
udp_body udp (a,b,c);
initial begin
$monitor(" B = %b C = %b A = %b",b,c,a);
b = 0; c = 0;
#1 b = 1;

#1 b = 0;
#1 c = 1;
#1 b = 1'bx;
#1 c = 0;
#1 b = 1;
#1 c = 1'bx;
#1 b = 0;
#1 $finish;
endmodule

output

B=0C=0A=0
B=1C=0A=1
B=0C=0A=0
B=0C=1A=1
B=xC=1A=1
B=xC=0A=x
B=1C=0A=1
B=1C=xA=1
B=0C=xA=x

table

Table is used for describing the function of


UDP. Verilog reserved word table marks the
start of table and reserved
word endtable marks the end of table.
Each line inside a table is one condition; when
an input changes, the input condition is
matched and the output is evaluated to reflect
the new change in input

Initial statement is used for initialization of


sequential UDPs. This statement begins with
the keyword 'initial'. The statement that follows
must be an assignment statement that assigns
a single bit literal value to the output terminal
reg

primitive udp_initial (a,b,c);


output a;
input b,c;
reg a;
// a has value of 1 at start of sim
initial a = 1'b1;
table
// udp_initial behaviour
Endtable
endprimitive

symbols

interpretation

logic

0,1,X

? Means the variable


can be 0 or 1 or X

0,1

Same as ?, but X is not


included

(10)

Falling edge on an input

(01)

Rising egde on an input

(01) or( 0X) or (X1) or


(1z) or (z1)

Rising edge including X


and Z

(10) Or(1x) or(x0) or(0z)


or (z0)

Falling edge including x


and Z

(??)

All transitions

No change

No change

Level sensitive sequential


primitive udp_latch(q, clk, d) ;
output q;
input clk, d;
reg q;
table
//clk d q q+
01:?:1;
00:?:0;
1?:?:-;
endtable
endprimitive

Edge sensitive UDPs

In level-sensitive behavior, the values of the inputs


and the current state are sufficient to determine
the output value.
Edge-sensitive behavior differs in that changes in
the output are triggered by specific transitions of
the inputs.
All transitions that should not affect the output
must be explicitly specified. Otherwise, they will
cause the value of the output to change to x. If the
UDP is sensitive to edges of any input, the
desired output state must be specified for all
edges of all inputs

edge

primitive udp_sequential(q, clk, d);


output q;
input clk, d;
reg q;
table
// obtain output on rising edge of clk
// clk d q q+
(01) 0 : ? : 0 ;
(01) 1 : ? : 1 ;
(0?) 1 : 1 : 1 ;
(0?) 0 : 0 : 0 ;

// ignore negative edge of clk


(?0) ? : ? : - ;
// ignore d changes on steady clk
? (??) : ? : - ;
endtable
endprimitive

With initial block

primitive udp_sequential_initial(q, clk, d);


output q;
input clk, d;
reg q;
initial begin
q = 0;
end
table

BEHAVIORAL
MODELING

Initial and Always Blocks

Basic components for behavioral modeling

initial
begin
imperative statements
end

always
begin
imperative statements
end

Runs when simulation starts


Terminates when control reaches
the end
Good for providing stimulus

Runs when simulation starts


Restarts when control reaches the
end
Good for modeling/specifying
hardware

Initial and Always

Run until they encounter a delay

initial begin
#10 a = 1; b = 0;
#10 a = 0; b = 1;
end

or a wait for an event

always @(posedge clk) q = d;


always begin wait(i); a = 0; wait(~i); a = 1; end

Procedural Assignment

Inside an initial or always block:

sum = a + b + cin;

Just like in C: RHS evaluated and assigned to


LHS before next statement executes

RHS may contain wires and regs

Two possible sources for data

LHS must be a reg

cont. assignment may set wire values

Contd..

If a procedure block contains more than one


statement, those statements must be enclosed
within

Sequential begin - end block


Parallel fork - join block

When using begin-end, we can give name to


that group. This is called named blocks.

Two Procedural Constructs


initial

Statement
always Statement

initial Statement : Executes only once


always Statement : Executes in a loop
Example:

initial begin
Sum = 0;
Carry = 0;
end

always @(A or B) begin


Sum = A ^ B;
Carry = A & B;
end

module initial_fork_join();
reg clk,reset,enable,data;
initial begin
$monitor("%g clk=%b reset=%b enable=%b data=%b",
$time, clk, reset, enable, data);
fork
#1 clk = 0;
#10 reset = 0;
#5 enable = 0;
#3 data = 0;
join
#1 $display ("%g Terminating simulation", $time);
$finish;
end

Output
clk=x reset=x enable=x data=x
1 clk=0 reset=x enable=x data=x
3 clk=0 reset=x enable=x data=0
5 clk=0 reset=x enable=0 data=0
10 clk=0 reset=0 enable=0 data=0
11 Terminating simulation

Imperative Statements
if (select == 1)
else

y = a;
y = b;

case (op)
2b00: y = a + b;
2b01: y = a b;
2b10: y = a ^ b;
default: y = hxxxx;
endcase

Delay

Inter-Assignment Delay

Example:
Sum = A ^ B;
#2 Carry = A & B;

Delayed execution

Intra-Assignment Delay

Example:
Sum = A ^ B;
Carry = #2 A & B;

Delayed assignment

Edge sensitive Event Controls

Delays execution of the next statement until the specified


transition on a signal.
syntax : @ (< posedge >|< negedge > signal) < statement >;

module edge_wait_example();
reg enable, clk, trigger;
always @ (posedge enable)
begin
trigger = 0;
// Wait for 5 clock cycles
repeat (5) begin
@ (posedge clk) ;
end
trigger = 1;
end

Level-Sensitive Even Controls (


Wait statements )

Delays execution of the next statement until <


expression > evaluates to true
syntax : wait (< expression >) < statement >;
Eg:
wait (data_ready == 1) #1 data = data_bus;

Discrete-event Simulation

Basic idea: only do work when something


changes
Centered around an event queue

Contains events labeled with the simulated time at


which they are to be executed

Basic simulation paradigm


Execute every event for the current simulated time
Doing this changes system state and may schedule
events in the future
When there are no events left at the current time
instance, advance simulated time soonest event in the
queue

Event

Event Control
Edge Triggered Event Control
Level Triggered Event Control

Edge Triggered Event Control


@ (posedge CLK) //Positive Edge of CLK
Curr_State = Next_state;

Level Triggered Event Control


@ (A or B) //change in values of A or B
Out = A & B;

For Loops

A increasing sequence of values on an output

reg [3:0] i, output;


for ( i = 0 ; i <= 15 ; i = i + 1 ) begin
output = i;
#10;
end

While Loops

A increasing sequence of values on an output

reg [3:0] i, output;

i = 0;
while (I <= 15) begin
output = i;
#10 i = i + 1;
end

Modeling A Flip-Flop With


Always

Very basic: an edge-sensitive flip-flop

reg q;

always @(posedge clk)


q = d;

q = d assignment runs when clock rises:


exactly the behavior you expect

Blocking vs. Nonblocking

Verilog has two types of procedural


assignment

Fundamental problem:
In

a synchronous system, all flip-flops sample


simultaneously
In Verilog, always @(posedge clk) blocks run in
some undefined sequence

A Flawed Shift Register

This doesnt work as youd expect:

reg d1, d2, d3, d4;

always @(posedge clk) d2 = d1;


always @(posedge clk) d3 = d2;
always @(posedge clk) d4 = d3;

These run in some order, but you dont know


which

Non-blocking Assignments

This version does work:

Nonblocking rule:
RHS evaluated when
assignment runs

reg d1, d2, d3, d4;


always @(posedge clk) d2 <= d1;
always @(posedge clk) d3 <= d2;
always @(posedge clk) d4 <= d3;
LHS updated only after all
events for the current instant
have run

Nonblocking Can Behave Oddly


A sequence of nonblocking assignments dont
a <= 1;
a communicate
= 1;

b = a;
c = b;

b <= a;
c <= b;

Blocking assignment:
a=b=c=1

Nonblocking assignment:
a=1
b = old value of a
c = old value of b

Nonblocking Looks Like


Latches
RHS of nonblocking taken from latches
aRHS
= 1; of blocking taken from wires

b = a;
c = b;

1
a <= 1;
b <= a;
c <= b;

b
c

Conditional statements

if Statement
Format:
if (condition)
procedural_statement
else if (condition)
procedural_statement
else

procedural_statement
Example:
if (Clk)
Q = 0;
else
Q = D;

Contd..

Case Statement
Example 1:
case (X)
2b00: Y = A + B;
2b01: Y = A B;
2b10: Y = A / B;
endcase

Example 2:
case (3b101 << 2)
3b100: A = B + C;
4b0100: A = B C;
5b10100: A = B / C; //This statement is executed
endcase

Contd..

Variants of case Statements:

casex and casez

casez z is considered as a dont care


casex both x and z are considered as dont
cares
Example:
casez (X)
2b1z: A = B + C;
2b11: A = B / C;
endcase

VERILOG AND LOGIC


SYNTHESIS

Logic Synthesis

Verilog is used in two ways


Model for discrete-event simulation
Specification for a logic synthesis system

Logic synthesis converts a subset of the Verilog


language into an efficient netlist
One of the major breakthroughs in designing logic
chips in the last 20 years
Most chips are designed using at least some logic
synthesis

Logic Synthesis

Takes place in two stages:

Translation of Verilog (or VHDL) source to a netlist

Register inference

Optimization of the resulting netlist to improve


speed and area
Most critical part of the process
Algorithms very complicated and beyond the scope of
this class: Take Prof. Nowicks class for details

Translating Verilog into Gates

Parts of the language easy to translate


Structural
Already

descriptions with primitives

a netlist

Continuous

assignment

Expressions

turn into little datapaths

Behavioral statements the bigger challenge

What Can Be Translated

Structural definitions

Behavioral blocks

Everything
Depends on sensitivity list
Only when they have reasonable interpretation as
combinational logic, edge, or level-sensitive latches
Blocks sensitive to both edges of the clock, changes on
unrelated signals, changing sensitivity lists, etc. cannot be
synthesized

User-defined primitives

Primitives defined with truth tables


Some sequential UDPs cant be translated (not latches or
flip-flops)

What Isnt Translated

Initial blocks
Used to set up initial state or describe finite testbench
stimuli
Dont have obvious hardware component

Delays

May be in the Verilog source, but are simply ignored

A variety of other obscure language features

In general, things heavily dependent on discrete-event


simulation semantics

Certain disable statements


Pure events

Register Inference

The main trick

reg does not always equal latch

Rule: Combinational if outputs always depend


exclusively on sensitivity list
Sequential if outputs may also depend on
previous values

Register Inference

Combinational:

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

Sensitive to changes on
all of the variables it reads

Y is always assigned

Sequential:

reg q;
always @(d or clk)
if (clk) q = d;

q only assigned when clk


is 1

Register Inference

A common mistake is not completely specifying a


case statement
This implies a latch:

always @(a or b)
case ({a, b})
2b00 : f = 0;
2b01 : f = 1;
2b10 : f = 1;
endcase

f is not assigned when


{a,b} = 2b11

Register Inference

The solution is to always have a default case

always @(a or b)
case ({a, b})
2b00: f = 0;
2b01: f = 1;
2b10: f = 1;
default: f = 0;
endcase

f is always assigned

Inferring Latches with Reset

Latches and Flip-flops often have reset inputs


Can be synchronous or asynchronous

Asynchronous positive reset:

always @(posedge clk or posedge reset)


if (reset)
q <= 0;
else q <= d;

Simulation-synthesis
Mismatches

Many possible sources of conflict

Synthesis ignores delays (e.g., #10), but


simulation behavior can be affected by them
Simulator models X explicitly, synthesis doesnt
Behaviors resulting from shared-variable-like
behavior of regs is not synthesized

always @(posedge clk) a = 1;


New value of a may be seen by other @(posedge clk)
statements in simulation, never in synthesis

Compared to VHDL

Verilog and VHDL are comparable languages


VHDL has a slightly wider scope
System-level modeling
Exposes even more discrete-event machinery

VHDL is better-behaved

Fewer sources of nondeterminism (e.g., no shared


variables)

VHDL is harder to simulate quickly


VHDL has fewer built-in facilities for hardware
modeling
VHDL is a much more verbose language

Most examples dont fit on slides

You might also like