A clean 8N1 UART transmitter and receiver in SystemVerilog — 8 data bits, no
parity, 1 stop bit — parameterized by CLKS_PER_BIT (clock frequency ÷ baud
rate). The receiver double-flops the incoming line to tame metastability and
samples each bit at its midpoint. Verified end-to-end with a TX→RX loopback
testbench.
UART is the serial link the APEX SoC used between its FPGA brain and its MSP432 vehicle body; this is that building block as a clean, reusable core.
uart_tx — drives a byte out, LSB first, with start/stop framing.
| Signal | Dir | Meaning |
|---|---|---|
tx_start |
in | pulse to begin sending tx_data |
tx_data[7:0] |
in | byte to send |
tx |
out | serial line (idles high) |
tx_busy |
out | high while transmitting |
tx_done |
out | 1-cycle pulse when the byte completes |
uart_rx — recovers a byte from the serial line.
| Signal | Dir | Meaning |
|---|---|---|
rx |
in | serial line |
rx_data[7:0] |
out | received byte |
rx_valid |
out | 1-cycle pulse when a byte is ready |
iverilog -g2012 -o sim.out rtl/uart.sv tb/uart_tb.sv
vvp sim.out # TX->RX loopback, 6/6 self-checking- Oversampling + mid-bit sampling. With
CLKS_PER_BITclocks per bit, the RX detects the start edge, waits half a bit to land in the middle of the start bit, then samples every full bit period — maximally far from the edges where jitter lives. - 2-flop synchronizer on
rx. The serial line is asynchronous toclk; double-flopping prevents metastability from propagating into the FSM. - False-start rejection. If the line isn't still low at the mid-start check, the RX returns to IDLE — a glitch won't trigger a phantom byte.
- LSB-first framing on both sides, matching the UART standard.
CLKS_PER_BIT = f_clk / baudmakes the core portable across clock/baud combinations without touching the logic.
Built by Efe Demir.