# Lab 10 and Lab 11
Name: Aarya
Roll No.: CS22B018
---
## 32 bit XOR
```verilog=
module NBitXOR(xor_out, a_in, b_in);
parameter n = 32;
input [n-1:0] a_in, b_in;
output [n-1:0] xor_out;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
xor(xor_out[i], a_in[i], b_in[i]);
end
endgenerate
endmodule
```
## 32 bit OR
```verilog=
module NBitOR(or_out, a_in, b_in);
parameter n = 32;
input [n-1:0] a_in, b_in;
output [n-1:0] or_out;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
or(or_out[i], a_in[i], b_in[i]);
end
endgenerate
endmodule
```
## 32 bit AND
```verilog=
module NBitAND(and_out, a_in, b_in);
parameter n = 32;
input [n-1:0] a_in, b_in;
output [n-1:0] and_out;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
and(and_out[i], a_in[i], b_in[i]);
end
endgenerate
endmodule
```
## 32 bit Subtractor
```verilog=
module HalfSubtractor(a, b, difference, borrow);
input a, b;
wire not_a;
output difference, borrow;
xor(difference, a, b);
not(not_a, a);
and(borrow, not_a, b);
endmodule
module FullSubtractor(a, b, borrow_in, difference, borrow_out);
input a, b, borrow_in;
output difference, borrow_out;
wire diff1, borrow1, borrow2;
HalfSubtractor hs1(a, b, diff1, borrow1);
HalfSubtractor hs2(diff1, borrow_in, difference, borrow2);
or(borrow_out, borrow1, borrow2);
endmodule
module NBitSubtractor(difference, minuend, subtrahend);
parameter n = 32;
input [n-1:0] minuend, subtrahend;
output [n-1:0] difference;
wire [n-1:0] borrow;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
if (i == 0) begin
HalfSubtractor hs(minuend[0], subtrahend[0], difference[0], borrow[0]);
end else begin
FullSubtractor fs(minuend[i], subtrahend[i], borrow[i-1], difference[i], borrow[i]);
end
end
endgenerate
endmodule
```
## 32 bit Adder
```verilog=
module HalfAdder(a, b, sum, carry_out);
input a, b;
output sum, carry_out;
xor(sum, a, b);
and(carry_out, a, b);
endmodule
module FullAdder(a, b, carry_in, sum, carry_out);
input a, b, carry_in;
output sum, carry_out;
wire sum1, carry1, carry2;
HalfAdder ha1(a, b, sum1, carry1);
HalfAdder ha2(sum1, carry_in, sum, carry2);
or(carry_out, carry1, carry2);
endmodule
module NBitAdder(sum, addend1, addend2);
input [31:0] addend1, addend2;
output [31:0] sum;
wire [32:0] carry;
assign carry[0] = 1'b0;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
FullAdder fa(addend1[i], addend2[i], carry[i], sum[i], carry[i + 1]);
end
endgenerate
endmodule
```
## 32 bit Comparator
```verilog=
module UnsignedComparator(less_than, operand1, operand2);
input [31:0] operand1, operand2;
output [31:0] less_than;
assign less_than = (operand1 < operand2) ? 32'b1 : 32'b0;
endmodule
module SignedComparator(less_than, operand1, operand2);
input [31:0] operand1, operand2;
output [31:0] less_than;
assign less_than = ($signed(operand1) < $signed(operand2)) ? 32'b1 : 32'b0;
endmodule
```
## Left shifter
```verilog=
module LeftShifter(shifted, operand, amount);
input [31:0] operand;
input [31:0] amount;
output [31:0] shifted;
assign shifted = operand << amount;
endmodule
```
## Right shifter
```verilog=
module RightShifter(shifted, operand, amount);
input [31:0] operand;
input [31:0] amount;
output [31:0] shifted;
assign shifted = operand >> amount;
endmodule
```
## Right Arithmetic shifter
```verilog=
module RightArithmeticShifter(shifted, operand, amount);
input [31:0] operand;
input [31:0] amount;
output [31:0] shifted;
assign shifted = operand >>> amount;
endmodule
```
## 2 to 1 MUX
```verilog=
module MuxT(a, b, sel, s);
input a, b;
input sel;
output s;
wire w11, w12, w13;
not(w11, sel);
and(w12, w11, a);
and(w13, sel, b);
or(s, w12, w13);
endmodule
```
## 4 to 1 MUX
```verilog=
module MuxF(a, a1, a2, a3, sel, s);
input a, a1, a2, a3;
input [1:0] sel;
output s;
wire w1, w2, w3;
MuxT m11(a, a1, sel[0], w1);
MuxT m12(a2, a3, sel[0], w2);
MuxT m2(w1, w2, sel[1], w3);
assign s = w3;
endmodule
```
## 8 to 1 MUX
```verilog=
module MuxE(a, a1, a2, a3, a4, a5, a6, a7, sel, s);
input a, a1, a2, a3, a4, a5, a6, a7;
input [2:0] sel;
output s;
wire w1, w2, w3;
MuxF m111(a, a1, a2, a3, sel[1:0], w1);
MuxF m112(a4, a5, a6, a7, sel[1:0], w2);
MuxT m21(w1, w2, sel[2], w3);
assign s = w3;
endmodule
```
## 16 to 1 MUX
```verilog=
module MuxSI(s, sel, a, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
input a, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
input [3:0] sel;
output s;
wire w1, w2, w3;
MuxE m1111(a, a1, a2, a3, a4, a5, a6, a7, sel[2:0], w1);
MuxE m1121(a8, a9, a10, a11, a12, a13, a14, a15, sel[2:0], w2);
MuxT m211(w1, w2, sel[3], w3);
assign s = w3;
endmodule
```
## ALU
```verilog=
module ArithmeticLogicUnit(a, b, result, operation);
parameter n = 32;
input [n-1:0] a, b;
output [n-1:0] result;
input [3:0] operation;
wire [n-1:0] temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
NBitAdder adder_result(temp1, a, b);
NBitSubtractor subtractor_result(temp2, a, b);
NBitXOR xor_result(temp3, a, b);
NBitOR or_result(temp4, a, b);
NBitAND and_result(temp5, a, b);
LeftShifter left_shifted(temp6, a, b);
RightShifter right_shifted(temp7, a, b);
RightArithmeticShifter right_arith_shifted(temp8, a, b);
UnsignedComparator unsigned_comp(temp9, a, b);
SignedComparator signed_comp(temp10, a, b);
NBitAdder adder_result2(temp11, a, b);
NBitAdder adder_result3(temp12, a, b);
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin
MuxSI mux_result(result[i], operation, temp1[i], temp2[i], temp3[i], temp4[i], temp5[i], temp6[i], temp7[i], temp8[i], temp9[i], temp10[i], temp11[i], temp12[i], temp13[i], temp14[i], temp15[i], temp16[i]);
end
endgenerate
endmodule
```
## Data Memeory File
```verilog=
module DataMemory(writeEnable, readEnable, address, writeData, readData, clk);
reg [31:0] memory[255:0];
input [31:0] address;
input [31:0] writeData;
input writeEnable, readEnable;
output reg [31:0] readData;
input clk;
always @(posedge clk) begin
if (writeEnable) begin
memory[address] = writeData;
end
if (readEnable) begin
readData = memory[address];
end
end
endmodule
```
## Instruction Memory File
```verilog=
module InstructionMemory(writeEnable, address, writeData, readData, clk);
reg [31:0] memory[255:0];
input [31:0] address;
input [31:0] writeData;
input writeEnable;
output reg [31:0] readData;
input clk;
initial
begin
memory[0] = 32'b00000000000100010000000110000001;
memory[1] = 32'b00000000000100010000001000000010;
end
always @(posedge clk) begin
if (writeEnable) begin
memory[address] = writeData;
end
readData = memory[address];
end
endmodule
```
## Register File
```verilog=
module RegisterFile(readEnable, rs1_index, rs2_index, rd_index, writeEnable, writeData, rsval1, rsval2, clk, opcode, immed);
reg [31:0] registers[31:0];
input [4:0] rs1_index, rs2_index, rd_index;
input [31:0] writeData;
input writeEnable, readEnable;
output reg [31:0] rsval1, rsval2;
input [3:0] opcode;
input [31:0] immed;
input clk;
initial
begin
registers[1]=32'b1;
registers[2]=32'b10;
end
always @(posedge clk) begin
if (writeEnable) begin
registers[rd_index] = writeData;
end
if (readEnable) begin
rsval1 = registers[rs1_index];
if (opcode == 10) begin
rsval2 = immed;
end else if (opcode == 11) begin
rsval2 = immed;
end else begin
rsval2 = registers[rs2_index];
end
end
end
endmodule
```
## Decoder
```verilog=
module InstructionDecoder(instruction, rs1_index, rs2_index, opcode, rd_index, immed, clk);
input [31:0] instruction;
output reg [4:0] rs1_index, rs2_index, rd_index;
output reg [3:0] opcode;
output reg [31:0] immed;
input clk;
always @(posedge clk) begin
opcode = instruction[3:0];
if (opcode == 10) begin
immed = {20'b00000000000000000000, instruction[31:20]};
rs1_index = instruction[19:15];
rd_index = instruction[11:7];
end else if (opcode == 11) begin
rs1_index = instruction[19:15];
immed = {20'b00000000000000000000, instruction[31:25], instruction[11:7]};
rs2_index = instruction[24:20];
end else begin
rs1_index = instruction[19:15];
rs2_index = instruction[24:20];
rd_index = instruction[11:7];
end
end
endmodule
```
## Processor
```verilog=
module CPU(clk);
input clk;
reg [31:0] pc;
wire [31:0] instruction;
reg write_enable1, write_enable2, write_enable3, write_enable4, read_enable, read_enable1, read_enable2;
reg [31:0] write_data;
wire [4:0] rs1_index, rs2_index, rd_index;
wire [31:0] immed_value;
wire [3:0] operation_code;
wire [31:0] alu_output;
wire [31:0] val1, val2, read_mem_data, write_mem_data;
InstructionMemory instruction_mem(write_enable1, pc, write_data, instruction, clk);
InstructionDecoder instruction_decoder(instruction, rs1_index, rs2_index, operation_code, rd_index, immed_value, clk);
RegisterFile reg_file(read_enable2, rs1_index, rs2_index, rd_index, write_enable2, read_mem_data, val1, val2, clk, operation_code, immed_value);
ArithmeticLogicUnit alu_unit(val1, val2, alu_output, operation_code);
DataMemory data_mem(write_enable3, read_enable, alu_output, read_mem_data, write_mem_data, clk);
RegisterFile reg_file2(read_enable1, rs1_index, rs2_index, rd_index, write_enable4, read_mem_data, val1, val2, clk, operation_code, immed_value);
initial begin
pc = 32'b0;
end
always @(posedge clk) begin
pc = pc + 1;
write_enable1 = 1'b0;
write_enable2 = 1'b0;
read_enable2 = 1'b1;
if (operation_code == 10) begin
read_enable = 1'b1;
write_enable3 = 1'b0;
write_enable4 = 1'b1;
read_enable1 = 1'b0;
end else if (operation_code == 11) begin
read_enable = 1'b0;
write_enable3 = 1'b1;
write_enable4 = 1'b0;
read_enable1 = 1'b0;
end else begin
read_enable = 1'b0;
write_enable3 = 1'b0;
write_enable4 = 1'b0;
read_enable1 = 1'b1;
end
end
endmodule
```
## Test Bench
```verilog=
module TB();
reg clk;
CPU p1(clk);
initial
begin
$dumpfile("alu.vcd");
$dumpvars(0,p1);
end
initial
begin
clk = 1'b0;
forever
begin
#5
clk = ~clk;
end
end
initial
begin
#200 $finish;
end
endmodule
```
