AssertMiner: Module-Level Assertions
- AssertMiner is a framework that generates module-level assertions for RTL designs by combining static AST analysis with LLM-guided inference.
- It systematically extracts module call graphs, I/O tables, and dataflow graphs to produce precise and semantically rich prompts for assertion synthesis.
- The approach improves early fault detection and enhances verification coverage, complementing traditional top-level assertion methods.
AssertMiner is a module-level assertion generation framework for Register-Transfer Level (RTL) designs that combines static structural analysis based on Abstract Syntax Trees (ASTs) with LLM-guided inference to synthesize SystemVerilog Assertions (SVAs). Unlike previous approaches that focus primarily on top-level assertions derived from design specifications, AssertMiner targets micro-architectural modules, where design errors are most frequent and difficult to localize. By systematically extracting and leveraging internal module context (module call graphs, I/O tables, and dataflow graphs), AssertMiner prompts LLMs with concise and semantically rich summaries to generate both specifications and deep module-level assertions, thereby increasing the coverage and efficacy of assertion-based verification (ABV) (Lyu et al., 13 Nov 2025).
1. Motivation and Conceptual Framework
Assertion-based verification in RTL design often relies on debugging functional anomalies using top-level assertions. However, errors at the module or submodule level tend to manifest late and lack precise localization. For example, a bug injected in a SHA3 "padder" submodule triggers only delayed or nonspecific alarms when guarded solely by top-level checks, extending debugging time and complicating root cause analysis. AssertMiner addresses this by generating deep, module-local assertions that fire earlier and pinpoint the faulty signal directly.
AssertMiner's central methodological distinction is the decoupling of module specification inference from potentially flawed RTL implementations. By constructing a static, language-agnostic structural representation of the design using ASTs, the framework provides LLMs with focused, implementation-independent prompts. These prompts facilitate the generation of precise, high-utility assertions that are resilient to both spec omissions and RTL-level bugs.
2. Static Structural Extraction
AssertMiner's initial phase conducts a comprehensive, design-wide static analysis to construct three foundational representations:
- Module Call Graph ():
The directed graph has nodes representing modules, with edges indicating that module instantiates .
- I/O Table per Module:
For every module , AssertMiner extracts , where is a port, designates direction (input or output), and is the corresponding signal at the parent level.
- Dataflow Graph ():
For each module, consists of signal identifiers and directed edges capturing intra-module assignments and dependencies (e.g., if influences ).
A recursive AST traversal algorithm records module declarations, port connectivity, instantiations, and data dependencies, and prunes internal-only signals to yield minimal "signal chains" connecting module inputs to outputs. The key steps are illustrated in the following pseudocode excerpt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function build_structures(AST_root): for each module_node in AST_root: V.add(module_node.name) IO[module_node.name] = parse_ports(module_node.ports) for each inst in module_node.instantations: E.add((module_node.name, inst.module_name)) resolve_connections(IO, module_node.name, inst) for each stmt in module_node.statements: if stmt is assignment or always: for (src in stmt.rhs_signals): D.add((src, stmt.lhs_signal)) for each module m: signal_chains[m] = backward_trace(IO[m].outputs, D) prune_internal(signal_chains[m], IO[m]) |
3. LLM-Guided Module Specification and Assertion Mining
With per-module structural artifacts established, AssertMiner employs a two-stage LLM prompting pipeline:
- Module-Level Specification Extraction:
Each module is described via a concise prompt incorporating: - the module and parent name (from ), - I/O table , - representative simplified signal chains, and - the top-level natural-language specification.
Example prompt:
1 2 3 4 5 6 7 |
You are given the following module structural summary: • Module: padder • Inputs: [clk, reset, data_in] • Outputs: [data_out, valid] • Signal chains: clk→pad_state→data_out; data_in→pad_logic→data_out The top-level design is a SHA3 hash function. Please infer a concise module-level functional specification for padder, in one or two sentences. |
Few-shot in-context examples strengthen generalization and mitigate LLM hallucinations or misattribution of RTL errors.
- Feature Decomposition and Assertion Generation:
The LLM further decomposes inferred module specifications into atomic verification features—concise, testable predicates. For each feature, the model generates a concrete SystemVerilog assertion using a unified template:
1 2 |
assert property (@(posedge <CLK>) (<AP1> && <AP2> …) |-> (<AP3> && <AP4> …) ); |
padder.pad_state == 0 or padder.data_out == {data_in, padding} instantiate the placeholders, standardized across assertion outputs.
4. Integration with Assertion Suites
Module-level assertions produced by AssertMiner are designed to complement top-level suites created by methods such as AssertLLM and Spec2Assertion. The practical workflow is:
- Run Spec2Assertion for top-level assertions.
- Run AssertMiner for module-local assertions.
- Aggregate both sets for input into formal property verification tools.
This unified strategy achieves broad functional coverage (via top-level properties) and efficient, localized bug identification (via deep module checks). Experimental measurements report increases in branch and statement coverage metrics (e.g., BFC up to 4.33% improvement for AssertLLM + AssertMiner, SFC up to 5.13% for Spec2Assertion + AssertMiner), with only a modest number of additional assertions introduced (Lyu et al., 13 Nov 2025).
5. Empirical Evaluation and Results
AssertMiner was evaluated on benchmarks derived from IWLS-2005, using designs such as I²C (1282 LOC), ECG (1635 LOC), Pairing (2145 LOC), and SHA3 (618 LOC). Key evaluation criteria include:
| Metric Symbol | Definition | Usage |
|---|---|---|
| N | Number of generated assertions | Overall yield |
| S | Number syntax-correct | Filtering syntactic errors |
| P | Number passing FPV (valid) | Assertion effectiveness |
| NVR | Non-Violation Rate | Assertion precision |
| BFC | Branch Functional Coverage | Coverage via JasperGold FPV |
| SFC | Statement Functional Coverage | Coverage via JasperGold FPV |
| TFC | Toggle Functional Coverage | Coverage via JasperGold FPV |
Notably, AssertMiner demonstrated P/N ratios from 46% to 83% and SFC/BFC above 80% across all tested designs (e.g., SHA3: 24 assertions, 20 valid, SFC=82.93%, BFC=80%). Integration with AssertLLM or Spec2Assertion consistently led to higher functional coverage and error-detection rates than standalone use or even manually crafted assertions (mutation-testing gains of 5%–19%).
6. Illustrative Examples
AssertMiner-generated specifications and assertions exemplify deep local semantic capture. For the SHA3 padder submodule:
- Inferred Specification:
"The padder module initializes on reset, then appends a single ‘1’ bit followed by the minimum number of ‘0’ bits to reach the required block length, asserting valid_out for one cycle."
- Generated Assertion (SystemVerilog fragment):
1 2 3 4 5 6 7 |
assert property (@(posedge clk) disable iff (reset)
(reset == 1) |-> (padder.pad_state == IDLE)
);
assert property (@(posedge clk)
(padder.valid_in && padder.pad_state != END)
|-> ##[1] (padder.data_out == {padder.data_in, 1'b1, {padder.pad_count{1'b0}})
); |
For an I²C controller:
- Inferred Specification:
"On start condition, the controller must drive SCL low within one cycle and pull SDA low to transmit the address bit."
- Generated Assertion:
1 2 3 4 |
assert property (@(posedge clk) disable iff (reset)
(i2c.start && i2c.bus_busy == 0)
|-> ##1 (i2c.SCL == 0 && i2c.SDA == address_bit)
); |
7. Limitations and Future Research Directions
AssertMiner's reliance on AST-based extraction is robust to language variations, but scaling challenges emerge for designs with deep or wide hierarchies. Traversal overhead and the complexity of resulting signal-chain summaries can become prohibitive. Inaccuracies in the AST—stemming from nonstandard preprocessing or vendor-specific constructs—could mislead the LLM, providing erroneous prompt contexts.
Potential avenues for future work include:
- Implementation of hierarchical pruning algorithms to focus the LLM on high-value subgraphs.
- Augmenting static analysis with simulation-based traces to provide dynamic context.
- Automated ranking of mined assertions based on novelty or predicted error-detection impact to improve reviewer efficiency (Lyu et al., 13 Nov 2025).
AssertMiner advances the practical automation of module-focused assertion-based verification, closing the specification-to-assertion gap at the micro-architectural level and enabling streamlined, early, and precise RTL bug discovery.