Control logic decides what happens and when. A finite state machine implements it with a state register, next-state logic, and outputs.
Topic | Lessons | After it you can… | Study time |
|---|---|---|---|
6 | Split a design into datapath and controller and code the FSM in two processes. | 2–3 h | |
4 | Choose an output style and register outputs when needed. | 1–2 h | |
4 | Compare binary, Gray, one-hot and Johnson; handle illegal states. | 2 h | |
4 | Build a shift-add multiplier and a latency-aware memory reader with timeout and abort. | 3 h | |
5 | Design and verify a complete serial transmitter. | 2–3 h | |
4 | Write a request/response controller and prove it with a scoreboard and mutations. | 2–3 h |
Study time covers reading each lesson and running its examples. The section's hands-on project takes extra hours on top.
So every output and the next state is assigned on every path. Anything left unassigned on some path becomes a latch. The coding rules lesson shows the latch Yosys reports when a default is missing.
Use these four questions to decide whether you are ready to move on: explain, predict, implement and debug. If one is shaky, each answer names the lesson to revisit. New readers can skip this until they finish the section.
A Moore output depends only on the state, so it changes one clock after the input that caused it and is decoded from the state register alone, never from a live input. A Mealy output also depends on the inputs, so it can react in the same cycle, but it is combinational from input to output: it can glitch and it adds to the next block's timing path. Revisit Moore and Mealy: the behavioral difference.
Binary needs 3 flops (ceiling of log2 5); one-hot needs 5. One-hot usually has simpler, shallower next-state and output decode, because each state is one bit, which is why it is common in FPGAs and fast paths; binary saves flops. Revisit Encodings compared.
States: S0 (nothing), S1 (seen 1), S10 (seen 10). From S10, an input 1 completes 101: the output is 1 and the next state is S1, because that last 1 can start the next match (10101 gives two detections). A non-overlapping detector would return to S0 instead. Revisit Side-by-side sequence detector.
A default in the next-state case that returns to a safe state (and ideally flags the error). Without it, an unused encoding has no defined exit and the FSM can stay there. Revisit Illegal states and recovery.
Authors can compile complete examples with node scripts/tools/check-rtl-snippets.mjs rtl/fsm and execute self-checking benches with node scripts/tools/run-rtl-testbenches.mjs rtl/fsm. These are separate validation commands, not an established every-build gate. Partial snippets and deliberately broken examples have documented exclusions in those scripts.
Coverage is bounded by each bench: GCD enumerates the 961 positive pairs in 1..31 at width 8, then exercises directed interface cases. That is not every 8-bit input or every parameter configuration.
Several lessons report mutation results: deliberately break the design and require the checker to reject it. Record source revision, simulator/tool versions, command, exclusions and final verdict when rerunning. Every self-checking bench in this section prints PASS under those commands; mutation results are rerun only where a lesson says so.
Waveforms illustrate the stated sampling convention; compare them with a fresh simulation of the same revision before treating them as execution evidence. Functional checks do not establish physical timing or mapped fault recovery.