Project: UART Transmitter

A complete serial transmitter: an FSM, a baud-rate counter and a shift register, checked by a receiver model in the testbench.

UART is the simplest serial protocol and a classic first hardware project: the line idles high, each byte is sent as a start bit (0), eight data bits least significant first, and a stop bit (1), each bit lasting a fixed time set by the baud rate. The transmitter combines everything so far: an FSM, a counter and a shift register.

The design

IDLE: hold tx high; on start, capture data into shreg and go to START.

START: drive tx low for one bit time.

DATA: drive bit bit_idx of shreg, eight times.

STOP: drive tx high for one bit time, then return to IDLE and drop busy.

clk_cnt counts clocks within a bit; bit_done marks the last clock of each bit.

Taking it further

tx <= shreg[7 - bit_idx]; // MSB first tx <= shreg[bit_idx]; // LSB first

UART sends the least significant bit first. Sending MSB first produces characters that are bit-reversed at the receiver.

With a 100 MHz clock, what CLKS_PER_BIT gives 9600 baud?

100,000,000 / 9600 = 10416.67, so 10417 (an error of about 0.003%, far inside UART's tolerance of a few percent).

How long does one 8N1 frame take at 115200 baud?

10 bits (start + 8 data + stop) / 115200 = about 86.8 µs.