---
# System prepended metadata

title: Lab 10 and Lab 11

---

# 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)
