🔢 ALU Design
The Arithmetic Logic Unit is the computational heart of the CPU. Explore how ALUs perform arithmetic and logic operations, how control signals select operations, and how 32-bit ALUs are constructed.
What is an ALU?
Core Definition
Arithmetic
Addition, subtraction, multiplication (via iterative add/shift), increment, decrement
Logic
AND, OR, XOR, NOR, NAND, NOT — bitwise operations on operands
Comparison
Set on less than (SLT), equality check, zero detection for branch decisions
ALU Block Diagram
Single-Bit ALU Core
Input A (32-bit)
A[31:0]
Input B (32-bit)
B[31:0]
ALU
Operation Select: 0000
ALU Control Signals
ALU Operations Table
| Operation | Opcode | Function | Description |
|---|---|---|---|
| ADD | 0000 | R[rd] = R[rs] + R[rt] | Arithmetic addition of two registers |
| SUB | 0001 | R[rd] = R[rs] - R[rt] | Arithmetic subtraction |
| AND | 0010 | R[rd] = R[rs] & R[rt] | Bitwise AND |
| OR | 0011 | R[rd] = R[rs] | R[rt] | Bitwise OR |
| XOR | 0100 | R[rd] = R[rs] ^ R[rt] | Bitwise XOR |
| NOR | 0101 | R[rd] = ~(R[rs] | R[rt]) | Bitwise NOR |
| SLT | 0110 | R[rd] = (R[rs] < R[rt]) ? 1 : 0 | Set on less than (signed comparison) |
| SLL | 0111 | R[rd] = R[rt] << shamt | Logical left shift |
Interactive ALU Simulator
Try It Yourself
A
10
B
3
Result
13
32-bit ALU Design Concept
Ripple-Carry Architecture
Key Design Components
- • Full Adders — One per bit position
- • MUX-based operation select — Chooses between ADD, AND, OR, etc.
- • Carry chain — Propagates carry from bit 0 through bit 31
- • Zero detection — NOR gate across all result bits
- • Overflow detection — XOR of carry-in and carry-out of MSB
Performance Optimizations
- • Carry Look-Ahead (CLA) — Computes carries in parallel
- • Carry Save Adder (CSA) — For multi-operand addition
- • Conditional Sum — Pre-computes with carry=0 and carry=1
- • Pipeline stages — For high-frequency ALU operations
Control Signals Reference
| Signal | Width | Purpose |
|---|---|---|
| RegDst | 1 bit | Selects destination register (rt vs rd) |
| ALUSrc | 1 bit | Selects second ALU operand (register vs immediate) |
| MemtoReg | 1 bit | Selects data written back (ALU result vs memory) |
| RegWrite | 1 bit | Enables register file write |
| MemRead | 1 bit | Enables memory read |
| MemWrite | 1 bit | Enables memory write |
| Branch | 1 bit | Indicates branch instruction |
| ALUOp | 2 bit | Encodes ALU operation type |
ALU in Verilog
Hardware Description
verilog
module alu_32bit (
input logic [31:0] a, b,
input logic [2:0] alu_op,
output logic [31:0] result,
output logic zero,
output logic overflow
);
always_comb begin
case (alu_op)
3'b000: result = a + b; // ADD
3'b001: result = a - b; // SUB
3'b010: result = a & b; // AND
3'b011: result = a | b; // OR
3'b100: result = a ^ b; // XOR
3'b101: result = ~(a | b); // NOR
3'b110: result = ($signed(a) < $signed(b)) ? 32'b1 : 32'b0; // SLT
3'b111: result = b << 1; // SLL
endcase
end
assign zero = (result == 32'b0);
assign overflow = (a[31] == b[31]) && (result[31] != a[31]);
endmoduleInterview Questions
Explain how a 1-bit ALU is constructed and how it scales to 32 bits.
A 1-bit ALU contains a full adder for arithmetic (sum = A XOR B XOR Cin, Cout = (A&B)|(B&Cin)|(A&Cin)), a logic unit for bitwise operations, and a MUX to select the output. For 32 bits, 32 such units are cascaded with carry ripple from bit 0 to bit 31. Each unit receives the same operation select lines. The Zero flag is computed via a 32-input NOR gate on the result.
What are the key control signals for an ALU and how do they relate to the instruction format?
ALUOp (2-3 bits) encodes the operation class (R-type, branch, memory). In R-type instructions, the funct field selects the specific ALU operation. ALUSrc chooses between register and immediate operand. RegDst selects the destination register. The control unit decodes the opcode and funct fields to generate these signals.
How does the ALU detect overflow, and why is it important?
Overflow occurs when the result of an arithmetic operation exceeds the representable range. For signed addition, overflow = (A[MSB] == B[MSB]) AND (Result[MSB] != A[MSB]) — meaning the sign is wrong. For subtraction, overflow = (A[MSB] != B[MSB]) AND (Result[MSB] == B[MSB]). Overflow detection is critical for correct arithmetic in two's complement representation.
Compare ripple-carry, carry-lookahead, and carry-save adder designs.
Ripple-carry is simplest but slowest: carry propagates through all 32 stages (O(n) delay). Carry-lookahead computes generate (G = A&B) and propagate (P = A XOR B) signals to compute carries in parallel (O(log n) delay). Carry-save adder reduces three numbers to two (sum and carry) without propagating carry, useful for multi-operand addition in multipliers.