10
Project Based on Verilog HDLs

This chapter includes VLSI projects based on digital circuit design using Verilog programming and functional verification with a truth table on Xilinx tool [12]. The project includes all four levels of abstraction of Verilog from the switch-level to behavioral-level model. Each project gives a basic description of design including truth table and design verification results.

Xilinx ISE is one of the useful simulators that uses Verilog/VHDL languages to design and implement any digital logic virtually. Figures 10.110.4 show how the Xilinx ISE simulator interfaces to create a project, select the Verilog module, text editor, and waveform window, respectively.

Figure 10.1 New project creation on Xilinx ISE simulator.

Figure 10.2 New source module creation on Xilinx.

Figure 10.3 Xilinx platform for Verilog HDL.

Figure 10.4 Behavioral simulation on Xilinx platform.

Step 1: file → new project → project name

Step 2: Right click on project created → new source → select Verilog module → module name. Choose option next and finish.

Step 3: Write a Verilog program using the platform of text editor. Select synthesis implementation for getting a circuit schematic.

Step 4: Write the test stimulus and select the option of behavioral simulation to obtain waveform and to verify the truth table.

10.1 Project Based on Combinational Circuit Design Using Verilog HDL

Any digital circuit can be designed on the Xilinx ISE platform using different levels of abstraction of Verilog HDL. Combinational circuits such as adder, subtractor, multiplier, comparators, etc. are usually part of many digital processors. In this section, a few additional examples of combinational circuit are presented using switch-level, gate-level, dataflow, and behavioral models.

10.1.1 Full Adder Using Switches at Structural-Level Model

In this example, a full-adder module has been designed using switch-level modules of logic gates AND, OR and XOR etc. The design consists of four modules including the top full-adder module with submodules of switches such as snot, sxor, sor, and sand. The switch-level implementation of logic gates at transistor level are discussed in Chapter 7.

//Main module
module Switch_fulladd(S, C, u, v, w);//Top module and port declaration
input u,v,w;
output S, C;
wire y1, c1, c2;
sxor u1(y1,u,v);
sxor u2(S,y1,w);
sand u3(c1,u,v);
sand u4(c2,y1,w);
sor u5(C, c2,c1);
endmodule
module sor(f,x,y); //module elaboration of OR-gate using switch (sor)
input x,y;
output f;
wire w;
snor x1(w,x,y); //call of module switch NOR-gate
snot x2(f,w);
endmodule
module snor(Op,x,y); //module elaboration of switch nor with port declaration
output Op;
input x,y;
//internal wires
wire w;
supply1 Vdd; //Power supply is connected to Vdd
supply0 Gnd; //Ground is connected to Gnd
pmos (w, Vdd, y);
pmos (Op, w, x);
nmos (Op, Gnd, x);
nmos (Op, Gnd, y);
endmodule
module sxor(Op,x,y);
input x,y;
output Op;
wire w1,w2,w3,w4,w5;
supply1 Vdd;
supply0 Gnd;
nmos (w3,Gnd,w2);
nmos (Op,w3,w1);
nmos (w4,Gnd,y);
nmos (Op,w4,x);
pmos (Op,w5,x);
pmos (Op,w5,y);
pmos (w5,Vdd,w1);
pmos (w5,Vdd,w2);
snot n1(w1,x);//call of module switch NOT-gate
snot n2(w2,y);
endmodule
module sand(Op,x,y);//module elaboration of AND-gate using switch (sand)
output Op;
input x, y;
wire w;
snand x1(w,x,y);
snot x2(Op,w);
endmodule
module snand(Op,x,y); //module elaboration of NAND-gate using switch (snand)
output Op;
input x,y;
wire c;
supply1 Vdd;
supply0 Gnd;
pmos (Op,Vdd, y);
pmos (Op,Vdd, x);
nmos (w, Gnd, x);
nmos (Op, w, y);
endmodule
module snot(Op,x);////module elaboration of NOT-gate using switch (snot)
input x;
output Op;
supply1 Vdd;
supply0 Gnd;
nmos (Op,Gnd,x);
pmos (Op,Vdd,x);
endmodule

10.1.2 Ripple-Carry Full Adder (RCFA)

A 4-bit RCFA has been designed with four blocks of 1-bit full adder using the structural-level model (Figure 10.5). A 1-bit full-adder module can be elaborated as a submodule using the gate or dataflow model which is discussed in Chapter 4. Variables M & Cout are considered 4-bit and 1-bit size output while U & V are considered 4-bit input variables. Cin is taken for initial carry input for the block of 4-bit RCFA.

Figure 10.5 4-bit ripple-carry full adder.

