Download as pdf or txt
Download as pdf or txt
You are on page 1of 57

Computer Organization

and Architecture
(19CSE211)

Lab programs

Sakthi Lakshmanan An

CH.EN.U4CSE19034

CSE – A

Semester - 4
Date: 20.01.2021 Lab – 1

Question 1:
Implement all basic logic gates in a single program.

Aim:
To implement all basic logic gates in a single program in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A and B as input pins.
Step 3: Initialize AND_AB, OR_AB, XOR_AB, NOT_A, NOT_B, NAND_AB, NOR_AB
and XNOR_AB as output pins.
Step 4: Assign AND_AB to the output of the and gate with the inputs as A and B.
Step 5: Assign OR_AB to the output of the or gate with the inputs as A and B.
Step 6: Assign XOR_AB to the output of the xor gate with the inputs as A and B.
Step 7: Assign NOT_A and NOT_B to the outputs of the two not gates with their inputs
as A and B respectively.
Step 8: Assign NAND_AB, NOR_AB and XNOR_AB to the outputs of the three not
gates with their inputs as AND_AB, OR_AB and XOR_AB respectively.
Step 9: End module.

Program:
module Source(
input A,
input B,
output AND_AB,
output OR_AB,
output XOR_AB,
output NOT_A,
output NOT_B,
output NAND_AB,
output NOR_AB,
output XNOR_AB
);

and (AND_AB, A, B);


or (OR_AB, A, B);
xor (XOR_AB, A, B);
not (NOT_A, A);
not (NOT_B, B);
not (NAND_AB, AND_AB);
not (NOR_AB, OR_AB);
not (XNOR_AB, XOR_AB);

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;
reg A;
reg B;
wire AND_AB;
wire OR_AB;
wire XOR_AB;
wire NOT_A;
wire NOT_B;
wire NAND_AB;
wire NOR_AB;
wire XNOR_AB;
Source uut (
.A(A),
.B(B),
.AND_AB(AND_AB),
.OR_AB(OR_AB),
.XOR_AB(XOR_AB),
.NOT_A(NOT_A),
.NOT_B(NOT_B),
.NAND_AB(NAND_AB),
.NOR_AB(NOR_AB),
.XNOR_AB(XNOR_AB)
);
initial begin
A = 1'b0;
B = 1'b0;
$monitor("Time=%0t\t\tInput values:
A=%B\tb=%B\t\tOutput values:
AND_AB=%B\tOR_AB=%B\tXOR_AB=%B\tNOT_A=%B\tNOT_B=%B\tNAND_A
B=%B\tNOR_AB=%B\tXNOR_AB=%B", $time, A, B, AND_AB, OR_AB,
XOR_AB, NOT_A, NOT_B, NAND_AB, NOR_AB, XNOR_AB);
end
always #250 begin
B = ~B;
$monitor("Time=%0t\t\tInput values:
A=%B\tb=%B\t\tOutput values:
AND_AB=%B\tOR_AB=%B\tXOR_AB=%B\tNOT_A=%B\tNOT_B=%B\tNAND_A
B=%B\tNOR_AB=%B\tXNOR_AB=%B", $time, A, B, AND_AB, OR_AB,
XOR_AB, NOT_A, NOT_B, NAND_AB, NOR_AB, XNOR_AB);
end
always #500 A = ~A;

endmodule

Simulation output:

Result:
Thus, all the basic logic gates are implemented in a single Verilog program, for which
a testbench is framed and the output is verified successfully.
Question 2:
Design a 16X1 multiplexer.

Aim:
To design a 16X1 multiplexer in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 16-bit bus input and SEL as a 4-bit bus input.
Step 3: Initialize OUT as an output pin.
Step 4: Assign OUT to the particular pin of IN, which is pointed by the difference of
4’d15 and SEL.
Step 5: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [15:0] IN,
input [3:0] SEL,
output OUT
);

