Skip to main content

SystemVerilog AST-mutation corpus generator. Source-level CDC-aware and FPV-aware mutations for fuzzer and mutation-testing harnesses.

Project description

rtl-buddy-xeno

SystemVerilog AST-mutation corpus generator. Consumes a hand-authored template, applies CDC-aware structural mutations, and emits mutants with a Prediction annotation declaring how downstream oracles should react.

Two consumers:

  • rtl-buddy-cdc fuzzer — oracle is cross-frontend agreement on the mutant's CDC-rule finding set (cdc#221, Stage 3 Layer B).
  • rb mut mutation-testing harness in rtl_buddy — oracle is FPV / regression property survival (rtl_buddy#206).

The name is an Alien xenomorph reference crossed with the CDC pun — "xeno" = crossing into a foreign clock domain.

Quickstart

from rtl_buddy_xeno import Mutator, MutationKind

mutator = Mutator.from_sv("path/to/template.sv")
for mutant in mutator.generate(
    kinds=[MutationKind.CLOCK_POLARITY_SWAP],
    count=10,
    seed=0,
):
    print(mutant.diff_summary)
    print(sorted(mutant.prediction.cdc_rules_added))
    # mutant.sv is the mutated source; feed it to the analyzer.

Each Mutant carries:

  • sv — the mutated SystemVerilog source.
  • diff_summary — short human-readable description.
  • seed — provenance token (operator-internal; reproduces this specific mutant given the same parent + operator).
  • prediction — a Prediction dataclass with both CDC-oracle fields (cdc_rules_added, cdc_rules_removed) and FPV-oracle fields (perturbs_signals, perturbs_liveness); empty defaults mean "no prediction in this dimension," distinct from a negative prediction.
  • kind — which MutationKind produced the mutant.

A mutant whose observed delta disagrees with prediction is actionable: either a real gap in the rule pack (file an issue against rtl-buddy-cdc) or a buggy mutation operator (fix here). That diagnostic loop is the point.

Use mutator.candidates(kinds=...) to enumerate Site objects without actually producing mutants — the budget-estimation primitive consumed by rb mut list (rtl_buddy#206). Use the schedule= kwarg on generate to choose between Schedule.SEQUENTIAL (default) and Schedule.ROUND_ROBIN; round-robin is the rb-mut idiom for budgeted runs across multiple kinds.

Mutation kinds

Eleven operators covering both consumer pools, all implemented. See umbrella xeno#2 for the full table including MCY-expressibility.

Kind Status Used by Parser layer Exercises
CLOCK_POLARITY_SWAP implemented cdc#221 regex (no extras) CDC-016 (chain-stage gated; standalone flops predict nothing)
ATTRIBUTE_TOGGLE implemented cdc#221 regex (no extras) CDC-002 / -003 / -010 / -019, RDC-001 / -007 (per attribute)
ASSIGN_DROP implemented rtl_buddy#206 Verible + slang property survival on the LHS
SYNC_CHAIN_DEPTH_PERTURB implemented cdc#221 Verible CDC-002 / -018 (rationale only — no positive claim)
BIT_EXTRACT_PERMUTE implemented cdc#221 Verible CDC-019 / -020 (rationale only — no positive claim)
RESET_POLARITY_FLIP implemented cdc#221 Verible (+ optional slang) RDC-007 (rationale only — no positive claim)
ARITH_FLIP (+ ↔ -, * ↔ /) implemented rtl_buddy#206 Verible (+ optional slang) property survival
BIT_OP_FLIP (& ↔ |, ~ ±) implemented rtl_buddy#206 Verible (+ optional slang) property survival
COND_NEGATE implemented rtl_buddy#206 Verible property survival
COND_CONST implemented rtl_buddy#206 Verible property survival
PORT_BINDING_SWAP implemented rtl_buddy#206 Verible property survival + maybe CDC

All eleven kinds are implemented — IMPLEMENTED_KINDS == frozenset(MutationKind), no operator raises NotImplementedError. The CDC rule-id predictions are deliberately conservative: an operator only populates cdc_rules_added when it can structurally justify the claim from its parser view (CLOCK_POLARITY_SWAP requires a ≥2-stage chain heuristic; ATTRIBUTE_TOGGLE keys off a known attribute name). The context-blind operators (SYNC_CHAIN_DEPTH_PERTURB, BIT_EXTRACT_PERMUTE, RESET_POLARITY_FLIP) leave cdc_rules_added empty and record the candidate rule in the rationale instead, so the downstream coverage report measures the actual fire rather than trusting an over-confident guess. The rule-ids above mirror rtl-buddy-cdc's rule pack by convention — they are string literals, with no code dependency on rtl-buddy-cdc.

Parser layering

Decision ratified in xeno#4 (supersedes the v0.0.1 text/slang two-layer sketch). Three orthogonal jobs, each operator picks which two or three it needs:

  1. Find candidate sites — locate operator tokens in legal SV positions (not inside strings, comments, `define bodies). Source-faithful CST. Verible, via rtl-buddy-view's public helpers (rtl_buddy_view.cst_cache etc., promoted in view#109).
  2. Semantic gating — "is this + inside a parameter expression, skip"; "is this always_ff a synchroniser chain head." Elaboration. pyslang under the [slang] extra.
  3. Emit the mutated source — byte-splice on the original source string. Pure string operation; no parser. Same pattern CLOCK_POLARITY_SWAP already uses.

Byte offsets are the lingua franca: both Verible CST nodes and pyslang AST nodes carry source ranges referencing the same bytes, so an operator that uses pyslang for semantic identification still emits the splice as a byte-range on the original source string. No round-trip through either AST for emission.

No-straddle rule: a single operator never mixes layers within itself. It's exactly one of regex-only, Verible-only, or Verible+slang. No half-and-half within one operator. The rule is enforceable by reading the top-level structure of src/rtl_buddy_xeno/operators/ — each module declares its parser choice via the imports it carries.

Install

Note: rtl-buddy-xeno is preparing for its first PyPI release. Until that lands (see RELEASING.md), install from source: pip install git+https://github.com/rtl-buddy/rtl-buddy-xeno.

# Bare install — only the regex-based operators (CLOCK_POLARITY_SWAP
# and ATTRIBUTE_TOGGLE) run without extras.
pip install rtl-buddy-xeno

# With Verible CST support (required by every structural operator
# except CLOCK_POLARITY_SWAP and ATTRIBUTE_TOGGLE). Pulls in
# `rtl-buddy-view>=0.2.0`. NB: until rtl-buddy-view publishes to PyPI
# this extra is only installable via git source — for local
# development use `uv sync --extra verible` against this repo.
pip install "rtl-buddy-xeno[verible]"

# With pyslang elaboration (used by the four semantically-gated
# operators: ASSIGN_DROP, RESET_POLARITY_FLIP, plus the optional
# semantic-gating path on ARITH_FLIP / BIT_OP_FLIP).
pip install "rtl-buddy-xeno[slang]"

# Most operators need both.
pip install "rtl-buddy-xeno[verible,slang]"

The [verible] and [slang] extras are independent; each operator's module imports lazily so the no-extras install path keeps working for CLOCK_POLARITY_SWAP and ATTRIBUTE_TOGGLE. Operators that require an absent extra raise ImportError with a clear pointer at which extra to install.

Library boundary

xeno never reads root_config.yaml itself — that's the orchestrator's job (rtl_buddy). Callers inject the Verible CST cache directory as a function argument; xeno's cst.py facade accepts a cache_dir parameter and passes it through to view's cst_cache.get_or_compute. This keeps xeno usable as a standalone library (including in unit tests) without any project-config dependency.

Development

uv sync                       # bare install
uv sync --extra verible       # + Verible CST
uv sync --extra slang         # + pyslang
uv sync --all-extras          # full

uv run ruff check
uv run ruff format --check
uv run mypy
uv run pytest -q

Python ≥3.11, src-layout, frozen dataclasses, pure functions in the operator path. Conventions mirror rtl-buddy-cdc.

Design references

  • xeno#2 — umbrella tracking source-level SV mutation across consumers; includes the operator pool / MCY-expressibility table and the prior-art positioning.
  • xeno#3 — API design (Prediction shape, full MutationKind enum, candidates method, Schedule enum).
  • xeno#4 — parser layering (Verible CST + pyslang + byte-splice; the three-job decision).
  • view#109 — upstream view-side helper promotion that unblocks xeno's [verible] extra.
  • cdc#221 — Stage 3 Layer B; the originating consumer.
  • cdc#222 — Stage 4; future downstream consumer (grammar-generated topologies flow through the same Mutator.from_sv surface).
  • rtl_buddy#206rb mut harness; second consumer.

License

BSD 3-Clause. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rtl_buddy_xeno-0.1.0.tar.gz (32.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rtl_buddy_xeno-0.1.0-py3-none-any.whl (48.2 kB view details)

Uploaded Python 3

File details

Details for the file rtl_buddy_xeno-0.1.0.tar.gz.

File metadata

  • Download URL: rtl_buddy_xeno-0.1.0.tar.gz
  • Upload date:
  • Size: 32.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rtl_buddy_xeno-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a9b05941bec50fa2446e774187bd7b28e616b017f87779791fcbddfce1b99863
MD5 c54b29d55ce48feb7cbc6020525a4866
BLAKE2b-256 150f5a180f98f91e47c7013ecb2a4a93759c5297336b54177661cda6835d0eec

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtl_buddy_xeno-0.1.0.tar.gz:

Publisher: release.yml on rtl-buddy/rtl-buddy-xeno

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rtl_buddy_xeno-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: rtl_buddy_xeno-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 48.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rtl_buddy_xeno-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b21e4eada39f8c05856f07e6bb8831814ab139a7f75440d8dee9b43a5c5c0fcc
MD5 d1604a8e3fdfa12c16321ed0a752c44d
BLAKE2b-256 08a5d1941be10d61bc4eff22362d8fd0af0c4d473aa338312d4647be98aedc17

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtl_buddy_xeno-0.1.0-py3-none-any.whl:

Publisher: release.yml on rtl-buddy/rtl-buddy-xeno

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page