Skip to content
VLSI Mentor

UART · Module 1

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.

Four chapters have built a complete picture of what a UART is. This one asks a question that picture invites and has not yet answered: why is a design this old still present on a chip taped out this year?

The honest answer is not tradition, and it is not that UART is good at moving data — it is not. The answer is structural, and it falls straight out of the previous four chapters. A UART needs almost nothing from the system around it. No shared clock, no negotiation, no enumeration, no arbitration, no software stack, no working memory controller, no operating system. That makes it useless where those things exist and can be relied on, and close to irreplaceable at the moments when they cannot.

UART survives because its requirements are nearly zero, and a system that is not working yet cannot satisfy requirements. Everything in this chapter is that sentence worked out in real architectures.

1. What the Previous Four Chapters Bought

Collect the properties established so far, because the rest of this chapter is an argument from exactly this list and nothing else.

It needs no shared timing. Chapter 1.2 established that the two endpoints need only agree a number in advance. No clock is distributed, no PLL must lock, no training sequence runs, no link comes up. Configure both ends and the link exists.

It needs no negotiation. There is no enumeration, no capability exchange, no address assignment, no handshake before the first byte. A transmitter that drives a frame at a correctly configured receiver is understood immediately — including the very first frame after power-on.

It needs almost no hardware. Chapter 1.3 showed that one permanent driver per conductor removes arbitration, turnaround, direction control and contention. What remains is a shift register, some counters and a small state machine.

Either side may speak unprompted. The two directions are independent, so a device can emit without being polled, asked, or granted permission. A system that has just crashed can still say so.

It is directly observable. Two conductors carry everything. An instrument on them sees exactly what each device drove, with no encoding, scrambling or framing hierarchy in between.

Its electrical layer is a separate choice. Chapter 1.4 showed the same controller reaches across a board, a cable or an industrial network by changing only what sits below the pins.

Read that list as a set of absent requirements. Every entry is something UART does not need — and a requirement you do not have is a requirement that cannot be unmet.

This is the arrangement an FPGA engineer meets first and uses most, and it is worth drawing precisely because the interesting part is how little of it is the FPGA's problem.

A host computer runs a terminal program which talks to an operating system driver, which communicates over USB to a USB-to-serial bridge device on the board. The bridge presents logic-level transmit and receive pins to the FPGA. Inside the FPGA a UART core connects to the user's design logic. From the FPGA's perspective the connection is the plain logic-level case: two pins at the fabric's own voltage, with no transceiver and no negotiation.Terminal on a hostopens a port, printsbytesUSBenumeration, drivers, astackUSB-serial bridgeon the boardUART corein the fabricDesign logicwhat you are debuggingbytesUSBtx / rxbytes12
Figure 1 — the FPGA debug path. From the FPGA's side this is the plain logic-level case of Chapter 1.4: two pins at fabric voltage. Everything to the left of the bridge is somebody else's engineering, which is exactly what makes this arrangement cheap to adopt.

Three things about this figure are worth stating explicitly.

The complexity is real but it is not yours. USB enumeration, driver stacks and operating-system port handling are genuinely complicated, and the bridge and host absorb all of it. The FPGA sees two pins. This is the practical reason UART persists on devices that are themselves attached to modern buses: it is the cheapest way to obtain a byte pipe, and somebody else already built the expensive half.

The bridge is invisible to the framing. It is a transceiver in the Chapter 1.4 sense — it preserves the bit stream and its timing while changing the physical representation. Nothing in the FPGA's design refers to it.

This path works before your design does. A UART core and a fixed status message can be brought up on their own, with the rest of the design held in reset. That is the property §1 identified, in its most concrete form: a way to get information out that does not depend on the thing being investigated.

What it costs to integrate

The integration surface is small enough to write down completely — which is itself the point.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Synthesizable SystemVerilog — FPGA top-level fragment.
// The whole integration surface of a debug UART. Nothing is elided.
module fpga_top (
    input  logic clk_100m,     // the board's fabric clock
    input  logic rst_n,
    input  logic uart_rx_i,    // from the bridge
    output logic uart_tx_o     // to the bridge
);

    logic [7:0] rx_data, tx_data;
    logic       rx_valid, tx_valid, tx_ready;

    uart_core u_uart (
        .clk        (clk_100m),   // no dedicated clock, no PLL, no MMCM
        .rst_n      (rst_n),
        .rx_i       (uart_rx_i),
        .tx_o       (uart_tx_o),
        .tx_data_i  (tx_data),
        .tx_valid_i (tx_valid),
        .tx_ready_o (tx_ready),
        .rx_data_o  (rx_data),
        .rx_valid_o (rx_valid)
    );

    // ... design logic produces tx_data / consumes rx_data ...

