An on-chip register bus carries 32-bit words between blocks. Errors are extremely rare, but when one happens, the team wants to know rather than silently write a wrong value into a control register. A full error-correcting code would add seven or eight bits and a decoder to every port. One extra wire per bus, and one XOR tree at each end, catches most of what can realistically go wrong.
What is the cheapest possible error detection, and what does it miss?
The obvious check is to send the data twice and compare. It catches everything except identical errors in both copies, and it doubles the wires. Most of that redundancy is wasted: to know that something changed, you need far less information than a full copy.
Even parity adds one bit chosen so the total number of 1s, data plus parity, is even. The receiver counts again (an XOR of all bits): if the result is odd, something changed. One flipped bit changes the count by one, so it is always detected. Two flipped bits change it by two (or zero), so the count is even again and the error is missed. In general, parity detects every odd number of flipped bits and misses every even number.
Flipped bits | Detected by parity? |
|---|---|
1 | Yes |
2 | No |
3 | Yes |
Any even number | No |
The sender computes parity over 8 data bits; the channel flips one, two or three bits in different cycles; the receiver recomputes parity and flags a mismatch. The checker confirms parity's rule exactly.
// Even parity on an 8-bit bus. The sender adds a parity bit so that the nine bits
// hold an even number of 1s; the receiver recomputes it and flags a mismatch. The
// channel flips bits in some cycles: one bit (detected), two bits (missed), and
// none. The checker confirms parity catches every odd number of flips and misses
// every even number.
module tb;
logic clk = 0;
always #5 clk = ~clk;
initial begin $dumpfile("wave.vcd"); $dumpvars(0, tb); end
int cyc = 0;
always @(posedge clk) cyc <= cyc + 1;
logic [7:0] data;
logic [7:0] flip; // which bits the channel flips
always_comb begin
data = 8'h00; flip = 8'h00;
case (cyc)
1: begin data = 8'hA5; flip = 8'h00; end // clean
2: begin data = 8'hA5; flip = 8'h01; end // one bit flipped
3: begin data = 8'h3D; flip = 8'h00; end // clean (five 1s: parity bit 1)
4: begin data = 8'h3D; flip = 8'h81; end // two bits flipped
5: begin data = 8'hFF; flip = 8'h07; end // three bits flipped
default: ;
endcase
end
wire par = ^data; // sender: even parity over the data
wire [7:0] rx = data ^ flip; // what arrives
wire err = (^rx) ^ par; // receiver: recompute and compare
int errors = 0;
always @(posedge clk) if (cyc >= 1 && cyc <= 5) begin
if (err != ($countones(flip) % 2 == 1)) errors++;
end
initial begin
#80;
if (errors == 0) $display("PASS: parity flagged the 1-bit and 3-bit errors and missed the 2-bit error, as expected");
else $display("FAIL: %0d mismatches", errors);
$finish;
end
endmoduleBoth ends are a single XOR reduction (^data): parity's whole hardware cost is one wire and two small XOR trees.
How to read it, slot by slot:
Slot 0: data 0xA5 (four 1s), parity 0, no flips: no error.
Slot 1: the channel flips bit 0 (flip 1). The receiver's count is now odd: err is 1.
Slots 2 and 3: data 0x3D has five 1s, so the parity bit is 1. In slot 3 the channel flips two bits (flip 0x81): the count is even again and err stays 0. The error is missed.
Slot 4: three bits flipped (flip 0x07) in 0xFF: an odd number, detected.
Use | Why parity fits |
|---|---|
On-chip buses and register paths | Errors are rare and almost always single bits; detection is enough to raise an alarm |
Cache tags and small memories, together with refetch | A parity error on clean data can be fixed by reading it again from memory |
Control signals of an interface (lesson 10.17) | Cheap protection for a few critical wires |
Serial lines such as UART (optional) | One bit per character, at low speed |
Parity is not enough where bursts are common (fast serial links, where a CRC is used), where errors must be corrected rather than just detected (memories holding the only copy, where ECC is used), or where missing a double error is unacceptable.
A design (illustrative) used one parity bit over a 64-bit bus whose wires ran side by side for several millimetres. Crosstalk occasionally flipped two neighbouring bits together, which parity cannot see. Splitting the bus into eight byte-wide parity groups, so neighbouring wires belong to different groups, made those double errors visible.
Four 1s, already even: the parity bit is 0.
Neighbouring wires that fail together then belong to different groups, so each group sees a single flip, which parity detects.
Parity adds one bit so the count of 1s is even; the receiver XORs everything to check.
It detects any odd number of flipped bits, misses any even number, and cannot correct.
Use it for rare single-bit errors on chip; use CRCs for bursts and ECC for data that must be corrected.