A new serial link passes every test with random data. Then a customer streams a large file that happens to contain long stretches of zero bytes, and the link starts reporting errors in exactly those stretches. Nothing is wrong with the zeros themselves. The receiver had lost track of where the bits were.
How does a receiver find bit timing with no clock wire at gigabit rates, and why can a long run of identical bits defeat it?
Two earlier answers both fail at these rates. A forwarded strobe (lesson 1.3) needs the strobe and data wires matched to a small fraction of a bit, which becomes impossible across connectors and cables when a bit lasts tens of picoseconds. Asynchronous framing (lesson 1.2) resynchronises only once per frame and relies on the clocks matching to a few percent over ten bits. At gigabit rates you want long frames, thousands of bits, between timing references. Neither scheme can do that.
Every time the data changes from 0 to 1 or 1 to 0, the edge marks a bit boundary. A clock and data recovery (CDR) circuit watches those edges and continually adjusts the phase of its own sampling clock so its samples land in the middle of each bit. Between edges it coasts on its own clock, which differs from the transmitter's by a small frequency offset measured in parts per million (ppm). So the sampling point drifts by that offset, a fraction of a bit per bit, until the next edge pulls it back.
The figure shows the loop. The phase detector compares data edges with the recovered clock and says "early" or "late"; the loop filter smooths those votes; the oscillator or phase interpolator moves the sampling clock; the sampler uses it.
Measure timing in unit intervals (UI), one bit time each. With a frequency offset of p ppm, the sampling point moves p × 10⁻⁶ UI per bit. A sample is wrong once it has moved half a bit from the centre. So the longest run of bits with no transition the receiver can survive is about:
This is the best case. It assumes the loop snaps back to the centre at every edge and that nothing else moves the sampling point. Real loops correct gradually, and jitter and noise take their share of the half bit, so real limits are much tighter.
The model drifts an ideal receiver's sampling point by the frequency offset on every bit of a run with no transitions, and finds the longest run that stays within half a bit, for three offsets.
"""Why a serial link needs transitions.
The receiver recovers the clock from data transitions. Between transitions its
sampling point drifts by the frequency offset between the two clocks, a few parts
per million (ppm) of a bit per bit. Here an ideal recovery circuit snaps back to
the bit centre at every transition. A sample is wrong once the drift exceeds half
a bit (0.5 UI), so the longest safe run of identical bits is about 0.5 / offset.
"""
def survives(run_length, ppm):
drift_per_bit = ppm * 1e-6 # in UI (fractions of a bit)
phase = 0.0 # offset from the bit centre, in UI
for _ in range(run_length): # a run of identical bits: no transitions
phase += drift_per_bit
if phase > 0.5:
return False
return True
print("offset longest safe run of identical bits")
for ppm in (100, 300, 600):
limit = int(0.5 / (ppm * 1e-6))
assert survives(limit, ppm) and not survives(limit + 1, ppm)
print(f"{ppm:4d} ppm {limit:6d} bits")
print("an 8b/10b stream never has more than 5 identical bits in a row")
print("PASS: the safe run length is 0.5 UI divided by the offset per bit")It prints:
offset longest safe run of identical bits
100 ppm 5000 bits
300 ppm 1666 bits
600 ppm 833 bits
an 8b/10b stream never has more than 5 identical bits in a row
PASS: the safe run length is 0.5 UI divided by the offset per bitEven in this generous model, a run of a few thousand identical bits is enough to lose a 100 ppm receiver, and a file full of zero bytes contains runs far longer than that. Real receivers need transitions far more often than the model's limit, which is why serial protocols do not leave transition density to chance. 8b/10b encoding, for example, never allows more than five identical bits in a row, hundreds of times inside the limit.
A CDR turns "when is the data valid?" into a promise the protocol must keep: there will be transitions often enough. Protocols keep it in three ways, each covered in Part 2:
Method | How it guarantees transitions | Cost |
|---|---|---|
Bit stuffing (lesson 2.4) | Insert an opposite bit after a fixed number of identical bits | Variable length; worst-case overhead depends on the data |
Block codes such as 8b/10b (lesson 2.6) | Map each byte to a 10-bit code with bounded runs and balance | 20% of the line rate |
Scrambling (lesson 2.7) | XOR the data with a pseudo-random sequence so long runs become very unlikely | Almost none, but only a probabilistic guarantee; usually paired with a small header that always contains a transition |
Clocking scheme | Distance and rate | What the protocol must provide |
|---|---|---|
Common clock (1.1) | Short and slow | Nothing; the budget does the work |
Source-synchronous (1.3) | Short, wide and fast | Matched routing; a strobe per group |
Embedded clock with CDR (this lesson) | Long and fast, one lane at a time | Guaranteed transitions; clock compensation (1.7); lane deskew for multi-lane links (1.5) |
Protocol | How it keeps the receiver's clock locked |
|---|---|
PCI Express Gen1–2 | 8b/10b encoding: runs of at most five identical bits, plus DC balance. |
PCI Express Gen3–5 | 128b/130b: a 2-bit sync header on every 130-bit block (always 01 or 10, so it always contains a transition) and scrambled data. |
USB 2.0 | NRZI encoding plus bit stuffing: a 0 is inserted after six consecutive 1s, and in NRZI every 0 is a transition. |
10 Gb/s Ethernet (10GBASE-R) | 64b/66b: a 2-bit sync header (01 for data, 10 for control) on every block and scrambled payload. |
The opening failure (illustrative): the link scrambled its data, but a configuration bug disabled the scrambler in one direction. Random test data has plenty of transitions, so every test passed. Real files with long zero runs then produced runs of thousands of identical bits, the CDR drifted off the bit centres, and errors appeared exactly in those stretches.
Symptom: errors that depend on the content of the data, not its rate.
Evidence: the error positions line up with long runs of identical bits on the wire.
Root cause: the mechanism that guarantees transitions was off; the CDR had nothing to lock to.
Fix: enable scrambling, and add a test with worst-case data patterns (all zeros, all ones, long runs) to the regression. Random data is the kindest data a link will ever see.
0.5 / (200 × 10⁻⁶) = 2,500 bits. Real limits are far lower because loops correct gradually and jitter uses part of the half bit.
Both patterns contain a transition, so every block delivers at least one edge, regardless of the scrambled payload.
Worst-case data patterns: all zeros, all ones and long runs of identical bits, which show whether the transition guarantee really works.
Embedded-clock links recover timing from data transitions with a CDR loop and coast between them.
Coasting drifts by the frequency offset; the ideal limit is about 0.5 UI divided by the offset per bit, and real limits are far tighter.
So every serial protocol must guarantee transitions, with bit stuffing, block codes or scrambling plus a header.