Verilog Basic Examples
Verilog Basic Examples
AND GATE
Truth Table
Verilog design
//in data flow model
module and_gate(
input a,b,
output y);
//Above style of declaring ports is ANSI style.Verilog2001 Feature
assign y = a & b;
endmodule
TestBench
module tb_and_gate;
reg A,B;
wire Y;
and_gate a1 (.a(A) ,.b(B),.y(Y));
//Above style is connecting by names
initial begin
A =1'b0;
B= 1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always @(Y)
$display( "time =%0t \tINPUT VALUES: \t A=%b B =%b \t output value Y =%b",$time,A,B,Y);
endmodule
output
time
time
time
time
time
=0
=6
=9
=12
=18
XOR GATE
Truth Table
Verilog design
//in Structural model
module xor_gate (
input a,b,
output y);
xor x1(y,a, b); //xor is a built in primitive. While using these primitives you should follow
the connection rules. First signal should be output and then inputs.
endmodule
TestBench
module tb_and_gate;
reg A,B;
wire Y;
xor_gate a1 (.a(A) ,.b(B),.y(Y));
initial begin
A =1'b0;
B= 1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always @(Y)
$display( "time =%0t \tINPUT VALUES: \t A=%b B =%b \t output value Y =%b",$time,A,B,Y);
endmodule
output
time
time
time
time
=0
=3
=6
=9
OR GATE
Truth Table
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
A=0
A=0
A=1
A=1
B =0
B =1
B =0
B =1
output
output
output
output
value Y =0
value Y =1
value Y =1
value Y =0
Verilog design
//in Behaviour model
module or_gate(
input a,b,
output reg y);
always @(a,b)
y = a |b;
endmodule
TestBench
module tb_and_gate;
reg A,B;
wire Y;
or_gate a1 (.a(A) ,.b(B),.y(Y));
initial begin
A =1'b0;
B= 1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always @(Y)
$display( "time =%0t \tINPUT VALUES: \t A=%b B =%b \t output value Y =%b",$time,A,B,Y);
endmodule
output
time
time
time
time
time
=0
=3
=12
=15
=24
output value Y =0
output value Y =1
output value Y =0
output value Y =1
output value Y =0
Half Adder
Truth Table
Verilog design
module half_adder(
input a,b,
output sum,carry);
assign sum = a^b;
assign carry = a & b;
endmodule
TestBench
module tb_half_adder;
reg A,B;
wire SUM,CARRY;
half_adder HA (.a(A) ,.b(B),.sum(SUM),.carry(CARRY))
initial begin
A =1'b0;
B= 1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always @(SUM,CARRY)
$display( "time =%0t \tINPUT VALUES: \t A=%b B =%b \t output value SUM =%b CARRY =%b ",
$time,A,B,SUM,CARRY);
endmodule
output
time
time
time
time
=0
=3
=6
=9
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
Full Adder
Verilog design
module full_adder(
A=0
A=0
A=1
A=1
B =0
B =1
B =0
B =1
output
output
output
output
value SUM
value SUM
value SUM
value SUM
=0
=1
=1
=0
CARRY =0
CARRY =0
CARRY =0
CARRY =1
input a,b,cin,
output reg sum,cout);
always @(*) begin
sum = a^b^cin;
cout = (a&b)+(b&cin)+(cin&a);
end
endmodule
TestBench
module tb_full_adder;
reg A,B,CIN;
wire SUM,COUT;
full_adder FA (.a(A) ,.b(B),.sum(SUM),.cin(CIN),.cout(COUT));
initial begin
A =1'b0;
B= 1'b0;
CIN = 1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always #12 CIN = ~CIN;
always @(SUM,COUT)
$display( "time =%0t \tINPUT VALUES: \t A =%b B =%b CIN =%b \t output value SUM
=%b COUT =%b ",$time,A,B,CIN,SUM,COUT);
endmodule
output
time
time
time
time
time
=0
=3
=9
=12
=15
wire COUT;
ripple_carry RCA(.a(A),.b(B),.cin(CIN),.sum(SUM),.cout(COUT));
initial begin
A= 4'b0000;
B= 4'b0000;
CIN =1'b0;
repeat(10)
input_generate(A,B,CIN);
#45 $finish;
end
task input_generate;
output [N-1:0]A_t,B_t;
output CIN_t;
begin
#4;
A_t = $random % 4;
//Above statement will generate Random values from -3 to +3.
B_t = $random % 4;
CIN_t =$random;
end
endtask
task display;
input [N-1:0] A_td,B_td,SUM_td;
input CIN_td,COUT_td;
$strobe("Time =%0t \t INPUT VALUES A=%b B=%b CIN =%b \t OUTPUT VALUES SUM =%b COUT
=%b",$time,A_td,B_td,CIN_td,SUM_td,COUT_td);
endtask
always@(SUM,A,COUT)
$display(A,B,SUM,CIN,COUT);
endmodule
output
Time =0 INPUT VALUES A=0000 B=0000 CIN =0 OUTPUT VALUES SUM =0000 COUT =0
Time
Time
Time
Time
Time
Time
Time
Time
Time
=4
=8
=12
=16
=20
=24
=28
=32
=36
Multiplexer(2:1)
Truth Table
Verilog design
module mux21(
input a,b,sel,
output y);
assign y = sel ?b:a;
endmodule
TestBench
module tb_mux21;
reg A,B,SEL;
wire Y;
mux21 MUX (.a(A) ,.b(B),.sel(SEL),.y(Y));
initial begin
A =1'b0;
B= 1'b0;
SEL =1'b0;
#45 $finish;
end
always #6 A =~A;
always #3 B =~B;
always #5 SEL = ~SEL;
always @(Y)
$display( "time =%0t \tINPUT VALUES: \t A=%b B =%b SEL =%b \t output value Y =%b ",
$time,A,B,SEL,Y);
endmodule
output
time
time
time
time
=0
=5
=6
=9
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
INPUT VALUES:
A=0
A=0
A=1
A=1
B =0
B =1
B =0
B =1
SEL =0
SEL =1
SEL =1
SEL =1
output
output
output
output
value Y =0
value Y =1
value Y =0
value Y =1
Multiplexer(4:1)
Verilog design
module mux41(
input i0,i1,i2,i3,sel0,sel1,
output reg y);
always @(*) //It includes all Inputs. You can use this instead of specifying all inputs in
//sensivity list.Verilog-2001 Feature
begin
case ({sel0,sel1})
2'b00 : y =
2'b01 : y =
2'b10 : y =
2'b11 : y =
endcase
end
i0;
i1;
i2;
i3;
endmodule
TestBench
module tb_mux41;
reg I0,I1,I2,I3,SEL0,SEL1;
wire Y;
mux41 MUX (.i0(I0),.i1(I1),.i2(I2),.i3(I3),.sel0(SEL0),.sel1(SEL1),.y(Y));
initial begin
I0 =1'b0;
I1= 1'b0;
I2 =1'b0;
I3 =1'b0;
SEL0 =1'b0;
SEL1 =1'b0;
#45 $finish;
end
always
always
always
always
always
always
#2 I0 = ~I0;
#4 I1 =~I1;
#6 I2 =~I1;
#8 I3 =~I1;
#3 SEL0 = ~SEL0;
#3 SEL1 = ~SEL1;
always @(Y)
$display( "time =%0t INPUT VALUES: \t I0=%b I1 =%b I2 =%b I3 =%b SEL0 =%b SEL1 =%b \t
output value Y =%b ",$time,I0,I1,I2,I3,SEL0,SEL1,Y);
endmodule
output
time
time
time
time
time
time
time
=0 INPUT VALUES:
=2 INPUT VALUES:
=3 INPUT VALUES:
=6 INPUT VALUES:
=8 INPUT VALUES:
=14 INPUT VALUES:
=15 INPUT VALUES:
Encoder(8:3)
Verilog design
module encoder83(
input en,
input [7:0]in,
output reg [2:0]out);
always@(*)
begin
if(!en) //Active low enable
out = 0;
else begin
output value Y =0
output value Y =1
output value Y =0
output value Y =1
output value Y =0
output value Y =1
output value Y =0
case ({in})
8'b0000_0001 : out =3'b000;
8'b0000_0010 : out =3'b001;
8'b0000_0100 : out =3'b010;
8'b0000_1000 : out =3'b011;
8'b0001_0000 : out =3'b100;
8'b0010_0000 : out =3'b101;
8'b0100_0000 : out =3'b110;
8'b1000_0000 : out =3'b110;
default
: out =3'bxxx;
endcase
end
end
endmodule
endtask
task display;
input en_t;
input [7:0]in_t;
input [2:0]out_t;
$display("time =%0t \t INPUT VALUES \t en =%b in =%b \t OUTPUT VALUES out =%b",
$time,en_t,in_t,out_t);
endtask
always@(out)
display(en,in,out);
endmodule
output
time
time
time
time
time
time
time
=0
=4
=8
=16
=24
=28
=40
Priority Encoder(8:3)
can
differentiate the output when enable is zero and when only LSB (in0) is active
Verilog design
module priority_enco(
input en,
input [3:0]in,
output reg v,
output reg [1:0]out );
integer i;
always@(*) begin
if(!en) begin
out = 2'b00;
v =1'b0;
end
else
begin :block1
for (i=3; i>=0; i= i-1) begin
//Priority Logic. each Time It will check Whether the MSB bit is active, If so it will
break //the loop. Otherwise It will decrement and continue the same
if (in[i]==1'b1) begin
case (i)
3: begin out = 2'b11; v= 1'b1; end
2: begin out = 2'b10; v= 1'b1; end
1: begin out = 2'b01; v= 1'b1; end
0: begin out = 2'b00; v= 1'b1; end
default :begin out = 2'bxx; v= 1'bx; end
endcase
disable block1;
//Disable statement is synthesizible
end
end
end
end
endmodule
task random_generation;
output [3:0]in_t;
output en_t;
begin
#4;
in_t = $random % 4;
en_t =$random;
end
endtask
task display;
input en_t;
input [3:0]in_t;
input [1:0]out_t;
input v_t;
$display("time =%0t \t INPUT VALUES \t en =%b in =%b \t OUTPUT VALUES out =%b v =%b",
$time,en_t,in_t,out_t,v_t);
endtask
always@(out)
display(en,in,out,v);
endmodule
output
time
time
time
time
time
time
time
time
time
time
time
=0
=8
=12
=24
=28
=44
=48
=60
=64
=72
=76
Decoder(8:3)
Verilog design
module decoder38(
input en,
input [2:0]in,
output reg [7:0]out);
always@(*)
begin
if(!en)
out = 0;
else begin
case ({in})
3'b000 : out = 8'b0000_0001;
3'b001 : out = 8'b0000_0010;
3'b010 : out = 8'b0000_0100;
3'b011 : out = 8'b0000_1000;
3'b100 : out = 8'b0001_0000;
3'b101 : out = 8'b0010_0000;
3'b110 : out = 8'b0100_0000;
3'b111 : out = 8'b1000_0000;
default : out = 8'bxxxx_xxxx;
endcase
end
end
endmodule
TestBench using $random and Tasks
module tb_decoder38;
reg en_tb;
reg [2:0]in_tb;
wire [7:0] out_d;
reg [7:0] out_tb;
decoder38 DEC (.en(en_tb),.in(in_tb),.out(out_d));
initial begin
en_tb =0;
in_tb =0;
repeat(10)
random_generation(in_tb,en_tb) ;
#45 $finish;
end
//Below Block is used to generate expected outputs in Test bench only. These outputs
//are used to compare with DUT output. You have Checker task (ScoreBoard in SV), for //that
you need Reference output
always@(in_tb,en_tb)
begin
if(!en_tb)
out_tb = 0;
else begin
case ({in_tb})
3'b000 : out_tb
3'b001 : out_tb
3'b010 : out_tb
3'b011 : out_tb
3'b100 : out_tb
3'b101 : out_tb
3'b110 : out_tb
3'b111 : out_tb
default : out_tb
endcase
end
end
= 8'b0000_0001;
= 8'b0000_0010;
= 8'b0000_0100;
= 8'b0000_1000;
= 8'b0001_0000;
= 8'b0010_0000;
= 8'b0100_0000;
= 8'b1000_0000;
= 8'bxxxx_xxxx;
task random_generation;
output [2:0]in_t;
output en_t;
begin
#4;
in_t = $random % 3;
en_t =$random;
end
endtask
task checker;
//In this block reference value and generated output are compared
input [7:0]outd_t;
input [7:0]outtb_t;
begin
if(outd_t === outtb_t)
$display("time =%0t \t DUT VALUE =%b TB VALUE =%b \tDUT and TB VALUES ARE
MATCHED ",$time,outd_t,outtb_t);
else
$display("time =%0t \tDUT and TB VALUES ARE NOT MATCHED ",$time);
end
endtask
always@(out_d,out_tb)
checker(out_d,out_tb);
endmodule
TestBench using $random and Tasks
time
time
time
time
time
time
time
=0
=4
=8
=16
=20
=28
=40
DUT VALUE =00000000 TB VALUE =00000000 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000100 TB VALUE =00000100 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000001 TB VALUE =00000001 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000000 TB VALUE =00000000 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000001 TB VALUE =00000001 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000000 TB VALUE =00000000 DUT and TB VALUES ARE MATCHED
DUT VALUE =00000001 TB VALUE =00000001 DUT and TB VALUES ARE MATCHED
D-Latch
Verilog design
module d_latch(
input en,d,
output reg q);
always@(en,d)
begin
if(en)
q <= d;
end
endmodule
TestBench
module tb_latch;
reg en,d;
wire q;
d_latch DLATCH (.en(en) ,.d(d) ,.q(q));
initial begin
en =1'b0;
d =1'b1;
#45 $finish;
end
always #6 en =~ en;
always #3 d =~d;
always@( q , en )
$display("time =%0t \t INPUT VALUES \t en =%b d =%b \t OUTPUT VALUES q=%b",
$time,en,d,q);
endmodule
output
time
time
time
time
time
time
time
=0
INPUT VALUES
=6
INPUT VALUES
=9
INPUT VALUES
=12 INPUT VALUES
=18 INPUT VALUES
=18 INPUT VALUES
=21 INPUT VALUES
en =0 d =1
en =1 d =1
en =1 d =0
en =0 d =1
en =1 d =1
en =1 d =1
en =1 d =0
D-FlipFlop(Asynchronous Reset)
Verilog design
module d_ff (
input clk,d,rst_n,
output reg q);
//Here is reset is Asynchronous, You have include in sensitivity list
=0
INPUT VALUES
=3
INPUT VALUES
=9
INPUT VALUES
=15 INPUT VALUES
D =0 RST_n =0
D =0 RST_n =0
D =1 RST_n =1
D =0 RST_n =1
OUTPUT VALUES Q =0
OUTPUT VALUES Q =0
OUTPUT VALUES Q =1
OUTPUT VALUES Q =0
time
time
time
time
time
=18
=21
=27
=33
=39
INPUT VALUES
INPUT VALUES
INPUT VALUES
INPUT VALUES
INPUT VALUES
D
D
D
D
D
=1
=1
=0
=1
=0
RST_n =0
RST_n =0
RST_n =1
RST_n =1
RST_n =1
OUTPUT VALUES
OUTPUT VALUES
OUTPUT VALUES
OUTPUT VALUES
OUTPUT VALUES
Q
Q
Q
Q
Q
=0
=0
=0
=1
=0
D-FlipFlop(Synchronous Reset)
Verilog design
module d_ff (
input clk,d,rst_n,
output reg q);
//In Synchronous Reset, Reset condition is verified wrt to clk.Here It is verified at
every //posedge of clk.
always@(posedge clk )
begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
endmodule
TestBench
module tb_dff;
reg RST_n, CLK,D;
wire Q;
d_ff DFF (.clk(CLK) ,.rst_n(RST_n) ,.q(Q),.d(D));
initial begin
RST_n = 1'b0;
CLK =1'b0;
D =1'b1;
#5 RST_n = 1'b1;
#7 RST_n = 1'b0;
#7 RST_n = 1'b1;
#45 $finish;
end
always #4 CLK = ~CLK;
always #6 D = ~D;
always @(posedge CLK )
$strobe("time =%0t \t INPUT VALUES \t D =%b RST_n =%b \t OUDPUT VALUES Q =%d",
$time,D,RST_n,Q);
endmodule
output
time
time
time
time
time
time
time
time
=4
=12
=20
=28
=36
=44
=52
=60
T-FlipFlop
Verilog design
module t_ff (
input clk,t,rst_n,
INPUT VALUES
time
time
time
time
time
time
time
=3
INPUT VALUES
=9
INPUT VALUES
=15 INPUT VALUES
=18 INPUT VALUES
=21 INPUT VALUES
=27 INPUT VALUES
=33 INPUT VALUES
T =0 RST_n =0
T =1 RST_n =1
T =0 RST_n =1
T =1 RST_n =0
T =1 RST_n =0
T =0 RST_n =1
T =1 RST_n =1
OUTPUT VALUES Q =0
OUTPUT VALUES Q =1
OUTPUT VALUES Q =1
OUTPUT VALUES Q =0
OUTPUT VALUES Q =0
OUTPUT VALUES Q =0
OUTPUT VALUES Q =1
3-Bit Counter
//Used Structural Model in RTL and Behavior Model in Test bench
Verilog design
module t_ff(
output reg q,
input t, rst_n, clk);
always @ (posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0;
else if (t) q <= ~q;
endmodule
//Standard counters are designed using either T or JK F/F.
module counter (
output [2:0] q,
input rst_n, clk);
wire t2;
t_ff ff0 ( q[0], 1'b1, rst_n, clk);
t_ff ff1 ( q[1], q[0], rst_n, clk);
t_ff ff2 ( q[2], t2, rst_n, clk);
and a1 (t2, q[0], q[1]);
endmodule
TestBench
module tb_counter_3bit;
reg clk,rst_n;
wire [2:0] q;
reg [2:0] count;
counter CNTR (.clk(clk),.rst_n(rst_n),.q(q));
initial begin
clk <= 1'b0;
forever #5 clk <= ~ clk;
end
initial
begin
rst_n <= 0;
@(posedge clk);
@(negedge clk);
rst_n <= 1;
repeat (10) @(posedge clk);
$finish;
end
//Below always block represents the 3-bit counter in behavior style.
//Here it is used to generate reference output
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 0;
else
count <= (count + 1);
end
always @( q ) scoreboard(count);
//Below task is used to compare reference and generated output. Similar to score
board //in SV Test bench
task scoreboard;
input [2:0]count;
input [2:0] q;
begin
if (count == q)
$display ("time =%4t q = %3b count = %b match!-:)",
$time, q, count);
else
$display ("time =%4t q = %3b count = %b <-- no match",
$time, q, count);
end
endtask
endmodule
output
time
time
time
time
time
time
time
time
time
time
=
=
=
=
=
=
=
=
=
=
Verilog Code
module greycode_counter_3bit(
input clk,rst_n,
=0
=25
=35
=45
=55
=65
=75
time =85
time =95
Divide by 2 clk
module div_2clk(
input clk,rst_n,
output reg clk_out);
always@(posedge clk,negedge rst_n) begin
if(rst_n)
clk_out <= 1'b0;
else
clk_out <= ~clk_out;
end
endmodule
TestBench
module tb_div_2clk;
reg clk,rst_n;
wire clk_out;
div2_clk clkby2 (.clk(clk),.rst_n(rst_n),.clk_out(clk_out));
initial begin
clk =1'b0;
rst_n =1'b0;
@(posedge clk);
@(posedge clk);
rst_n = 1'b1;
repeat(15) @(posedge clk);
//It will run till 15 clock cycles
$finish;
end
always #5 clk = ~clk;
always @(clk_out)
Divide by 3 clk
This is an example for two always block FSM
in this Example you have Two FSMs, one is operating at posedge clk and other //operating at
negedge clk. In Double Data Rate (DDR2) also data transfer occur at both //the edges. It is
synthesizable
Verilog Code
module div_3clk(
input clk,rst_n,
output clk_by_3);
parameter ST10 =2'b00,
ST11 =2'b01,
ST12 = 2'b10;
parameter ST20 =2'b00,
ST21 =2'b01,
ST22 = 2'b10;
reg clk_temp1,clk_temp2;
reg [1:0] pr_state1,nx_state1;
reg [1:0] pr_state2,nx_state2;
always@(posedge clk ,negedge rst_n) begin
if(!rst_n)
pr_state1 <= ST10;
else
pr_state1 <= nx_state1;
end
always @(pr_state1) begin
//In second always block only we have output logic and next state logic
case (pr_state1)
ST10 : begin clk_temp1 = 1'b1; nx_state1 =ST11; end
ST11 : begin clk_temp1 = 1'b0; nx_state1 =ST12; end
ST12 : begin clk_temp1 = 1'b0; nx_state1 =ST10; end
default : begin clk_temp1 = 1'bx; nx_state1 =ST10; end
endcase
end
always@(negedge clk ,posedge rst_n) begin
if(!rst_n)
pr_state2 <= ST20;
else
pr_state2 <= nx_state2;
end
always @(pr_state2) begin
case (pr_state2)
ST20 : begin clk_temp2 = 1'b0; nx_state1 =ST21; end
TestBench
module tb_div_2clk;
reg clk,rst_n;
wire clk_out;
div_3clk clkby3 (.clk(clk),.rst_n(rst_n),.clk_by_3(clk_out));
initial begin
clk =1'b0;
rst_n =1'b0;
@(posedge clk);
@(posedge clk);
rst_n = 1'b1;
repeat(15) @(posedge clk);
$finish;
end
always #5 clk = ~clk;
always @(clk_out)
$display("time = %0t \t Input clk =%b \t output clk=%b ",$time,clk,clk_out);
endmodule
output