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 mutmutation-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— aPredictiondataclass 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— whichMutationKindproduced 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:
- Find candidate sites — locate operator tokens in legal SV
positions (not inside strings, comments,
`definebodies). Source-faithful CST. Verible, viartl-buddy-view's public helpers (rtl_buddy_view.cst_cacheetc., promoted in view#109). - Semantic gating — "is this
+inside aparameterexpression, skip"; "is thisalways_ffa synchroniser chain head." Elaboration. pyslang under the[slang]extra. - Emit the mutated source — byte-splice on the original source
string. Pure string operation; no parser. Same pattern
CLOCK_POLARITY_SWAPalready 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-xenois preparing for its first PyPI release. Until that lands (seeRELEASING.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,
candidatesmethod,Scheduleenum). - 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_svsurface). - rtl_buddy#206 —
rb mutharness; second consumer.
License
BSD 3-Clause. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9b05941bec50fa2446e774187bd7b28e616b017f87779791fcbddfce1b99863
|
|
| MD5 |
c54b29d55ce48feb7cbc6020525a4866
|
|
| BLAKE2b-256 |
150f5a180f98f91e47c7013ecb2a4a93759c5297336b54177661cda6835d0eec
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rtl_buddy_xeno-0.1.0.tar.gz -
Subject digest:
a9b05941bec50fa2446e774187bd7b28e616b017f87779791fcbddfce1b99863 - Sigstore transparency entry: 1708160730
- Sigstore integration time:
-
Permalink:
rtl-buddy/rtl-buddy-xeno@39d0a631c9ec0660ddbc9aa857fab8f6bed581b1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rtl-buddy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@39d0a631c9ec0660ddbc9aa857fab8f6bed581b1 -
Trigger Event:
pull_request
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b21e4eada39f8c05856f07e6bb8831814ab139a7f75440d8dee9b43a5c5c0fcc
|
|
| MD5 |
d1604a8e3fdfa12c16321ed0a752c44d
|
|
| BLAKE2b-256 |
08a5d1941be10d61bc4eff22362d8fd0af0c4d473aa338312d4647be98aedc17
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rtl_buddy_xeno-0.1.0-py3-none-any.whl -
Subject digest:
b21e4eada39f8c05856f07e6bb8831814ab139a7f75440d8dee9b43a5c5c0fcc - Sigstore transparency entry: 1708160834
- Sigstore integration time:
-
Permalink:
rtl-buddy/rtl-buddy-xeno@39d0a631c9ec0660ddbc9aa857fab8f6bed581b1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rtl-buddy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@39d0a631c9ec0660ddbc9aa857fab8f6bed581b1 -
Trigger Event:
pull_request
-
Statement type: