0% found this document useful (0 votes)
3 views12 pages

DSD Assignment 02

Uploaded by

bigghitler
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views12 pages

DSD Assignment 02

Uploaded by

bigghitler
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Digital System Design

Assignment No. : 02

Submitted to: Dr. Qurat ul Ain

Submitted by: Huzaifa Ahmad

CMS ID: 424981


Date: 17/05/2025
Problem 1:
Design, implement, and simulate a 32-bit Arithmetic Logic Unit (ALU) in Verilog HDL that
performs both arithmetic and logical operations based on a 4-bit control signal (ALU_Sel).

 Operations (controlled by ALU_Sel):


 0000: AND
 0001: OR
 0010: ADD
 0110: SUBTRACT
 0111: SET LESS THAN (SLT)
 1100: NOR
 Inputs:
 A: 32-bit input
 B: 32-bit input
 ALU_Sel: 4-bit control input
 Outputs:
 Result: 32-bit output
 Zero: 1-bit output (set to 1 if Result is all zeros)
 Requirement: Simulate using a Verilog simulator.

Code:
module alu #(
parameter WIDTH = 32 // Parameterized width, default 32 bits
) (
input [WIDTH-1:0] A, // 32-bit input A
input [WIDTH-1:0] B, // 32-bit input B
input [3:0] ALU_Sel, // 4-bit operation select
output [WIDTH-1:0] Result, // 32-bit result
output Zero, // Zero flag
output CarryOut, // Carry-out flag
output Overflow // Overflow flag
);
reg [WIDTH-1:0] Result_reg;
reg CarryOut_reg, Overflow_reg;
wire [WIDTH-1:0] Sum;
wire CarryIn;

// Compute sum for ADD and SUBTRACT


assign CarryIn = (ALU_Sel == 4'b0110) ? 1'b1 : 1'b0; // 1 for SUBTRACT
assign Sum = A + (CarryIn ? ~B : B) + CarryIn;
// ALU operation logic
always @(*) begin
case (ALU_Sel)
4'b0000: begin // AND
Result_reg = A & B;
CarryOut_reg = 1'b0; Overflow_reg = 1'b0;
end
4'b0001: begin // OR
Result_reg = A | B;
CarryOut_reg = 1'b0;
Overflow_reg = 1'b0;
end
4'b0010: begin // ADD
Result_reg = Sum;
CarryOut_reg = (A[WIDTH-1] & B[WIDTH-1]) |
(A[WIDTH-1] & ~Sum[WIDTH-1]) |
(B[WIDTH-1] & ~Sum[WIDTH-1]);
Overflow_reg = (A[WIDTH-1] == B[WIDTH-1]) &&
(A[WIDTH-1] != Sum[WIDTH-1]);
end
4'b0110: begin // SUBTRACT
Result_reg = Sum;
CarryOut_reg = (~A[WIDTH-1] & B[WIDTH-1]) |
(~A[WIDTH-1] & Sum[WIDTH-1]) |
(B[WIDTH-1] & Sum[WIDTH-1]);
Overflow_reg = (A[WIDTH-1] != B[WIDTH-1]) &&
(A[WIDTH-1] != Sum[WIDTH-1]);
end
4'b0111: begin // SLT (Set Less Than)
Result_reg = (A[WIDTH-1] == B[WIDTH-1]) ?
(A < B ? 1 : 0) :
(A[WIDTH-1] ? 1 : 0);
CarryOut_reg = 1'b0;
Overflow_reg = 1'b0;
end
4'b1100: begin // NOR
Result_reg = ~(A | B);
CarryOut_reg = 1'b0;
Overflow_reg = 1'b0;
end
default: begin
Result_reg = {WIDTH{1'b0}};
CarryOut_reg = 1'b0;
Overflow_reg = 1'b0;
end
endcase
end
// Assign outputs
assign Result = Result_reg;
assign Zero = (Result_reg == {WIDTH{1'b0}}) ? 1'b1 : 1'b0;
assign CarryOut = CarryOut_reg;
assign Overflow = Overflow_reg;
Wave Form Output:

Problem 2:

Write a Verilog testbench module that:

 Applies at least 3 different test cases for each ALU operation.


 Displays inputs, selected operation, and output using $display or $monitor.
 Verifies correct functionality by comparing expected vs. actual results

Test Bench:
module alu_tb;
// Parameters
parameter WIDTH = 32;

// Signals
reg [WIDTH-1:0] A, B;
reg [3:0] ALU_Sel;
wire [WIDTH-1:0] Result;
wire Zero, CarryOut, Overflow;
// Expected results
reg [WIDTH-1:0] Expected_Result;
reg Expected_Zero, Expected_CarryOut, Expected_Overflow;
// Instantiate ALU
alu #(WIDTH) uut (
.A(A),
.B(B),
.ALU_Sel(ALU_Sel),
.Result(Result),
.Zero(Zero),
.CarryOut(CarryOut),
.Overflow(Overflow)
);

// Operation names for display


reg [31*8:0] op_name;

// Test procedure
initial begin
$monitor("Time=%0t A=%h B=%h ALU_Sel=%b (%s) Result=%h Zero=%b
CarryOut=%b Overflow=%b Expected_Result=%h Pass=%b",
$time, A, B, ALU_Sel, op_name, Result, Zero, CarryOut,
Overflow, Expected_Result,
(Result == Expected_Result && Zero == Expected_Zero &&
CarryOut == Expected_CarryOut && Overflow ==
Expected_Overflow));
// Test cases
// AND (0000)
ALU_Sel = 4'b0000; op_name = "AND";
A = 32'hFFFF0000; B = 32'h0000FFFF; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'hAAAAAAAA; B = 32'h55555555; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'hFFFFFFFF; B = 32'hFFFFFFFF; Expected_Result =
32'hFFFFFFFF; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;

// OR (0001)
ALU_Sel = 4'b0001; op_name = "OR";
A = 32'hFFFF0000; B = 32'h0000FFFF; Expected_Result =
32'hFFFFFFFF; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'hAAAAAAAA; B = 32'h55555555; Expected_Result =
32'hFFFFFFFF; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'h00000000; B = 32'h00000000; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;

// ADD (0010)
ALU_Sel = 4'b0010; op_name = "ADD";
A = 32'h00000001; B = 32'h00000001; Expected_Result =
32'h00000002; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'h7FFFFFFF; B = 32'h00000001; Expected_Result =
32'h80000000; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 1; #10;
A = 32'hFFFFFFFF; B = 32'h00000001; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 1;
Expected_Overflow = 0; #10;
// SUBTRACT (0110)
ALU_Sel = 4'b0110; op_name = "SUBTRACT";
A = 32'h00000002; B = 32'h00000001; Expected_Result =
32'h00000001; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'h80000000; B = 32'h00000001; Expected_Result =
32'h7FFFFFFF; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 1; #10;
A = 32'h00000000; B = 32'h00000001; Expected_Result =
32'hFFFFFFFF; Expected_Zero = 0; Expected_CarryOut = 1;
Expected_Overflow = 0; #10;
// SLT (0111)
ALU_Sel = 4'b0111; op_name = "SLT";
A = 32'h00000001; B = 32'h00000002; Expected_Result =
32'h00000001; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'hFFFFFFFF; B = 32'h00000000; Expected_Result =
32'h00000001; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'h00000002; B = 32'h00000001; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;

// NOR (1100)
ALU_Sel = 4'b1100; op_name = "NOR";
A = 32'hFFFF0000; B = 32'h0000FFFF; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'hAAAAAAAA; B = 32'h55555555; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
A = 32'h00000000; B = 32'h00000000; Expected_Result =
32'hFFFFFFFF; Expected_Zero = 0; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
// Invalid ALU_Sel
ALU_Sel = 4'b1111; op_name = "INVALID";
A = 32'hAAAAAAAA; B = 32'h55555555; Expected_Result =
32'h00000000; Expected_Zero = 1; Expected_CarryOut = 0;
Expected_Overflow = 0; #10;
$finish;
end endmodule
Console Output:
Problem 3:

Choose any two of the following enhancements for the ALU:

1. Add Shift Left Logical (SLL) and Shift Right Logical (SRL) operations.
2. Add a carry-out flag and overflow flag.
3. Make the ALU parameterized for N-bit width.
4. Integrate the ALU into a simple datapath (e.g., for a MIPS-like processor).

Code:
Enhancement 1: Carry-out and Overflow Flags (Implementation)
Enhancement 2: Parameterized N-bit Width (Ref. to Waveform)

module alu #(
parameter WIDTH = 32
) (
input [WIDTH-1:0] A, B,
input [3:0] ALU_Sel,
output [WIDTH-1:0] Result,
output Zero,
output CarryOut,
output Overflow
);
reg [WIDTH-1:0] Result_reg;
reg CarryOut_reg, Overflow_reg;
wire [WIDTH-1:0] Sum;
wire CarryIn;

assign CarryIn = (ALU_Sel == 4'b0110) ? 1'b1 : 1'b0; // 1 for SUBTRACT


assign Sum = A + (CarryIn ? ~B : B) + CarryIn;

always @(*) begin


case (ALU_Sel)
4'b0010: begin // ADD
Result_reg = Sum;
CarryOut_reg = (A[WIDTH-1] & B[WIDTH-1]) |
(A[WIDTH-1] & ~Sum[WIDTH-1]) |
(B[WIDTH-1] & ~Sum[WIDTH-1]);
Overflow_reg = (A[WIDTH-1] == B[WIDTH-1]) &&
(A[WIDTH-1] != Sum[WIDTH-1]);
end
4'b0110: begin // SUBTRACT
Result_reg = Sum;
CarryOut_reg = (~A[WIDTH-1] & B[WIDTH-1]) |
(~A[WIDTH-1] & Sum[WIDTH-1]) |
(B[WIDTH-1] & Sum[WIDTH-1]);
Overflow_reg = (A[WIDTH-1] != B[WIDTH-1]) &&
(A[WIDTH-1] != Sum[WIDTH-1]);
end
default: begin // For AND, OR, SLT, NOR, etc.
CarryOut_reg = 1'b0;

Overflow_reg = 1'b0;
// ... (other operations as in full code)
end
endcase
end

assign Result = Result_reg;


assign Zero = (Result_reg == {WIDTH{1'b0}}) ? 1'b1 : 1'b0;
assign CarryOut = CarryOut_reg;
assign Overflow = Overflow_reg;
endmodule

Wave Form Snippet:

Console Output:
ADD (Time 60–90 ns):
SUBTRACT (Time 90–120 ns):

AND (0 ns, showing 32-bit operation):

Conclusion:
This project successfully achieved the design, implementation, and simulation of a 32-bit
Arithmetic Logic Unit (ALU) using Verilog HDL, fulfilling all the assignment requirements.
The ALU accurately performed six core operations based on a 4-bit control signal, with correct
output generation for the Result and Zero flags. A comprehensive testbench validated the ALU's
functionality across multiple test cases, with all results matching the expected outputs.
Additionally, enhancements such as parameterization for scalability and the inclusion of
CarryOut and Overflow flags demonstrated a deeper understanding of digital system design. The
simulation results, including waveforms and console outputs, confirmed the ALU’s reliable and
accurate performance. Overall, this project reflects a strong grasp of Verilog HDL and
fundamental digital design principles.

You might also like