//Design module
module RCFA_4_bit (M,Cout,U,V,Cin);
input [3:0] U,V;
input Cin;
output [3:0]M;
output Cout;
wire C0,C1,C2;
fulladd f1(M[0],C0,U[0],V[0],Cin);
fulladd f2(M[1],C1,U[1],V[1],C0);
fulladd f3(M[2],C2, U[2],V[2],C1);
fulladd f4(M[3],Cout, U[3],V[3],C2);
endmodule

10.1.3 4-bit Carry Look-ahead Adder (CLA)

CLAs come under the category of fast adders. Here, the full-adder (FA) block need not wait for the carry generated from the previous block of FA. However, it takes more hardware logic block compared to an RCFA. Figure 10.6 presents a 4-bit CLA block. The design of a CLA block is done using the dataflow model on a Verilog HDL platform.

Figure 10.6 4-bit CLA adder.

//Design module

module carrylookahead_adder(S,Cout,U,V,Cin);
input [3:0]U,V;
input Cin;
output [3:0]S;
output Cout;
wire h0,k0,h1,k1,h2,k2,h3,k3;
wire C3,C2,C1;
assign k0 = U[0]^V[0];
assign k1 = U[1]^V[1];
assign k2 = U[2]^V[2];
assign k3 = U[3]^V[3];
assign h0 = U[0]&V[0];
assign h1 = U[1]&V[1];
assign h2 = U[2]&V[2];
assign h3 = U[3]&V[3];
assign S[0] = U[0]^V[0]^Cin;
assign S[1] = U[1]^V[1]^C1;
assign S[2] = U[2]^V[2]^C2;
assign S[3] = U[3]^V[3]^C3;
assign C1 = h0|(k0&Cin);
assign C2 = h1|(k1&C1);
assign C3 = h2|(k2&C2);
assign Cout = h3|(k3&C3);
endmodule
//Test Stimulus
module carrylookahead_adder_test;
reg [3:0]U,V;
reg Cin;
wire [3:0]S;
wire Cout;
carrylookahead_adder u(S,Cout,U,V,Cin);
initial begin
$monitor ($time,”S = %d,Cout = %d,U = %b,V = %b,Cin = %b”,S,Cout,U,V,Cin);
U = 4ʹd1;V = 4ʹd2;Cin = 0;
#15 U = 4ʹd2;V = 4ʹd5;Cin = 0;
#15 U = 4ʹd4;V = 4ʹd4;Cin = 1;
#15 U = 4ʹd3;V = 4ʹd5;Cin = 0;
#20 $stop;
end endmodule

10.1.4 Design of a 4-bit Carry Save Adder (CSA)

A 4-bit carry save adder is designed at the structural level using gate-level modules of a 1-bit full adder as shown in Figure 10.7. CSAs are mainly used for the addition of three or more than three binary numbers such as multipliers where the addition of more than two binary numbers is frequently performed in multiplication operations. Here, a full-adder module has been called to implement CSA that can be declared using either the gate or dataflow level in a separate module.

Figure 10.7 4-bit CSA block diagram.

//Main module
module CSA(u,v,w,s,cout);
input [3:0] u,v,w;
output [4:0] s;
output cout;
wire [3:0] c1,s1,c2;
fulladd fa_10(u[0],v[0],w[0],s1[0],c1[0]); //calling of full blocks
fulladd fa_11(u[1],v[1],w[1],s1[1],c1[1]);
fulladd fa_12(u[2],v[2],w[2],s1[2],c1[2]);
fulladd fa_13(u[3],v[3],w[3],s1[3],c1[3]);
fulladd fa_20(s1[1],c1[0],1ʹb0,s[1],c2[1]);
fulladd fa_21(s1[2],c1[1],c2[1],s[2],c2[2]);
fulladd fa_22(s1[3],c1[2],c2[2],s[3],c2[3]);
fulladd fa_23(1ʹb0,c1[3],c2[3],s[4],cout);
assign s[0] = s1[0];
endmodule

10.1.5 2-bit Array Multiplier

module arraymultiplier_2bit(C,X,Y);
input [1:0]X,Y;
output [3:0]C;
wire w1,w2,w3,w4;
and x1(C[0],X[0],Y[0]);
and x2(w1,X[0],Y[1]);
and x3(w2,X[1],Y[0]);
and x4(w4,X[1],Y[1]);
ha h1(C[1],w3,w1,w2);
ha h2(C[2],C[3],w3,w4);
endmodule
module ha(s,c,x,y);
input x,y;
output s,c;
xor r1(s,x,y);
and r2(c,x,y);
endmodule
module arraymultiplier_2bit_test;
reg [1:0]x,y;
wire [3:0]C;
arraymultiplier_2bit u(C,x,y);
initial begin
x = 2ʹd0;y = 2ʹd0;
#5 x = 2ʹd0;y = 2ʹd1;
#5 x = 2ʹd1;y = 2ʹd0;
#5 x = 2ʹd2;y = 2ʹd3;
#5 $stop;
end endmodule

