A multi-state Mealy/Moore FSM digital controller implemented in synthesizable SystemVerilog. Features one-hot state encoding optimized for FPGA targets, hardware timeout detection, SVA assertion-based verification, and a constrained-random testbench with functional coverage.
The controller implements a 4-state FSM that orchestrates a simplified fetch-execute cycle with built-in error handling:
start=1
┌─────────────────┐
│ ▼
┌──────┐ ┌───────┐
───▶│ IDLE │ │ FETCH │──── data_valid=1 ────┐
└──────┘ └───────┘ │
▲ │ ▼
│ timeout_flag=1 ┌─────────┐
│ │ │ EXECUTE │
│ ▼ └─────────┘
│ ┌──────┐ │
└─────────────│ HALT │ done=1 │
start=0 └──────┘◀───────────────────┘
(auto-return)
State Descriptions:
| State | Encoding (One-Hot) | Description |
|---|---|---|
IDLE |
4'b0001 |
Waiting for start signal |
FETCH |
4'b0010 |
Reading memory; asserts mem_read |
EXECUTE |
4'b0100 |
Processing data; asserts alu_enable |
HALT |
4'b1000 |
Error state entered on timeout |
- Synthesizable RTL — Strict use of
always_ffandalways_comb; no latches, no blocking assignments in sequential logic - Mealy + Moore Hybrid — State-dependent (Moore) control signals with input-dependent (Mealy) error outputs
- One-Hot State Encoding — Optimized for Xilinx FPGA synthesis with minimal next-state decode logic
- Hardware Timeout Detection — Configurable cycle counter triggers
HALTifFETCHstalls - SVA Assertions — Inline SystemVerilog Assertions verify protocol invariants during simulation
- Constrained-Random Testbench — 20-iteration randomized stimulus with directed corner-case tests
- Functional Coverage Points —
cover propertystatements track normal flow and timeout path coverage - Parameterized Design —
TIMEOUT_CYCLESandDATA_WIDTHconfigurable via package parameters
FSM-Digital-Controller/
├── rtl/
│ ├── fsm_pkg.sv # Type definitions, parameters, structs
│ └── fsm_controller.sv # FSM RTL module with SVA assertions
├── tb/
│ └── tb_fsm_controller.sv # Constrained-random + directed testbench
├── Makefile # Icarus Verilog build & simulation flow
├── LICENSE # MIT License
└── README.md
- Icarus Verilog (
iverilog≥ 12.0 recommended for full SV support) - GTKWave (optional, for waveform viewing)
# Compile and simulate
make sim
# View waveforms (after simulation)
make wave
# Clean generated files
make clean╔══════════════════════════════════════════╗
║ FSM Digital Controller — Testbench ║
║ Author: Kushal Pitaliya ║
╚══════════════════════════════════════════╝
=== Test 1: Reset Behavior ===
[PASS] After reset, state is IDLE
[PASS] After reset, done is 0
[PASS] After reset, error is 0
=== Test 2: Normal Operation Flow ===
[PASS] After start, state is FETCH
[PASS] In FETCH, mem_read is high
[PASS] After data_valid, state is EXECUTE
[PASS] In EXECUTE, done is high
[PASS] In EXECUTE, data_out matches
[PASS] In EXECUTE, alu_enable is high
[PASS] After EXECUTE, state returns to IDLE
=== Test 3: Timeout Path ===
[PASS] State is FETCH
[PASS] After timeout, state is HALT
[PASS] In HALT, error is high
[PASS] In HALT, halt signal is high
=== Test 4: HALT Recovery ===
[PASS] State is HALT
[PASS] After HALT recovery, state is IDLE
=== Test 5: Constrained-Random Stimulus (20 iterations) ===
[PASS] Random iter 0: ...
...
╔══════════════════════════════════════════╗
║ Test Summary ║
╠══════════════════════════════════════════╣
║ Total: 36+ ║
║ Passed: 36+ ║
║ Failed: 0 ║
╚══════════════════════════════════════════╝
✅ ALL TESTS PASSED
One-hot encoding (4'b0001, 4'b0010, ...) is chosen because:
- FPGA-optimized: Xilinx/Altera FPGAs have abundant flip-flops but limited LUT inputs. One-hot uses more FFs but produces simpler, faster next-state logic.
- Glitch-free outputs: Only one bit transitions per state change, reducing combinational hazards.
- For ASIC targets, the encoding can be switched to binary (
2'b00,2'b01, ...) by modifyingfsm_pkg.sv.
The design uses a hybrid approach:
- Moore outputs (
ctrl.mem_read,ctrl.alu_enable,ctrl.halt,done): Depend only oncurrent_state. These are stable and glitch-free, ideal for driving downstream control logic. - Mealy outputs (
errorinFETCHstate): Depend on both state andtimeout_flag. This provides immediate error signaling without waiting for the next clock edge and state transition.
rst_n (active-low, asynchronous) is chosen because:
- Industry standard: Most FPGA and ASIC designs use active-low reset for compatibility with board-level reset circuits.
- Asynchronous assertion: Guarantees the FSM enters a known state even if the clock is not running (e.g., during power-up sequencing).
- Synchronous de-assertion: The reset is released synchronously by the
always_ffconstruct, preventing metastability on the reset recovery edge.
| Tool | Purpose |
|---|---|
| Icarus Verilog | RTL compilation and simulation |
| GTKWave | Waveform viewing and debug |
| Xilinx ISE/Vivado | Target FPGA synthesis platform |
| SystemVerilog | IEEE 1800-2017 design language |
Kushal Pitaliya
This project is licensed under the MIT License — see the LICENSE file for details.