assign OUT = IN[4'd15 - SEL];

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [15:0] IN;


reg [3:0] SEL;
wire OUT;
Source uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 16'd14422;
SEL = 4'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%d", $time, IN, SEL, OUT);
end
always #62 begin
SEL = SEL + 4'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%d", $time, IN, SEL, OUT);
end

endmodule

Simulation output:

Result:
Thus, a 16X1 multiplexer is designed in Verilog, for which a testbench is framed and
the output is verified successfully.
Question 3:
Implement a half adder in Verilog.

Aim:
To implement a half adder in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A and B as input pins.
Step 3: Initialize S and C as output pins.
Step 4: Concatenate the pins S and C, and then assign them to the output of the binary
addition of A and B.
Step 5: End module.

Program:
`timescale 1ns / 1ps

module Source(
input A,
input B,
output S,
output C
);

assign {C, S} = A + B;

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg A;
reg B;
wire S;
wire C;
Source uut (
.A(A),
.B(B),
.S(S),
.C(C)
);
initial begin
A = 1'b0;
B = 1'b0;
$monitor("Time=%0t\t\tInput values:
A=%b\tB=%b\t\tOutput values: Sum=%b\tCarry=%b", $time, A,
B, S, C);
end
always #250 begin
B = ~B;
$monitor("Time=%0t\t\tInput values:
A=%b\tB=%b\t\tOutput values: Sum=%b\tCarry=%b", $time, A,
B, S, C);
end
always #500 A = ~A;

endmodule

Simulation output:
Result:
Thus, a half adder is implemented in Verilog, for which a testbench is framed and the
output is verified successfully.
Date: 27.01.2021 Lab – 2

Question 1:
Implementation of a 4 to 1 MUX using Gate Level Design.

Aim:
To implement a 4X1 multiplexer using gate level design in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and SEL as a 2-bit bus input.
Step 3: Initialize OUT as an output pin and declare it as a wor.
Step 4: Initialize not_sel as a 2-bit bus wire.
Step 5: Assign not_sel[0] and not_sel[1] to the outputs of the two not gates with their
inputs as SEL[0] and SEL[1] respectively.
Step 6: Assign OUT to the outputs of the multiple and gates with the inputs as;
• not_sel[1], not_sel[0] and IN[3]
• not_sel[1], SEL[0] and IN[2]
• SEL[1], not_sel[0] and IN[1]
• SEL[1], SEL[0] and IN[0]

Step 7: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [1:0] SEL,
output wor OUT
);

wire [1:0] not_sel;


not (not_sel[0], SEL[0]), (not_sel[1], SEL[1]);
and (OUT, not_sel[1], not_sel[0], IN[3]), (OUT,
not_sel[1], SEL[0], IN[2]), (OUT, SEL[1], not_sel[0],
IN[1]), (OUT, SEL[0], SEL[1], IN[0]);

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [1:0] SEL;
wire OUT;
Source uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 4'd5;
SEL = 2'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
#500 IN = 4'd10;
end
always #125 begin
SEL = SEL + 2'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
end

endmodule
Simulation output:

Result:
Thus, a 4X1 multiplexer is implemented using gate level design in Verilog, for which
a testbench is framed and the output is verified successfully.

Question 2:
Implementation of 1 bit adder (Full adder) using gate level implementation.

Aim:
To implement a one-bit full adder using gate level implementation in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A, B and Cin as input pins.
Step 3: Initialize S and Cout as output pins. Also, declare Cout as a wor.
Step 4: Assign S to the output of the xor gate with the inputs as A, B and Cin.
Step 5: Assign Cout to the outputs of the multiple and gates with the inputs as;
• A and B
• A and Cin
• B and Cin

Step 6: End module.

Program:
`timescale 1ns / 1ps

module Source(
input A,
input B,
input Cin,
output S,
output wor Cout
);

xor (S, A, B, Cin);


and (Cout, A, B), (Cout, A, Cin), (Cout, B, Cin);

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg A;
reg B;
reg Cin;
wire S;
wire Cout;
Source uut (
.A(A),
.B(B),
.Cin(Cin),
.S(S),
.Cout(Cout)
);
initial begin
A = 0;
B = 0;
Cin = 0;
$monitor("Time=%0t\tInput values:
A=%b\tB=%b\tCin=%b\tOutput values: Sum=%b\tCarry=%b",
$time, A, B, Cin, S, Cout);
end
always #125 begin
Cin = ~Cin;
$monitor("Time=%0t\tInput values:
A=%b\tB=%b\tCin=%b\tOutput values: Sum=%b\tCarry=%b",
$time, A, B, Cin, S, Cout);
end
always #250 B = ~B;
always #500 A = ~A;

endmodule

Simulation output:

Result:
Thus, a one-bit full adder is implemented using gate level implementation in Verilog,
for which a testbench is framed and the output is verified successfully.
Date: 03.02.2021 Lab – 3

Question 1:
Implementation of 4 to 1 MUX with data flow.

Aim:
To implement a 4X1 multiplexer with data flow design in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and SEL as a 2-bit bus input.
Step 3: Initialize OUT as an output pin.
Step 4: Assign OUT to the particular pin of IN, which is pointed by the difference of
2’d3 and SEL.
Step 5: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [1:0] SEL,
output OUT
);

assign OUT = IN[2'd3 - SEL];

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;
reg [3:0] IN;
reg [1:0] SEL;
wire OUT;
Source uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 4'd5;
SEL = 2'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
#500 IN = 4'd10;
end
always #125 begin
SEL = SEL + 2'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
end

endmodule

Simulation output:
Result:
Thus, a 4X1 multiplexer is implemented with data flow design in Verilog, for which a
testbench is framed and the output is verified successfully.

Question 2:
Implementation of 4 to 1 MUX using conditional operator.

Aim:
To implement a 4X1 multiplexer using conditional operator in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and SEL as a 2-bit bus input.
Step 3: Initialize OUT as an output pin.
Step 4: Assign OUT to the output of the conditional operator with the condition applied
on SEL[1] and its two expressions are;
❖ If true, return the output of another nested conditional operator, which applies
the condition on SEL[0] and again its two expressions are;
• If true, return IN[0].
• Else, return IN[1].
❖ Else, return the output of another nested conditional operator, which applies
the condition on SEL[0] and again its two expressions are;
• If true, return IN[2].
• Else, return IN[3].

Step 5: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [1:0] SEL,
output OUT
);
assign OUT = SEL[1] ? (SEL[0] ? IN[0] : IN[1]) : (SEL[0] ?
IN[2] : IN[3]);

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [1:0] SEL;
wire OUT;
Source uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 4'd5;
SEL = 2'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
#500 IN = 4'd10;
end
always #125 begin
SEL = SEL + 2'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
end

endmodule
Simulation output:

Result:
Thus, a 4X1 multiplexer is implemented using conditional operator in Verilog, for
which a testbench is framed and the output is verified successfully.

Question 3:
Implementation of Full adder with data flow.

Aim:
To implement a full adder with data flow design in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A, B and Cin as input pins.
Step 3: Initialize S and Cout as output pins.
Step 4: Concatenate the pins S and Cout, and then assign them to the output of the
combined binary addition of A, B and Cin.
Step 5: End module.

Program:
`timescale 1ns / 1ps

module Source(
input A,
input B,
input Cin,
output S,
output Cout
);

assign {Cout, S} = A + B + Cin;

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg A;
reg B;
reg Cin;
wire S;
wire Cout;
Source uut (
.A(A),
.B(B),
.Cin(Cin),
.S(S),
.Cout(Cout)
);
initial begin
A = 0;
B = 0;
Cin = 0;
$monitor("Time=%0t\tInput values:
A=%b\tB=%b\tCin=%b\tOutput values: Sum=%b\tCarry=%b",
$time, A, B, Cin, S, Cout);
end
always #125 begin
Cin = ~Cin;
$monitor("Time=%0t\tInput values:
A=%b\tB=%b\tCin=%b\tOutput values: Sum=%b\tCarry=%b",
$time, A, B, Cin, S, Cout);
end
always #250 B = ~B;
always #500 A = ~A;

endmodule

Simulation output:

Result:
Thus, a full adder is implemented with data flow design in Verilog, for which a
testbench is framed and the output is verified successfully.

Question 4:
Implementation of 2 to 4 decoder (with enable) using dataflow.
Aim:
To implement a 2 to 4 decoder with enable pin using dataflow design in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 2-bit bus input and E as an input pin.
Step 3: Initialize OUT as a 4-bit bus output.
Step 4: Assign OUT[0] to the output of the bit-wise and, which has the input
expressions as another bit-wise and, which again has the input expressions as negation of IN[1]
and negation of IN[0], and E.
Step 5: Assign OUT[1] to the output of the bit-wise and, which has the input
expressions as another bit-wise and, which again has the input expressions as negation of IN[1]
and IN[0], and E.
Step 6: Assign OUT[2] to the output of the bit-wise and, which has the input
expressions as another bit-wise and, which again has the input expressions as IN[1] and
negation of IN[0], and E.
Step 7: Assign OUT[3] to the output of the bit-wise and, which has the input
expressions as another bit-wise and, which again has the input expressions as IN[1] and IN[0],
and E.
Step 8: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [1:0] IN,
input E,
output [3:0] OUT
);

assign OUT[0] = ~IN[1] & ~IN[0] & E;


assign OUT[1] = ~IN[1] & IN[0] & E;
assign OUT[2] = IN[1] & ~IN[0] & E;
assign OUT[3] = IN[1] & IN[0] & E;

endmodule
Testbench code:
`timescale 1ns / 1ps

module TB;

reg [1:0] IN;


reg E;
wire [3:0] OUT;
Source uut (
.IN(IN),
.E(E),
.OUT(OUT)
);
initial begin
IN = 0;
E = 0;

$monitor("Time=%0t\tEnable=%b\tInput=%d\tOutput=%d",
$time, E, IN, OUT);
end
always #125 begin
IN = IN + 1'b1;

$monitor("Time=%0t\tEnable=%b\tInput=%d\tOutput=%d",
$time, E, IN, OUT);
end
always #500 E = ~E;

endmodule
Simulation output:

Result:
Thus, a 2 to 4 decoder with enable pin is implemented using dataflow design in Verilog,
for which a testbench is framed and the output is verified successfully.
Date: 10.02.2021 Lab – 4

Question 1:
Implementation of 2 to 4 decoder using behavioural modelling.

Aim:
To implement a 2 to 4 decoder using behavioural modelling in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 2-bit bus input.
Step 3: Initialize OUT as a 4-bit bus output and declare it as a reg.
Step 4: Start the always structure which depends on IN.
Step 5: Assign all the OUT pins to 4’b0.
Step 6: Assign a particular OUT pin to 1’b1, which is pointed by IN.
Step 7: End the always structure.
Step 8: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [1:0] IN,
output reg [3:0] OUT
);

always @ (IN) begin


OUT = 4'b0;
OUT[IN] = 1'b1;
end