10.1.6 2 × 2 Bit Division Circuit Design

A 2 × 2 bit division circuit has been designed with the help of a truth table and K-map simplification. Here, the simple rule of division is followed as: 0/0 = x;0/1 = 0;1/1;1/0 = x etc. Figure 10.8 illustrates the truth table and K-map for simplified output expressions.

Figure 10.8 Truth table and K-map.

//Main module

module division2x2 (Q,A,B);
input [1:0]A,B;
output [1:0]Q;
assign Q1 = A1& ~ B1;
assign Q2 = (A1&A0)|(A1&B0)|(A0B1ʹB0);
endmodule

10.1.7 2-bit Comparator

In this example, a 2-bit comparator circuit is designed with the help of truth table and dataflow models. Here, f1, f2, and f3 are used to show the relation between A < B, A > B, and A = B, respectively. The expression is obtained through K-map.

//Main module
module comparator_2bit(f1,f2,f3,A,B);
input [1:0]A,B;
output f1,f2,f3;
assign f1=(~A[1]&B[1])|(~A[1]&~A[0]&B[0])|(~A[0]&B[1]&B[0]);
assign f2=(A[0]&~B[1]&~B[0])|(A[1]&~B[1])|(A[1]&A[0]&~B[0]);
assign f3=(~A[1]&~A[0]&~B[1]&~B[0])|(~A[1]&A[0]&~B[1]&B[0])|(A[1]&~A[0]&B[1]&~B[0])|(A[1]&A[0]&B[1]&B[0]);
endmodule


10.1.8 16-bit Arithmetic Logic Unit

//Design module
module ALU_16bit(out,a,b,s);
input [15:0]a,b;
input [3:0]s;
output reg [31:0]out;
always@(s)
begin
case(s)
4'd0:out=a+b;
4'd1:out=a*b;
4'd2:out=a&b;
4'd3:out=a^b;
4'd4:out=a<<2;
4'd5:out=b>>2;
4'd6:out={a,b}; //concatenation operator
4'd7:out={2{a}}; //Replication operator
4'd8:out=a-b;
4'd9:out=~a;
4'd10:out=|b;
4'd11:out=a>>1; //right shift 1 bit
4'd12:out=b<<1; //left shift 1 bit
4'd13:out=~a^b;
4'd14:out=&a; //reduction operator
4'b15:out=~(a|b);
endcase
end endmodule

10.1.9 Design and Implementation of 4 × 16 Decoder Using 2 × 4 Decoder

Decoders are part of various circuits that have multiple input and output lines. In this example, a 4 × 16 decoder circuit has been designed with the help of submodules of 2 × 4 decoder using structural-level and dataflow models. The outputs of the decoder in the first stage are used to enable the decoders in the second stage. Figure 10.9 illustrates the logic block for implementation of 4 × 16 decoder design using 2 × 4 decoder blocks.

Figure 10.9 1.8: 4 × 16 decoder using a 2 × 4 decoder.

//Design modules
module decoder_4x16(f,el,x);
output [15:0] f,
input [3:0] x,
input el;
wire [3:0] w;
dec_2x4 r0(w, x[3:2], el);
dec_2x4 r1(f[3:0], x[1:0], w[0]);
dec_2x4 r2(f[7:4], x[1:0], w(1));
dec_2x4 r3(f[11:8], x[1:0], w(2));
dec_2x4 r4(f[15:12], x[1:0], w[3]);
endmodule
module dec_2x4 (f0,f1,f2,f3,el,a,b);
input a, b, en;
output f0,f1,f2,f3;
assign f0 = (~a) & (~b) & en;
assign f1 = (~a) & b & en;
assign f2 = a & (~ b) & en;
assign f3 = a & b & en;
end module

10.2 Project Based on Sequential Circuit Design Using Verilog HDL

Similar to a combinational circuit, sequential circuits are also implemented using different levels of abstraction Verilog using logic blocks, F/Fs, and the clock signal. The behavioral-level model is the most preferred for sequential circuit design. In this section, a few examples of sequential circuit implementations have been described.

10.2.1 Design of 4-bit Up/down Counter

Counter is an example of a sequential circuit that counts pulses. In this example, a counter has been designed to perform both up-counting as well as down-counting with the help of the behavioral-level model. Here, the counter block is triggered with the positive edge of the clock signal. A clear signal is used to clear the values stored in different F/Fs of up-down counters. The input up_down is used here to select between the up or down counting process.

//Design module
module asyn_up_down(out, clock, clear, up_down);
input clock, clear, up_down;
output reg[3:0] out;
always@(posedge clock, posedge clear)
begin
if(clear = = 0)
begin
if(up_down = = 1)
out = out + 1;
else out = out-1;
end
else
out = 4ʹd0;
end
endmodule

10.2.2 LFSR Based 8-bit Test Pattern Generator

Linear feedback shift registers (LFSRs) are used to generate random test input sequences. They are frequently used in built-in-self-test circuits to generate the desired test input patterns. The required number of F/Fs depends on the number of bits in sequence. Here, x1,x2,x3 show different blocks of F/F. Figure 10.10 presents an 8-bit LFSR logic block.

Figure 10.10 8-bit LFSR.

//Design module:2 LFSR
//Design module
module lfsr8_xor(out,clk,rst);
output reg [7:0] out;
input clk, rst;
wire xx0,xx1,xx2;
assign xx2 = (out[6] ^ out[7]);
assign xx1 = (out[5] ^ xx0);
assign xx0 = (out[4] ^ xx1);
always @(posedge clk, posedge rst)
begin
if (rst)
out = 8ʹd00000001;
else
out = {out[6:0],xx2};
end
endmodule
//Test Stimulus
module lfsr_tb();
reg clk;
reg rst;
wire [7:0] out;
lfsr8_xor u(out,clk,rst);
initial begin
clk = 0;rst = 1;
#15 rst = 0;
#200;
end
always #5clk = ~ clk;
end
endmodule

10.3 Counter Design

Counter design is easily done with the help of conditional or loop statements at behavioral-level model. if/else or for loop-based examples are provided here.

10.3.1 Random Counter that Counts Sequence like 2,4,6,8,2,8…and so On

This is an example of random counter with the use of if else statement in Verilog HDL.

//Design module
module counter_random(count, clk, rst);
input clk,rst;
output reg [3:0]count;
always@(posedge clk)
begin
if(rst)
count ≤ 4ʹd0;
else if(count < 10)
count ≤ count + 2;
else
count ≤ 4ʹd2;
end
endmodule
module counter_random_test;
reg clk,rst;
wire [3:0]count;
counter_random u(count,clk,rst);
initial begin
clk = 0;
forever #5clk = ~ clk;
end
initial begin
rst = 1;
#10 rst = 0;
#200 $stop;
end
endmodule
//Mod16 up-counter that count from 0-15

module count_mod16(co,clk,rst);
input clk,rst;
output reg [3:0]co;
integer i;
always@(posedge clk)
begin
if(rst)
co ≤ 0;
else
for(i = 0;i < 15;i = i + 1) //use of for loop
co ≤ co + 1;
end
endmodule
//Mod10 down counter that count from 0-9

module counter_down(coclk,rst);
input clk,rst;
output reg [3:0]co;
always@(posedge clk)
begin
if(rst) //use of if else
co ≤ 0;
else if(co = = 0)
co ≤ 4ʹd9;
else
co ≤ co-1;
end
endmodule

10.3.2 Use of Task at the Behavioral-Level Model

In this example, a logic has been developed to count the number of 1 from input binary string using tasks as subroutine in the behavioral-level model.

//Main module
module task_count_1(cout,x);
input [7:0]x;
output reg [3:0]cout;
integer i;
always@(x)
count_1(cout,x);
task count_1;
output [3:0]cout;
input [7:0]x;
begin
cout = 8ʹd0;
for(i = 0;i < 8;i = i + 1)
if(x[i]) //x[i] is true
cout = cout + 1;
else
cout = cout;
end
endtask
endmodule
//Test bench
module task_count_1test;
reg [7:0]x;
wire [3:0]cout;
task_count_1 u(cout,x);
initial begin
x = 8ʹd0;
#5 x = 8ʹd7;
#5 x = 8ʹd9;
#5 x = 8ʹd8;
#5 x = 8ʹd15;
#5 $stop;
end
endmodule

10.3.3 Traffic Signal Light Controller

//Design module
module traffic_signal_lights;
reg clk, cred, cyellow, cgreen;
parameter on = 1, off = 0, cred_tics = 30,
cyellow_tics = 3, cgreen_tics = 20;
initial cred = off;
initial cyellow = off;
initial cgreen = off;
always begin
cred = on;
light(cred, cred_tics);
cgreen = on;
light(green, green_tics);
cyellow = on;
light(cyellow, cyellow_tics);
end
//task to wait for positive edge clocks of tic
task light;
output col;
input [31:0] tic;
begin
repeat (tic) @ (posedge clk);
col = off;
end
endtask
always begin
#15 clk = 0;
#1 clk = 1;
end
endmodule

