UART · Module 7
Baud Enable and TX Bit Timing
What advances the transmitter from one bit interval to the next, stated precisely — the tick's semantics, the measured cost of launching on a free-running enable, and frame durations derived and then confirmed in simulation.
Chapter 7.2 built a state machine in which every transition is gated on baud_tick_i, and treated that signal as given. This chapter says exactly what it is.
That sounds like a small job, and the reason it is not is the same reason Chapter 6.3 needed a chapter for two counters: timing defects are semantic, not arithmetic. Whether a tick is one cycle or a level, whether the interval begins on the edge carrying it or the one after, and what happens when a request arrives one cycle before a tick — each is a one-line difference in RTL and a visible difference on the wire.
There is also a question Chapter 7.2 deferred and cannot be avoided any longer: between a request being accepted and the start bit appearing, what happens?
1. The Rule, Stated Once
The transmitter has ONE clock — clk — and advances on an ENABLE.
baud_tick_i is that enable. It is never a clock.Chapter 8.1 develops why at length. The short form: dividing clk to make a baud_clk would create a clock domain crossing inside the transmitter between the divider and everything else, requiring synchronisers and constraints, for a signal that is already perfectly usable as an enable. Nothing is gained and a domain is created.
What this chapter needs from that rule is a structural consequence: because the tick is an enable, the transmitter's entire timing behaviour is visible in one if, and everything not inside it is timing-independent.
2. The Six Questions
Answered before any RTL, following the discipline Chapter 6.3 §1 established for the receiver's counters.
| Question | Answer |
|---|---|
Is baud_tick_i a pulse or a level? | A pulse, high for exactly one clk cycle. |
| How often? | Once per bit interval. Not oversampled — see §6. |
| Does a bit interval begin on the edge carrying the tick, or the next one? | On the edge carrying it. That edge is the boundary. |
When does tx_o update? | On that same edge, since tx_o is written inside the tick branch. |
| Does the transmitter reset or re-phase the generator? | No. The tick free-runs; §4 is about what that costs. |
| What if a request arrives on the same edge as a tick? | It is accepted and launched on that edge — §5. |
The third and fourth together are the whole of bit timing: the edge carrying the tick is simultaneously the end of one interval and the start of the next, and the line changes exactly there. Every interval is therefore the distance between two consecutive ticks, which is one bit period by the generator's construction.
3. What the Line Does Between Ticks
Nothing, and that is the point Chapter 7.2 §1 made structurally rather than by assertion.
tx_o changes only on a baud tick
10 cyclesThe divisor does not appear anywhere in the transmitter. At 100 MHz and 115,200 baud it is about 868 (Chapter 4.3); at 9,600 baud it is about 10,417. The transmitter's RTL is byte-identical in both cases, because it counts intervals and not cycles.
4. Launch Latency: the Cost of a Free-Running Tick
Here is the question Chapter 7.2 deferred.
A request can be accepted on any clock cycle. A bit interval begins only on a tick. So something must happen in between, and there are two defensible architectures.
Architecture A — launch immediately, re-phase the generator. Drive the start bit the instant the request is accepted, and reset the baud generator so the next tick arrives one full bit period later. Launch latency becomes zero and every interval is still exact.
Architecture B — launch on the next tick. Accept the request, hold the line at idle, and begin the start bit at the next boundary of the free-running tick. Launch latency is between zero and one bit period; every interval is exact.
This transmitter uses B, and the reason is a boundary rather than a preference.
5. The Cost, Measured
Launch latency is the delay from the accepting clock edge to the start bit appearing. Measured across every phase of the bit interval, with an illustrative divisor of 7 clocks per interval so that all phases fit in a table:
| request offset | latency to start bit |
|---|---|
| 0 | 6 clks |
| 1 | 6 clks |
| 2 | 5 clks |
| 3 | 4 clks |
| 4 | 3 clks |
| 5 | 2 clks |
| 6 | 1 clk |
Bounded by one bit interval, uniformly distributed inside it. A request landing just after a tick waits almost a full interval; one landing just before waits almost nothing. With a real divisor of 868 the same structure holds and the worst case is 867 clocks — 8.67 µs at 100 MHz, against a frame time of 86.8 µs.
So the honest statement of the trade is: up to 10% added latency on the first frame of a burst, and none thereafter — because once the transmitter is streaming, Chapter 7.4's back-to-back path launches each frame directly from the previous frame's final tick, where the latency is zero by construction.
That is a small price for block independence, and it is a price worth stating rather than discovering: a design with a hard first-byte latency requirement needs Architecture A and the coupled generator that comes with it.
6. One Tick Per Bit — Not Sixteen
Worth making explicit, because it is the sharpest asymmetry between the two halves of the link.
| Receiver | Transmitter | |
|---|---|---|
| Ticks per bit interval | OVERSAMPLE — typically 16 | 1 |
| Why | must find the boundary it was never told about | defines the boundary |
| Consequence | needs a grid, a phase counter, a centre comparison | needs a single enable |
Chapter 5.3 spent a chapter on why the receiver needs a grid of positions inside each interval. The transmitter needs none of it. It is not sampling anything; it is deciding when intervals begin, and one event per interval is exactly enough information to do that.
This is also the reason the two halves cannot trivially share one enable: a generator producing 16 × f_baud serves the receiver directly and must be divided by 16 for the transmitter, and one producing f_baud serves the transmitter directly and is useless to the receiver. Chapter 8.4 owns that decision and its consequences.
7. Frame Duration, Derived and Measured
The interval count follows from the frame structure alone:
frame intervals = 1 start + DATA_W + (parity enabled ? 1 : 0) + stop bits| Configuration | start | data | parity | stop | intervals | duration at 115,200 |
|---|---|---|---|---|---|---|
| 8N1 | 1 | 8 | 0 | 1 | 10 | 86.81 µs |
| 8E1 | 1 | 8 | 1 | 1 | 11 | 95.49 µs |
| 8O1 | 1 | 8 | 1 | 1 | 11 | 95.49 µs |
| 7E1 | 1 | 7 | 1 | 1 | 10 | 86.81 µs |
| 5N1 | 1 | 5 | 0 | 1 | 7 | 60.76 µs |
Measured from the compiled design, counting ticks from the start bit to the return to idle:
8N1 : 10 intervals (expected 10 = 1 + 8 + 0 + 1) ✓
8E1 : 11 intervals (expected 11 = 1 + 8 + 1 + 1) ✓
8O1 : 11 intervals (expected 11 = 1 + 8 + 1 + 1) ✓This check is worth automating. An off-by-one in the terminal comparison (Chapter 7.2 §7) changes the interval count by exactly one, so a bench that counts ticks per frame catches it on the first frame — whereas a bench that only compares the decoded byte may not catch it at all, depending on what the spurious bit happened to be.
Note that 7E1 and 8N1 both take 10 intervals. A frame's duration does not identify its configuration, which is why Chapter 3.5 insisted that both ends be configured rather than inferring.
8. Verification
Sweep the request phase across a full bit interval. §5's table is that sweep, and it is the test that catches a transmitter which launches at the wrong moment — a defect that is invisible when the request always arrives at the same point relative to the tick, which is exactly what a simple directed test does.
Count ticks per frame, per §7, rather than only checking the decoded byte.
Vary the divisor. The transmitter should be byte-identical in behaviour at any divisor; running the same tests at two different values confirms nothing has crept in that depends on the tick rate. A deliberately odd divisor is useful here for the same reason a non-power-of-two oversampling factor was useful in Chapter 6.3 §2 — it breaks any accidental assumption of a convenient value.
Check line stability against the tick, not against a state. The property is the line changes only on a cycle carrying a tick, which is checkable without knowing anything about frames:
// Checker — the line moves only at a bit boundary.
// Written against baud_tick_i rather than against state, so it holds during
// idle, during a frame, and across back-to-back frames alike.
logic tx_prev, tick_d;
always_ff @(posedge clk) begin
if (!rst_n) begin
tx_prev <= 1'b1;
tick_d <= 1'b0;
end else begin
if ((tx_o !== tx_prev) && !tick_d)
$error("tx_o changed with no baud tick at %0t", $time);
tx_prev <= tx_o;
tick_d <= baud_tick_i;
end
endtick_d is a deliberate one-cycle delay. tx_o is assigned inside the tick branch, so a new value is first observable on the cycle after the tick. Comparing against the live baud_tick_i would report a false failure on every legitimate change — a checker bug that looks exactly like a design bug, and one this module's verification hit.
9. What This Means on an FPGA
No generated clock means no clock constraint and no CDC report. The transmitter contributes one clock domain to the design and nothing for timing analysis to reason about beyond ordinary paths. That is the practical payoff of the rule in §1, and Module 12 covers what the alternative would have required.
The enable is a broadcast signal with high fanout at low toggle rate. It reaches the state register, the shift register, the bit counter and the line register. At 868 clocks between pulses it toggles rarely, so it is neither a power concern nor a timing concern — but it should be a plain synchronous signal, not a gated clock the tool may interpret.
Do not gate clk with baud_tick_i. It is a logically equivalent idea and a structurally different one: clock gating creates a derived clock with all the constraint and CDC consequences §1 exists to avoid, and on an FPGA it usually maps to something worse than an enable. Enables are what the fabric is built for.
Probe baud_tick_i alongside tx_o during bring-up. Two signals answer the most common transmit question immediately: if ticks are arriving at the wrong rate, the problem is the generator and Module 8's; if ticks are correct and the line is wrong, the problem is here.
10. Understanding Check
11. Summary
The transmitter has one clock and advances on an enable. baud_tick_i is a one-cycle pulse, once per bit interval, and the edge carrying it is simultaneously the end of one interval, the start of the next, and the moment tx_o updates.
The divisor appears nowhere in the transmitter. It counts intervals, not cycles, which is what makes the same RTL work at any rate and with either kind of generator.
One tick per bit, not sixteen. The receiver needs a grid because it must find a boundary it was never told about; the transmitter defines the boundary, so one event per interval is exactly enough.
Launching waits for the next tick. The alternative — re-phasing the generator for zero latency — would require the generator to expose a reset, couple the two blocks, and pre-empt the question of whether the receive and transmit halves share one generator. The measured cost is up to one bit interval on the first frame of a burst and none thereafter, since back-to-back frames launch from the previous frame's final tick.
Frame duration is 1 + DATA_W + parity + stop intervals, derived and then confirmed in simulation at 10, 11 and 11 for 8N1, 8E1 and 8O1. Counting ticks per frame catches a terminal off-by-one on the first frame, which a byte comparison may miss entirely. And 7E1 and 8N1 are both ten intervals — duration does not identify configuration.
12. What Comes Next
Two chapters have now used the word accepted without defining it, and §4's latency was measured from an "accepting clock edge" that has had no specification.
Chapter 7.4 provides it. It defines the upstream transaction precisely — who owns the payload before acceptance, at which edge ownership transfers, and what tx_ready_o actually promises — and distinguishes ready from busy, which are routinely conflated and mean different things. It then confronts the case the registry blurb calls "no gaps the producer did not ask for": how the transmitter accepts the next byte at the final boundary of the current frame so that back-to-back frames run with no idle interval and no shortened stop bit — including what happens when a frame completes and a new request is accepted on the same clock edge.
Browse the full path on the UART tutorials index. For the bit period this chapter's ticks measure out, read back to Chapter 2.2.
Continue learning
Related tutorials
- Related topic
Integer Dividers and Baud-Rate Error
The ratio is a fraction and a counter holds an integer, so rounding is a design decision with a measurable cost. Three policies, the actual rate each produces, and why the error belongs in units of a bit period rather than as a bare percentage.
- Related topic
Oversampling Strategies: 8×, 16× and the Alternatives
Oversampling is a grid of sample positions inside each bit interval. A higher factor buys placement resolution and costs tick rate, counter width and generator accuracy — and 16× became conventional for an arithmetic reason the standard crystal frequencies make obvious.
- Related topic
TX Datapath and Parallel-to-Serial Conversion
The datapath that turns a parallel word into a bit stream — why the transmitter must capture the payload rather than index a live bus, how LSB-first emission falls out of a right shift, and where the frame's fixed bits come from.
- Related topic
The TX FSM and Frame Sequencing
Five states, eight transitions, and one rule that keeps the line honest: tx_o is a register written only inside the bit-boundary branch. Includes the off-by-one that emits nine data bits, and the state table the RTL was checked against.
Where this fits
Part of the UART curriculum.
