FSM-Based Coverage
generate-fsm creates state-coverage-enhanced C++ testbenches for sequential designs with finite state machines (FSMs). Instead of random input patterns, it uses depth-first search (DFS) over the FSM state graph to reach every state and transition.
When to Use It
Sequential designs with FSMs (clocks, resets, internal state)
Random testing misses states because reaching them requires specific input sequences
Designs with internal timers/counters that gate transitions
Traditional stg generate relies on random inputs, which often fails to hit states like S_PED_WALK that need multi-cycle sequences. generate-fsm discovers the FSM structure and generates targeted tests.
Quick Start
Without LLM (Deterministic)
stg generate-fsm design.sv \
--golden golden.sv \
--out tb.cpp \
--out-exe tb \
--fsm-method deterministic
With LLM (More Flexible)
Requires an API key (GOOGLE_API_KEY, OPENAI_API_KEY, or OPENROUTER_API_KEY in .env or environment):
stg generate-fsm design.sv \
--golden golden.sv \
--out tb.cpp \
--out-exe tb \
--fsm-method lm \
--lm-provider gemini
FSM Extraction Methods
Method |
Description |
Requirements |
|---|---|---|
|
Parser-based (iverilog/sv-parser) |
None |
|
LLM identifies FSM from source |
API key, |
deterministic: Fast and reliable. Works for standard FSM coding styles.
lm: Better for complex or unusual FSMs. Uses an LLM to interpret the RTL.
State Analysis Caching
Use --state-analysis to save and reuse FSM analysis:
# First run: analyze design and save to fsm.json
stg generate-fsm design.sv --golden golden.sv --out tb.cpp \
--state-analysis fsm.json
# Later runs: load from fsm.json (skips analysis)
stg generate-fsm design.sv --golden golden.sv --out tb.cpp \
--state-analysis fsm.json
If the file exists: load it and skip FSM identification.
If it does not exist: run analysis and save to that path.
Examples
Traffic Light (Deterministic)
cd examples/traffic_light
stg generate-fsm traffic_light_controller.sv \
--golden traffic_light_controller_golden.sv \
--out tb.cpp \
--out-exe tb \
--clock clk \
--reset rst_n \
--reset-active low \
--fsm-method deterministic \
--verilator-coverage
./tb
Sequence Detector (LM-Based)
cd examples/seq_detector
# Set API key: export GOOGLE_API_KEY="..."
stg generate-fsm seq_detector.sv \
--golden seq_detector_golden.sv \
--out tb.cpp \
--out-exe tb \
--fsm-method lm \
--lm-provider gemini \
--state-analysis state_analysis.json
./tb
Output
Testbench: C++ file using Verilator
State analysis JSON: FSM states, transitions, control/data signals
Executable (with
--out-exe): Compiled testbench binary
The testbench traverses the FSM via DFS, applies inputs that satisfy transition conditions, and compares DUT outputs to the golden model.
Transition Verification Model
For each attempted transition edge:
Apply
input_conditionto controllable inputs.Wait up to
--transition-timeoutcycles forwait_condition.Compare DUT outputs against golden outputs.
Read DUT internal FSM state and verify expected
to_state.
By default, a transition is considered successful when steps 2-4 pass.
Optional Line Execution Check
Use --line-coverage-check to add an extra verification gate based on Verilator runtime counters (getCounters()):
stg generate-fsm design.sv \
--golden golden.sv \
--out tb.cpp \
--out-exe tb \
--fsm-method deterministic \
--line-coverage-check
When enabled:
STG auto-enables Verilator
--coverageforgenerate-fsmcompilation.The generated testbench snapshots coverage counters before/after each transition attempt.
A transition passes only if:
wait-condition succeeds,
state reaches expected target,
and at least one relevant line/block counter increased.
This helps distinguish “state appeared correct” from “transition logic actually executed.”
Edge Status in Statistics
test_stats.json includes per-edge status and lines_executed:
covered: transition verified successfullyimpossible: input condition unsatisfiabletimeout: wait condition did not become true in timestate_mismatch: wait succeeded but target state mismatchedno_lines_executed: state/wait checks passed but no line counter increase (only when line check enabled)unreachable: DFS did not reach/close the edge
Summary fields include:
line_coverage_check_enabledline_check_passed_transitionsline_check_failed_transitions
Verilator Binary Selection
For Verilator-based compilation, STG uses:
Default:
verilatorfrom yourPATHOverride: set
STG_VERILATOR_PATHto another Verilator binary
Troubleshooting
“No state machines found”
The design may have no detectable FSM, or the coding style is not recognized. Try --fsm-method lm for LLM-based extraction.
LM method fails
Ensure
uvis installed: https://docs.astral.sh/uv/Check API keys in
.envor environmentSupported keys:
GOOGLE_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY
Missed states in coverage
Increase
--dfs-passesfor more edge coverageIncrease
--transition-timeoutif internal conditions take many cyclesUse
--state-analysisto inspect the extracted FSM; fix or adjust if extraction is wrong
See Also
Modes Overview — General STG modes and design types
CLI Reference — Full
generate-fsmflag referenceAdvanced Features — Coverage analysis with Verilator