10.3.4 Hamming Code(h,k) Encoder/Decoder

Hamming code is one of the techniques to check and correct error bit from an input bit stream. It can be designed in blocks named as generator, checker, and corrector circuit.

//Encoder:
module ham_en(clk,i,co);
input clk;
input [3:0] i;
output reg[6:0] co;
always@(posedge clk)
begin
co[6]=i[3];
co[5]=i[2];
co[4]=i[1];
co[3]=i[1]^i[2]^i[3];
co[2]=i[0];
co[1]=i[0]^i[2]^i[3];
co[0]=i[0]^i[1]^i[3];
end
endmodule
//Decoder
module ham_dec(co,clk,w,cout,d);
input clk;
input[6:0] co;
output reg[2:0]w;
output reg[6:0] cout;
output reg[3:0]d;
always@(posedge clk)
begin
w[2]=co[0]^co[4]^co[5]^co[6];
w[1]=co[1]^co[2]^co[5]^co[6];
w[0]=co[0]^co[2]^co[4]^co[6];
cout=co;
if(w)
cout[w-1]=~c[w-1];
end
always@(cout)
begin
d[0]=cout[2];
d[1]=cout[4];
d[2]=cout[5];
d[3]=cout[6];
end
endmodule

Frequency Divider Circuit

A frequency divider is useful to increase clock pulse duration by frequency divison f/n, where n = 1,2,3…so on. As per the expression of clock time period, T =1f= 11MHz=1µsec for 1 MHz frequency. Such a high-frequency clock pulse cannot be observed by the human eye because of the very low time period. For FPGA-based high-frequency implementation, a frequency divider circuit is required to observe the response in terms of input and output variations with increased delay as per required. A Verilog program for frequency divider has been illustrated below for frequency division circuit f/225 for the frequency above 100 MHz.

//Design Module
module clockdivide(clk, nclk); //clk and nclk are the clock input and output of divider circuit
input clk;
output reg nclk;
reg [31:0]count = 32ʹd0;
always@(posedge clk)
begin
count = count + 1;
nclk = count[25];
end
endmodule
//Test Stimulus
module clockdivide_test;
reg clk;
wire nclk;
clockdivide uu(clk, nclk);
initial begin
clk = 0;
forever #5clk = ~ clk;
end
initial
# 1000000000 $stop;
endmodule

Review Questions

Q1 Design and write a Verilog program for 32 × 1 multiplexer using 4 × 1 multiplexer.

Q1 Write a Verilog program of decoder circuit to drive seven-segment display.

Q3 Write a Verilog program for frequency divider to increase with increased clock pulse delay by 4 times.

Q4 Write a Verilog program of 2-to-4 line decoder using switches.

Q5 Write a Verilog program of 4-bit adder/subtractor circuit using the dataflow model.

Multiple Choice Questions

Q1 Which statement is true for test stimulus in Verilog HDL?

  1. The stimulus block instantiates the design block and directly drives the signals in the design block
  2. Stimulus is to instantiate both the stimulus and design blocks in a top-level dummy module
  3. The stimulus block interacts with the design block only through the interface
  4. All of the above

Q2 Choose the correct syntax of 4 × 1 multiplexer using conditional operator

  1. assign Y = S1?(S0?d3:d2):(S0?D1:D0);
  2. assign Y = S1?(S0?d3:d2):(S1?D1:D0);
  3. assign Y = S0?(S1?d3:d2):(S0?D1:D0);
  4. None of the above

Q3 Which is the correct syntax for the implementation of Y(a,b) = ∑m(0,2)?

  1. assign Y = (~a| ~ b)&(a| ~ b);
  2. assign Y = (~a& ~ b)|(a& ~ b);
  3. assign Y = (~a&b)I(a& ~ b);
  4. assign Y = (a& ~ b)I(a& ~ b);

Q4 For frequency divider f/4, the clock period will be:

  1. T/4
  2. 4T
  3. T
  4. None

Q5 For 100 MHz frequency, time period will be:

  1. 0.1µsec
  2. 0.01µsec
  3. 0.001msec
  4. none

References

  1. [1] XILINX. (2021). Website. https://www.xilinx.com (accessed 22 June 2021).
  2. [2] Man, M. and Ciletti, M.D. (2013). Digital Design: With an Introduction to the Verilog HDL, 5e. ed. Upper Saddle River, NJ: Pearson.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.54.108