---
# System prepended metadata

title: Lab 10

---

# Lab 10
Name:Aditya Raghuveer
Roll No.:CS22B019 

---
## Question 1
```verilog=
**Main Code** 
module ALU (
  input [31:0] A,
  input [31:0] B,
  input [2:0] ALUControl,
  output reg [31:0] Result,
  output reg Zero
);

  wire [31:0] AddResult, SubResult, AndResult, OrResult, XorResult, BorrowOut, CarryOut;
  wire [31:0] ShiftedResult;
  wire [4:0] ShiftAmt;  // Increased width for larger shifts (optional)
  output reg LessThan, LessThanU;

  // Instantiate Full Adders for addition 
  genvar i;
  generate
    for (i = 0; i < 32; i = i + 1) begin
      full_adder adder_i (
        .A(A[i]),
        .B(B[i]),
        .Cin((i > 0) ? CarryOut[i-1] : ALUControl[0]),
        .Sum(AddResult[i]),
        .Cout(CarryOut[i])
      );
    end
  endgenerate

  // Instantiate Full Subtractors
  genvar j;
  generate
    for (j = 0; j < 32; j = j + 1) begin
      full_subtractor subtractor_j (
        .A(A[j]),
        .B(B[j]),
        .Bin((j == 0) ? ALUControl[1] : BorrowOut[j-1]), 
        .Difference(SubResult[j]),
        .BorrowOut(BorrowOut[j])  
      );
    end
  endgenerate

  assign AndResult = A & B;
  assign OrResult = A | B;
  assign XorResult = A ^ B;

  // Extract lower 5 bits for shift amount (adjust if needed)
  assign ShiftAmt = B[4:0];

  // Select output based on ALUControl
 always @(*) begin
    case (ALUControl)
      3'b000: Result = AddResult;  // Addition
      3'b001: Result = SubResult;  // Subtraction
      3'b010: Result = AndResult;  // Bitwise AND
      3'b011: Result = OrResult;    // Bitwise OR
      3'b100: Result = XorResult;   // Bitwise XOR
      3'b101: Result = A << ShiftAmt; // Shift Left Logical (sll)
      3'b110: Result = A >> ShiftAmt; // Shift Right Logical (srl)
      3'b111: begin                 // Set Less Than (slt, sltu)
        LessThan = A < B;
        LessThanU = $unsigned(A) < $unsigned(B);
        Result = (ALUControl[2]) ? LessThanU : LessThan;
      end
      default: Result = 32'bx; // Unknown for unused opcodes
    endcase

    Zero = (Result == 0);
  end
endmodule

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

  assign Sum = (A ^ B) ^ Cin;
  assign Cout = (A & B) | (A ^ B) & Cin;
endmodule

module full_subtractor (
  input A,
  input B,
  input Bin,
  output reg Difference,
  output reg BorrowOut
);

  // Implement the full subtraction logic using expressions
  always @(*) begin
    Difference = A ^ B ^ Bin;
    BorrowOut = (~A & B) | (~(A ^ B) & Bin);
  end
endmodule

**Testbench Code**

module ALU_tb;

  reg [31:0] A, B;
  reg [2:0] ALUControl;
  wire [31:0] Result;
  wire Zero, LessThan, LessThanU;

  // Instantiate the ALU
  ALU alu (A, B, ALUControl, Result, Zero, LessThan, LessThanU);

  initial begin
    // Test cases for various ALU operations
    $display("Testing ALU operations:");

    // Addition
    A = 32'd5;
    B = 32'd7;
    ALUControl = 3'b000;
    #10;  // Wait for simulation time
    $display("A + B = %d (Expected: 12)", Result);

    // Subtraction
    A = 32'd15;
    B = 32'd8;
    ALUControl = 3'b001;
    #10;
    $display("A - B = %d (Expected: 7)", Result);

    // Bitwise AND
    A = 32'hFFFFAA55;
    B = 32'hAAAA55FF;
    ALUControl = 3'b010;
    #10;
    $display("A & B = %h (Expected: AAAA00AA)", Result);

    // Bitwise OR
    A = 32'hFFFFAA55;
    B = 32'hAAAA55FF;
    ALUControl = 3'b011;
    #10;
    $display("A | B = %h (Expected: FFFFFFFF)", Result);

    // Bitwise XOR
    A = 32'hFFFFAA55;
    B = 32'hAAAA55FF;
    ALUControl = 3'b100;
    #10;
    $display("A ^ B = %h (Expected: 5555FFFF)", Result);

    // Shift Left Logical (sll)
    A = 32'h12345678;
    B = 32'd2;  // Shift amount (2 bits)
    ALUControl = 3'b101;
    #10;
    $display("A << %d = %h (Expected: 48C913F0)", B, Result);

    // Shift Right Logical (srl)
    A = 32'hF0F0F0F0;
    B = 32'd4;  // Shift amount (4 bits)
    ALUControl = 3'b110;
    #10;
    $display("A >> %d = %h (Expected: 0F0F0F0F)", B, Result);

    // Set Less Than (slt)
    A = 32'd10;
    B = 32'd20;
    ALUControl = 3'b111;
    #10;
    $display("A < B = %d (Expected: 1)", LessThan);

    // Set Less Than Unsigned (sltu)
    A = 32'hFFFFFFFF;
    B = 32'd0;
    ALUControl = 3'b111;
    #10;
    $display("A <u B = %d (Expected: 0)", LessThanU);

    // Test for unknown opcode
    ALUControl = 3'bXXX;
    #10;
    $display("Unknown opcode: Result = %h (Expected: Unknown)", Result);

    $finish;
  end

endmodule 


```
---