CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

UART Receiver Data Shifter

HardVerilog / SystemVerilogBuild

UART receivers must robustly sample asynchronous serial data. To avoid data corruption from slight baud rate mismatches between the sender and receiver, the receiver oversamples the incoming stream to find the exact middle of each bit period. This module implements the core shifting and sampling logic for a UART receiver using a standard 16x oversampling approach.

The module receives a serial data line rx and a sample_tick enable signal that pulses 16 times per baud period. When rx drops low, the module interprets this as a potential start bit. It waits 8 sample_tick pulses to sample the middle of the start bit. If rx is still low, it proceeds to sample the next 8 data bits (LSB first), waiting 16 sample_tick pulses between each sample. Finally, it waits 16 ticks to sample the stop bit. If the stop bit is high, the assembled byte is valid. If the stop bit is low, a framing error has occurred.

  • Clock edge: posedge clk
  • Reset type: Asynchronous, active-low rst_n
  • Reset behaviour: data_out resets to 8'h00; data_valid and frame_err reset to 0
  • Output rules: All outputs are registered. When the 16th sample_tick of the stop bit is processed, data_valid (if valid) or frame_err (if invalid) must assert on the next clock edge. They must remain high for exactly one clock cycle. data_out must update on the same clock edge that data_valid goes high.

Worked Trace: Cycle 1: rst_n=0 → state=IDLE, data_valid=0, frame_err=0 Cycle 2: rst_n=1, rx=1, sample_tick=1 → state=IDLE Cycle 3: rx=0, sample_tick=1 → state=START, tick_cnt=0 Cycle 4: rx=0, sample_tick=0 → state=START, tick_cnt=1 (hold) Cycle 5: rx=0, sample_tick=1 → state=START, tick_cnt=1 ... Cycle 17: rx=0, sample_tick=1 → state=START, tick_cnt=7. Middle of start bit sampled; valid. Next state=DATA. Cycle 18: rx=1, sample_tick=1 → state=DATA, tick_cnt=0, bit_idx=0. ... Cycle 150: sample_tick=1 → state=STOP, tick_cnt=15. Stop bit sampled as 1. Cycle 151: sample_tick=0 → state=IDLE, data_valid=1, data_out=assembled_byte (1-cycle pulse) Cycle 152: sample_tick=0 → state=IDLE, data_valid=0

flowchart LR
    RESET(( )) -->|reset| IDLE
    IDLE((IDLE)) -->|rx=0 & tick| START
    START -->|tick & cnt=7 & rx=0| DATA
    START -->|tick & cnt=7 & rx=1| IDLE
    DATA -->|tick & cnt=15 & bit=7| STOP
    DATA -->|tick & cnt=15 & bit<7| DATA
    STOP(["STOP ★"]):::out -->|tick & cnt=15 & rx=1| IDLE
    STOP -->|tick & cnt=15 & rx=0| IDLE
    classDef out fill:#6C5CE7,stroke:#5B4FE8,color:#fff

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered system clock | | rst_n | input | 1 | Asynchronous active-low reset | | rx | input | 1 | Asynchronous serial data line | | sample_tick | input | 1 | Enable pulse that asserts 16 times per baud period | | data_out | output | 8 | Assembled byte; updates when a valid frame is received | | data_valid| output | 1 | Pulses high for exactly 1 clock cycle when a valid byte is received | | frame_err | output | 1 | Pulses high for exactly 1 clock cycle if the stop bit is 0 |

Constraints

  • The module must ignore glitches on the start bit; if rx is high at the 8th tick of the START state, the module must immediately return to IDLE without asserting any errors.
  • The data_valid and frame_err signals must never be asserted simultaneously.
  • The data_out signal must hold its value until a new valid frame is completely received.
  • Data is transmitted LSB first.
  • sample_tick may not be asserted every clock cycle; the module must only advance its internal counters when sample_tick is 1.

Topics

FSMShift RegisterTimingInterfaces

Solve this problem

Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.

This problem is part of Codiode Pro. The statement above is free to read.

Sign in to solveSee what Pro unlocks

The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks