# 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 ``` ![CO LAb10](https://hackmd.io/_uploads/BkRNLox7A.jpg)