endmodule
Testbench code:
`timescale 1ns / 1ps

module TB;

reg [1:0] IN;


wire [3:0] OUT;
Source uut (
.IN(IN),
.OUT(OUT)
);
initial begin
IN = 2'b0;
$monitor("Time=%0t\tInput=%d\tOutput=%d", $time,
IN, OUT);
end
always #250 begin
IN = IN + 1'b1;
$monitor("Time=%0t\tInput=%d\tOutput=%d", $time,
IN, OUT);
end

endmodule

Simulation output:
Result:
Thus, a 2 to 4 decoder is implemented using behavioural modelling in Verilog, for
which a testbench is framed and the output is verified successfully.

Question 2:
Implementation of priority encoder (8 to 3) using behavioural modelling.

Aim:
To implement an 8 to 3 priority encoder using behavioural modelling in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as an 8-bit bus input.
Step 3: Initialize OUT as a 3-bit bus output and declare it as a reg.
Step 4: Initialize i as an integer.
Step 5: Start the always structure which depends on IN.
Step 6: Assign all the OUT pins to 3’bz.
Step 7: Assign i to 0.
Step 8: Check if i is less than 8;
❖ If true, go to step 9.
❖ Else, go to step 11.

Step 9: If a particular IN pin pointed by i is true, then assign OUT to i. Else, go to step
10.
Step 10: Increment the value of i by 1 and go to step 8.
Step 11: End the always structure.
Step 12: End module.
Program:
`timescale 1ns / 1ps

module Source(
input [7:0] IN,
output reg [2:0] OUT
);

integer i;
always @ (IN) begin
OUT = 3'bz;
for (i=0; i<8; i=i+1)
if (IN[i]) OUT = i;
end

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [7:0] IN;


wire [2:0] OUT;
Source uut (
.IN(IN),
.OUT(OUT)
);
initial begin
IN = 8'd3;
$monitor("Time=%0t\tInput=%d\tOutput=%d", $time,
IN, OUT);
end
always #111 begin
IN = IN * 8'd2;
$monitor("Time=%0t\tInput=%d\tOutput=%d", $time,
IN, OUT);
end

endmodule
Simulation output:

Result:
Thus, an 8 to 3 priority encoder is implemented using behavioural modelling in Verilog,
for which a testbench is framed and the output is verified successfully.
Date: 17.02.2021 Lab – 5

Question 1:
Implementation of 4X1 MUX using switch case.

Aim:
To implement a 4X1 multiplexer using switch case in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and SEL as a 2-bit bus input.
Step 3: Initialize OUT as an output pin and declare it as a reg.
Step 4: Start the always structure which depends on all the input variables.
Step 5: Begin the switch case statement with the decision-making expression as SEL
and the branches as;
❖ If SEL is 3, then assign OUT to IN[0].
❖ If SEL is 2, then assign OUT to IN[1].
❖ If SEL is 1, then assign OUT to IN[2].
❖ If SEL is 0, then assign OUT to IN[3].

Step 6: End the switch case.


Step 7: End the always structure.
Step 8: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [1:0] SEL,
output reg OUT
);

always @ (*) begin


case (SEL)
3: OUT = IN[0];
2: OUT = IN[1];
1: OUT = IN[2];
0: OUT = IN[3];
endcase
end

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [1:0] SEL;
wire OUT;
Source uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 4'd5;
SEL = 2'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
#500 IN = 4'd10;
end
always #125 begin
SEL = SEL + 2'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
end

endmodule
Simulation output:

Result:
Thus, a 4X1 multiplexer using switch case is implemented in Verilog, for which a
testbench is framed and the output is verified successfully.

Question 2:
Implementation of multiplication algorithm.

Aim:
To implement multiplication algorithm in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A and B as 32-bit bus inputs.
Step 3: Initialize C as a 64-bit bus output and declare it as a reg.
Step 4: Initialize i as an integer.
Step 5: Start the always structure which depends on all the input variables.
Step 6: Assign C to 64’b0.
Step 7: Assign i to 0.
Step 8: Check if i is less than 32;
❖ If true, go to step 9.
❖ Else, go to step 11.

Step 9: If a particular A pin pointed by i is true, then assign C to the output of the binary
addition of C with i bit(s) logically left shifted B. Else, go to step 10.
Step 10: Increment the value of i by 1 and go to step 8.
Step 11: End the always structure.
Step 12: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [31:0] A, //Multiplier
input [31:0] B, //Multiplicand
output reg [63:0] C
);

