You are on page 1of 43

Verilog - Basic

Salahuddin Ahmed
Gate-Level Minimization
HDL
HDL describes the hardware of digital systems.
It describes hardware structures and behavior.
It represents logic diagrams, Boolean functions
and other more complex digital circuits.
To simulate a digital system, the design is first
described in HDL and then verified by simulating
the design and checking it with a test bench.
Logic synthesis is the process of deriving a netlist
from the model of a digital system written in HDL.
There are two standard HDLs:
VHDL and Verilog HDL.
Module Representation
Verilog uses about 100 keywords predefined,
lowercase, identifiers that defines the language
constructs. e.g.
module, endmodule, input, output, wire, and, or, not
etc.
Comments start with two slashes (//)
Blank spaces are ignored
Names are case sensitive
Each statement is terminated with a ;
Output is always listed first, followed by inputs
Verilog Example
// description of simple circuit A e
g1
module smpl_circuit( x, y, A, B, C );
B x
input A, B, C; g3
output x, y; C y

wire e; g2
and g1( e, A, B );
not g2( y, C );
or g3( x, e, y );
endmodule
Gate Delays
Simulator defaults to certain time unit,
usually 1 ns but could be changed with
`timescale 1ns / 100ps
Delay is specified in terms of time units
and the symbol #
and #(10) gate1(e, A, B)
Test Bench Example
A e
// description of test bench g1
module smpl_ckt_tb; B g3
x
reg A, B, C; y
C
wire x, y;
g2

smpl_circuit inst1(x,y,A,B,C);
// description of simple circuit
initial module smpl_circuit( x, y, A, B, C );
begin input A, B, C;
A=1b0; B=1b0; C=1b0; output x, y;
#100 A=1b1; B=1b1; C=1b1; wire e;
#100 $finish; and #(30) g1( e, A, B );
end not #(20) g2( y, C );
or #(10) g3( x, e, y );
endmodule endmodule

An HDL description that provides the stimulus to a design is called a test bench
Boolean Expression in Verilog
// Circuit with Boolean expression
module smpl_circuit( x, y, A, B, C ); A e
input A, B, C; g1
output x, y; B g3
x
assign y = ~C; C y

assign x = (A & B) | (~C); g2
endmodule
User Defined Primitives (UDP)
// User defined primitive (UDP) // Instantiate primitive
primitive crctp (x, A, B, C); module test_crctp;
output x; reg x, y, z;
input A, B, C; wire w;
// truth table for x(A,B,C) = (0,2,4,6,7) crctp (w, x, y, z);
table endprimitive
// A B C : x
0 0 0 : 1;
0 0 1 : 0;
The system recognizes the variables
0 1 0 : 1;
by the order that they are listed in the
0 1 1 : 0;
input declaration.
1 0 0 : 1;
1 0 1 : 0; User-defined primitive can be employed
1 1 0 : 1; in construction of other digital circuits
1 1 1 : 1; just as the system primitives are used.
endtable
endprimitive
UDP (cont.)
Declared with keyword primitive followed by a name and
port list.
Only one output must be listed first in the port list and
declared with output keyword.
Any number of inputs allowed order in the input must
be same as the values in the table that follows.
Truth table is enclosed within table and endtable.
Values of inputs end with a colon (:) Output is the last
entry in a row followed by a semicolon (;)
UDP ends with the keyword endprimitive.
and, or, not etc. gates are referred to as system primitive
Combinational Logic
HDL Models
Verilog module can be described in any of
the following modeling techniques:
Gate level modeling using instantiation of
primitive gates and user defined modules.
Dataflow modeling using continuous
assignment statements with keyword assign.
Behavioral modeling using procedural
assignment statements with keyword always.
Used to describe digital systems at a higher level
of abstraction.
Gate Level Modeling
Specifies circuit by its logic gates and their
interconnections.
Provides textual description of schematic
diagram.
Verilog recognizes 12 basic gates as
predefined primitives.
and, nand, or, nor, xor, xnor, not, buf
4 are tri-state type: bufif1, bufif0, notif1, notif0
Output is listed first, followed by inputs.
Primitive Gates
Two more logic values other than 0 and 1
Unknown (x)
Unassigned or ambiguous value
High Impedance (z)
Unconnected wire or output of a disabled tri-state gate

and 0 1 x z or 0 1 x z xor 0 1 x z not input output

0 0 0 0 0 0 0 1 x x 0 0 1 x x 0 1

1 0 1 x x 1 1 1 1 1 1 1 0 x x 1 0

x 0 x x x x x 1 x x x x x x x x x

z 0 x x x z x 1 x x z x x x x z z
Example
// gate level description of a 2-to-4 decoder

module decoder_2to4 (Yb, A, B, E);


input A, B, E; Multiple bit widths
output [3:0] Yb; are called vectors
wire Abar, Bbar, Ebar;
First number is the
not n1 (Abar, A), MSB of the vector
n2 (Bbar, B),
n3 (Ebar, E);
Multiple instances
nand n4 (Yb[0], Abar, Bbar, Ebar), of same gate
n5 (Yb[1], A, Bbar, Ebar), separated by ,
n6 (Yb[2], Abar, B, Ebar),
n7 (Yb[3], A, B, Ebar);
endmodule
Hierarchical Design
// description of a half adder // description of a 4-bit adder
module halfadder (S, C, x, y);
input x, y; module _4bit_adder (S, C4, A, B, C0);
output S, C; input [3:0] A, B;
xor (S, x, y); input C0;
and (C, x, y); output [3:0] S;
endmodule output C4;

// description of a full adder wire C1, C2, C3;


module fulladder (S, C, x, y, z);
input x, y, z; fulladder FA0 (S[0], C1, A[0], B[0], C0),
output S, C; FA1 (S[1], C2, A[1], B[1], C1),
wire S1, D1, D2; FA2 (S[2], C3, A[2], B[2], C2),
halfadder HA1 (S1, D1, x, y), FA3 (S[3], C4, A[3], B[3], C3);
HA2 (S, D2, S1, z); endmodule
or g1 (C, D1, D2);
endmodule
Three State Gates
// description of a half adder
module muxtri (A, B, Select, OUT); A out
input A, B, Select;
output OUT;
tri OUT;
bufif1 (OUT, A, Select); B
bufif0 (OUT, B, Select); Select
endmodule

Nets represent connections between hardware elements.


wire and tri are examples of net data type

Net represents the data types of wire, wor, wand, tri, suply1 and supply0
wire takes values of 0 or 1 tri takes values of 0, 1 or z
wor is wired-OR wand is wired-AND
supply1 is power supply supply0 is ground
Verilog HDL Operators
Operator Operation Operator Operation
Symbol Symbol
Type Performed Type Performed
+ Addition >> Shift Right
Subtraction Shift << Shift Left
Arithmetic * Multiplication {,} Concatenation
/ Division > Greater than
% Modulus < Less than
~ Complement == Equality
Logic & AND != Inequality
(reduction) Relational
(bit-wise) | OR Greater than
>=
^ XOR or equal
! Negation Less than or
<=
Logical && AND equal
|| OR Conditional ?:
Dataflow Modeling
// description of a 2-to-4 decoder // description of a 4-bit adder
module decoder_2to4 (Yb, A, B, E); module _4bit_adder (S, C4, A, B, C0);
input A, B, E; input [3:0] A, B;
output [3:0] Yb; input C0;
assign Yb[0] = ~(~A & ~B & ~E), output [3:0] S;
Yb[1] = ~(~A & B & ~E), output C4;
Yb[2] = ~(A & ~B & ~E),
Yb[3] = ~(A & B & ~E); assign {C4, S} = A + B + C0;
endmodule endmodule

// description of a 4bit comparator


module magcomp (A, B, ALTB, AGTB, AEQB);
input [3:0] A, B; // description of a 2-to-1 MUX
output ALTB, AGTB, AEQB; module mux_2to1 (A, B, Select, OUT);
assign ALTB = (A < B), input A, B, Select;
AGTB = (A > B), output OUT;
AEQB = (A == B); assign OUT = Select ? A : B;
endmodule endmodule
Behavioral Modeling
// description of a 2-to-1 MUX // description of a 4-to-1 MUX
module mux_2to1(A, B, select, Y); module mux_4to1 ( i0, i1, i2, i3, select, y);
input A, B, select; input i0, i1, i2, i3;
output Y; input [1:0] select;
reg Y; output reg y;
always @ (select or A or B) always @ (i0, i1, i2, i3, select)
if (select == 1) Y = A; case ( select )
else Y = B; 2b00: y = i0;
endmodule 2b01: y = i1;
2b10: y = i2;
2b11: y = i3;
endcase
endmodule
Test Bench
module testname.
declare local reg and wire identifiers.
instantiate the design module under test.
generate stimulus using initial and always statements.
display the output response.
endmodule

Design Module Testbench Module

module circuit (C, A, B); module test_bench


input A, B; reg TA, TB;
output C; wire TC;
circuit cr (TC, TA, TB);
Test Bench
initial block executes only once starting at time = 0 to
provide stimulus to the design module.
Multiple statements within initial block are enclosed
between begin and end.
repeat specifies a looping statement to repeat the next
statement n number of times after specified time units.

initial initial
begin begin
A = 0; B = 0; D = 3b000;
#10 A = 1; repeat (7)
#20 A = 0; B = 1; #10 D = D + 3b001;
end end
Test Bench System Tasks
Built in system functions begin with the symbol $
System tasks useful for display are:
$display
display values of variables or strings and goes to next line
$write
Same as $display w/o going to next line
$monitor
Display variables whenever a value changes
$time
Displays simulation time
$finish
Terminates the simulation
Test Bench
// stimulus for mux_2to1
module testmux;
reg TA, TB, TS; // inputs for mux
wire Y; // output from mux Simulation log
// instantiate mux
mux_2to1 mx (TA, TB, TS, Y); select = 1 A = 0 B = 1 Y = 0 time = 0
initial select = 1 A = 1 B = 0 Y = 1 time = 10
begin select = 0 A = 1 B = 0 Y = 0 time = 20
TS = 1; TA = 0; TB = 1; select = 0 A = 0 B = 1 Y = 1 time = 30
#10 TA = 1; TB = 0;
#10 TS = 0;
#10 TA = 0; TB = 1;
end
initial
$monitor(select = %b A = %b B = %b Y = %b time = %0d,
TS, TA, TB, Y, $time);
endmodule
Test Bench
Assuming design module for circuit of Fig 4-2 is defined as:
module analysis (F1, F2, A, B, C);

// testbench for ckt of Fig 4-2 Simulation log


module test_circuit;
reg [2:0] D; ABC = 000 F1 = 0 F2 = 0
wire F1, F2; ABC = 001 F1 = 1 F2 = 0
analysis fig42 (F1, F2, D[2], D[1], D[0]); ABC = 010 F1 = 1 F2 = 0
initial ABC = 011 F1 = 0 F2 = 1
begin ABC = 100 F1 = 1 F2 = 0
D = 3b000; ABC = 101 F1 = 0 F2 = 1
repeat (7) ABC = 110 F1 = 0 F2 = 1
#10 D = D + 1b1; ABC = 111 F1 = 1 F2 = 1
end
initial
$monitor (ABC = %b F1 = %b F2 = %b, D, F1, F2);
endmodule
Synchronous Sequential Logic
HDL for Sequential Circuits
There are 2 kinds of behavioral statements
initial
Executes only once beginning at time = 0
always
Execute repeatedly and re-executes until the simulation
terminates
A module may contain an arbitrary number of
initial or always statements.
These statements execute concurrently with
respect to each other at time 0.
HDL for Sequential Circuits
initial initial
begin begin
clock = 1b0; clock = 1b0;
repeat (30) #300 $finish;
#10 clock = ~clock; end
end always
#10 clock = ~clock;

always @ (event control expression) A procedural assignment is an


Procedural assignment statement. assignment within an initial or
always statement
always @ (A or B or Reset)
Two kinds of procedural
always @ (posedge clock or negedge reset) assignments: blocking ( = )
and non-blocking ( <= )
Always Block
Verilog syntax requires that procedural statement
be contained inside an always block.
An always block can contain one or more
statement(s).
Statements inside an always block are evaluated
in the order given in the code.
Continuous assignment statements are evaluated
concurrently.
Part of always block after @ is called sensitivity
list.
The statements inside an always block are executed
by the simulator only when one or more of the signals
in the sensitivity list changes value.
Procedural Statement
Procedural statement must be placed inside an
always block
e.g. for statement, if-else statement etc.
Any signal that is assigned a value by a
statement within an always block must retain this
value until it is re-evaluated.
Such signals are declared to be of reg type
Changes in the sensitivity variables given in the
always statement invokes the re-evaluation of
the procedural statements
Latches & Flops
always @( Control or B ) What happens if Control = 0 ?
if( Control )
A=B

In the absence of an assigned value, the Verilog compiler assumes that the
value of A caused by the if statement must be maintained until the next time
this if statement is evaluated. This notion of implied memory is realized by
instantiating a latch in the circuit.

module D_latch ( Q, D, Clk ); module D_FF ( Q, D, Clk );


input D, Clk; input D, Clk;
output reg Q; output reg Q;

always @ (D, Clk) always @ (posedge Clk)


if( Clk ) Q = D;
Q = D; endmodule
endmodule
Flip-Flops
module TFF ( Q, T, CLK, RST ); module JKFF ( Q, J, K, CLK, RST );
output Q; output Q;
input T, CLK, RST; input J, K, CLK, RST;
wire DT; wire JK;
assign DT = Q ^ T; assign JK = (J & ~Q) | (~K & Q);
DFF TF1 ( Q, DT, CLK, RST ); DFF JK1 ( Q, JK, CLK, RST );
endmodule endmodule

module DFF ( Q, D, CLK, RST );


output reg Q;
input D, CLK, RST;
always @ (posedge CLK or negedge RST)
if (~RST) Q = 1b0; D flip-flop with
else Q = D; asynchronous
endmodule reset
JK and T Flip-Flop
module JK_FF ( Q, Qn, J, K, CLK ); module T_FF ( Q, Qn, T, CLK );
output Q, Qn; output Q, Qn;
input J, K, CLK; input T, CLK;
reg Q; reg Q;
assign Qn = ~ Q; assign Qn = ~ Q;
always @ ( posedge CLK ) always @ ( posedge CLK )
case ( J, K ) if ( T ) Q = ~ Q;
2b00 : Q = Q; else Q = Q;
2b01 : Q = 1b0; endmodule
2b10 : Q = 1b1;
2b11 : Q = ~ Q;
endcase
endmodule
Blocking & Non-Blocking
Assignment
= creates a blocking assignment.
If a variable is given a value by blocking assignment
statement, then this new value is used in evaluating all
subsequent statements in the block.
<= creates a non-blocking assignment
All non-blocking assignment statements in an always
block are evaluated using the values that the variables
have when the always block is entered.
A given variable has the same value for all statements
in the block.
The meaning of non-blocking is that the result of each
assignment is not seen until the end of always block
Assignment
D D Q Q1
module non_shift_reg (D, Clk, Q1, Q2);
input D, Clk;
Clk
output reg Q1, Q2;
always @(posedge Clk)
D Q Q2
begin
Q1 = D;
Q2 = Q1;
end The synthesized ckt has 2 parallel flops, one of
endmodule which will likely get deleted during optimization

module shift_reg (D, Clk, Q1, Q2);


input D, Clk; Q1
D D Q D Q Q2
output reg Q1, Q2;
always @(posedge Clk)
begin Clk
Q1 <= D;
Q2 <= Q1; The synthesized ckt has 2 cascaded flops,
end which implements a shift register.
endmodule
State Diagram in HDL
module Mealy_mdl ( y, x, CLK, RST ); 0/0 1/0
input x, CLK, RST;
0/1
output reg y; A C
reg [1:0] Prstate, Nxtstate;
parameter A=2b00, B=2b01, C=2b10, D=2b11; 1/0 0/1 0/1 1/0
always @ (posedge CLK or negedge RST)
if ( ~RST ) Prstate = A; // initialize 1/0
else Prstate = Nxtstate; B D
always @ (Prstate or x) // next state
case (Prstate)
A : Nxtstate = ( x ) ? B : A; always @ ( Prstate or x ) // output
B : Nxtstate = ( x ) ? D : A; case
C : Nxtstate = ( ~x ) ? A : C; A : y = 0;
D : Nxtstate = ( x ) ? C : A; B : y = ( x ) ? 1b0 : 1b1;
endcase C : y = ( x ) ? 1b0 : 1b1;
D : y = ( x ) ? 1b0 : 1b1;
endcase
endmodule
State Diagram in HDL
1
module Moore_mdl (x, AB, CLK, RST); 1
input x, CLK, RST; 0
00 11
output [1:0] AB;
reg [1:0] state;
parameter A=2b00, B=2b01, C=2b10, D=2b11;
0 0 0
always @ (posedge CLK or negedge RST)
if ( ~RST ) state = A; // initialize
else
case ( state )
01 1
10
A : state = ( ~x ) ? B : A;
B : state = ( x ) ? C : D; 1
C : state = ( ~x ) ? D : C;
D : state = ( ~x ) ? A : D;
endcase
assign AB = state; // output of flip-flop
endmodule
Structural Description
x T0
T Q Q y
0

C QN module T_FF (Q, T, CLK);


input T, CLK;
output reg Q;
T1
T Q
Q1 always @ (posedge CLK)
Q = Q ^ T;
CLK C QN endmodule

module Tckt (x, y, Q0, Q1, CLK); module Tckt_tb;


input x, CLK; reg x, CLK;
output y, Q0, Q1; wire y, Q0, Q1;
wire T0, T1; initial begin
Tckt TC (x, y, Q0, Q1, CLK);
assign T1 = x, //input eqn x = 0;
T0 = x & B; initial begin #15 x = 1;
assign y = Q0 & Q1; CLK = 0; repeat (8)
T_FF TF0 (Q0, T0, CLK); repeat (16) #10 x = ~x;
T_FF TF1 (Q1, T1, CLK); #5 CLK = ~CLK; end
endmodule end endmodule
Registers & Counters
Registers
// Behavioral description of Universal shift register
module shiftreg (s1, s0, Pin, lfin, rtin, A, CLK, Clr);
input s1, s0; // Select inputs
input lfin, rtin; // Serial inputs
input CLK, Clr; // Clock and Clear
input [3:0] Pin; // Parallel input
output reg [3:0] A; // Register output

always @ (posedge CLK or negedge Clr)


if ( ~Clr) A = 4b0000;
else
case ( {s1,s0} )
2b00 : A = A; // No change
2b01 : A = { rtin, A[3:1] }; // Shift right
2b10 : A = { A[2:0], lfin }; // Shift left
2b11 : A = Pin; // Parallel load input
endcase
endmodule
Counters
// Ripple counter
module rcntr ( A0, A1, A2, A3, Count, Reset );
output A0, A1, A2, A3;
input Count, Reset; // Ripple counter test bench
// instantiate complementing FF module ripplecounter_tb;
CF F0 ( A0, Count, Reset ); wire A0, A1, A2, A3;
CF F1 ( A0, Count, Reset ); reg Count, Reset;
CF F2 ( A0, Count, Reset ); // instantiate ripple counter
CF F3 ( A0, Count, Reset ); rcntr RC ( A0, A1, A2, A3, Count, Reset );
endmodule always
#5 Count = ~Count;
// Complementing FF with delay
initial
// Input to D flip-flop = Q
begin
module CF ( Q, CLK, Reset );
Count = 1b0; Reset = 1b1;
output reg Q;
#4 Reset = 1b0;
input CLK, Reset;
#165 $finish;
always @ (negedge CLK or posedge Reset)
end
if ( Reset ) Q = 1b0;
endmodule
else Q = #2 ( ~Q ); // 2 unit delay
endmodule
Memory & Programmable Logic
Memory
// Read and write operations of memory
// Memory size is 64 words of 4 bits each
module memory ( En, Rd_Wr, Adr, Din, Dout );
input En, Rd_Wr;
input [3:0] Din; 2-D array of 64 registers,
input [5:0] Adr; each containing 4-bit word
output reg [3:0] Dout;
reg [3:0] Mem [0:63]; // 64 x 4 memory
always @ ( En, Rd_Wr ) Transfers 4-bits data from
if( En ) selected memory word
if( Rd_Wr ) specified by address, Adr.
Dout = Mem[Adr]; // Read
else
Mem[Adr] = Din; // Write
else Transfers from 4-bits Din
Dout = 4bz; lines into memory word
endmodule selected by address, Adr.

You might also like