endmodule

The instantiation is unremarkable, and that is the teaching point. Read what is absent from it:

No clock generation. clk_100m is the clock the design already has. A UART derives its serial rate from whatever it is given, by counting — logic that Module 8 builds. Nothing here needs a PLL, an MMCM or a dedicated clock resource, which matters because those are finite and usually already committed.

No bus attachment. There is no address, no chip-select, no bus interface. The core exchanges bytes through plain valid/ready style ports. Attaching a UART to a processor bus is a real and useful thing to do, and it is Module 13's subject — but it is an addition, not a prerequisite. A debug UART in a design with no processor at all is a completely ordinary arrangement.

No interrupt, and no memory. Nothing is queued unless you add queueing, which is Module 10. At this level a byte appears, and logic either consumes it or does not.

Two pins, and nothing else on the boundary. The entire external cost is one input, one output, and a clock the design already had.

3. Architecture Two — the Boot Console

On an SoC, the same core appears in a different role, and the reason is the order in which a system becomes able to do things.

Immediately after reset, a processor executes from a small internal ROM. At that instant very little is available: main memory is unconfigured, no filesystem exists, no operating system has been loaded, and most peripherals are in their reset state. The boot code's job is to make the system progressively more capable — configure the memory controller, load the next stage, hand over.

Every one of those steps can fail, and a step that fails before the system can report anything fails invisibly. So boot code needs an output channel, and the constraint on that channel is severe: it must work using only what is available at the earliest moment, and it must not depend on any of the machinery whose failure it might have to report.

A UART satisfies that constraint about as well as anything can. Configuring one is a small number of register writes, it needs no memory beyond the byte being sent, no interrupt handling, no driver, and no cooperation from the far end. A processor with a working clock and a working ROM can emit a diagnostic message. That is why boot ROMs ship with UART support and why a serial console is where an engineer looks when a board does not come up.

The same channel then persists upward through the stack — early boot stages, later boot stages, the kernel, and userspace all writing to the same physical link — because the alternative is to switch diagnostic mechanisms exactly when the system is most fragile.

4. Architecture Three — Board Bring-Up and First Light

The third role is less an architecture than a moment: a new board, powered for the first time, with nothing yet proven.

At that point the engineer's problem is not performance but evidence. Is the clock running? Did the device come out of reset? Is the logic loaded? Does anything execute? A UART is frequently the first mechanism to produce an answer, for two reasons already established.

It can be brought up alone. A transmitter emitting a fixed pattern exercises the clock, the reset, the design's ability to hold state, and an I/O pin — using almost none of the design. If a character appears, several independent things have been proven simultaneously. If nothing appears, the fault is in a small and enumerable list.

It is visible from outside. Two conductors carry the entire conversation in a form an instrument reads directly (Chapter 1.3). When the question is whether the design is doing anything at all, an external observation is worth more than any internal one, because internal observation presumes the mechanism doing the observing works.

This also explains a practice that looks like superstition and is not: bringing the two conductors out to a header on boards that will never ship with a serial connector. The cost is two pins and some board area. The return is a diagnostic path that survives the failure of almost everything else — and Module 17 is built on exactly this observation.

5. Where UART Is the Wrong Choice

A chapter that only explains why something survives teaches a bias. The same property set that makes UART right for the roles above makes it wrong for most others, and the boundaries are sharp.

When throughput matters. A UART moves bytes at a configured rate with per-frame overhead and no mechanism for going faster. Anything with a meaningful data rate — storage, video, networking, a memory interface — is outside its range by orders of magnitude, and no amount of tuning changes that.

When many devices must share a medium. Chapter 1.4 showed that an electrical layer can make sharing possible, and that UART supplies no addressing, arbitration or collision handling. If a system genuinely needs many devices on one medium, an interface that defines those things is a better starting point than building them on top.

