Day 7: Finite State Machines¶
Course: Accelerated HDL for Digital System Design¶
Week 2, Session 7 of 16¶
Student Learning Objectives¶
- SLO 7.1: Distinguish Moore and Mealy machines and select the appropriate model for a given design problem.
- SLO 7.2: Translate a state diagram into synthesizable Verilog using the 3-always-block coding style.
- SLO 7.3: Use
localparamorparameterfor named state encoding and evaluate binary vs. one-hot trade-offs. - SLO 7.4: Design and implement a multi-state FSM with timed transitions (counters as timers).
- SLO 7.5: Write a thorough testbench that verifies every state transition and timing constraint.
Pre-Class Video (~50 min)¶
| # | Segment | Duration | File |
|---|---|---|---|
| 1 | Moore vs. Mealy: outputs on state only vs. state + input | 12 min | video/day07_seg1_moore_vs_mealy.mp4 |
| 2 | State diagrams to HDL: a systematic translation process | 12 min | video/day07_seg2_state_to_hdl.mp4 |
| 3 | 3-always-block FSM coding style: state register, next-state, output | 14 min | video/day07_seg3_three_block_style.mp4 |
| 4 | State encoding: binary, one-hot, gray — trade-offs | 12 min | video/day07_seg4_state_encoding.mp4 |
Session Timeline¶
| Time | Activity | Duration |
|---|---|---|
| 0:00 | Warm-up: testbench review, pre-class questions | 5 min |
| 0:05 | Mini-lecture: FSM design methodology, live design | 30 min |
| 0:35 | Lab Exercise 1: Traffic light controller | 35 min |
| 1:10 | Lab Exercise 2: Traffic light testbench | 20 min |
| 1:30 | Break | 5 min |
| 1:35 | Lab Exercise 3: Pattern detector | 30 min |
| 2:05 | Lab Exercise 4 (Stretch): Mealy pattern detector | 15 min |
| 2:20 | Wrap-up and Day 8 preview | 10 min |
In-Class Mini-Lecture (30 min)¶
FSM Design Methodology (10 min)¶
- Draw the state diagram — on paper first, always
- Enumerate states and transitions — build a state table
- Code it using the 3-always-block pattern
- Simulate it — verify every transition
- Why three always blocks? Separation of concerns: the state register is trivial and never changes, next-state logic is purely combinational, output logic is isolated for easy modification.
Why Three Always Blocks? (5 min)¶
- Block 1 — State register:
always @(posedge clk)— just loadsnext_stateintostate - Block 2 — Next-state logic:
always @(*)— combinational, usescase(state)withifon inputs - Block 3 — Output logic:
always @(*)— combinational,case(state)determines outputs - Benefit: clean separation makes debugging straightforward, modifications are localized
Live Design: Paper to Code (15 min)¶
- Design a simple vending machine or pattern detector on the whiteboard
- Draw the state diagram together
- Walk through the 3-block translation step by step
- Discuss: where do counters fit? (They become enable signals or transition conditions)
Lab Exercises¶
Exercise 1: Traffic Light Controller (35 min)¶
Objective (SLO 7.2, 7.3, 7.4): Build a classic FSM with timed state transitions.
Tasks:
1. Design a traffic light controller with states: GREEN, YELLOW, RED.
- GREEN → YELLOW after ~3 seconds (75,000,000 cycles at 25 MHz, or use a shorter count for simulation)
- YELLOW → RED after ~1 second
- RED → GREEN after ~4 seconds
2. Use localparam for state names: localparam GREEN = 2'b00, YELLOW = 2'b01, RED = 2'b10;
3. Implement using the 3-always-block style.
4. Drive LEDs on the Go Board to represent the traffic light (e.g., LED 0 = green, LED 1 = yellow, LED 2 = red).
5. Use a counter for timing. Tip: Use a parameterized counter limit so you can use short values for simulation and long values for hardware.
Checkpoint: Traffic light cycles through states at visible speed on hardware.
Exercise 2: Traffic Light Testbench (20 min)¶
Objective (SLO 7.5): Write a testbench that verifies all state transitions and timing.
Tasks:
1. Instantiate the traffic light with short timer values (e.g., GREEN_TIME = 10, YELLOW_TIME = 5, RED_TIME = 15) for fast simulation.
2. Verify the complete state sequence: GREEN → YELLOW → RED → GREEN → ...
3. Check timing: verify each state lasts the correct number of cycles.
4. Check reset: assert reset mid-cycle, verify return to GREEN.
5. Self-checking: compare state output against expected state at each transition.
Checkpoint: Testbench verifies at least 2 full cycles through all states.
Exercise 3: Pushbutton Pattern Detector (30 min)¶
Objective (SLO 7.1, 7.2, 7.4): Build a Moore FSM that recognizes a specific input sequence.
Tasks: 1. Design a Moore FSM that detects a 3-button sequence (e.g., Button 0, Button 1, Button 0). 2. Draw the state diagram first (on paper or whiteboard). States: IDLE, GOT_B0, GOT_B0_B1, MATCH. 3. On successful match, light an LED for ~1 second, then return to IDLE. 4. On wrong button at any point, return to IDLE. 5. Use debounced button inputs (reuse the debouncer from Day 5). 6. Simulate with a testbench that verifies: correct sequence → match, incorrect sequence → no match, partial correct then wrong → reset to IDLE. 7. Program on the Go Board.
Checkpoint: Pattern detector working on hardware with debounced buttons.
Exercise 4 (Stretch): Mealy Pattern Detector (15 min)¶
Objective (SLO 7.1): Compare Moore and Mealy implementations of the same specification.
Tasks: 1. Implement a Mealy version of the pattern detector: output goes high on the same clock edge as the final matching input (one cycle earlier than Moore). 2. Simulate both versions side by side. Observe the one-cycle output difference. 3. Discuss: when does this timing difference matter? (Hint: think about downstream logic that uses the match signal.)
Deliverable¶
Traffic light FSM running on the Go Board with a waveform-verified testbench showing all state transitions.
Assessment Mapping¶
| Exercise | SLOs Assessed | Weight |
|---|---|---|
| 1 — Traffic light FSM | 7.2, 7.3, 7.4 | Core |
| 2 — Traffic light TB | 7.5 | Core |
| 3 — Pattern detector | 7.1, 7.2, 7.4 | Core |
| 4 — Mealy detector | 7.1 | Stretch (bonus) |
⚠️ Common Pitfalls & FAQ¶
Day 7 is your first FSM. State machines are powerful but have specific patterns that must be followed precisely.
- Missing
defaultin next-statecase? Everycasestatement in combinational logic needs adefault. Without one, Yosys infers a latch — and your FSM will behave unpredictably. This is the same latch rule from Day 3, now applied to state transitions. - Should the counter live inside the FSM? No — keep them separate. Put the FSM logic (state transitions) in one
alwaysblock, and the counter in another. Mixing them makes the FSM harder to debug and harder to read. - Simulation is very slow? If your timer counts to 25,000,000 in simulation, it will take forever. Parameterize your timeout values: use small values (10–100 cycles) for simulation, real values for synthesis. The Makefile can pass different parameters via
iverilog -D. - Confused about one-hot encoding? Don't worry about it yet. Use simple binary
localparamvalues (S_IDLE = 2'b00,S_GREEN = 2'b01, etc.) for your state definitions. The synthesis tool can re-encode to one-hot if it helps — that's its job, not yours. - Don't have a working debouncer from Day 5? The
shared/lib/debounce.vmodule is a drop-in replacement. Use it so you can focus on FSM design.
Preview: Day 8¶
Hierarchy, parameters, and generate — the tools for building reusable, scalable designs. You'll parameterize modules, use generate blocks for hardware replication, and get your second hands-on experience with AI-assisted testbench generation — this time for parameterized modules.