51 / 63 · Concept
The ALU and zero, negative, carry and overflow flags
Build ADD/SUB with a shared adder, separate carry from signed overflow, and derive comparison conditions.
Lessons are free to read. Enroll to save your learning progress.
Prerequisites: two's complementTwo's complement A representation of signed integers using fixed-width bit patterns. The n-bit range is −2^(n−1) through 2^(n−1)−1. Learn more, adders, combinational MUXesMultiplexer A combinational circuit that connects one of several inputs to the output according to a select signal. Specify how select bits map to input numbers. Learn more and bit-width extension.
An ALU produces both a result and status
An ALU selects the result of an operation and emits status bits needed to interpret it. In this design, inputs and result are bits, supporting ADD, SUB, AND, OR and XOR. Arithmetic results are always truncated to their low bits. The same pattern can be read as unsignedUnsigned A rule for interpreting a bit pattern as a nonnegative integer. The n-bit range is 0 through 2^n−1 and may differ from the signed interpretation of the same bits. Learn more or two's-complement signed, so carry and overflow are separate outputs. Different signed interpretations do not require two adders.
The flags are and . Z is a reduction NOR of the entire selected result; N is its most significant bit. N=1 means the stored pattern is negative under signed interpretation. After overflow, that sign may differ from the true infinite-precision result.
Separate carry from overflow
For addition, C is the highest bit of extended sum .
V is 1 when both input signs match but the result sign differs. With denoting their most significant bits,
In eight bits, gives R=0, C=1, V=0: signed is in range. Conversely, gives R=0x80, C=0, V=1. Unsigned 128 fits, but it exceeds signed maximum 127. Combining C and V loses this distinction.
For subtraction, invertInversion The NOT operation, which changes 0 to 1 and 1 to 0. A bar over an expression applies NOT to the entire expression beneath it. Learn more only the W-bit B, then extend it with a leading 0: . Inverting all W+1 bits changes the meaning of the final carry. This lesson defines C=1 as no borrow, so unsigned is .
Signed subtraction can overflow only when the operand signs differ. A compare operation can use SUB flags without storing R. Signed is ; signed is . For example, is stored as +127, but V=1 corrects the error that using N alone would make.
The eight-bit ADD example below has a representable unsigned result but an out-of-range signed result. Notice that the same sum can give C=0 and V=1.
- A=7F · B=01: signed 127 + 1
- Nine-bit sum T: 0_10000000
- Eight-bit result R: 80 → signed −128
- Status flags: Z=0 · N=1 · C=0 · V=1
A shared adder and explicit output rules
The RTL below assumes W≥2. Opcodes 0–4 select ADD, SUB, AND, OR and XOR. Logical operations set C,V to 0. Unused opcodes set R=0, hence Z=1, with all other flags 0. These are this ALU's interface rules, not an imitation of a particular CPU instruction set.
module alu #(parameter int W = 8) (
input logic [W-1:0] a, b,
input logic [2:0] op,
output logic [W-1:0] y,
output logic z, n, c, v
);
logic sub;
logic [W-1:0] bx;
logic [W:0] sum;
always_comb begin
sub = (op == 3'd1);
bx = b ^ {W{sub}};
sum = {1'b0, a} + {1'b0, bx}
+ {{W{1'b0}}, sub};
y = '0;
c = 1'b0;
v = 1'b0;
case (op)
3'd0, 3'd1: begin
y = sum[W-1:0];
c = sum[W];
if (sub)
v = (a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
else
v = ~(a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
end
3'd2: y = a & b;
3'd3: y = a | b;
3'd4: y = a ^ b;
default: y = '0;
endcase
z = ~(|y);
n = y[W-1];
end
endmoduleConditional inversion of B and an initial carry express ADD/SUB with one adder structure. Computing Z and N after the selected branch has determined y gives consistent status for logical operations too. Defaults define every output path and prevent latchesLatch A storage element that follows its input while its control is active and holds its value while inactive. It differs from a flip-flop, which captures only at an edge. Learn more. There are no registersRegister A circuit that stores multiple bits of state. The synchronous registers in this course store their specified inputs at a clock edge. Learn more here, hence no clock-cycle computation latency, but physical propagation delay remains. The operation-selection MUX and zero detector must also settle within the next register's setup budget.
Pair 0, the unsigned maximum, signed extrema and values on either side of boundaries in verification. Check R against a modulo reference, C against an extended unsigned sum, and V against signed range overflow independently. Correct R does not guarantee correct flags.
For a real example separating negative, zero, unsigned carry and signed overflow flags, see Arm's explanation of condition flags.
Try it yourself
For an eight-bit ALU, find R,Z,N,C,V for (1) 0x7F+0x01, (2) 0xFF+0x01, (3) 0x00−0x01 and (4) 0x80−0x01. Explain why N alone gives an incorrect signed comparison in (4).
Read the explanation
In (R,Z,N,C,V) order: (1) (0x80,0,1,0,1), (2) (0x00,1,0,1,0), (3) (0xFF,0,1,0,0), (4) (0x7F,0,0,1,1). In (3), unsigned subtraction borrows, so C=0, while signed −1 is representable. In (4), unsigned 128−1=127 needs no borrow, so C=1. Signed −128−1=−129 is out of range, so V=1; the stored result's N=0 does not reflect the true difference's sign. Signed A<B uses N xor V=1 and correctly returns true.