Size, platform and safety needs suggest candidates; mapped resource/timing results and the fault contract decide. Illegal-state behaviour still needs a check whichever encoding wins.
Stop at the first yes. Every branch still keeps the RTL as a named enum, so changing the answer later is a one-line edit.
Situation | Encoding |
|---|---|
Small FSM (≤ 8 states), area-sensitive ASIC | Binary (let the tool choose) |
FPGA, medium or large FSM, speed matters | Try one-hot; compare target timing/resource reports |
State is read asynchronously or crosses a clock domain | Handshake a stable status snapshot; raw Gray FSM state or a registered copy alone is insufficient |
Long sequence where each step must decode cheaply | Johnson |
Safety-critical (fault tolerance matters) | One-hot or Hamming-distance-2 codes with illegal-state detection |
Unsure | Write |
// snippet
// The enum hides the code. Synthesis tools may re-encode it (one-hot, Gray, binary) on request,
// while the RTL and the testbench stay unchanged.
typedef enum logic [2:0] {IDLE, START, DATA, PARITY, STOP, ERROR} state_t;
state_t state, next;
// Vendor attributes (spelling differs by tool) request the encoding without touching the logic:
// (* fsm_encoding = "one_hot" *) state_t state; // Vivado
// syn_encoding = "onehot" // Synplify-styleUse named enum values everywhere, never bare numbers. A change of encoding then changes nothing else.
Never decode bits of the state (state[2]) outside the FSM. That bakes the encoding in.
Register FSM outputs that need a clean downstream value (see Moore vs Mealy).
Check the synthesis log: tools report re-encoded FSMs, so confirm the result matches the intent.
The primary Yosys FSM documentation describes extraction of control outputs, including a directly used state bit whose value is preserved as a control output. Detection heuristics and forced encoding attributes have tool-specific limits; inspect the report rather than assuming every enum will be recoded.
if (state[1]) in a block outside the FSM. What is the risk?It couples source behavior to the written code, making manual encoding changes less portable and potentially limiting extraction/recoding. Correct synthesis must preserve that defined output, possibly by retaining decode logic. Expose a named decoded flag and verify equivalence instead of expecting automatic recoding to break semantics.