Draft preview. Lessons are being written and reviewed.

Digital Design / Module 2: Combinational building blocks

10. Subtractors, comparators and an ALU

Combine blocks into a datapath.

Lecture coming soon

See it move

The idea

An ALU is a set of operations computed in parallel, with a mux choosing the result. Conceptually, every operation runs each cycle, and the opcode only picks which answer to keep. Sharing one adder between add and subtract saves area.

Subtraction

A - B = A + ~B + 1. Feed B through XOR gates controlled by a sub signal, and use the same signal as the carry in. One small addition turns the adder into an adder-subtractor.

Flags

FlagMeaningHow it is computed
ZResult is zeroNOR of all result bits
NResult is negativeTop bit of the result
CUnsigned carry outCarry out of the top bit
VSigned overflowCarry into top bit XOR carry out of it

Signed overflow, explained

Adding two positive numbers and getting a negative result can't be right, and neither can adding two negatives and getting a positive. An addition of opposite signs can never overflow. In 8 bits, 127 + 1 produces 10000000, which is fine as unsigned 128 but wrong as signed -128. So V = 1 and C = 0. Each flag answers a different question, and which one to look at depends on how you are reading the bits.

Comparators

Equality is simple: XOR the bits, then NOR the results. Less-than is simplest as a subtraction. For unsigned values, A < B when A - B has no carry out (given the A + ~B + 1 form). For signed values, A < B when N ^ V is 1.

always @(*) begin
  case (op)
    2'b00:   {c, r} = a + b;
    2'b01:   {c, r} = a + {1'b0, ~b} + 1'b1;  // see the note below
    2'b10:   begin r = a & b; c = 1'b0; end
    default: begin r = a ^ b; c = 1'b0; end
  endcase
  z = (r == 0);
end

A width trap in that code

Writing a + ~b + 1 directly would be wrong here. The 9-bit target makes Verilog extend b to 9 bits before inverting it, so the top bit becomes 1 and the carry comes out inverted. Writing {1'b0, ~b} inverts first, then extends.

Common mistake

Using the N flag alone to decide a signed less-than. If the subtraction overflowed, N has the wrong sign. That is why the correct test is N ^ V.

Key ideas

  • Subtract with A + ~B + 1.
  • Signed overflow occurs when the carries into and out of the sign bit differ.
  • Equality is a reduction NOR of a bitwise XOR.

Your exercise

Design a 4-function 8-bit ALU with zero and overflow flags.

Find the bug

This code has one deliberate bug. Read the symptom, then click the line you think is wrong.

What goes wrong: 5 - 5 gives the right result of 0, but the carry flag is 0 when it should be 1. The flag is inverted for every subtraction.

Interview questions

coreHow do you detect signed overflow?

basicCompute 20 - 13 in 8 bits as A + ~B + 1. What is the carry out?

basicHow do you produce a zero flag for an 8-bit result r in Verilog?

coreIn 8 bits, compute -100 + -100. Give the result and the C, V, N and Z flags.

coreThe 8-bit patterns A = 50 and B = 200 are compared by computing A - B. Is A less than B? Answer for unsigned and for signed.

coreThis adder-subtractor line gives r = 7 but c = 0 for 20 - 13, although the carry out should be 1. Why?

reg [7:0] a, b, r;
reg       c;
always @(*) {c, r} = a + ~b + 1'b1;

coreWhy do ALUs share one adder for addition and subtraction instead of having a separate subtractor?

advancedWith signed 8-bit A = -128 and B = 1, compute A - B and the flags. Does N XOR V correctly report A < B?

advancedWrite the signed overflow flag for an 8-bit subtraction d = a - b using only sign bits.

wire [7:0] d = a - b;
wire v = (a[7] ^ b[7]) & (d[7] ^ a[7]);

Practise these 9 questions with animations