Topic 21 · Digital Electronics

ALU Design
Arithmetic Logic Unit

The computational heart of every processor — design an 8-operation ALU with status flags from the ground up, with interactive simulator and complete Verilog.

ADD / SUBAND / OR / XORShifts Zero / Carry / Overflow / NegativeVerilog

ALU Operations & Opcode Table

Op[2:0]OperationResultFlags updated
000ADDA + BZ, C, V, N
001SUBA − B = A + ~B + 1Z, C, V, N
010ANDA & BZ, N
011ORA | BZ, N
100XORA ^ BZ, N
101NOT~AZ, N
110SHL (shift left)A << 1Z, C, N
111SHR (shift right)A >> 1Z, N

Status Flags

FlagNameCondition
ZZeroresult == 0 (reduction NOR of all bits)
CCarryCarry out of MSB (unsigned overflow)
VOverflowSigned overflow: carry_in ⊕ carry_out at MSB
NNegativeresult[MSB] = 1 (negative in 2's complement)

Interactive 8-bit ALU Simulator

A (decimal)
B (decimal)
Operation
Zero (Z)
Carry (C)
Overflow (V)
Negative (N)

ALU Architecture — SUB via Adder

Subtraction without a subtractor: A − B = A + NOT(B) + 1. The ALU XORs all B bits with the Sub control signal: when Sub=1, B bits are inverted and Cin is set to 1. The same adder hardware handles both ADD and SUB — this is the fundamental insight behind 2's complement.
Sub signalB input to adderCinResult
0B (unchanged)0A + B
1~B (inverted)1A + ~B + 1 = A − B

Verilog — Parameterized 8-operation ALU

module alu #(parameter N = 8) (
  input  logic [N-1:0] a, b,
  input  logic [2:0]   op,
  output logic [N-1:0] result,
  output logic         zero, carry, overflow, negative
);
  logic [N:0] tmp;  // N+1 bits for carry detection

  always_comb begin
    tmp = '0;
    case (op)
      3'b000: tmp = {1'b0, a} + {1'b0, b};        // ADD
      3'b001: tmp = {1'b0, a} + {1'b0, ~b} + 1;  // SUB
      3'b010: tmp = {1'b0, a  &  b};               // AND
      3'b011: tmp = {1'b0, a  |  b};               // OR
      3'b100: tmp = {1'b0, a  ^  b};               // XOR
      3'b101: tmp = {1'b0, ~a};                    // NOT
      3'b110: tmp = {a[N-1], a[N-2:0], 1'b0};    // SHL
      3'b111: tmp = {1'b0, 1'b0, a[N-1:1]};      // SHR
    endcase
  end

  assign result   = tmp[N-1:0];
  assign carry    = tmp[N];
  assign zero     = ~|result;           // reduction NOR
  assign negative = result[N-1];       // MSB
  // Overflow: signed overflow for ADD/SUB
  assign overflow = (op[1:0] == 2'b00) ?
    (a[N-1] == b[N-1] && result[N-1] != a[N-1]) : 1'b0;
endmodule

Frequently Asked Questions

What is an ALU?

The Arithmetic Logic Unit performs all arithmetic (ADD/SUB) and logic (AND/OR/XOR/NOT) operations in a CPU. It takes two operands and an op-select code, producing a result and status flags.

How does an ALU subtract without a separate subtractor?

A−B = A + NOT(B) + 1 (2's complement negation). XOR gates invert B bits when Sub=1, and Cin=1 is added. Same adder handles both ADD and SUB.

What are ALU status flags?

Z=result is zero, C=carry out (unsigned overflow), V=signed overflow (carry_in XOR carry_out at MSB), N=result MSB is 1 (negative in 2's complement).