UART · Module 5
Sampling Under Clock Mismatch
Walk the receiver's sampling positions across a real frame under a real frequency error: the migration in oversample ticks, why the final interval always fails first, and why a voting window fails before a single sample would.
Every mechanism in this module has been developed against a static picture. Chapter 5.2 placed a timing origin, Chapter 5.3 built a grid from it, Chapter 5.4 put a window at a position on that grid — and all three assumed the positions stay where the receiver put them.
They do not. Chapter 2.4 established that the two endpoints' bit periods differ and that the difference accumulates; Chapter 4.5 budgeted for it abstractly. This chapter puts the two together and does what neither could alone: walk the actual sampling positions of a real receiver architecture across a real frame and watch them move.
The result answers a question engineers meet in the lab constantly — why does the end of the frame fail and not the beginning? — and produces a second result that is not obvious: a voting window fails before a single sample would.
1. The Model, Consumed
From Chapter 2.4, the displacement between the transmitter's intervals and the receiver's prediction after n intervals is:
Δt(n) / T_bit = n x ε_rel in UIlinear in n, with ε_rel ≈ ε_TX − ε_RX and the sign convention of Chapter 4.1: positive ε means running fast.
What this module adds is the unit the receiver actually works in. Chapter 5.3 built a grid of M positions per interval, so the same displacement is:
drift in oversample ticks = n x ε_rel x MAnd because the receiver aims at the centre of each cell, the effective sampling position inside interval n is:
position(n) = 0.5 + n x ε_rel UI, measured from the interval's opening boundaryThat single expression is the whole chapter. Everything below is reading it carefully.
2. Walking the Frame
Take a concrete, unremarkable case: TX at +0.5%, RX at −0.5%, so ε_rel = 1.0% — two endpoints each comfortably within a 0.5% specification, at opposite extremes, which Chapter 2.4 §4 identified as the hard combination. 8N1 framing, 115,200 baud, M = 16.
Interval n | position | drift | ticks at M=16 | ticks at M=8 | ns |
|---|---|---|---|---|---|
| 1 — data[0] | 0.5100 UI | 0.0100 UI | 0.160 | 0.080 | 86.8 |
| 2 — data[1] | 0.5200 UI | 0.0200 UI | 0.320 | 0.160 | 173.6 |
| 4 — data[3] | 0.5400 UI | 0.0400 UI | 0.640 | 0.320 | 347.2 |
| 6 — data[5] | 0.5600 UI | 0.0600 UI | 0.960 | 0.480 | 520.8 |
| 8 — data[7] | 0.5800 UI | 0.0800 UI | 1.280 | 0.640 | 694.4 |
| 9 — stop | 0.5900 UI | 0.0900 UI | 1.440 | 0.720 | 781.2 |
Read the tick column. By the end of the frame the receiver is sampling a full oversample tick and a half away from where it intended. The grid it so carefully constructed in Chapter 5.3 has slid out from under it, and nothing in the receiver knows.
Sample position migrating across a frame
10 cyclesAt 1% nothing fails — 0.59 UI is well inside the cell. The mechanism is working exactly as designed, and that is worth noticing: this much drift is normal and harmless. The question is where it stops being harmless.
3. Which Bit Fails First
Because position(n) is linear and increasing in n, the largest displacement is always at the largest n — the frame's final interval. There is no other candidate.
At ε_rel = 6%, above the idealised bound Chapter 4.5 derived for 8N1:
Crossing the boundary — the last interval only
10 cyclesThree consequences follow, and all three are diagnostic.
The failure presents as a framing error, not a data error. In 8N1 the final interval is the stop condition, so the first thing to fail is the stop check (Chapter 3.4). An engineer sees framing errors with payloads that look plausible — because the payload was sampled correctly — and reasonably suspects the frame configuration. The configuration is fine.
It is a cliff, not a gradient. Below the boundary every interval is sampled correctly and the link is perfect. Above it, the final interval fails on every frame. There is no region of rising error rate, because nothing here is statistical. A marginal link therefore looks completely healthy until it does not.
Longer configurations fail at lower mismatch. n_max = N_frame − 1, so 8E2 reaches 0.11 UI of drift at ε_rel = 1% where 8N1 reaches 0.09 — and crosses the boundary at a proportionally lower mismatch. A link that fails at 8E2 and works at 8N1 is demonstrating exactly this.
4. The Window Fails Before the Centre Does
Now the result this module makes available and Chapter 4.5 could not derive.
Chapter 5.4 established that a three-sample window places its outer samples 1/M UI either side of the centre. Under drift, the whole window migrates together — so the trailing outer sample reaches the closing boundary before the centre does.
At n = 9 with ε_rel = 1% and M = 16:
centre at 0.5000 + 0.0900 = 0.5900 UI
outer samples at 0.5900 ± 0.0625 = 0.5275 and 0.6525 UI
margin of the trailing sample to the boundary = 1.0 − 0.6525 = 0.3475 UIStill comfortable. But solve for the mismatch at which the trailing sample reaches the boundary, rather than the centre:
single sample: ε_rel,max = 0.5 / 9 = 5.556%
3-sample at M = 16: ε_rel,max = (0.5 − 0.0625) / 9 = 4.861%
3-sample at M = 8: ε_rel,max = (0.5 − 0.1250) / 9 = 4.167%5. The Budget, Now Fully Derived
Chapter 4.5 wrote the inequality with δ_sample as an unresolved symbol. Module 5 has supplied every part of it:
0.5 > δ_origin + δ_grid + δ_window + (N_frame − 1) x ε_rel + δ_reserve| Term | Source | Value at M=16, 115,200, 100 MHz |
|---|---|---|
δ_origin | Chapter 5.2 — clock quantisation of the observed edge; the synchroniser's latency is a fixed offset accounted separately | 0.001152 UI |
δ_grid | Chapter 5.3 — placement onto the tick grid, conservative bound 1/M | 0.0625 UI |
δ_window | Chapter 5.4 — outer sample offset | 0.0625 UI |
(N_frame−1) x ε_rel | Chapter 2.4 — accumulated mismatch | 0.09 UI at 1%, 8N1 |
δ_reserve | the designer | chosen |
δ_grid and δ_window together — 0.125 UI at 16× — dominate every implementation term, and both are direct consequences of choices made in this module. Chapter 4.5 found the far end's crystal dominating the whole budget at 26× the local terms; with the receiver architecture now specified, the sampling terms are the largest thing the designer actually controls.
That is the module's contribution to the budget, and it is why Chapter 4.5 could not finish the calculation: the sampling terms do not exist until a receiver architecture does.
6. Verification: Find the Boundary, Do Not Assume It
The cliff of §3 dictates the method.
Sweep ε_rel and locate the failure empirically. Because the transition is sharp, a bisection over mismatch finds it quickly and precisely. The result is this design's boundary — which, per Chapter 4.5 §4, is not a property of UART and not transferable to another receiver.
// Testbench SystemVerilog — NOT synthesizable. Drives frames at a
// deliberately skewed bit period and reports whether the frame survives.
//
// The expected boundary is COMPUTED from the design's own parameters, so
// it moves when OVERSAMPLE, the frame length or the window changes.
task automatic drive_frame_at_mismatch(input real eps_rel, input byte payload);
realtime tx_bit = T_BIT_NOMINAL * (1.0 + eps_rel);
rx_i <= 1'b0; #(tx_bit); // start interval
for (int k = 0; k < 8; k++) begin
rx_i <= payload[k]; #(tx_bit); // LSB first — Chapter 3.2
end
rx_i <= 1'b1; #(tx_bit); // stop interval
endtask
initial begin
// Predicted boundary: the trailing sample of the window reaches the
// cell boundary. Derived, not tabulated.
real d_window = 1.0 / OVERSAMPLE;
real predicted = (0.5 - d_window) / real'(N_FRAME - 1);
for (real e = 0.0; e < 0.10; e += 0.0005) begin
drive_frame_at_mismatch(e, 8'hA6);
@(posedge frame_done);
if (framing_error || rx_data !== 8'hA6) begin
$display("first failure at eps_rel = %0.4f%% (predicted %0.4f%%)",
e*100.0, predicted*100.0);
break;
end
end
endSweep both signs, and drive the two endpoints independently. ε_rel is a difference, so a generator varying one combined knob cannot distinguish (+0.5%, −0.5%) from (+1.0%, 0) — and a design that treats them differently has a defect worth finding. Chapter 2.4 §4 identified opposite signs as the hard case.
Frame length is an independent axis by the N_frame − 1 factor, so the longest supported configuration is the worst case by construction. A boundary measured at 8N1 does not apply at 8E2.
Assert the failure signature, not just the failure. A design just past its boundary must corrupt the final interval and nothing earlier. A checker that records which interval failed distinguishes a mismatch failure from a start-qualification offset — which fails from the beginning with a constant displacement (Chapter 5.2 §6) — and from a hard-coded phase literal, which fails at every interval equally (Chapter 5.3 §6). Three different defects, three different signatures, one byte-level symptom.
Soak testing finds nothing here. Below the boundary every frame is perfect and above it every frame fails identically, so duration buys no information. Parameter variation buys all of it.
7. Diagnosis in the Lab
8. What This Means on an FPGA
The tick grid drifts with the fabric clock, not against it. The receiver's M positions are generated from the local clock, so ε_RX moves the entire grid uniformly. There is no relative motion inside the receiver — only between the receiver's grid and the transmitter's intervals. That is why one number, ε_rel, captures the whole effect.
Raising M helps twice and costs twice. It reduces δ_grid and δ_window together, buying tolerance — but Chapter 5.3 §5 showed the tick generator's own divisor shrinks, so its rate error grows and feeds back into ε_RX. At 100 MHz and 115,200, going from 8× to 16× moves the divisor from 108.5 to 54.25. The net is usually favourable and it is a net, not a gain.
Measure across many intervals. A single-interval measurement cannot resolve a 1% error. The technique from Chapter 4.3 §5 — f = N / Δt over N intervals — is what makes ε_rel observable at all.
And instrument which interval failed. If the design can expose the bit index at which a framing error occurred, §7's three-way diagnosis becomes a single observation rather than an investigation.
9. Understanding Check
10. Summary
The receiver's sampling positions do not stay where it put them. Consuming Chapter 2.4's model in this module's units, the effective position inside interval n is:
position(n) = 0.5 + n x ε_rel UI drift in ticks = n x ε_rel x MAt ε_rel = 1% — two endpoints each within 0.5%, at opposite extremes — an 8N1 frame's stop sample lands at 0.59 UI, 1.44 oversample ticks from where the receiver intended. Nothing fails; the drift is normal and invisible to the receiver.
Because the expression is linear and increasing in n, the last interval always fails first. That produces three diagnostic consequences: the symptom is a framing error with plausible payloads, because in 8N1 the final interval is the stop condition; it is a cliff rather than a gradient, since nothing here is statistical; and longer configurations fail at lower mismatch, because n_max = N_frame − 1.
The window of Chapter 5.4 migrates with the centre, so its trailing sample reaches the boundary first. A three-sample window lowers the idealised 8N1 tolerance from 5.556% to 4.861% at 16× and 4.167% at 8× — the voter buys glitch rejection and pays in clock-mismatch tolerance, at an exchange rate set by M.
The budget of Chapter 4.5 is now fully derived, with δ_grid and δ_window together — 0.125 UI at 16× — dominating every implementation term. Those are the largest quantities the receiver designer actually controls.
And three defects share one byte-level symptom: mismatch corrupts from the frame's end, a false start from its beginning, a misplaced phase uniformly. Capturing which interval failed first separates them.
11. Where Module 5 Leaves You
Five chapters have built every timing mechanism a UART receiver needs.
Chapter 5.1 established the asymmetry — the transmitter executes a schedule it wrote, the receiver makes four judgements from one edge — and set the synchronisation boundary every later chapter assumed. Chapter 5.2 detected the departure from idle, distinguished a candidate from an accepted start, and showed that the choice of timing origin decides correctness. Chapter 5.3 built the grid, explained why 16× became conventional by closing the loop with Chapter 4.2's crystal frequencies, and supplied δ_grid. Chapter 5.4 added the multi-sample decision, stated exactly what it rejects and cannot, and supplied δ_window. This chapter set everything in motion and showed where it breaks.
An engineer holding this chain can look at a receiver's oversampling factor, its window, its start qualification and a far-end datasheet, and say where the samples will land at every interval of any configuration — and which one will fail first.
What they cannot yet do is build the receiver. Every mechanism here is a fragment: a synchroniser, a qualifier, a phase counter, a voter. None of them holds a byte, tracks which bit is arriving, checks parity, validates the stop condition, reports an error, or tells anything upstream that data is ready.
12. What Comes Next
Module 6 assembles them. It partitions the receiver into blocks and justifies each boundary, builds the state machine that sequences a frame and the error transitions implementations most often get wrong, adds the sample and bit counters and the shift register that reassembles the byte in the order it arrived, checks parity and validates the stop condition without corrupting the next frame, generates the data-valid handshake and confronts the overrun that follows a missed read — and finally reviews the complete architecture the way a reviewer would.
Browse the full path on the UART tutorials index. For the budget this module completed, read back to Chapter 4.5 now that every one of its terms has a derivation.
Continue learning
Related tutorials
- Related topic
The UART Timing Budget: How Much Mismatch a Frame Survives
The familiar five percent is the exact output of one idealised model with five stated assumptions, all false in hardware. Putting the terms back shows the usable budget moving by a quarter of its value under ordinary implementation choices — which is why the number belongs to a design, not to UART.
- Related topic
Stop Bits, Frame Boundaries and Back-to-Back Frames
The stop interval is a required mark condition the receiver checks at a known position — not a pause, not recovery time, and not a resynchronisation. What a framing error reports, what it cannot tell you, and why two frames may follow with no idle between them.
- Related topic
Start-Edge Detection and Start-Bit Validation
Detecting a departure from idle is a comparison on the synchronised input. Deciding it was a start bit rather than a disturbance is a judgement with a cost — and the receiver's entire frame timing hangs on which event it treats as the origin.
- Related topic
Where UART Lives: Debug Consoles, Boot and Bring-Up
UART survives for a structural reason: its requirements are nearly zero, so it works at the moments when nothing else does yet. The FPGA debug link, the SoC boot console and board bring-up — and the two-pin integration surface a debug UART actually costs.
Where this fits
Part of the UART curriculum.
