← ProblemsCircuits / Sequential Logic / Finite State Machines

Serial receiver with parity checking

5%fsmdatapathserial-protocols

Add odd parity checking to the serial receiver. The frame format changes to: start bit (0), then 9 data bits — 8 data bits (LSB first) followed by 1 parity bit — then a stop bit (1). Odd parity means the 9 data bits together must contain an odd number of 1s.

Behavior:

  • A 0 while waiting is a start bit; the next 9 cycles carry the 8 data bits and the parity bit; the cycle after that must carry the stop bit (1).
  • Assert done for one cycle (the cycle after the stop bit) only if the stop bit was 1 and the parity check passed. If the stop bit was 1 but parity failed, do not assert done — simply resume waiting for a start bit (the cycle after the stop bit may already contain one, exactly as in the done case).
  • On a framing error (in = 0 in the stop-bit cycle), wait until in = 1 before searching for a start bit again. No done.
  • out_byte[7:0] must hold the 8 data bits (LSB first) whenever done is high. As before, implement it as a right-shift register that updates only at the end of each of the first 8 data-bit cycles (the parity bit is not shifted in); it holds its value otherwise and is not cleared by reset.
  • Active-high synchronous reset.

You are given the following helper module (also included in the starter code) — instantiate it to count 1 bits. Its reset is synchronous, and odd is 1 whenever an odd number of 1s have arrived on its in since its last reset:

module parity (
    input clk,
    input reset,
    input in,
    output reg odd);

    always @(posedge clk)
        if (reset) odd <= 0;
        else if (in) odd <= ~odd;
endmodule

Hold the helper in reset except during the 9 data-bit cycles, and feed it the serial line; then odd holds the parity result during the stop-bit cycle, exactly when you need it.