UART Receiver (8N1) with Glitch Filter and Framing Error

Hard · Counters & Timers · Finite State Machines

Design a UART receiver for the 8N1 format (8 data bits, LSB first, no parity, 1 stop bit). The line rx idles high. A frame is a start bit (0), data bits d0 (LSB) ... d7 (MSB), and a stop bit (1); each bit lasts CLKS_PER_BIT clock cycles.

A robust receiver does not trust edges. It finds the middle of the start bit, checks that the line is still low there (otherwise the falling edge was just a glitch), and then samples every following bit once, in its middle.

Parameters

ParameterDefaultMeaning
CLKS_PER_BIT8Clock cycles per bit, 4 <= CLKS_PER_BIT <= 65535. Your design must work for every value in this range (odd ones too): the hidden tests also use non-default values, including the smallest.

Let H = CLKS_PER_BIT / 2 (integer division; H = 4 for the default).

Ports

PortDirWidthMeaning
clkinput1Clock.
rstinput1Synchronous, active-high reset (takes effect only at a rising edge of clk).
rxinput1Serial line. It is already synchronized to clk; use it directly.
dataoutput8Received byte. Only required to be correct while valid = 1.
validoutput1One-cycle pulse: a frame was received correctly (registered).
frame_erroroutput1One-cycle pulse: the stop bit was 0 (registered).

Behavior

rx is sampled at every rising edge of clk. The receiver only looks at the samples listed below; all other samples are ignored.

  1. Idle. The receiver waits for a sample rx = 0. Call the edge where it sees this

first 0 edge t0.

  1. Start-bit check at edge t0 + H. If rx = 1 there, the low pulse was a glitch:

the receiver returns to idle, produces no output, and can detect a new start bit from edge t0 + H + 1 on. If rx = 0, reception continues.

  1. Data bits. Bit d[i] (i = 0..7) is the sample at edge t0 + H + (i+1)·CLKS_PER_BIT.
  2. Stop bit. The sample at edge ts = t0 + H + 9·CLKS_PER_BIT:
  3. rx = 1: the frame is good. In the cycle right after edge ts, valid = 1 and

data = {d7, ..., d0}. The receiver is idle again starting with edge ts + 1 (that edge may already be the t0 of the next frame).

valid = 0. The receiver then waits until it samples rx = 1 (at some edge ≥ ts + 1); only at the edges after that one can it detect a new start bit. This keeps a "break" (line held low) from being received as a stream of 0x00 frames.

  1. valid and frame_error are 0 in every other cycle (each is a pulse of exactly one

cycle per frame, and they are never both 1).

  1. Reset (edge with rst = 1): any reception in progress is abandoned; valid = 0,

frame_error = 0; the receiver is idle (the first edge with rst = 0 can be a t0). Reset is synchronous: raising rst during a cycle in which valid or frame_error is 1 does not cut that pulse short; it ends at the next rising edge as usual.

A transmitter with the same CLKS_PER_BIT that starts its start bit just before edge t0 produces CLKS_PER_BIT samples per bit, so the sample points above fall in the middle of each bit. Back-to-back frames (the next start bit immediately after a stop bit) are received without loss.

Example (CLKS_PER_BIT = 8, H = 4, receiving 8'h35 = 0011_0101)

whatedge (relative to t0)rx sampled
first 0 (t0)00
start check40
d0 ... d712, 20, 28, 36, 44, 52, 60, 681, 0, 1, 0, 1, 1, 0, 0
stop761 → valid = 1, data = 8'h35 in the next cycle

A low glitch that is sampled as 0 for at most H consecutive edges is ignored (its sample at t0 + H is 1).

The diagram below illustrates the sample points with a smaller CLKS_PER_BIT = 4 (H = 2) so that it fits: the start bit, d0 = 1 and d1 = 0. t0 is the edge at the end of the first low cycle; the marked cycles end at the sampling edges t0 + 2 (start check), t0 + 6 (d0) and t0 + 10 (d1).

Sign up free to solve UART Receiver (8N1) with Glitch Filter and Framing Error in your browser.

More Counters & Timers problems