name: "Keypad Access Control FSM"
category: "Embedded Control & I/O"
complexity: "Medium"
description: >
  Implement a digital lock controller that monitors keypad presses and
  asserts an unlock pulse when the correct 4-digit access code has been
  entered.

  The module receives one key event at a time. A key press is accepted
  only on a rising clock edge when `key_valid` is high. There is no key
  debounce logic in this task; each accepted key event represents exactly
  one key press.

  ACCESS CODE:
  - The fixed access code is 2, 4, 6, 2.
  - `key_code` values 4'h0 through 4'h9 represent decimal digits 0
    through 9.
  - `key_code` value 4'hF is a CLEAR key.
  - Other `key_code` values will not be used by the tests.

  MATCHING RULES:
  - A correct next digit advances the current progress through the code.
  - If an incorrect digit is entered, the current progress is cleared.
  - Exception: if the incorrect digit is 2, it must immediately count as
    the first digit of a new attempt.
  - If the CLEAR key is entered, any partial progress is cleared and the
    module must not unlock.
  - When `key_valid` is low, the module ignores `key_code` and retains
    the current progress.

  OUTPUT BEHAVIOUR:
  - Assert `unlock` for exactly one clock cycle when the final digit of
    the code is accepted.
  - The unlock pulse occurs on the clock cycle in which the last correct
    key press is accepted.
  - After generating the unlock pulse, the internal progress resets to
    the idle state.

  RESET:
  - `rst` is synchronous and active-high.
  - On reset, clear all internal state and drive `unlock` low.

interface:
  module_name: "digital_lock_keypad_fsm"
  clocked: true
  ports:
    - name: "clk"
      type: "input"
      width: "1"
      description: "Clock signal"
    - name: "rst"
      type: "input"
      width: "1"
      description: "Synchronous active-high reset"
    - name: "key_valid"
      type: "input"
      width: "1"
      description: "High when key_code contains a new key press to accept"
    - name: "key_code"
      type: "input"
      width: "4"
      description: "Keypad code: 0-9 for digits, F for CLEAR"
    - name: "unlock"
      type: "output"
      width: "1"
      description: "One-cycle pulse asserted when the correct code is completed"

target_platform:
  device_family: "AMD Xilinx Zynq-7000"

tasks:
  - name: "Area-Efficient Keypad Lock FSM"
    constraints:
      max_lut: 40
      max_ff: 16
      max_bram: 0
      max_dsp: 0
      min_frequency: 200
    objective:
      goal: "minimise"
      target: "LUT"
