Day 11 · UART Transmitter

The UART Protocol

Video 1 of 4 · ~10 minutes

Dr. Mike Borowczak · Electrical & Computer Engineering · CECS · UCF

ProtocolTX ArchitectureImplementationPC Connection

🌍 Where This Lives

In Industry

Every Arduino. Every Raspberry Pi's debug console. Every ESP32. Every car's OBD-II diagnostic port. Every GPS module, every Bluetooth module, every cellular modem. Every server's IPMI console. The SiM cards in your phone use UART-based protocols. Your FPGA's JTAG is a UART cousin. UART is the universal debug and configuration protocol — simpler than USB or Ethernet, older than anyone in this class, still in every new product shipping in 2026.

In This Course

Today: protocol. Video 2: transmitter architecture. Video 3: working implementation. Video 4: connect to your laptop and print “HELLO”. By Friday your Go Board communicates with real software on a real computer. UART is the first time your Verilog escapes the FPGA.

Career tag: Writing a UART from scratch is a textbook interview question. Master it once and you'll reach for the answer automatically.

⚠️ No Clock Line? Then How?

❌ Wrong Model

“A serial protocol must have a clock line. How else does the receiver know when to sample the data?”

✓ Right Model

UART is asynchronous. Both ends agree in advance on the bit duration (the baud rate). A start bit announces “byte incoming;” the receiver times its own samples from there. No shared clock wire — which is why it's only 2 wires (TX, RX) instead of 3+ (clock + data + maybe more). Baud-rate accuracy: typical ±2% tolerance.

The receipt: “Asynchronous” is the A in UART. Universal Asynchronous Receiver-Transmitter. Both ends run independent clocks; the start bit resynchronizes them for each byte.

👁️ I Do — UART Frame Format (8N1)

  IDLE       FRAME (10 bit times)                         IDLE
  ───┐     ┌────┬────┬────┬────┬────┬────┬────┬────┐     ┌───
     │     │ D0 │ D1 │ D2 │ D3 │ D4 │ D5 │ D6 │ D7 │     │
     └─────┘    │    │    │    │    │    │    │    └─────┘
     start       ↑↑↑↑↑↑↑↑↑↑↑↑                         stop
     (LOW, 1 bt)  data bits (LSB first, 8 bits)        (HIGH, 1 bt)
    
My thinking — 8N1 means 8 data bits, No parity, 1 stop bit:
  • Idle: line HIGH
  • Start bit: LOW for 1 bit time (signals “byte incoming”)
  • Data bits: 8 bits, LSB first, each 1 bit time
  • Stop bit: HIGH for 1 bit time (guarantees framing gap before next byte)
  • Total: 10 bit times per byte.

🤝 We Do — Baud Rate Math

Common baud rates and their bit durations:

BaudBit timeCycles @ 25 MHzByte time (10 bits)
9,600104.2 µs2,6041.04 ms → 960 bytes/s
115,2008.68 µs21786.8 µs → 11,520 bytes/s
1,000,0001.0 µs2510 µs → 100k bytes/s
3,000,000333 ns8.33 (too close!)3.3 µs → 300k bytes/s
Together: For each bit, your logic waits CYCLES_PER_BIT = CLK_RATE / BAUD cycles. At 25 MHz, 9600 baud → 2604 cycles/bit. 115,200 baud → 217 cycles/bit. Keep CYCLES_PER_BIT ≥ ~20 to have margin — 3,000,000 baud at 25 MHz clock is too tight (only 8.33 cycles, not integer).

🧪 You Do — Decode This Waveform

Captured UART line (8N1, LSB first):

Time:  0-----1-----2-----3-----4-----5-----6-----7-----8-----9-----10----
Line:  HIGH- LOW-- LOW-- HIGH- LOW-- HIGH- LOW-- LOW-- LOW-- LOW-- HIGH-
             start  D0    D1    D2    D3    D4    D5    D6    D7    stop

What byte was transmitted?

Answer: Reading data bits in order: D0=0, D1=1, D2=0, D3=1, D4=0, D5=0, D6=0, D7=0 → LSB-first = 00001010 binary = 0x0A = ASCII LF (newline). Simple debugging skill: always reverse the order when reading bytes off a scope or logic analyzer.
▶ LIVE DEMO

Real UART Trace on a Scope

~4 minutes

▸ COMMANDS

cd labs/week3_day11/ex1_protocol/
# read a saved .csv capture of a
# real UART transmitting 'A' @ 115200
python3 decode_uart.py capture.csv
gtkwave trace.vcd &

▸ EXPECTED STDOUT

Baud rate: 115200
Start bit at: 0 us
Data bits: 1,0,0,0,0,0,1,0
Assembled byte: 0x41
ASCII: 'A'
Stop bit confirmed

▸ KEY OBSERVATION

Real UART line looks exactly like the textbook diagram. Start bit falls, 8 data bits at the agreed rate, stop bit returns to idle. Your job today: build the hardware that produces this pattern from any input byte.

🔧 Protocol Variants You'll Encounter

ConfigBitsUse
8N1 (default)8 data, 0 parity, 1 stop~99% of modern use
8N28 data, 0 parity, 2 stopOld/slow receivers, some industrial
7E17 data, 1 even parity, 1 stopLegacy ASCII terminals
9N19 data, 0 parity, 1 stopSome multi-drop systems
Checkpoint: If someone says “UART” without specifying, they mean 8N1. Support that and you handle the overwhelming majority of cases. Parameterize your design and you can handle the rest.

🤖 Check the Machine

Ask AI: “At 115200 baud, how many clock cycles at 100 MHz system clock does one UART bit take? Derive and show your work.”

TASK

AI computes cycles-per-bit.

BEFORE

Predict: 100e6 / 115200 = 868 cycles/bit.

AFTER

Strong AI notes rounding error. Weak AI just divides.

TAKEAWAY

Integer rounding matters. 868 cycles → 115207 baud (0.006% error, OK).

Key Takeaways

 UART is asynchronous — no shared clock. Only TX + RX + GND.

 8N1 framing: start(0) + 8 data LSB-first + stop(1) = 10 bit times.

 Baud rate = CLK / CYCLES_PER_BIT. Parameterize these.

 ±2% baud tolerance. Both ends need reasonable clock accuracy.

UART is the oldest protocol you'll ever build. And still one of the best.

🔗 Transfer

UART TX Architecture

Video 2 of 4 · ~10 minutes

▸ WHY THIS MATTERS NEXT

You know the protocol. Video 2 turns it into an architecture: FSM + datapath decomposition. You'll see how your Week 2 modules (PISO shift register + mod-N counter + FSM template) compose into a complete UART transmitter. No new primitives — only architecture.