name: "Oversampled 8N1 UART Receiver"
category: "Embedded Control & I/O"
complexity: "Medium"
description: |
  Implement a synchronous UART receiver for 8-N-1 serial frames.

  FRAME FORMAT:
  - Serial line `rx` is idle high.
  - Each frame consists of:
      - 1 start bit = 0
      - 8 data bits, least-significant bit first
      - 1 stop bit = 1
  - There is no parity bit.

  BIT TIMING:
  - One UART bit period is exactly 16 rising edges of `clk`.
  - The receiver is idle while waiting for a potential start bit.
  - A candidate start bit begins when the receiver is idle and observes
    `rx=0` on a rising edge of `clk`.
  - Exactly 8 rising edges of `clk` after that detection edge, sample the
    middle of the start bit:
      - If `rx` is 0 at that midpoint sample, accept the frame.
      - If `rx` is 1 at that midpoint sample, treat it as a false start and
        return to the idle state with no output pulse.
  - After a valid start bit, sample the 8 data bits every 16 rising edges of
    `clk`, beginning 16 rising edges after the start midpoint sample.
  - Sample the stop bit 16 rising edges after the sample of data bit 7.

  OUTPUT BEHAVIOUR:
  - If the stop-bit sample is 1, pulse `data_valid` high for exactly one
    cycle and drive the received byte on `data_out`.
  - If the stop-bit sample is 0, pulse `framing_error` high for exactly one
    cycle and do not assert `data_valid`.
  - `data_valid` and `framing_error` must never be high in the same cycle.
  - `data_out` is only required to be valid in cycles where `data_valid` is
    high.

  RECEPTION RULES:
  - While a frame is in progress, the receiver must ignore intermediate
    transitions on `rx` except at the defined sample points.
  - Back-to-back valid frames are allowed. No extra idle cycles are required
    beyond the single stop bit.
  - The benchmark will not present breaks, parity bits, or configurable baud
    rates.

  RESET:
  - `rst` is synchronous and active-high.
  - While `rst` is high, clear any partial reception state and drive both
    `data_valid` and `framing_error` low.
  - If `rst` is asserted in the middle of a frame, abandon that frame and
    return to the idle state immediately after that rising edge of `clk`.

interface:
  module_name: "uart_receiver"
  clocked: true
  ports:
    - name: "clk"
      type: "input"
      width: "1"
      description: "System clock running at 16x the UART baud rate"
    - name: "rst"
      type: "input"
      width: "1"
      description: "Synchronous active-high reset"
    - name: "rx"
      type: "input"
      width: "1"
      description: "Asynchronous UART serial input, idle high"
    - name: "data_out"
      type: "output"
      width: "8"
      description: "Received byte, valid only when data_valid is high"
    - name: "data_valid"
      type: "output"
      width: "1"
      description: "One-cycle pulse for a correctly received frame"
    - name: "framing_error"
      type: "output"
      width: "1"
      description: "One-cycle pulse when the stop bit is sampled low"

target_platform:
  device_family: "AMD Xilinx Zynq-7000"

tasks:
  - name: "Area-Efficient UART Receiver"
    constraints:
      max_lut: 95
      max_ff: 72
      max_bram: 0
      max_dsp: 0
      min_frequency: 180
    objective:
      goal: "minimise"
      target: "LUT"