When the link must be self-describing. UART requires both ends to be configured identically in advance, and a mismatch corrupts data silently (Chapter 1.2). An interface with enumeration or negotiation removes a whole class of configuration error — at the cost of the machinery that made it useless during boot.

When correctness must be guaranteed by the link. There is no acknowledgement, no retry, and only weak error detection. A system needing reliable delivery must build it above, and an interface that provides it natively will do it better.

That is not a weakness list. It is the same trade read from the other direction, and it is precisely the material Chapter 1.6 turns into a decision procedure.

6. Consequences for RTL, Verification and FPGA Work

For RTL design, the roles in this chapter are an argument for a particular kind of block: small, parameterisable, dependent on nothing but a clock and a reset, and usable without a bus. A UART core whose only external requirement is clk, rst_n and two pins can be dropped into any design, including one with no processor. A core that assumed a bus interface, needed a dedicated clock resource, or required software configuration to emit anything would fail the boot-console and bring-up roles entirely — which is a design constraint that comes from where the block is used, not from the protocol.

For verification, this chapter sharpens what the environment must support. A design used as a diagnostic channel is used in states other blocks never see: immediately after reset, before configuration is complete, while other logic is held inactive, and while the system is in a state somebody considers broken. Those are legitimate test conditions rather than exotic ones. The most specific consequence is that transmit must be verified as working from reset with minimal setup, because that is the boot-console requirement — and a test that always configures everything before transmitting never establishes it. The same is true for the absence of dependencies: if a testbench always provides a clean bus and a full configuration, it cannot demonstrate that the core works without them.

For FPGA work, the practical points are the ones §2's instantiation makes concrete. Two pins and the existing fabric clock, constrained like any other I/O. No PLL or MMCM consumed. uart_rx_i arrives from outside the design and must be treated as an asynchronous input before any logic decides from it — a Module 12 obligation, and the same one for a bridge, a transceiver or a direct connection, because all three are outside the local clock's domain. And the debug UART should be instantiable independently of the design under investigation, because a diagnostic path that shares a reset domain or a clock enable with the logic it is meant to observe goes quiet exactly when it is needed.

7. Understanding Check

8. Summary

UART persists for a structural reason rather than a historical one. The previous four chapters produced a specific property set — no shared timing, no negotiation, almost no hardware, either side may speak unprompted, directly observable, electrical layer chosen separately — and every entry on it is an absent requirement. A requirement you do not have is one that cannot be unmet.

That is exactly the property a system needs when it is not working yet. Early boot, a design under bring-up, a board at first light and a system that has just failed all share the same condition: the machinery that a more capable interface would depend on is either absent or under suspicion. Capability and availability trade against each other, and UART sits at the available end.

The recurring architectures are the same argument in three forms. The FPGA debug link obtains a byte pipe for two pins and the fabric clock, with the expensive half — USB, drivers, host software — absorbed by a bridge that the framing never sees. The boot console gives ROM code an output channel that depends on nothing it might have to report on, and that persists upward through every later software stage. Bring-up uses the link as evidence, because a character appearing proves clock, reset, state, I/O and wiring simultaneously, and because two conductors are observable from outside the design that is under suspicion.

The integration cost is genuinely small — a clock the design already has, a reset, and two pins — and that smallness is a design requirement inherited from the roles, not an accident. A core is not a peripheral: the register interface, FIFOs and interrupts that make a UART feel heavy are additions built in later modules.

And the same properties make UART wrong wherever throughput matters, many devices must share a medium, the link should describe itself, or delivery must be guaranteed. That is the same trade read backwards, and it is what the next chapter turns into a decision.

9. What Comes Next

This chapter argued that UART's absent requirements are what make it survive, and named the places where those same absences disqualify it. Chapter 1.6 closes Module 1 by making that a comparison an architect can act on — UART against SPI, I²C, USB, CAN and Ethernet, along the dimensions that actually decide a choice: the clocking model, the wires, the topology, the complexity each demands, and what each buys in exchange.

After that, Module 2 returns to the inside of the link and answers the question every chapter so far has deferred: given two independent timebases and one alignment event per frame, how much error accumulates, over what span, and why does the arrangement work at all.

Browse the full path on the UART tutorials index. For the boot-console role from the software-visible side — the registers a processor actually writes to emit a character — see UART APB Interface; the equivalent register-model view used in verification is UART Register Model.

Continue learning

Where this fits

Part of the UART curriculum.