CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/FSM Design

Unreachable State Recovery

HardVerilog / SystemVerilogBuild

In high-reliability environments like aerospace and medical devices, single-event upsets (SEUs) caused by radiation or electromagnetic noise can spontaneously flip register bits. If a finite state machine (FSM) uses a 3-bit register to encode 5 valid states, a bit flip can push the machine into one of the 3 undefined states. Without explicit recovery logic, the FSM will hang permanently, requiring a full system reset.

The seu_recovery_fsm module implements a 5-state circular counter with self-correcting logic. The valid states are IDLE (3'b000), S1 (3'b001), S2 (3'b010), S3 (3'b011), and S4 (3'b100). During normal operation, the FSM advances to the next state on every clock cycle where en is high, wrapping from S4 back to IDLE. If en is low, the FSM holds its current state.

To simulate SEUs, a fault_inject signal forces the state register to immediately load the value of fault_vector on the next clock edge. If the FSM ever finds itself in an illegal state (3'b101, 3'b110, or 3'b111), it must assert the error flag and unconditionally return to IDLE on the subsequent clock edge, regardless of the en signal.

The module operates on the positive edge of clk and resets on the negative edge of rst_n. On reset, the state becomes IDLE (3'b000) and all outputs evaluate accordingly. The done output is asserted purely combinationally whenever the FSM is in state S4. The error output is asserted purely combinationally whenever the FSM is in an illegal state. The state_out port continuously exposes the internal 3-bit state register.

Cycle 1: rst_n=0 → state_out=000, done=0, error=0 Cycle 2: rst_n=1, en=1, fault_inject=0 → state_out=001, done=0, error=0 Cycle 3: en=1 → state_out=010, done=0, error=0 Cycle 4: en=0 → state_out=010, done=0, error=0 (hold) Cycle 5: fault_inject=1, fault_vector=110 → state_out=110, done=0, error=1 Cycle 6: fault_inject=0, en=1 → state_out=000, done=0, error=0 (recovery)

flowchart LR
    RESET(( )) -->|reset| IDLE
    IDLE((000)) -->|en=1| S1((001))
    S1 -->|en=1| S2((010))
    S2 -->|en=1| S3((011))
    S3 -->|en=1| S4((100))
    S4:::out -->|en=1| IDLE
    IDLE -->|en=0| IDLE
    S1 -->|en=0| S1
    S2 -->|en=0| S2
    S3 -->|en=0| S3
    S4 -->|en=0| S4
    ERR1(["101 ★"]):::err -->|unconditional| IDLE
    ERR2(["110 ★"]):::err -->|unconditional| IDLE
    ERR3(["111 ★"]):::err -->|unconditional| IDLE
    classDef out fill:#6C5CE7,stroke:#5B4FE8,color:#fff
    classDef err fill:#D63031,stroke:#B33939,color:#fff
{ "signal": [
  { "name": "clk",          "wave": "p......" },
  { "name": "rst_n",        "wave": "01....." },
  { "name": "en",           "wave": "x110x1." },
  { "name": "fault_inject", "wave": "000010." },
  { "name": "fault_vector", "wave": "xxxx=x.", "data": ["110"] },
  {},
  { "name": "state_out",    "wave": "=======", "data": ["xxx", "000", "001", "010", "010", "110", "000"] },
  { "name": "error",        "wave": "0....10" }
], "head": { "text": "Cycle-by-cycle trace showing normal operation, fault injection, and recovery." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; state goes to 3'b000 | | en | input | 1 | Enable signal; advances state when high | | fault_inject | input | 1 | Forces state to load fault_vector on next posedge | | fault_vector | input | 3 | The 3-bit state to load when fault_inject is high | | state_out | output | 3 | Exposes the current value of the internal state register | | done | output | 1 | Combinational active-high output; 1 when state is 3'b100 | | error | output | 1 | Combinational active-high output; 1 when state is illegal |

Constraints

  • The done output must be exactly 1 when state_out is 3'b100, and 0 otherwise.
  • The error output must be exactly 1 when state_out is 3'b101, 3'b110, or 3'b111, and 0 otherwise.
  • The fault_inject signal takes priority over all other inputs except rst_n.
  • If the FSM is in an illegal state and fault_inject is 0, the next state must be 3'b000 regardless of the value of en.
  • Both done and error must be purely combinational outputs, updating immediately when the state changes.

Topics

FSMSequential LogicState MachineReliability

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

  • Glitch Free Gray Code FSMHard
  • Serial Adder Mealy MachineMedium
  • Three Process Moore FSM TemplateEasy
  • Lookahead FSM Sequence DetectorHard
  • Traffic Light Controller with TimerMedium
  • Arbiter FSM with Fixed PriorityHard
  • One Hot Encoding Flip Flop CountMedium
  • Typedef Enum State MachineEasy

Browse all problems · Learning tracks