UART · Module 3
Data Bits and LSB-First Transmission
Three different orderings get called bit order: numerical significance, array index, and time on the wire. UART fixes only the third, and the byte is never reversed — a verified byte-to-wire walkthrough, the shift-register invariant, and how to annotate a capture without fooling yourself.
Chapter 3.1 anchored the frame: a transition supplies the origin, a start interval occupies the first position, and the payload begins at the next one. The positions exist. This chapter decides what goes in them.
The question sounds trivial and is responsible for a disproportionate share of bring-up time:
Given a value held in parallel inside a device, which of its bits goes onto the conductor first?
UART's answer is the least significant bit. The trouble is not the rule — it is one line — but that three different things are casually called "bit order", and an engineer holding two of them at once will mis-annotate a perfectly good capture and conclude the hardware is broken. Separating the three is most of this chapter.
1. Three Things Called Bit Order
Write an eight-bit value down and three different orderings are already present. They agree often enough to be confused and differ exactly where it matters.
Numerical significance. Bit 7 contributes 128, bit 0 contributes 1. This is a property of the value and has nothing to do with wires or time.
Array index. In logic [7:0] data, data[0] is the least significant element and data[7] the most. This is a property of the declaration, and it is a convention the designer chose — [0:7] would reverse the indices while leaving the value identical.
Temporal order. Which bit occupies the earliest bit interval on the conductor. This is a property of the protocol, and it is the only one UART specifies.
UART's rule is stated entirely in the third: the least significant payload bit occupies the first payload interval. Under the usual [N-1:0] declaration that makes data[0] first and data[N-1] last — but that correspondence comes from the declaration convention, not from the protocol.
2. A Byte on the Wire
Take a deliberately asymmetric value. Symmetric patterns like 0x55 are a poor first example precisely because a bit-order mistake leaves them looking correct.
value = 0xA6
binary, b7..b0 = 1010_0110
significance:
bit 7 6 5 4 3 2 1 0
value 1 0 1 0 0 1 1 0
weight 128 64 32 16 8 4 2 1Now the same value laid out along time, LSB first:
interval D0 D1 D2 D3 D4 D5 D6 D7
source b0 b1 b2 b3 b4 b5 b6 b7
line 0 1 1 0 0 1 0 1Read the line row left to right — 0110 0101 — and it is not 1010 0110. Both are correct descriptions of 0xA6; they are laid out along different axes.
A second value, chosen because its wire pattern differs from the first in a way a careless reading would miss:
value = 0x96
binary, b7..b0 = 1001_0110
interval D0 D1 D2 D3 D4 D5 D6 D7
line 0 1 1 0 1 0 0 10xA6 and 0x96 differ in one bit position — bit 5 versus bit 4 — and on the conductor that difference appears at intervals D4 and D5. Anyone annotating a capture by eye, without writing the interval labels down, will mix these two values up.
0xA6 = 1010_0110, transmitted LSB first
10 cycles3. The Mapping, on Both Sides
The convention is one rule, and each endpoint implements it as an invariant rather than as a transformation.
Transmitter: the shift-register invariant
// Synthesizable SystemVerilog — payload serialisation only.
// Deliberately absent: baud timing (Modules 4 and 8) produces bit_advance_i,
// and the frame sequencer (Module 7) decides when load_i and the start,
// parity and stop intervals occur. This is the payload field alone.
module uart_tx_shift #(
parameter int unsigned DATA_W = 8
) (
input logic clk,
input logic rst_n,
input logic load_i, // capture a new payload
input logic [DATA_W-1:0] data_i,
input logic bit_advance_i, // one pulse per bit interval
output logic serial_bit_o // drives the line this interval
);
logic [DATA_W-1:0] shreg;
// THE INVARIANT: shreg[0] is always the next payload bit to place on
// the line. Everything else follows from maintaining it.
assign serial_bit_o = shreg[0];
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
shreg <= '0;
end else if (load_i) begin
shreg <= data_i; // bit 0 is now at shreg[0]
end else if (bit_advance_i) begin
shreg <= {1'b0, shreg[DATA_W-1:1]}; // shift right: bit 1 moves in
end
end
endmoduleWhy bit 0 is presented first is not a property of the shift direction — it is the assignment on serial_bit_o. The output is tied to element 0, so whatever occupies element 0 is what the line carries. After load_i, that is data_i[0], the least significant bit.
Why it shifts right follows from the invariant rather than the other way round. To make data_i[1] the next bit on the line, it must arrive at element 0 — so the register moves toward lower indices. Stating the invariant first makes the direction a consequence; stating the shift first makes the direction a thing to memorise and get backwards.
What shifts in is a zero here, and it does not reach the line within this frame: after DATA_W advances the payload field is complete and the sequencer moves to the next field. The fill value is a don't-care that is given a definite value rather than left undriven.
bit_advance_i is one pulse per bit interval, produced by the rate logic of Modules 4 and 8. It is an enable in this clock domain, not a second clock — the architecture Chapter 2.2 §7 introduced.
Reset clears rather than loading. The payload is meaningless until load_i, and the frame sequencer will not be driving payload onto the line before then.
Receiver: store into the index, do not reverse the stream
// Conceptual SystemVerilog — payload assembly only, not a receiver.
// bit_index_i comes from the phase counter of Chapter 2.3, and
// sample_valid_i from the sampling mechanism of Module 5.
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) rx_data <= '0;
else if (sample_valid_i) rx_data[bit_index_i] <= sampled_bit_i;
endThis is the receive-side counterpart of the same invariant, and it is written as an indexed store for a reason.
The tempting alternative is to shift samples into a register and reverse at the end, or to shift left because the arriving bits "look reversed". Both work if the direction is chosen correctly and both are easy to get backwards, because neither expresses what is actually true. The indexed form states it directly: the sample taken during payload interval k belongs in bit position k. That sentence is the protocol rule, and code shaped like it cannot be off by a reversal.
It also generalises to a configurable width without change, which the shift-and-reverse form does not — reversing an eight-bit register and using the low seven bits is not the same as assembling a seven-bit value.
4. Payload Width Is a Configuration Choice
The payload field does not have a universal length. Implementations commonly expose a choice among five, six, seven, eight and nine payload bits, and which subset a particular UART offers is a capability of that IP, published in its documentation — not something the framing guarantees. A design that assumes every UART it meets supports nine-bit payloads will be disappointed; so will one that assumes every UART supports five.
Two consequences matter here, with the full configuration treatment in Chapter 3.5.
Width changes the frame's length, not just its content. Chapter 2.2 gave N_frame as a sum of field counts. A narrower payload makes a shorter frame, which — by Chapter 2.4's linear accumulation — is a frame with less drift at its end.
"Frame" and "byte" are not synonyms. They coincide at eight payload bits and diverge elsewhere. A seven-bit configuration carries seven payload bits per frame, and calling that "a byte" is the kind of slip that leads to buffers sized wrongly and masks forgotten.
5. Reading a Capture Without Fooling Yourself
This is the practical skill the chapter exists to produce, and the failure mode is specific enough to name.
6. What This Means for Verification
Bit ordering is a property that a badly chosen stimulus set will not test at all.
Symmetric payloads are nearly useless here. 0x00, 0xFF and 0x55 are all invariant or near-invariant under bit reversal, so a design that serialises in the wrong direction passes every one of them. A test suite built from convenient constants can miss a total inversion of the payload order. Asymmetric values are the ones that discriminate, and a value and its bit-reversal — 0xA6 and 0x65 — make an excellent pair, because a reversed implementation maps one onto the other exactly.
Walking patterns locate the fault. A payload with exactly one bit set, applied at each position in turn, maps each source bit to a specific interval. When something is wrong, the position that fails tells you which mapping is broken, where a random payload only tells you that something is.
Width is an axis. Every supported payload width should be exercised, and the extremes matter most: the narrowest and widest supported configurations exercise the sequencer's field-length comparison at its boundaries, and an off-by-one there transmits or assembles the wrong number of intervals.
The checker should assemble, not compare raw. A scoreboard that reconstructs the value by the same indexed rule as §3 is checking the protocol. One that compares a captured bit string against a literal is encoding an assumption about layout, and will report a failure the first time someone changes the capture format.
7. What This Means on an FPGA
Instrument the payload with labels, not with a bus. An internal logic-analyser capture of rx_i shows the same time axis a bench instrument does, so the same annotate-then-read discipline applies. Capturing the assembled parallel value alongside the line is more useful still: the two together immediately separate an ordering fault from a sampling fault.
Width parameterisation is where re-targeting breaks. A design parameterised on DATA_W needs its payload register, its interval counter and the sequencer's comparison to move together. Deriving the counter width from the parameter, as Chapter 2.2 §7 did, is what keeps them consistent when the parameter changes.
The shift register is small and the temptation is to hand-optimise it. Writing the shift as an explicit concatenation, as §3 does, synthesises to exactly the intended structure and stays readable. A design that reverses on load to allow a left shift produces the same waveform and an implementation nobody can review against the protocol rule.
8. Understanding Check
9. Summary
Three orderings are casually called bit order: numerical significance, a property of the value; array index, a property of the declaration; and temporal order, a property of the protocol. UART specifies only the third — the least significant payload bit occupies the first payload interval. Under the usual [N-1:0] declaration that makes data[0] first, but that correspondence comes from the declaration convention, not from the framing.
Nothing is reversed. A written value runs along the significance axis and a capture runs along the time axis, which makes them look like mirror images. 0xA6 = 1010_0110 appears on the conductor as 0110 0101 across D0 to D7, and both describe the same unchanged value. Believing a reversal occurs leads to implementing one, and a design that reverses interoperates only with itself.
Each side maintains an invariant rather than performing a transformation. The transmitter's is shreg[0] is the next bit to place on the line — from which the right shift follows as a consequence. The receiver's is the sample from payload interval k belongs in bit position k, which an indexed store expresses directly and a shift-and-reverse expresses only accidentally, breaking when the width becomes configurable.
Payload width is a configuration choice, commonly a subset of five to nine bits, and which subset exists is a capability of a particular IP rather than a framing guarantee. Width changes the frame's length as well as its content, and frame and byte are not synonyms outside the eight-bit case.
The practical discipline is to annotate before reading: label the start interval, then D0 onward, then assemble by index. Reading a capture left to right as a binary literal compares two different axes and always disagrees, which makes it useless for distinguishing a working link from a broken one.
10. What Comes Next
The payload field is defined and its positions are unambiguous. Chapter 3.3 adds the field that may follow it: a single optional interval carrying a parity bit, derived from the payload by an XOR reduction. It is the smallest error-detection mechanism in common use, and the chapter's real subject is the sharp boundary between the corruption it provably catches and the corruption it provably cannot.
Browse the full path on the UART tutorials index. For the same serialisation problem treated as an RTL pattern rather than a protocol rule, see UART (FSM + shift register + baud timer).
Continue learning
Related tutorials
- 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
Sample Counters, Bit Counters and the RX Shift Register
Two counters and a shift register, with every width derived from the parameters and every semantic stated before the RTL — plus the simulator-extracted trace of a byte being reassembled, and why the bit counter wrapping to zero is harmless.
- 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
What a UART Actually Is
Two digital systems need to exchange a small amount of data over very few wires, and no clock travels with it. A UART is the logic that answers that problem — it converts between locally meaningful parallel data and timed activity on a single line, and the timing agreement it depends on is what the rest of the curriculum builds.
Where this fits
Part of the UART curriculum.
