A fully functional UART (Universal Asynchronous Receiver Transmitter) implemented in Verilog from scratch. Includes a transmitter, receiver, and full loopback test that sends the message "HELLO" over a single serial wire — simulated using Icarus Verilog and EPWave on EDA Playground.
UART is a serial communication protocol that allows two devices to exchange data using just 2 wires (TX and RX) without a shared clock signal. It is used in virtually every embedded system — Arduino, ESP32, STM32, GPS modules, Bluetooth modules and more all use UART internally.
Every byte is transmitted as a 10-bit frame: Line: 1 1 1 0 b0 b1 b2 b3 b4 b5 b6 b7 1 1 idle start D0 D1 D2 D3 D4 D5 D6 D7 stop idle
- Idle line sits HIGH
- Start bit (0) signals beginning of transmission
- 8 data bits sent LSB first
- Stop bit (1) signals end of transmission
- Both sides must agree on baud rate — no clock wire needed
| Parameter | Value |
|---|---|
| Clock frequency | 50 MHz |
| Baud rate | 9600 |
| Data bits | 8 |
| Parity | None |
| Stop bits | 1 |
| Clocks per bit | 5208 |
┌─────────────────┐ ┌─────────────────┐
│ UART │ tx_wire │ UART │
│ Transmitter │ ───────────► │ Receiver │
│ (uart_tx.v) │ │ (uart_rx.v) │
└─────────────────┘ └─────────────────┘
│ │
sends bits reconstructs
serially byte
- Takes an 8-bit parallel input
- Serializes it into start + 8 data + stop bits
- Sends each bit for exactly CLKS_PER_BIT clock cycles
busysignal goes HIGH during transmission- State machine: IDLE → START → DATA → STOP → DONE
- Watches RX line for start bit (HIGH to LOW transition)
- Waits half a bit period to center-sample the start bit
- Samples each data bit at center of its period
- Reconstructs the full byte and pulses
validfor 1 cycle - Includes noise rejection — false start bits are ignored
- State machine: IDLE → START → DATA → STOP → DONE
- Connects TX output directly to RX input
- Tests full end-to-end transmission
- Sends "HELLO" character by character and verifies each one
Both TX and RX use the same 5-state FSM:
start=1 all bits sent
IDLE ──────────► START ──────────► DATA ──────────► STOP ──► DONE
▲ │
└──────────────────────────────────────────────────────────────┘
back to IDLE
================================
UART Full Loopback Test
Sending: H E L L O
Sent: H (0x48) | Received: H (0x48) | PASS
Sent: E (0x45) | Received: E (0x45) | PASS
Sent: L (0x4c) | Received: L (0x4c) | PASS
Sent: L (0x4c) | Received: L (0x4c) | PASS
Sent: O (0x4f) | Received: O (0x4f) | PASS
Loopback Test Complete!
| Tool | Purpose |
|---|---|
| EDA Playground | Online Verilog IDE |
| Icarus Verilog 12.0 | Verilog compiler and simulator |
| EPWave | Online waveform viewer |
| VS Code | Local code editor |
| Git + GitHub | Version control |
uart/
├── uart_tx.v # Transmitter module
├── uart_tx_tb.v # Transmitter testbench
├── uart_rx.v # Receiver module
├── uart_rx_tb.v # Receiver testbench
├── uart_loopback.v # Full loopback top module
├── uart_loopback_tb.v # Full loopback testbench
└── README.md # This file
- Go to edaplayground.com
- Paste design file in left box
- Paste testbench in right box
- Select Icarus Verilog 12.0, enable EPWave
- Hit Run
# Install tools
sudo apt install iverilog gtkwave
# Transmitter test
iverilog -o tx_sim uart_tx.v uart_tx_tb.v
vvp tx_sim
# Receiver test
iverilog -o rx_sim uart_rx.v uart_rx_tb.v
vvp rx_sim
# Full loopback test
iverilog -o loop_sim uart_loopback.v uart_loopback_tb.v
vvp loop_sim
# View waveform
gtkwave dump.vcd- Verilog HDL and hardware description
- Serial communication protocol implementation
- Finite state machine (FSM) design
- Baud rate timing and clock cycle calculations
- Center sampling for reliable bit detection
- Noise rejection on start bit detection
- Parallel to serial conversion (TX)
- Serial to parallel conversion (RX)
- Hardware simulation and waveform analysis
Muniem Amjad Computer Engineering Student