integer i;
always@(*) begin
C = 64'b0;
for (i=0; i<32; i=i+1) if(A[i]) C = C + (B << i);
end

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [31:0] A;
reg [31:0] B;
wire [63:0] C;
Source uut (
.A(A),
.B(B),
.C(C)
);
initial begin
A = 32'd14;
B = 32'd4;
$monitor("Time=%0t\tInput: A=%d\tB=%d\tOutput:
C=%d", $time, A, B, C);
end
always #100 begin
A = A * 20;
B = B * 2;
$monitor("Time=%0t\tInput: A=%d\tB=%d\tOutput:
C=%d", $time, A, B, C);
end

endmodule

Simulation output:

Result:
Thus, multiplication algorithm is implemented in Verilog, for which a testbench is
framed and the output is verified successfully.
Question 3:
Use of repeat construct.

Aim:
To implement multiplication algorithm with repeat construct in Verilog.

Algorithm:
Step 1: Begin Source module.
Step 2: Initialize A and B as 32-bit bus inputs.
Step 3: Initialize C as a 64-bit bus output and declare it as a reg.
Step 4: Initialize i as an integer.
Step 5: Start the always structure which depends on all the input variables.
Step 6: Assign C to 64’b0.
Step 7: Assign i to 0.
Step 8: Start the repeat construct with the iteration value of 32.
Step 9: If a particular A pin pointed by i is true, then assign C to the output of the binary
addition of C with i bit(s) logically left shifted B. Else, go to step 10.
Step 10: Increment the value of i by 1.
Step 11: End repeat construct.
Step 12: End the always structure.
Step 13: End module.

Program:
`timescale 1ns / 1ps

module Source(
input [31:0] A,
input [31:0] B,
output reg [63:0] C
);
integer i;
always @ (*) begin
C = 64'b0;
i = 0;
repeat (32) begin
if(A[i]) C = C + (B << i);
i = i + 1;
end
end
endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [31:0] A;
reg [31:0] B;
wire [63:0] C;
Source uut (
.A(A),
.B(B),
.C(C)
);
initial begin
A = 32'd14;
B = 32'd4;
$monitor("Time=%0t\tInput: A=%d\tB=%d\tOutput:
C=%d", $time, A, B, C);
end
always #100 begin
A = A * 20;
B = B * 2;
$monitor("Time=%0t\tInput: A=%d\tB=%d\tOutput:
C=%d", $time, A, B, C);
end

endmodule
Simulation output:

Result:
Thus, multiplication algorithm is implemented with repeat construct in Verilog, for
which a testbench is framed and the output is verified successfully.
Date: 10.03.2021 Lab – 6

Question 1:
Design a 4:1 mux using the 2:1 mux.

Aim:
To implement a 4X1 multiplexer using 2X1 multiplexers in Verilog.

Algorithm:
i) Mux_4x1.v
Step 1: Begin Mux_4x1 module.
Step 2: Initialize IN as a 4-bit bus input and SEL as a 2-bit bus input.
Step 3: Initialize OUT as an output pin.
Step 4: Initialize t as a 2-bit bus wire.
Step 5: Assign t[0] to the output of the mux_2x1 with the inputs as IN[1:0]
and SEL[0].

Step 6: Assign t[1] to the output of the mux_2x1 with the inputs as IN[3:2]
and SEL[0].

Step 7: Assign OUT to the output of the mux_2x1 with the inputs as t and
SEL[1].

Step 8: End module.

ii) Mux_2x1.v
Step 1: Begin mux_2x1 module.
Step 2: Initialize IN as a 2-bit bus input and SEL as an input pin.
Step 3: Initialize OUT as an output pin.
Step 4: Assign OUT to a particular pin of IN, which is pointed by the
difference of 1’d1 and SEL.

Step 5: End module.


Program:
i. Mux_4x1.v
`timescale 1ns / 1ps

module Mux_4x1(
input [3:0] IN,
input [1:0] SEL,
output OUT
);

wire [1:0] t;
mux_2x1 m1(IN[1:0], SEL[0], t[0]);
mux_2x1 m2(IN[3:2], SEL[0], t[1]);
mux_2x1 m3(t, SEL[1], OUT);

endmodule

ii. Mux_2x1.v
`timescale 1ns / 1ps

module Mux_2x1(
input [1:0] IN,
input SEL,
output OUT
);

assign OUT = IN[1'b1 - SEL];

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [1:0] SEL;
wire OUT;
Mux_4x1 uut (
.IN(IN),
.SEL(SEL),
.OUT(OUT)
);
initial begin
IN = 4'd5;
SEL = 2'd0;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
#500 IN = 4'd10;
end
always #125 begin
SEL = SEL + 2'd1;
$monitor("Time=%0t\tInput=%d\tSelector
value=%d\tOutput=%b", $time, IN, SEL, OUT);
end

endmodule

Simulation output:

Result:
Thus, a 4X1 multiplexer is implemented using 2X1 multiplexers in Verilog, for which
a testbench is framed and the output is verified successfully.
Question 2:
Design a 4-bit adder by using 1-bit full adder.

Aim:
To design a 4-bit adder using 1-bit full adders in Verilog.

Algorithm:
i) Adder_4bit.v
Step 1: Begin Adder_4bit module.
Step 2: Initialize A and B as 4-bit bus inputs.
Step 3: Initialize OUT as a 5-bit bus output.
Step 4: Initialize t as a 3-bit bus wire.
Step 5: Assign C[0] and t[0] to the outputs of the Full_Adder with the inputs
as A[0], B[0] and 1’b0.

Step 6: Assign C[1] and t[1] to the outputs of the Full_Adder with the inputs
as A[1], B[1] and t[0].

Step 7: Assign C[2] and t[2] to the outputs of the Full_Adder with the inputs
as A[2], B[2] and t[1].

Step 8: Assign C[3] and C[4] to the outputs of the Full_Adder with the inputs
as A[3], B[3] and t[2].

Step 9: End module.

ii) Full_Adder.v
Step 1: Begin Source module.
Step 2: Initialize A, B and Cin as input pins.
Step 3: Initialize S and Cout as output pins.
Step 4: Concatenate the pins S and Cout, and then assign them to the output
of the combined binary addition of A, B and Cin.

Step 5: End module.

Program
i. Adder_4bit.v
`timescale 1ns / 1ps
module Adder_4bit(
input [3:0] A,
input [3:0] B,
output [4:0] C
);

wire [2:0] t;
Full_Adder fa1(A[0], B[0], 1'b0, C[0], t[0]);
Full_Adder fa2(A[1], B[1], t[0], C[1], t[1]);
Full_Adder fa3(A[2], B[2], t[1], C[2], t[2]);
Full_Adder fa4(A[3], B[3], t[2], C[3], C[4]);

endmodule

ii. Full_Adder.v
`timescale 1ns / 1ps

module Full_Adder(
input A,
input B,
input Cin,
output Sum,
output Cout
);

assign {Cout, Sum} = A + B + Cin;

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] A;
reg [3:0] B;
wire [4:0] C;
Adder_4bit uut (
.A(A),
.B(B),
.C(C)
);
initial begin
A = 4'd0;
B = 4'd1;
#100;
$monitor("Time=%0t\tA=%d\tB=%d\tC=%d", $time, A,
B, C);
end
always #125 begin
A = A + 4'd2;
B = B + 4'd2;
$monitor("Time=%0t\tA=%d\tB=%d\tC=%d", $time, A,
B, C);
end

endmodule

Simulation output:

Result:
Thus, a 4-bit adder is implemented using 1-bit full adders in Verilog, for which a
testbench is framed and the output is verified successfully.
Question 3 i):
Simulate 4-bit combinational shifter using Verilog. Implement this in gate-level
model.

Aim:
To simulate a 4-bit combinational shifter using gate-level model in Verilog.

Algorithm:
i) Source.v
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and OP as a 3-bit bus input.
Step 3: Initialize OUT as a 4-bit bus output and OF as an output pin.
Step 4: Initialize det, chk and of as wires and initialize nop as a 2-bit bus wire.
Step 5: Assign nop[0] and nop[1] to the outputs of the two not gates
with their inputs as OP[0] and OP[1] respectively.
Step 6: Assign chk to the output of the nand gate with the inputs as OP[2] and
OP[1].

Step 7: Assign det to the output of the and gate with the inputs as OP[2] and
IN[3].

Step 8: Assign OUT[3] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as IN[2], det, IN[2] and IN[0].
• OP[1:0]
• chk

Step 9: Assign OUT[2] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[1] and IN[3].
• OP[1:0]
• chk

Step 10: Assign OUT[1] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[0] and IN[2].
• OP[1:0]
• chk

Step 11: Assign OUT[0] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as 1’b0, IN[1], IN[3] and IN[1].
• OP[1:0]
• chk

Step 12: Assign of to the output of the and gate with the inputs as OP[2],
nop[1] and nop[0].

Step 13: Assign OF to the output of the bufif1 gate with the inputs as IN[3]
and of.

Step 14: End module.

ii) mux_4x1.v :
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input, SEL as a 2-bit bus input and E as an
input pin.

Step 3: Initialize OUT as an output pin.


Step 4: Initialize not_sel as a 2-bit bus wire.
Step 5: Initialize tout as a wor.
Step 6: Assign not_sel[0] and not_sel[1] to the outputs of the two not gates
with their inputs as SEL[0] and SEL[1] respectively.

Step 7: Assign tout to the outputs of the multiple and gates with the inputs as;
• not_sel[1], not_sel[0] and IN[3]
• not_sel[1], SEL[0] and IN[2]
• SEL[1], not_sel[0] and IN[1]
• SEL[1], SEL[0] and IN[0]

Step 8: Assign OUT to the output of the bufif1 gate with the inputs as tout and
E.

Step 9: End module.

Program:
i. Source.v
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [2:0] OP,
output [3:0] OUT,
output OF
);
/* OP Meanings
0 Logical shift left
1 Logical shift right
2 Circular shift left
3 Circular shift right
4 Arithmetic shift left
5 Arithmetic shift right
6,7 Invalid opcode */

wire det, chk, of, nop[1:0];


not (nop[0], OP[0]), (nop[1], OP[1]);
nand (chk, OP[2], OP[1]);
and (det, OP[2], IN[3]);
mux_4x1 m1({IN[2], det, IN[2], IN[0]}, OP[1:0],
chk, OUT[3]);
mux_4x1 m2({2{IN[1], IN[3]}}, OP[1:0], chk,
OUT[2]);
mux_4x1 m3({2{IN[0], IN[2]}}, OP[1:0], chk,
OUT[1]);
mux_4x1 m4({1'b0, IN[1], IN[3], IN[1]}, OP[1:0],
chk, OUT[0]);
and (of, OP[2], nop[1], nop[0]);
bufif1 (OF, IN[3], of);

endmodule

ii. mux_4x1.v
`timescale 1ns / 1ps

module mux_4x1(
input [3:0] IN,
input [1:0] SEL,
input E,
output OUT
);

wire [1:0] not_sel;


wor tout;
not (not_sel[0], SEL[0]), (not_sel[1], SEL[1]);
and (tout, not_sel[1], not_sel[0], IN[3]), (tout,
not_sel[1], SEL[0], IN[2]), (tout, SEL[1],
not_sel[0], IN[1]), (tout, SEL[0], SEL[1], IN[0]);
bufif1 (OUT, tout, E);

endmodule
Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [2:0] OP;
wire [3:0] OUT;
wire OF;
Source uut (
.IN(IN),
.OP(OP),
.OUT(OUT),
.OF(OF)
);
initial begin
IN = 4'b0110;
OP = 3'b000;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
forever #62 begin
OP = OP + 3'b001;
case(OP)
0: $monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
1: $monitor("Time=%0t\tAfter logical right
shifting\t%b\tis\t%b", $time, IN, OUT);
2: $monitor("Time=%0t\tAfter circular left
shifting\t%b\tis\t%b", $time, IN, OUT);
3: $monitor("Time=%0t\tAfter circular
right shifting\t%b\tis\t%b", $time, IN, OUT);
4: $monitor("Time=%0t\tAfter arithmetic
left shifting\t%b\tis\t%b", $time, IN, OUT);
5: $monitor("Time=%0t\tAfter arithmetic
right shifting\t%b\tis\t%b", $time, IN, OUT);
default: $monitor("Time=%0t\tIncorrect
Operator", $time);
endcase
end
end
initial begin
#496
IN = 4'b1010;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
end

endmodule
Simulation output:

Result:
Thus, a 4-bit combinational shifter is simulated using gate-level model in Verilog, for
which a testbench is framed and the output is verified successfully.

Question 3 ii):
Simulate 4-bit combinational shifter using Verilog. Implement this in data-flow
model.

Aim:
To simulate a 4-bit combinational shifter using data-flow model in Verilog.

Algorithm:
i) Source.v
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and OP as a 3-bit bus input.
Step 3: Initialize OUT as a 4-bit bus output and OF as an output pin.
Step 4: Initialize chk as a wire.
Step 5: Assign chk to the output of the negation of bitwise and, which has the
inputs as OP[2] and OP[1].

Step 6: Assign OUT[3] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as IN[2], output of bitwise and,
with the inputs as OP[2] and IN[3], IN[2] and IN[0].
• OP[1:0]
• chk

Step 7: Assign OUT[2] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[1] and IN[3].
• OP[1:0]
• chk

Step 8: Assign OUT[1] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[0] and IN[2].
• OP[1:0]
• chk

Step 9: Assign OUT[0] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as 1’b0, IN[1], IN[3] and IN[1].
• OP[1:0]
• chk

Step 10: Assign OF to the output of the conditional operator with the
condition applied as OP == 3’b100 and its two expressions are;
• If true, return IN[3].
• Else, return 1’bz.

Step 11: End module.

ii) mux_4x1.v :
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input, SEL as a 2-bit bus input and E as an
input pin.

Step 3: Initialize OUT as an output pin.


Step 4: Assign OUT to the output of the conditional operator with the
condition applied on E and its two expressions are;
• If true, return a particular pin of IN, pointed by the difference of 2’d3 and
SEL.
• Else, return 1’bz.

Step 5: End module.

Program:
i. Source.v
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [2:0] OP,
output [3:0] OUT,
output OF
);

/* OP Meanings
0 Logical shift left
1 Logical shift right
2 Circular shift left
3 Circular shift right
4 Arithmetic shift left
5 Arithmetic shift right
6,7 Invalid opcode */

wire chk;
assign chk = !(OP[2] & OP[1]);
mux_4x1 m1({IN[2], OP[2] & IN[3], IN[2], IN[0]},
OP[1:0], chk, OUT[3]);
mux_4x1 m2({2{IN[1], IN[3]}}, OP[1:0], chk,
OUT[2]);
mux_4x1 m3({2{IN[0], IN[2]}}, OP[1:0], chk,
OUT[1]);
mux_4x1 m4({1'b0, IN[1], IN[3], IN[1]}, OP[1:0],
chk, OUT[0]);
assign OF = (OP==3'b100) ? IN[3] : 1'bz;

endmodule

ii. mux_4x1.v
`timescale 1ns / 1ps

module mux_4x1(
input [3:0] IN,
input [1:0] SEL,
input E,
output OUT
);

assign OUT = E ? IN[2'd3 - SEL] : 1'bz;

endmodule

Testbench code:
`timescale 1ns / 1ps

module TB;

reg [3:0] IN;


reg [2:0] OP;
wire [3:0] OUT;
wire OF;
Source uut (
.IN(IN),
.OP(OP),
.OUT(OUT),
.OF(OF)
);
initial begin
IN = 4'b0110;
OP = 3'b000;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
forever #62 begin
OP = OP + 3'b001;
case(OP)
0: $monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
1: $monitor("Time=%0t\tAfter logical right
shifting\t%b\tis\t%b", $time, IN, OUT);
2: $monitor("Time=%0t\tAfter circular left
shifting\t%b\tis\t%b", $time, IN, OUT);
3: $monitor("Time=%0t\tAfter circular
right shifting\t%b\tis\t%b", $time, IN, OUT);
4: $monitor("Time=%0t\tAfter arithmetic
left shifting\t%b\tis\t%b", $time, IN, OUT);
5: $monitor("Time=%0t\tAfter arithmetic
right shifting\t%b\tis\t%b", $time, IN, OUT);
default: $monitor("Time=%0t\tIncorrect
Operator", $time);
endcase
end
end
initial begin
#496
IN = 4'b1010;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
end

endmodule

Simulation output:

Result:
Thus, a 4-bit combinational shifter is simulated using data-flow model in Verilog, for
which a testbench is framed and the output is verified successfully.

Question 3 iii):
Simulate 4-bit combinational shifter using Verilog. Implement this in behavioural
model.
Aim:
To simulate a 4-bit combinational shifter using behavioral model in Verilog.

Algorithm:
i) Source.v
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input and OP as a 3-bit bus input.
Step 3: Initialize OUT as a 4-bit bus output and OF as an output pin. Also
declare OF as a reg.

Step 4: Initialize chk as a reg.


Step 5: Start the always structure which depends on OP[2:1].
Step 6: Assign chk to the output of the negation of bitwise and, which has the
inputs as OP[2] and OP[1].

Step 7: End the always structure.


Step 8: Assign OUT[3] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as IN[2], output of bitwise and
with the inputs as OP[2] and IN[3], IN[2] and IN[0].
• OP[1:0]
• chk

Step 9: Assign OUT[2] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[1] and IN[3].
• OP[1:0]
• chk

Step 10: Assign OUT[1] to the output of the mux_4x1 with the input
expressions as;
• Doubly concatenated 2-bit bus, with the inputs as IN[0] and IN[2].
• OP[1:0]
• chk

Step 11: Assign OUT[0] to the output of the mux_4x1 with the input
expressions as;
• Concatenated 4-bit bus, with the inputs as 1’b0, IN[1], IN[3] and IN[1].
• OP[1:0]
• chk

Step 12: Start the always structure which depends on OP and IN[3].
Step 13: Assign OF to the output of the conditional operator with the
condition applied as OP == 3’b100 and its two expressions are;
• If true, return IN[3].
• Else, return 1’bz.

Step 14: End the always structure.


Step 15: End module.

ii) mux_4x1.v :
Step 1: Begin Source module.
Step 2: Initialize IN as a 4-bit bus input, SEL as a 2-bit bus input and E
as an input pin.
Step 3: Initialize OUT as an output pin and declare it as a reg.
Step 4: Start the always structure which depends on all the input
variables.
Step 5: Begin the switch case statement with the decision-making
expression as output of the concatenation of E and SEL, and the branches as;
❖ If the concatenation of E and SEL is 7, then assign OUT to IN[0].
❖ If the concatenation of E and SEL is 6, then assign OUT to IN[1].
❖ If the concatenation of E and SEL is 5, then assign OUT to IN[2].
❖ If the concatenation of E and SEL is 4, then assign OUT to IN[3].
❖ Else, assign OUT to 1’bz.

Step 6: End the switch case.


Step 7: End the always structure.
Step 8: End module.

Program:
i. Source.v
`timescale 1ns / 1ps

module Source(
input [3:0] IN,
input [2:0] OP,
output [3:0] OUT,
output reg OF
);
/* OP Meanings
0 Logical shift left
1 Logical shift right
2 Circular shift left
3 Circular shift right
4 Arithmetic shift left
5 Arithmetic shift right
6,7 Invalid opcode */

reg chk;
always @(OP[2:1]) chk = !(OP[2] & OP[1]);
mux_4x1 m1({IN[2], OP[2] & IN[3], IN[2], IN[0]},
OP[1:0], chk, OUT[3]);
mux_4x1 m2({2{IN[1], IN[3]}}, OP[1:0], chk,
OUT[2]);
mux_4x1 m3({2{IN[0], IN[2]}}, OP[1:0], chk,
OUT[1]);
mux_4x1 m4({1'b0, IN[1], IN[3], IN[1]}, OP[1:0],
chk, OUT[0]);
always @(OP, IN[3]) OF = (OP==3'b100) ? IN[3] :
1'bz;

endmodule

ii. mux_4x1.v
`timescale 1ns / 1ps

module mux_4x1(
input [3:0] IN,
input [1:0] SEL,
input E,
output reg OUT
);

always @ (*) begin


case ({E, SEL})
7: OUT = IN[0];
6: OUT = IN[1];
5: OUT = IN[2];
4: OUT = IN[3];
default: OUT = 1'bz;
endcase
end

endmodule
Testbench code:
`timescale 1ns / 1ps

module TB;
reg [3:0] IN;
reg [2:0] OP;
wire [3:0] OUT;
wire OF;
Source uut (
.IN(IN),
.OP(OP),
.OUT(OUT),
.OF(OF)
);
initial begin
IN = 4'b0110;
OP = 3'b000;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
forever #62 begin
OP = OP + 3'b001;
case(OP)
0: $monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
1: $monitor("Time=%0t\tAfter logical right
shifting\t%b\tis\t%b", $time, IN, OUT);
2: $monitor("Time=%0t\tAfter circular left
shifting\t%b\tis\t%b", $time, IN, OUT);
3: $monitor("Time=%0t\tAfter circular
right shifting\t%b\tis\t%b", $time, IN, OUT);
4: $monitor("Time=%0t\tAfter arithmetic
left shifting\t%b\tis\t%b", $time, IN, OUT);
5: $monitor("Time=%0t\tAfter arithmetic
right shifting\t%b\tis\t%b", $time, IN, OUT);
default: $monitor("Time=%0t\tIncorrect
Operator", $time);
endcase
end
end
initial begin
#496
IN = 4'b1010;
$monitor("Time=%0t\tAfter logical left
shifting\t%b\tis\t%b", $time, IN, OUT);
end
endmodule
Simulation output:

Result:
Thus, a 4-bit combinational shifter is simulated using behavioral model in Verilog, for
which a testbench is framed and the output is verified successfully.

You might also like