name: "Hamming SECDED Decoder"
category: "Cryptography & Compression"
complexity: "Medium"
description: |
  Implement a synchronous decoder for an 8-bit data word protected by an
  extended Hamming SECDED code.

  The input `codeword_in` contains a 13-bit codeword formed from:
  - 8 data bits
  - 4 Hamming parity bits
  - 1 overall parity bit

  The decoder must classify each received codeword as one of:
  - no error
  - a single-bit error that can be corrected
  - a double-bit error that must be detected but not corrected

  INPUT/OUTPUT TIMING:
  - A codeword is accepted on a rising edge when `in_valid` is high.
  - The decoder has a single registered output stage. For each accepted
    codeword, `out_valid` must be asserted for exactly 1 cycle
    immediately after that same rising edge, with no additional delay
    cycle.
  - `data_out`, `single_error_corrected`, and `double_error_detected`
    must update on that same clock edge and remain aligned with the
    `out_valid` pulse.
  - The interface accepts a new valid codeword every cycle.
  - When `in_valid` is low, no new codeword is sampled, and the module
    must not produce an output for that clock cycle.

  CODEWORD BIT LAYOUT:
  - `codeword_in[0]`  = parity bit p1   (position 1)
  - `codeword_in[1]`  = parity bit p2   (position 2)
  - `codeword_in[2]`  = data bit d0     (position 3)
  - `codeword_in[3]`  = parity bit p4   (position 4)
  - `codeword_in[4]`  = data bit d1     (position 5)
  - `codeword_in[5]`  = data bit d2     (position 6)
  - `codeword_in[6]`  = data bit d3     (position 7)
  - `codeword_in[7]`  = parity bit p8   (position 8)
  - `codeword_in[8]`  = data bit d4     (position 9)
  - `codeword_in[9]`  = data bit d5     (position 10)
  - `codeword_in[10]` = data bit d6     (position 11)
  - `codeword_in[11]` = data bit d7     (position 12)
  - `codeword_in[12]` = overall parity p0

  DATA OUTPUT ORDER:
  - `data_out[0] = d0`
  - `data_out[1] = d1`
  - `data_out[2] = d2`
  - `data_out[3] = d3`
  - `data_out[4] = d4`
  - `data_out[5] = d5`
  - `data_out[6] = d6`
  - `data_out[7] = d7`

  PARITY CONVENTION:
  - Use even parity throughout.
  - The Hamming parity bits protect positions 1 through 12 as follows:
      p1 covers positions 1, 3, 5, 7, 9, 11
      p2 covers positions 2, 3, 6, 7, 10, 11
      p4 covers positions 4, 5, 6, 7, 12
      p8 covers positions 8, 9, 10, 11, 12
  - The overall parity bit `p0` makes the total parity across all 13 bits
    even.

  DECODING RULES:
  - Compute the 4-bit syndrome from the Hamming parity checks.
  - Compute whether the total parity across all 13 received bits is even
    or odd.
  - If the syndrome is 0 and total parity is even, treat the codeword as
    error-free.
  - If the syndrome is non-zero and total parity is odd, treat this as a
    single-bit error in positions 1 through 12. Correct the bit indicated
    by the syndrome before extracting `data_out`, and assert
    `single_error_corrected`.
  - If the syndrome is 0 and total parity is odd, treat this as a
    single-bit error in the overall parity bit `p0`. The data bits are
    already correct, and `single_error_corrected` must still assert.
  - If the syndrome is non-zero and total parity is even, treat this as a
    detected double-bit error. Do not attempt correction. In this case,
    output the data bits exactly as received in the corrupted codeword and
    assert `double_error_detected`.
  - `single_error_corrected` and `double_error_detected` must never both
    be high for the same output.

  RESET:
  - `rst` is synchronous and active-high.
  - On reset, clear any in-flight output so that `out_valid`,
    `single_error_corrected`, and `double_error_detected` are low.
  - When `out_valid` is low, `single_error_corrected` and
    `double_error_detected` must both be low.

interface:
  module_name: "hamming_secded_decoder"
  clocked: true
  ports:
    - name: "clk"
      type: "input"
      width: "1"
      description: "Clock signal"
    - name: "rst"
      type: "input"
      width: "1"
      description: "Synchronous active-high reset"
    - name: "in_valid"
      type: "input"
      width: "1"
      description: "High when codeword_in contains a valid SECDED codeword to decode"
    - name: "codeword_in"
      type: "input"
      width: "13"
      description: "Received 13-bit extended Hamming SECDED codeword"
    - name: "out_valid"
      type: "output"
      width: "1"
      description: "High for one cycle when the decoded result is valid"
    - name: "data_out"
      type: "output"
      width: "8"
      description: "Decoded 8-bit data word, corrected only for correctable single-bit errors"
    - name: "single_error_corrected"
      type: "output"
      width: "1"
      description: "High when the accepted codeword contained a correctable single-bit error"
    - name: "double_error_detected"
      type: "output"
      width: "1"
      description: "High when the accepted codeword contained a detected uncorrectable double-bit error"

target_platform:
  device_family: "AMD Xilinx Zynq-7000"

tasks:
  - name: "Area-Efficient Hamming SECDED Decoder"
    constraints:
      max_lut: 90
      max_ff: 48
      max_bram: 0
      max_dsp: 0
      min_frequency: 200
    objective:
      goal: "minimise"
      target: "LUT"
