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

Verilog Basic Examples

This document provides Verilog code examples for basic logic gates and components including AND, OR, XOR gates, half adders, full adders, ripple carry adders, multiplexers, encoders, and priority encoders. Testbenches are included to simulate and test the behavior of each design. The examples cover different Verilog modeling styles such as dataflow, structural, and behavioral and utilize tasks and generate statements.

Uploaded by

Vij Ay
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
140 views

Verilog Basic Examples

This document provides Verilog code examples for basic logic gates and components including AND, OR, XOR gates, half adders, full adders, ripple carry adders, multiplexers, encoders, and priority encoders. Testbenches are included to simulate and test the behavior of each design. The examples cover different Verilog modeling styles such as dataflow, structural, and behavioral and utilize tasks and generate statements.

Uploaded by

Vij Ay
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 35

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

INPUT VALUES: A=0 B =0


INPUT VALUES: A=1 B=0
INPUT VALUES: A=1 B =1
INPUT VALUES: A=0 B =0
INPUT VALUES: a=1 b =0

output value Y=0


output value Y =0
output value Y =1
output value Y =0
output value y =0

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

INPUT VALUES: A=0 B =0


INPUT VALUES: A=0 B =1
INPUT VALUES: A=0 B =0
INPUT VALUES: A=0 B =1
INPUT VALUES: A=0 B =0

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

INPUT VALUES: A =0 B =0 CIN =0


INPUT VALUES: A =0 B =1 CIN =0
INPUT VALUES: A =1 B =1 CIN =0
INPUT VALUES: A =0 B =0 CIN =1
INPUT VALUES: A =0 B =1 CIN =1

output value SUM =0 COUT =0


output value SUM =1 COUT =0
output value SUM =0 COUT =1
output value SUM =1 COUT =0
output value SUM =0 COUT =1

Ripple Carry Adder(Parameterized and using generate )


Verilog design
`include "full_adder.v"
//Full_added.v contains above defined(Full ADDER) program
module ripple_carry(a,b,cin,cout,sum);
parameter N=4;
input [N-1 :0] a,b;
input cin;
output [N-1:0]sum;
output cout;
wire [N:0]carry;
assign carry[0]=cin;
//generate statement without using label is verilog-2005 feature. Generate statement is
verilog-2001 feature.
genvar i;
generate for(i=0;i<N;i=i+1) begin
full_adder FA (.a(a[i]),.b(b[i]),.cin(carry[i]),.sum(sum[i]),.cout(carry[i+1]));
end
endgenerate
assign cout = carry[N];
endmodule
TestBench Using $random
module tb_ripple_carry;
parameter N=4;
reg [N-1:0]A,B;
reg CIN;
wire [N-1:0]SUM;

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

INPUT VALUES A=0000 B=1101 CIN =1


INPUT VALUES A=1111 B=0001 CIN =1
INPUT VALUES A=1101 B=1110 CIN =1
INPUT VALUES A=0001 B=0010 CIN =1
INPUT VALUES A=0001 B=0000 CIN =1
INPUT VALUES A=1110 B=1101 CIN =0
INPUT VALUES A=0001 B=1111 CIN =0
INPUT VALUES A=0011 B=0010 CIN =0
INPUT VALUES A=0000 B=1101 CIN =0

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;

OUTPUT VALUES SUM =1110 COUT =0


OUTPUT VALUES SUM =0001 COUT =1
OUTPUT VALUES SUM =1100 COUT =1
OUTPUT VALUES SUM =0100 COUT =0
OUTPUT VALUES SUM =0010 COUT =0
OUTPUT VALUES SUM =1011 COUT =1
OUTPUT VALUES SUM =0000 COUT =1
OUTPUT VALUES SUM =0101 COUT =0
OUTPUT VALUES SUM =1101 COUT =0

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:

I0=0 I1 =0 I2 =0 I3 =0 SEL0 =0 SEL1 =0


I0=1 I1 =0 I2 =0 I3 =0 SEL0 =0 SEL1 =0
I0=1 I1 =0 I2 =0 I3 =0 SEL0 =1 SEL1 =1
I0=1 I1 =1 I2 =0 I3 =0 SEL0 =0 SEL1 =0
I0=0 I1 =0 I2 =0 I3 =0 SEL0 =0 SEL1 =0
I0=1 I1 =1 I2 =1 I3 =0 SEL0 =0 SEL1 =0
I0=1 I1 =1 I2 =1 I3 =0 SEL0 =1 SEL1 =1

Encoder(8:3)

*Disadvantage of Encoder is that at a time only one Input is active.


*Output is zero for when all inputs are zero and when enable is zero

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

TestBench using $random and Tasks


module tb_encoder83;
reg en;
reg [7:0]in;
wire [2:0] out;
encoder83 ENC (.en(en),.in(in),.out(out));
initial begin
en =0;
in =0;
repeat(10)
random_generation(in,en);
#45 $finish;
end
task random_generation;
output [7:0]in_t;
output en_t;
begin
#4;
in_t = $random % 8;
en_t =$random;
end

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

INPUT VALUES en =0 in =00000000


INPUT VALUES en =1 in =00000100
INPUT VALUES en =1 in =11111001
INPUT VALUES en =0 in =11111101
INPUT VALUES en =1 in =00000110
INPUT VALUES en =0 in =00000101
INPUT VALUES en =1 in =00000101

OUTPUT VALUES out =000


OUTPUT VALUES out =010
OUTPUT VALUES out =xxx
OUTPUT VALUES out =000
OUTPUT VALUES out =xxx
OUTPUT VALUES out =000
OUTPUT VALUES out =xxx

Priority Encoder(8:3)

Priority Encoder overcomes all drawbacks of encoder.


* At a time more than one input can be active, Based on priority output will come.
* "v" is a valid Indicator, it become HIGH only when at least one input is active. You

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

TestBench using $random and Tasks


module tb_prior_enco ;
reg en;
reg [2:0]in;
wire [1:0] out;
wire v;
priority_enco PRIOR_ENC (.en(en),.in(in),.out(out),.v(v));
initial begin
en =0;
in =0;
repeat(19)
random_generation(in,en);
#65 $finish;
end

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

INPUT VALUES en =0 in =0000


INPUT VALUES en =1 in =1101
INPUT VALUES en =1 in =0001
INPUT VALUES en =1 in =0010
INPUT VALUES en =0 in =0001
INPUT VALUES en =1 in =1110
INPUT VALUES en =0 in =0010
INPUT VALUES en =1 in =1101
INPUT VALUES en =0 in =1111
INPUT VALUES en =1 in =0010
INPUT VALUES en =1 in =1110

Decoder(8:3)

Verilog design
module decoder38(
input en,
input [2:0]in,
output reg [7:0]out);
always@(*)

OUTPUT VALUES out =00 v =0


OUTPUT VALUES out =11 v =1
OUTPUT VALUES out =00 v =1
OUTPUT VALUES out =01 v =1
OUTPUT VALUES out =00 v =0
OUTPUT VALUES out =11 v =1
OUTPUT VALUES out =00 v =0
OUTPUT VALUES out =11 v =1
OUTPUT VALUES out =00 v =0
OUTPUT VALUES out =01 v =1
OUTPUT VALUES out =11 v =1

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

OUTPUT VALUES q=x


OUTPUT VALUES q=1
OUTPUT VALUES q=0
OUTPUT VALUES q=0
OUTPUT VALUES q=0
OUTPUT VALUES q=1
OUTPUT VALUES q=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

always@(posedge clk ,negedge rst_n)


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'b0;
#5 RST_n = 1'b1;
#13 RST_n = 1'b0;
#7 RST_n = 1'b1;
#45 $finish;
end
always #3 CLK = ~CLK;
always #6 D = ~D;
always @(posedge CLK ,negedge RST_n)
$strobe("time =%0t \t INPUD VALUES \t D =%b RST_n =%b \t OUDPUD VALUES Q =%d",
$time,D,RST_n,Q);
//$strobe will execute as a last statement in current simulation.
endmodule
output
time
time
time
time

=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

INPUT VALUES D =1 RST_n =0 OUTPUT VALUES Q =0


INPUT VALUES D =1 RST_n =0 OUTPUT VALUES Q =0
INPUT VALUES D =0 RST_n =1 OUTPUT VALUES Q =0
INPUT VALUES D =1 RST_n =1 OUTPUT VALUES Q =1
INPUT VALUES D =1 RST_n =1 OUTPUT VALUES Q =1
INPUT VALUES D =0 RST_n =1 OUTPUT VALUES Q =0
INPUT VALUES D =1 RST_n =1 OUTPUT VALUES Q =1
INPUT VALUES D =1 RST_n =1 OUTPUT VALUES Q =1

T-FlipFlop

Verilog design
module t_ff (
input clk,t,rst_n,

output reg q);


always@(posedge clk ,negedge rst_n)
begin
if (!rst_n)
q <= 1'b0;
else if(t)
q <= ~q;
else
q <= q;
end
endmodule
TestBench
module tb_tff;
reg RST_n, CLK,T;
wire Q;
t_ff TFF (.clk(CLK) ,.rst_n(RST_n) ,.q( Q ),.t(T));
initial begin
RST_n = 1'b0;
CLK =1'b0;
T =1'b0;
#5 RST_n = 1'b1;
#13 RST_n = 1'b0;
#7 RST_n = 1'b1;
#45 $finish;
end
always #3 CLK = ~CLK;
always #6 T = ~T;
always @(posedge CLK ,negedge RST_n)
$strobe("time =%0t \t INPUT VALUES \t T =%b RST_n =%b \t OUTPUT VALUES Q =%d",
$time,T,RST_n,Q);
endmodule
output
time =0

INPUT VALUES

T =0 RST_n =0 OUTPUT VALUES Q =0

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

=
=
=
=
=
=
=
=
=
=

0 q = 000 count = 000 match!-:)


15 q = 001 count = 001 match!-:)
25 q = 010 count = 010 match!-:)
35 q = 011 count = 011 match!-:)
45 q = 100 count = 100 match!-:)
55 q = 101 count = 101 match!-:)
65 q = 110 count = 110 match!-:)
75 q = 111 count = 111 match!-:)
85 q = 000 count = 000 match!-:)
95 q = 001 count = 001 match!-:)

17. Gray code counter (3-bit) Using FSM.


It will have following sequence of states. It can be implemented without FSM also.
000
001
011
010
110
111
101
100
FSM Design IN VERILOG
There are many ways of designing FSM.Most efficient are
(i)Using Three always Block (ex: Gray code counter)
(ii)Using Two always block (Ex: divide by 3 counter)

Verilog Code
module greycode_counter_3bit(
input clk,rst_n,

output reg [2:0]count);


reg [2:0] pr_state,nx_state;
parameter cnt0 =3'b000,
cnt1 =3'b001,
cnt2 =3'b011,
cnt3 =3'b010,
cnt4 =3'b110,
cnt5 =3'b111,
cnt6 =3'b101,
cnt7 =3'b100;
always@(posedge clk, negedge rst_n) begin // FIRST ALWAYS BLOCK
//This always block is used for State assignment. Sequential always block.
if(!rst_n)
pr_state <= cnt0;
else
pr_state <=nx_state;
end
always@(pr_state) begin //SECOND ALWAYS BLOCK
//this always block used for next state logic, Combinational
case (pr_state)
cnt0 : nx_state = cnt1;
cnt1 : nx_state = cnt2;
cnt2 : nx_state = cnt3;
cnt3 : nx_state = cnt4;
cnt4 : nx_state = cnt5;
cnt5 : nx_state = cnt6;
cnt6 : nx_state = cnt7;
cnt7 : nx_state = cnt0;
default : nx_state = cnt0;
endcase
end
always@(posedge clk ,negedge rst_n) begin //THIRD ALWAYS BLOCK
//this always block used for output assignment,Sequential
if(!rst_n)
count <= 3'b000;
else begin
case (pr_state)
cnt0 : count <= 3'b000;
cnt1 : count <= 3'b001;
cnt2 : count <= 3'b011;

cnt3 : count <= 3'b010;


cnt4 : count <= 3'b110;
cnt5 : count <= 3'b111;
cnt6 : count <= 3'b101;
cnt7 : count <= 3'b100;
default :count <=3'bxxx;
endcase
end
end
endmodule
TestBench
module tb_greycode_counter;
reg clk,rst_n;
wire [2:0] count;
greycode_counter_3bit COUNTER(.clk(clk),.rst_n(rst_n),.count(count));
initial begin
clk =1'b0;
rst_n = 1'b0;
@(posedge clk);
@(posedge clk);
rst_n = 1'b1;
repeat(9) @(posedge clk);
$finish;
end
always #5 clk = ~clk;
always@(count)
$display("time =%0t \t rst_n =%b count =%b",$time,rst_n,count);
endmodule
output
time
time
time
time
time
time
time

=0
=25
=35
=45
=55
=65
=75

rst_n =0 count =000


rst_n =1 count =001
rst_n =1 count =011
rst_n =1 count =010
rst_n =1 count =110
rst_n =1 count =111
rst_n =1 count =101

time =85
time =95

rst_n =1 count =100


rst_n =1 count =000

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)

$display("time = %0t \t Input clk =%b \t output clk=%b ",$time,clk,clk_out);


endmodule
output

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

ST21 : begin clk_temp2 = 1'b0; nx_state1 =ST22; end


ST22 : begin clk_temp2 = 1'b1; nx_state1 =ST20; end
default : begin clk_temp2 = 1'bx; nx_state1 =ST20; end
endcase
end
assign clk_divby3 = clk_temp1|| clk_temp1;
endmodule

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

You might also like