Verilog HDL
Verilog is a concurrent programming language unlike C, which is sequential in nature.
“initial” block - executes once at time 0. If there is more then one block, each execute concurrently
“always” block – executes continuously
Modeling Levels
Switch-Level, Gate-Level, Dataflow, Behavioral
Assignments
Blocking assignment: “=”– executed in order they appear in a block
Nonblocking assignment: “<=”– allow scheduling of assignments without blocking execution of
statements that follow in a sequential block
Continuous assignment “assign A = B;” – connects nets permanently.
Example 1:
#10 A = 1’b1;
counter = 0; //executed at 10 (after A assignment)
Example 2:
A <= #10 1’b1;
counter <= 0; // executed at time 0 (before A assignment)
Sequential Black – begin-end
Parallel Blocks – fork-join
Module definition:
module <module_name> (<module_terminal_list>); // semicolon required!!!
<module_terminal_definitions>
…
<functionality_of_module>
…
endmodule // no semicolon!!!
Gate-Level Modeling
Example 1: Full Adder
module FullAdder(X, Y, Cin, Cout, Sum);
input X, Y, Cin; // input terminal definitions
output Cout, Sum; // output terminal definitions
wire w1, w2, w3, w4; // internal net declarations
xor #(10) (w1, X, Y); // delay time of 10 units
xor #(10) xor2(Sum, w1, Cin); // with instance name
and #(10) (w2, X, Y);
and #(10) (w3, X, Cin);
and #(10) (w4, Y, Cin);
or #(10, 8)(Cout, w2, w3, w4); // 3 input or (rise time of 10, fall // time of
8)
endmodule
Example 2: 4-bit Full Adder
module Adder4(A, B, Cin, S, Cout);
input[3:0] A, B;
input Cin;
output[3:0] S;
output Cout;
wire c1, c2, c3;
// 4 instantiated 1-bit Full Adders
FullAdder fa0(A[0], B[0], Cin, C1, sum[0]);
FullAdder fa1(A[1], B[1], C1, C2, sum[1]);
FullAdder fa2(A[2], B[2], C2, C3, sum[2]);
FullAdder fa3(A[3], B[3], C3, Cout, sum[3]);
endmodule
Example 3: Stimulus Module for 4-bit Full Adder
module stimulus;
// declare variables
reg[3:0] A, B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
//Instantiate 4-bit Full Adder
Adder4 FA1(A, B, C_IN, SUM, C_OUT);
initial
begin
$monitor($time, “A=%b B=%b Cin=%b, -> Sum = %b Cout=%b\n”, A, B, C_IN, SUM,
C_OUT);
end
// stimulate inputs
initial
begin // sequential block begins
A = 4’d0; B = 4’d0, C_IN = 1’b0; // 0 + 0 + 0
#10 A = 4’d2; B=4’d2; // 2 + 2 + 0
#10 A = 4’d5; B=4’d8; // 5 + 8 + 0
#10 C_IN = 1’b1 // 5 + 8 + 1
end
endmodule
Dataflow Modeling
Example 4: 4-to-1 Multiplexer
module mux4_to_1(in, out, sel);
input [3:0] in;
output out;
input [1:0]sel;
// continuous assignment with delay
assign #10 out = (~sel[1] & ~sel[0] & in[0]) |
(~sel[1] & sel[0] & in[1]) |
( sel[1] & ~sel[0] & in[2]) |
( sel[1] & sel[0] & in[3]);
endmodule
Example 5: 4-bit Full Adder with dataflow operators
module Adder4(A, B, Cin, S, Cout);
input[3:0] A, B;
input Cin;
output[3:0] S;
output Cout;
assign {Cout, S} = A + B + Cin; // concatenation
endmodule
Behavioral Modeling
All behavioral statements must be in initial or always blocks
Example 6: Clock Generator
module ClkGen;
reg clk;
initial
clk = 1’b0;
always
#10 clk = ~clk;
initial
#1000 $finish; //or $stop to end simulation
endmodule
Example 7: Behavioral 4-to-1 Multiplexer
module mux4_to_1(in, out, sel);
input [3:0] in;
output out;
input [1:0]sel;
reg out;
always @(sel or in)
begin
case(sel)
2’b00: out = in[0];
2’b01: out = in[1];
2’b10: out = in[2];
2’b11: out = in[3];
default: out = 1’bx;
endcase
end
endmodule
Example 8: D-Type Latch
module Latch(D, C, Q)
input D, C;
output Q;
reg Q; // output must preserve values
initial
Q = 1’b0;
always @(C or D)
begin
if(C == 1'b1)
#10 Q = D;
end
endmodule
Example 9: D-type Flip-Flop (with clear and set inputs)
module DFF(D, C, Q, QN, CLRN, SETN)
input D, C, CLRN, SETN;
output Q, QN;
reg Q, QN; // output must preserve values
initial
begin
Q = 1’b0;
QN = 1’b1;
end
always @(negedge CLRN or negedge SETN or posedge C)
begin
if(CLRN == 1’b0)
begin
#10 Q = 1’b0;
QN = 1’b1;
end
else if(SETN == 1’b0)
begin
#10 Q = 1’b1;
QN = 1’b0;
end
else
begin
#10 Q = D;
QN = ~D;
end
end
endmodule
Example 10: Ripple-Carry Counter (with active high reset)
4-bit Ripple-carry counter. Instantiates 4 negative edge triggered T-flipflops from D-flipflop
module RCC(Q, CLK, RESET);
output [3:0]Q;
input CLK, RESET;
TFF tff0(Q[0], CLK, !RESET);
TFF tff1(Q[1], Q[0], !RESET);
TFF tff2(Q[2], Q[1], !RESET);
TFF tff3(Q[3], Q[2], !RESET);
endmodule
module TFF(Q, CLK, RESET);
output Q;
input CLK, RESET;
wire D, QN;
DFF dff(D, !CLK, Q, QN, RESET, 1’b1);
assign D = QN;
endmodule
Example 11: 7-segment LCD Display Driver (for non-multiplexed LCDs)
‘define DSP0 7’b1111110;
‘define DSP1 7’b0110000;
‘define DSP2 7’b1101101;
‘define DSP3 7’b1111001;
‘define DSP4 7’b0110011;
‘define DSP5 7’b1011011;
‘define DSP6 7’b1011111;
‘define DSP7 7’b1110010;
‘define DSP8 7’b1111111;
‘define DSP9 7’b1111011;
‘define BLANK 7’b0000000;
module LCD_DRV(DATA, CLK, SEGMENTS, COM);
input [3:0] DATA; // BCD input
input CLK; // 60-100Hz clock input
output [6:0] SEGMENTS; // LCD A-G segment lines
output COM; // LCD COM line
always @(DATA or CLK)
begin
assign COM = CLK;
case (DATA)
4’b0000: if(CLK == 1’b0)
SEGMENTS = ‘DSP0;
else
SEGMENTS = ‘DSP0 ^ 7’b1111111;
4’b0001: if(CLK == 1’b0)
SEGMENTS = ‘DSP1;
else
SEGMENTS = ‘DSP1 ^ 7’b1111111;
4’b0010: if(CLK == 1’b0)
SEGMENTS = ‘DSP2;
else
SEGMENTS = ‘DSP2 ^ 7’b1111111;
4’b0011: if(CLK == 1’b0)
SEGMENTS = ‘DSP3;
else
SEGMENTS = ‘DSP3 ^ 7’b1111111;
4’b0100: if(CLK == 1’b0)
SEGMENTS = ‘DSP4;
else
SEGMENTS = ‘DSP4 ^ 7’b1111111;
4’b0101: if(CLK == 1’b0)
SEGMENTS = ‘DSP5;
else
SEGMENTS = ‘DSP5 ^ 7’b1111111;
4’b0110: if(CLK == 1’b0)
SEGMENTS = ‘DSP6;
else
SEGMENTS = ‘DSP6 ^ 7’b1111111;
4’b0111: if(CLK == 1’b0)
SEGMENTS = ‘DSP7;
else
SEGMENTS = ‘DSP7 ^ 7’b1111111;
4’b1000: if(CLK == 1’b0)
SEGMENTS = ‘DSP8;
else
SEGMENTS = ‘DSP8 ^ 7’b1111111;
4’b1001: if(CLK == 1’b0)
SEGMENTS = ‘DSP9;
else
SEGMENTS = ‘DSP9 ^ 7’b1111111;
default: if(CLK == 1’b0)
SEGMENTS = ‘BLANK;
else
SEGMENTS = ‘BLANK ^ 7’b1111111;
endcase
end
endmodule
Example 12: State Machine
Two roads intersect: the highway and the country road. On the highway the green light is always on
unless the sensor on the country road detects a car. The green light on the country road stays on until all
cars leave that road. Model the traffic lights there. Set 3 clock cycle delay for yellow to red signal
change and 2 for red to green for both directions.
S0 – Highway = Green, Country = Red
S1 – Highway = Yellow, Country = Red
S2 – Highway = Red, Country = Red
S3 – Highway = Red, Country = Green
S4 – Highway = Red, Country = Yellow
‘define RED 2’d0
‘define YELLOW 2’d1
‘define GREEN 2’d2
‘define S0 3’d0
‘define S1 3’d1
‘define S2 3’d2
‘define S3 3’d3
‘define S4 3’d4
// delays in clock cycles
‘define Y2RDELAY 3
‘define R2GDELAY 2
module sig_control(highway_signal, country_signal, sensor, clock)
output [1:0] highway_signal, country_signal;
reg [1:0] highway_signal, country_signal;
input sensor, clock;
reg[2:0] state, nextstate;
initial
begin
state = ‘S0;
nextstate = ‘S0;
highway_signal = ‘GREEN;
country_signal = ‘RED;
end
always @(posedge clock)
state = nextstate;
always @(state)
begin
case (state)
‘S0: begin
highway_signal = ‘GREEN;
country_signal = ‘RED;
end
‘S1: begin
highway_signal = ‘YELLOW;
country_signal = ‘RED;
end
‘S2: begin
highway_signal = ‘RED;
country_signal = ‘RED;
end
‘S3: begin
highway_signal = ‘RED;
country_signal = ‘GREEN;
end
‘S4: begin
highway_signal = ‘RED;
country_signal = ‘YELLOW;
end
endcase
end
always @(state or sensor)
begin
case(state)
‘S0: if(sensor)
nextstate = ‘S1;
else
nextstate = ‘S0;
‘S1: begin
repeat(Y2RDELAY) @(posedge clock)
nextstate = ‘S2;
end
‘S2: begin
repeat(R2GDELAY) @(posedge clock)
nextstate = ‘S3;
end
‘S3: if(sensor)
nextstate = ‘S3;
else
nextstate = ‘S4;
‘S4: begin
repeat(Y2RDELAY) @(posedge clock)
nextstate = ‘S0;
end
default: nextstate = ‘S0;
endcase
end
endmodule
Example 13: Left/Right Shifter Using Verilog Functions
module shifter;
‘define LEFT_SHIFT 1’b0;
‘define RIGHT_SHIFT 1’b1;
reg [31:0] addr, left_addr, right_addr;
reg control;
always @(addr)
begin
left_addr = shift(addr, ‘LEFT_SHIFT);
right_addr = shift(addr, ‘RIGHT_SHIFT);
end
// Define the shift function. The output is a 32-bit value
function [31:0] shift;
input [31:0] address;
input control;
begin
shift = (control == ‘LEFT_SHIFT) ? (address << 1) : (address >> 1);
end
endfunction
endmodule
Example 14: Bitwise Operator Using Verilog Tasks
module operation;
parameter delay = 10;
reg[15:0] A, B;
reg[15:0] AB_AND, AB_OR, AB_XOR;
always @(A or B)
begin
bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B);
end
taks bitwise_oper;
output [15:0] ab_and, ab_or, ab_xor;
input [15:0] a, b
begin
#delay ab_and = a & b;
ab_or = a | b;
ab_xor = a ^ b;
end
endtask
endmodule
Switch-Level Modeling
Example 15: 2-to-1 Multiplexer
module mux(out, in, sel);
output out;
input[1:0]in;
input sel;
wire sel_b;
//declare power and ground
supply1 pwr;
supply2 gnd;
// implement the NOT gate
pmos(sel_b, pwr, sel);
nmos(sel_b, gnd, sel);
// implement 2 pass gate switch gates
cmos(out, in[0], sel_b, sel);
cmos(out, in[1], sel, sel_b);
endmodule