rtl-buddy 3.2.2__tar.gz → 3.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.github/workflows/release.yml +11 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/PKG-INFO +14 -5
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/README.md +11 -2
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/plugins.md +9 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/root-config.md +2 -13
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/tests.md +2 -0
- rtl_buddy-3.2.3/docs/index.md +40 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/install.md +1 -1
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/migrations/v2-to-v3.md +2 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/reference/cli.md +0 -19
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/reference/yaml.md +4 -10
- rtl_buddy-3.2.3/docs/robots.txt +4 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/mkdocs.yml +4 -1
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/pyproject.toml +14 -2
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/scripts/gen_cli_reference.py +1 -1
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/__init__.py +0 -1
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/root.py +0 -19
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/verible.py +11 -22
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/logging_utils.py +0 -4
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/rtl_buddy.py +13 -58
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/runner/test_runner.py +4 -2
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/skill/SKILL.md +0 -7
- rtl_buddy-3.2.3/src/rtl_buddy/tools/artifact_paths.py +30 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/vlog_cov.py +2 -1
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/vlog_sim.py +8 -9
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_setup_failures.py +102 -5
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_vlog_sim_paths.py +11 -0
- rtl_buddy-3.2.2/docs/index.md +0 -31
- rtl_buddy-3.2.2/src/rtl_buddy/config/surfer.py +0 -78
- rtl_buddy-3.2.2/src/rtl_buddy/tools/surfer_wcp.py +0 -282
- rtl_buddy-3.2.2/src/rtl_buddy/tools/wave_launcher.py +0 -83
- rtl_buddy-3.2.2/tests/test_surfer_wcp.py +0 -260
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.agents/skills/audit-bundled-skill/SKILL.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.agents/skills/audit-docs/SKILL.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.agents/skills/audit-template/SKILL.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.github/workflows/claude.yml +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.github/workflows/docs.yml +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/.gitignore +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/AGENTS.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/CLAUDE.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/CONTRIBUTORS +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/LICENSE +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/CONTRIBUTING.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/agents.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/cocotb.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/coverage.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/regressions.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/concepts/spec-traceability.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/known-issues.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/migrations/submodule-to-uv.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/docs/quickstart.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/pytest.ini +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/scripts/check_docs_frontmatter.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/__init__.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/__main__.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/coverage.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/coverview.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/model.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/platform.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/reg.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/rtl.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/spec.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/suite.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/test.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/config/uvm.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/docs_access.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/errors.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/runner/__init__.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/runner/test_results.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/seed_mode.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/skill/__init__.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/skill/gitignore_snippet.txt +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/skill_install.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/__init__.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/cocotb_sim.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/coverage.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/coverview.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/spec_trace.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/verible.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/verilator_cov_analysis.md +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/vlog_filelist.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/src/rtl_buddy/tools/vlog_post.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_cocotb_post.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_coverage_paths.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_docs_access.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_logging.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_skill_install.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/tests/test_vlog_cov_metric_parsing.py +0 -0
- {rtl_buddy-3.2.2 → rtl_buddy-3.2.3}/uv.lock +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
|
+
run-name: >-
|
|
4
|
+
${{ github.event_name == 'workflow_dispatch'
|
|
5
|
+
&& format('Release ({0}{1}) from {2}', inputs.bump, inputs.pre_release == 'true' && ', pre-release' || '', github.ref_name)
|
|
6
|
+
|| format('Release from PR #{0} ({1})', github.event.pull_request.number, github.head_ref) }}
|
|
7
|
+
|
|
3
8
|
on:
|
|
4
9
|
pull_request:
|
|
5
10
|
types: [closed]
|
|
@@ -100,6 +105,12 @@ jobs:
|
|
|
100
105
|
echo "is_prerelease=${IS_PRERELEASE}" >> "$GITHUB_OUTPUT"
|
|
101
106
|
echo "Bumping ${LATEST} -> ${NEW_TAG}"
|
|
102
107
|
|
|
108
|
+
- name: Log release parameters
|
|
109
|
+
run: |
|
|
110
|
+
echo "Version : ${{ steps.version.outputs.new_tag || '(none — no version label on PR)' }}"
|
|
111
|
+
echo "Branch : ${{ github.event_name == 'workflow_dispatch' && github.ref_name || github.head_ref }}"
|
|
112
|
+
echo "Trigger : ${{ github.event_name }}"
|
|
113
|
+
|
|
103
114
|
- name: Require release token
|
|
104
115
|
if: steps.version.outputs.new_tag != ''
|
|
105
116
|
env:
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rtl_buddy
|
|
3
|
-
Version: 3.2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 3.2.3
|
|
4
|
+
Summary: Python CLI for Verilog and SystemVerilog RTL testing, randomized regressions, coverage, and simulator workflow automation.
|
|
5
5
|
Project-URL: Source, https://github.com/rtl-buddy/rtl_buddy
|
|
6
6
|
Project-URL: Documentation, https://rtl-buddy.github.io/rtl_buddy/
|
|
7
7
|
Project-URL: Tracker, https://github.com/rtl-buddy/rtl_buddy/issues
|
|
8
8
|
Author: Zhi-Hern Loh, Xie Jiacheng
|
|
9
9
|
License-Expression: BSD-3-Clause
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Keywords: ASIC,FPGA,SystemVerilog,Verilog
|
|
11
|
+
Keywords: ASIC,EDA,FPGA,RTL,SystemVerilog,VCS,Verilator,Verilog,coverage,regression testing,verification
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Operating System :: MacOS
|
|
14
14
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -32,10 +32,19 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
[](LICENSE)
|
|
33
33
|
[](https://rtl-buddy.github.io/rtl_buddy/)
|
|
34
34
|
|
|
35
|
-
`rtl_buddy` is a CLI for running RTL tests, regressions, filelist generation, and adjacent
|
|
35
|
+
`rtl_buddy` is a Python CLI for running Verilog and SystemVerilog RTL tests, randomized regressions, filelist generation, Verilator/VCS simulator workflows, and adjacent verification automation. It is designed to work well for both humans and AI agents.
|
|
36
36
|
|
|
37
37
|
It is built to sit on top of the tools your project already uses, while giving you a cleaner, more repeatable interface for day-to-day verification work. The primary supported flows are Verilator and VCS-based compile, simulation, and regression workflows. Basic Verible command integration exists, while broader first-class Verible and PeakRDL workflows are on the roadmap.
|
|
38
38
|
|
|
39
|
+
Typical commands look like:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv run rb test basic
|
|
43
|
+
uv run rb test smoke --repeat 20
|
|
44
|
+
uv run rb regression
|
|
45
|
+
uv run rb regression --coverage-merge
|
|
46
|
+
```
|
|
47
|
+
|
|
39
48
|
## Why `rtl_buddy`
|
|
40
49
|
|
|
41
50
|
`rtl_buddy` gives RTL projects a lightweight control plane for common verification tasks:
|
|
@@ -74,7 +83,7 @@ Prerequisites:
|
|
|
74
83
|
- A simulator on `PATH`
|
|
75
84
|
- Verilator is the recommended open-source starting point
|
|
76
85
|
- VCS is also supported as a first-class flow
|
|
77
|
-
- Optional Verible
|
|
86
|
+
- Optional: Verible if you want to use `uv run rb verible ...` — e.g. `brew tap chipsalliance/verible && brew install verible` on macOS, or see [Verible releases](https://github.com/chipsalliance/verible/releases) for other platforms
|
|
78
87
|
- Optional system-level coverage tools:
|
|
79
88
|
- `lcov` for LCOV and HTML coverage export
|
|
80
89
|
- [Coverview](https://github.com/antmicro/coverview) for Coverview package generation
|
|
@@ -5,10 +5,19 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://rtl-buddy.github.io/rtl_buddy/)
|
|
7
7
|
|
|
8
|
-
`rtl_buddy` is a CLI for running RTL tests, regressions, filelist generation, and adjacent
|
|
8
|
+
`rtl_buddy` is a Python CLI for running Verilog and SystemVerilog RTL tests, randomized regressions, filelist generation, Verilator/VCS simulator workflows, and adjacent verification automation. It is designed to work well for both humans and AI agents.
|
|
9
9
|
|
|
10
10
|
It is built to sit on top of the tools your project already uses, while giving you a cleaner, more repeatable interface for day-to-day verification work. The primary supported flows are Verilator and VCS-based compile, simulation, and regression workflows. Basic Verible command integration exists, while broader first-class Verible and PeakRDL workflows are on the roadmap.
|
|
11
11
|
|
|
12
|
+
Typical commands look like:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
uv run rb test basic
|
|
16
|
+
uv run rb test smoke --repeat 20
|
|
17
|
+
uv run rb regression
|
|
18
|
+
uv run rb regression --coverage-merge
|
|
19
|
+
```
|
|
20
|
+
|
|
12
21
|
## Why `rtl_buddy`
|
|
13
22
|
|
|
14
23
|
`rtl_buddy` gives RTL projects a lightweight control plane for common verification tasks:
|
|
@@ -47,7 +56,7 @@ Prerequisites:
|
|
|
47
56
|
- A simulator on `PATH`
|
|
48
57
|
- Verilator is the recommended open-source starting point
|
|
49
58
|
- VCS is also supported as a first-class flow
|
|
50
|
-
- Optional Verible
|
|
59
|
+
- Optional: Verible if you want to use `uv run rb verible ...` — e.g. `brew tap chipsalliance/verible && brew install verible` on macOS, or see [Verible releases](https://github.com/chipsalliance/verible/releases) for other platforms
|
|
51
60
|
- Optional system-level coverage tools:
|
|
52
61
|
- `lcov` for LCOV and HTML coverage export
|
|
53
62
|
- [Coverview](https://github.com/antmicro/coverview) for Coverview package generation
|
|
@@ -31,6 +31,8 @@ The sweep hook runs before the test flow and expands a single test entry into mu
|
|
|
31
31
|
| `logger` | Logger | Use this for all logging so output goes through `rtl_buddy`'s log system |
|
|
32
32
|
| `test_cfg` | TestConfig (immutable) | The original test entry from `tests.yaml` |
|
|
33
33
|
| `root_cfg` | RootConfig (mutable) | The loaded root config |
|
|
34
|
+
| `suite_dir` | string | Absolute path to the directory containing `tests.yaml` |
|
|
35
|
+
| `artifact_dir` | string | Artifact root for the incoming test name under `suite_dir/artefacts/` |
|
|
34
36
|
| `out_test_cfgs` | list | **Assign** the expanded list of `TestConfig` objects here |
|
|
35
37
|
| `__file__` | string | Absolute path to the current sweep script |
|
|
36
38
|
|
|
@@ -74,14 +76,21 @@ The pre-processing hook runs after sweep expansion but before the compilation st
|
|
|
74
76
|
| `logger` | Logger | Use for all logging |
|
|
75
77
|
| `test_cfg` | TestConfig (mutable) | Modify this to change compile/sim parameters |
|
|
76
78
|
| `root_cfg` | RootConfig (mutable) | The loaded root config |
|
|
79
|
+
| `suite_dir` | string | Absolute path to the directory containing `tests.yaml` |
|
|
80
|
+
| `artifact_dir` | string | Artifact root for this test under `suite_dir/artefacts/` |
|
|
77
81
|
| `__file__` | string | Absolute path to the current pre-processing script |
|
|
78
82
|
|
|
83
|
+
Plusargs are still passed through verbatim. If a plusarg value should reference a suite-local file, resolve it explicitly against `suite_dir` in preproc. Output filenames that should land in the per-test artefact tree can remain relative to `artifact_dir`.
|
|
84
|
+
|
|
79
85
|
**Example:**
|
|
80
86
|
|
|
81
87
|
```python
|
|
82
88
|
# my_preproc.py
|
|
83
89
|
import os
|
|
90
|
+
from pathlib import Path
|
|
91
|
+
|
|
84
92
|
test_cfg.plusargs["BUILD_ID"] = os.environ.get("CI_BUILD_ID", "local")
|
|
93
|
+
test_cfg.plusargs["stimulus"] = str(Path(suite_dir) / "vectors" / "streaming_contract.txt")
|
|
85
94
|
```
|
|
86
95
|
|
|
87
96
|
If a pre-processing script raises an exception, the affected test is marked as a setup failure and the rest of the run continues.
|
|
@@ -37,7 +37,7 @@ cfg-rtl-builder:
|
|
|
37
37
|
|
|
38
38
|
cfg-verible:
|
|
39
39
|
- name: "verible-macos"
|
|
40
|
-
path: "
|
|
40
|
+
path: "/opt/homebrew/bin"
|
|
41
41
|
extra_args:
|
|
42
42
|
lint:
|
|
43
43
|
- "--rules=-module-filename"
|
|
@@ -63,18 +63,7 @@ Defines simulation tool configurations. Each entry has:
|
|
|
63
63
|
|
|
64
64
|
**`cfg-verible`**
|
|
65
65
|
|
|
66
|
-
Defines Verible tool configurations for lint and syntax checks.
|
|
67
|
-
|
|
68
|
-
**`cfg-surfer`** *(optional)*
|
|
69
|
-
|
|
70
|
-
Configures the Surfer waveform viewer for `rb wave`. Fields:
|
|
71
|
-
|
|
72
|
-
- `path`: bare executable name (resolved via PATH, e.g. `"surfer"`) or a relative/absolute path to the binary
|
|
73
|
-
- `wcp-port`: TCP port rtl-buddy listens on; Surfer connects with `--wcp-initiate` (default: `0` — OS auto-assigns a free port)
|
|
74
|
-
- `editor-cmd`: command template with `%f` (file path) and `%l` (line number) placeholders — e.g. `"vim +%l %f"`, `"code --goto %f:%l"`
|
|
75
|
-
- `editor-terminal`: how to open terminal editors — `tmux` (new tmux window), `iterm2`, `terminal` (macOS Terminal.app), or `""` to run the command directly (for GUI editors)
|
|
76
|
-
|
|
77
|
-
`rb wave <test>` looks for a signal layout file at `<test>.surfer` in the same directory as `tests.yaml` (e.g. `verif/sandbox/basic.surfer`). If found it is passed to Surfer via `-c`; if not, Surfer opens with no pre-loaded signals. If no FST exists for the test, `rb wave` runs a debug sim automatically before launching Surfer.
|
|
66
|
+
Defines Verible tool configurations for lint and syntax checks. `path` is the directory containing Verible executables — absolute or relative to `root_config.yaml`.
|
|
78
67
|
|
|
79
68
|
**`cfg-rtl-reg`**
|
|
80
69
|
|
|
@@ -167,6 +167,8 @@ For machine-readable logs (JSON Lines), use `--machine`. See [For Agents](../age
|
|
|
167
167
|
|
|
168
168
|
Paths in `tests.yaml` (such as `model_path`) are resolved relative to the suite file's directory, not the invocation directory.
|
|
169
169
|
|
|
170
|
+
Plusargs are passed to the simulator verbatim. If a plusarg should reference a suite-local file, resolve it explicitly in preproc using `suite_dir`. Bare output filenames can remain artifact-relative so they land under `artefacts/{test_name}/`.
|
|
171
|
+
|
|
170
172
|
## Full schema
|
|
171
173
|
|
|
172
174
|
See [YAML Formats: tests.yaml](../reference/yaml.md#testsyaml) for the complete field reference.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: RTL Buddy is a Python CLI for Verilog and SystemVerilog regression testing, Verilator and VCS simulation workflows, coverage, and YAML-based RTL verification automation.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# RTL Buddy
|
|
6
|
+
|
|
7
|
+
RTL Buddy is a Python CLI for Verilog and SystemVerilog RTL verification workflows, including test execution, randomized regression testing, Verilator and VCS simulation, coverage collection, and YAML-based automation.
|
|
8
|
+
|
|
9
|
+
It wraps simulation tools and project scripts to provide a structured, config-driven test and regression system for ASIC and FPGA projects. The primary supported flows are Verilator on macOS/Linux and VCS on Linux.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Run individual Verilog/SystemVerilog tests or full regressions from YAML config files
|
|
14
|
+
- Randomized seed testing with repeat and replay support
|
|
15
|
+
- Plugin hooks for sweep generation, test pre-processing, and post-processing
|
|
16
|
+
- Filelist generation from `models.yaml`
|
|
17
|
+
- Verilator coverage collection, merge, summary, and export workflows
|
|
18
|
+
- Basic Verible command integration for lint, syntax, formatting, and preprocessing
|
|
19
|
+
- Machine-readable JSONL logging for use with AI agents and CI pipelines
|
|
20
|
+
|
|
21
|
+
`rtl_buddy` can be adapted to different project toolchains, but the primary supported flows are Verilator and VCS. Broader first-class Verible and PeakRDL workflows are on the roadmap.
|
|
22
|
+
|
|
23
|
+
## SystemVerilog Regression Testing
|
|
24
|
+
|
|
25
|
+
RTL Buddy keeps simulator invocation, seeds, logs, result handling, and regression selection consistent across repeated verification runs. Projects describe suites, tests, platforms, builders, and models in readable YAML files instead of scattering that logic across ad hoc shell scripts.
|
|
26
|
+
|
|
27
|
+
## Verilator and VCS Simulation Workflows
|
|
28
|
+
|
|
29
|
+
The CLI gives RTL projects one command surface for open-source Verilator flows and Linux VCS flows, with optional hooks for project-specific compile, simulation, sweep, and post-processing behavior.
|
|
30
|
+
|
|
31
|
+
## Getting Started
|
|
32
|
+
|
|
33
|
+
- [Installation](install.md) — how to add `rtl_buddy` to your project
|
|
34
|
+
- [Quick Start](quickstart.md) — run your first test in minutes
|
|
35
|
+
- [Concepts](concepts/root-config.md) — understand the config model
|
|
36
|
+
|
|
37
|
+
## Reference
|
|
38
|
+
|
|
39
|
+
- [CLI Reference](reference/cli.md) — all subcommands and options
|
|
40
|
+
- [YAML Formats](reference/yaml.md) — full schema for all config files
|
|
@@ -11,7 +11,7 @@ description: How to install rtl_buddy into a project using uv, including prerequ
|
|
|
11
11
|
- Python 3.11 or later
|
|
12
12
|
- `uv`
|
|
13
13
|
- Simulation tool on `PATH`: Verilator (macOS/Linux) or VCS (Linux)
|
|
14
|
-
- Optional Verible
|
|
14
|
+
- Optional: Verible if you want to use `uv run rb verible ...` — e.g. `brew tap chipsalliance/verible && brew install verible` on macOS, or see [Verible releases](https://github.com/chipsalliance/verible/releases) for other platforms
|
|
15
15
|
- Optional system-level coverage tools:
|
|
16
16
|
- `lcov` for `.info` export and HTML reports
|
|
17
17
|
- Antmicro `coverview` for Coverview package generation
|
|
@@ -31,6 +31,8 @@ artefacts/{test_name}/run-0001/coverage.dat
|
|
|
31
31
|
|
|
32
32
|
Compile outputs (`compile.log`, `run.f`) remain at `artefacts/{test_name}/` — they are shared across all iterations of the same test.
|
|
33
33
|
|
|
34
|
+
Hook scripts that previously relied on suite-relative file paths resolving from the simulator working directory must now resolve those paths explicitly. Use the preproc hook's `suite_dir` variable for suite-local inputs; keep output filenames artifact-relative when they should land under `artefacts/{test_name}/`.
|
|
35
|
+
|
|
34
36
|
### Symlinks
|
|
35
37
|
|
|
36
38
|
The convenience symlinks `test.log`, `test.err`, and `test.randseed` at the suite root still exist and still point to the latest run.
|
|
@@ -47,7 +47,6 @@ Usage: rtl-buddy [OPTIONS] COMMAND [ARGS]...
|
|
|
47
47
|
│ regression run rtl regression │
|
|
48
48
|
│ filelist generate filelists using models.yaml │
|
|
49
49
|
│ verible run verible cmd │
|
|
50
|
-
│ wave open waveform viewer for a test │
|
|
51
50
|
│ skill manage the rtl_buddy agent skill │
|
|
52
51
|
│ docs browse bundled documentation │
|
|
53
52
|
│ spec spec traceability commands │
|
|
@@ -188,24 +187,6 @@ Usage: rtl-buddy verible [OPTIONS] CMD [VERIBLE_ARGS]...
|
|
|
188
187
|
╰──────────────────────────────────────────────────────────────────────────────────────╯
|
|
189
188
|
```
|
|
190
189
|
|
|
191
|
-
## wave
|
|
192
|
-
|
|
193
|
-
```text
|
|
194
|
-
Usage: rtl-buddy wave [OPTIONS] TEST_NAME
|
|
195
|
-
|
|
196
|
-
open waveform viewer for a test
|
|
197
|
-
|
|
198
|
-
╭─ Arguments ──────────────────────────────────────────────────────────────────────────╮
|
|
199
|
-
│ * test_name TEXT name of test to open waveform for [required] │
|
|
200
|
-
╰──────────────────────────────────────────────────────────────────────────────────────╯
|
|
201
|
-
╭─ Options ────────────────────────────────────────────────────────────────────────────╮
|
|
202
|
-
│ --test-config -c TEXT tests.yaml to use [default: tests.yaml] │
|
|
203
|
-
│ --surfer TEXT cfg-surfer entry name [default: surfer-default] │
|
|
204
|
-
│ --resim force re-run of debug sim even if FST exists │
|
|
205
|
-
│ --help Show this message and exit. │
|
|
206
|
-
╰──────────────────────────────────────────────────────────────────────────────────────╯
|
|
207
|
-
```
|
|
208
|
-
|
|
209
190
|
## skill
|
|
210
191
|
|
|
211
192
|
```text
|
|
@@ -45,7 +45,7 @@ cfg-rtl-builder:
|
|
|
45
45
|
|
|
46
46
|
cfg-verible:
|
|
47
47
|
- name: "verible-macos"
|
|
48
|
-
path: "
|
|
48
|
+
path: "/opt/homebrew/bin"
|
|
49
49
|
extra_args:
|
|
50
50
|
lint:
|
|
51
51
|
- "--rules=-module-filename"
|
|
@@ -60,13 +60,6 @@ cfg-coverview:
|
|
|
60
60
|
config:
|
|
61
61
|
# inline Coverview JSON configuration values
|
|
62
62
|
|
|
63
|
-
cfg-surfer:
|
|
64
|
-
- name: "surfer-default"
|
|
65
|
-
path: "surfer" # bare name → found via PATH; or relative/absolute path
|
|
66
|
-
wcp-port: 0 # 0 = OS auto-assigns a free port
|
|
67
|
-
editor-cmd: "vim +%l %f" # %f = file path, %l = line number
|
|
68
|
-
editor-terminal: "tmux" # tmux | iterm2 | terminal | "" (empty = run cmd directly)
|
|
69
|
-
|
|
70
63
|
cfg-rtl-reg:
|
|
71
64
|
reg-cfg-path: "design/regression.yaml"
|
|
72
65
|
```
|
|
@@ -78,8 +71,8 @@ cfg-rtl-reg:
|
|
|
78
71
|
- `--builder-mode` selects which named `builder-opts` entry to use for compile-time and run-time flags.
|
|
79
72
|
- `cfg-coverage` is keyed by simulator family (e.g. `verilator`). `use-lcov: true` enables `.info` export and LCOV HTML generation when `--coverage-html` is used.
|
|
80
73
|
- `cfg-coverview` is keyed by simulator family. `generate-tables` sets the coverage type for Coverview tables. `config` is a dict of inline Coverview JSON configuration values.
|
|
81
|
-
- `cfg-surfer` configures the Surfer waveform viewer used by `rb wave`. `path` is a bare executable name (resolved via PATH) or a relative/absolute path to the binary. `editor-cmd` supports `%f` (file path) and `%l` (line number) placeholders. `editor-terminal` controls how the editor is launched: `tmux` opens a new tmux window, `iterm2` and `terminal` use AppleScript, empty string runs the command directly (suitable for GUI editors like VS Code).
|
|
82
74
|
- `cfg-rtl-reg.reg-cfg-path` is the fallback regression file for `rtl-buddy regression` when no `./regression.yaml` exists in the cwd.
|
|
75
|
+
- `cfg-verible[].path` is the directory containing Verible executables. Absolute paths are used as-is; relative paths are resolved from the directory containing `root_config.yaml`.
|
|
83
76
|
|
|
84
77
|
---
|
|
85
78
|
|
|
@@ -255,7 +248,7 @@ cocotb writes a JUnit XML results file (`cocotb_results.xml`) instead of `PASS`/
|
|
|
255
248
|
- `plusargs`: converted to `+KEY` (no value) or `+KEY=VALUE`.
|
|
256
249
|
- `sim_timeout`: applies per test run, not per iteration in `randtest`.
|
|
257
250
|
- `sweep.path`: Python script that expands one test entry into a list of `TestConfig` objects. See [Plugins](../concepts/plugins.md).
|
|
258
|
-
- `preproc.path`: Python script executed before compile; can mutate `test_cfg` and `root_cfg
|
|
251
|
+
- `preproc.path`: Python script executed before compile; can mutate `test_cfg` and `root_cfg`, and receives `suite_dir` plus `artifact_dir` in its execution namespace. See [Plugins](../concepts/plugins.md).
|
|
259
252
|
|
|
260
253
|
## Path semantics and cwd
|
|
261
254
|
|
|
@@ -263,6 +256,7 @@ cocotb writes a JUnit XML results file (`cocotb_results.xml`) instead of `PASS`/
|
|
|
263
256
|
- Per-test artifacts are written to `artefacts/{test_name}/` under the suite root. Single runs write `test.log`, `test.err`, `test.randseed`, `compile.log`, `run.f`, and (if enabled) `coverage.dat` there directly. Repeated runs (`randtest`) write sim outputs into numbered subdirectories: `artefacts/{test_name}/run-0001/`, etc.
|
|
264
257
|
- `test` and `randtest` do **not** automatically change into the suite directory. Run from the suite directory, or use `--test-config` with a full path.
|
|
265
258
|
- `regression` does `chdir` into each suite directory before executing.
|
|
259
|
+
- Preproc plusargs are passed to the simulator verbatim. Resolve suite-local input paths explicitly against `suite_dir`; keep output filenames artifact-relative when they should land under `artefacts/{test_name}/`.
|
|
266
260
|
- For portable configs in multi-suite repos, make paths in `tests.yaml` explicit and verify they resolve correctly from the intended invocation directory.
|
|
267
261
|
|
|
268
262
|
---
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
site_name: RTL Buddy
|
|
2
|
-
site_description: CLI
|
|
2
|
+
site_description: Python CLI for Verilog and SystemVerilog regression testing, Verilator and VCS simulation workflows, RTL test automation, coverage, and YAML-based verification flows.
|
|
3
|
+
site_author: RTL Buddy contributors
|
|
4
|
+
repo_url: https://github.com/rtl-buddy/rtl_buddy
|
|
5
|
+
repo_name: rtl-buddy/rtl_buddy
|
|
3
6
|
docs_dir: docs
|
|
4
7
|
site_url: https://rtl-buddy.github.io/rtl_buddy/
|
|
5
8
|
remote_name: origin
|
|
@@ -19,11 +19,23 @@ authors = [
|
|
|
19
19
|
{ name = "Xie Jiacheng"}
|
|
20
20
|
]
|
|
21
21
|
|
|
22
|
-
description = "
|
|
22
|
+
description = "Python CLI for Verilog and SystemVerilog RTL testing, randomized regressions, coverage, and simulator workflow automation."
|
|
23
23
|
readme = "README.md"
|
|
24
24
|
license = "BSD-3-Clause"
|
|
25
25
|
license-files = ["LICENSE"]
|
|
26
|
-
keywords = [
|
|
26
|
+
keywords = [
|
|
27
|
+
"SystemVerilog",
|
|
28
|
+
"Verilog",
|
|
29
|
+
"RTL",
|
|
30
|
+
"ASIC",
|
|
31
|
+
"FPGA",
|
|
32
|
+
"EDA",
|
|
33
|
+
"Verilator",
|
|
34
|
+
"VCS",
|
|
35
|
+
"regression testing",
|
|
36
|
+
"verification",
|
|
37
|
+
"coverage",
|
|
38
|
+
]
|
|
27
39
|
|
|
28
40
|
classifiers = [
|
|
29
41
|
"Development Status :: 4 - Beta",
|
|
@@ -11,7 +11,7 @@ from pathlib import Path
|
|
|
11
11
|
|
|
12
12
|
REPO_ROOT = Path(__file__).parent.parent
|
|
13
13
|
OUTPUT = REPO_ROOT / "docs" / "reference" / "cli.md"
|
|
14
|
-
SUBCOMMANDS = ["test", "randtest", "regression", "filelist", "verible", "
|
|
14
|
+
SUBCOMMANDS = ["test", "randtest", "regression", "filelist", "verible", "skill", "docs", "spec"]
|
|
15
15
|
|
|
16
16
|
HEADER = """\
|
|
17
17
|
---
|
|
@@ -15,7 +15,6 @@ from .rtl import RtlBuilderConfig
|
|
|
15
15
|
from .verible import VeribleConfig, VeribleConfigFile
|
|
16
16
|
from .coverage import CoverageConfig, CoverageConfigFile
|
|
17
17
|
from .coverview import CoverviewConfig, CoverviewConfigFile
|
|
18
|
-
from .surfer import SurferConfig, SurferConfigFile
|
|
19
18
|
from ..errors import FatalRtlBuddyError
|
|
20
19
|
from ..logging_utils import log_event
|
|
21
20
|
|
|
@@ -78,7 +77,6 @@ class RootConfigFile:
|
|
|
78
77
|
veribles: list[VeribleConfigFile] = field(rename='cfg-verible', default_factory=list)
|
|
79
78
|
coverages: list[CoverageConfigFile] = field(rename='cfg-coverage', default_factory=list)
|
|
80
79
|
coverviews: list[CoverviewConfigFile] = field(rename='cfg-coverview', default_factory=list)
|
|
81
|
-
surfers: list[SurferConfigFile] = field(rename='cfg-surfer', default_factory=list)
|
|
82
80
|
|
|
83
81
|
class RootConfig:
|
|
84
82
|
"""
|
|
@@ -114,7 +112,6 @@ class RootConfig:
|
|
|
114
112
|
self.verible_cfgs = dict()
|
|
115
113
|
self.coverage_cfgs = dict()
|
|
116
114
|
self.coverview_cfgs = dict()
|
|
117
|
-
self.surfer_cfgs = dict()
|
|
118
115
|
self.platform_cfg = None
|
|
119
116
|
self.reg_cfg = None # initialise later when get_rtl_reg_cfg is called
|
|
120
117
|
|
|
@@ -143,11 +140,6 @@ class RootConfig:
|
|
|
143
140
|
cfg.name: cfg.initialise(self.root_cfg_path) for cfg in data.coverviews
|
|
144
141
|
}
|
|
145
142
|
|
|
146
|
-
# Populate surfer configs
|
|
147
|
-
self.surfer_cfgs = {
|
|
148
|
-
cfg.name: cfg.initialise(self.root_cfg_path) for cfg in data.surfers
|
|
149
|
-
}
|
|
150
|
-
|
|
151
143
|
# Initialise regression config
|
|
152
144
|
self.cfg_rtl_reg = data.cfg_rtl_reg
|
|
153
145
|
self.reg_cfg = RegConfig(
|
|
@@ -280,17 +272,6 @@ class RootConfig:
|
|
|
280
272
|
cfg = self.get_coverage_cfg(simulator_name)
|
|
281
273
|
return False if cfg is None else cfg.get_use_lcov()
|
|
282
274
|
|
|
283
|
-
def get_surfer_cfg(self, name: str = 'surfer-default') -> 'SurferConfig | None':
|
|
284
|
-
"""
|
|
285
|
-
Get Surfer configuration by name.
|
|
286
|
-
|
|
287
|
-
Args:
|
|
288
|
-
name (str): cfg-surfer entry name. Defaults to "surfer-default".
|
|
289
|
-
Returns:
|
|
290
|
-
cfg (SurferConfig|None): Matching Surfer configuration, if present.
|
|
291
|
-
"""
|
|
292
|
-
return self.surfer_cfgs.get(name)
|
|
293
|
-
|
|
294
275
|
def get_coverview_cfg(self, simulator_name:str):
|
|
295
276
|
"""
|
|
296
277
|
Get Coverview packaging configuration for a simulator family.
|
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
logger = logging.getLogger(__name__)
|
|
3
3
|
import pprint
|
|
4
4
|
import os
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
from dataclasses import dataclass
|
|
7
8
|
from serde import serde, field
|
|
@@ -14,14 +15,12 @@ class VeribleConfig:
|
|
|
14
15
|
|
|
15
16
|
Attributes:
|
|
16
17
|
name (str): Unique verible identifier.
|
|
17
|
-
path (str): Path to the Verible
|
|
18
|
+
path (str): Path to the directory containing Verible executables.
|
|
18
19
|
extra_args (dict[str, list[str]]): List of arguments to be supplied to verible, grouped by command.
|
|
19
|
-
root_cfg_path (str): Directory of the root configuration
|
|
20
20
|
"""
|
|
21
21
|
name: str
|
|
22
22
|
path: str
|
|
23
23
|
extra_args: dict[str, list[str]]
|
|
24
|
-
root_cfg_path: str
|
|
25
24
|
available: bool
|
|
26
25
|
|
|
27
26
|
def get_name(self):
|
|
@@ -42,26 +41,16 @@ class VeribleConfig:
|
|
|
42
41
|
Returns:
|
|
43
42
|
extra_args (list[str]): The list of extra_args associated with the command. If none are found, returns an empty array.
|
|
44
43
|
"""
|
|
45
|
-
#logger.info(pprint.pformat(self.cfg))
|
|
46
44
|
return self.extra_args[cmd] if cmd in self.extra_args else []
|
|
47
45
|
|
|
48
|
-
def get_path(self):
|
|
49
|
-
"""
|
|
50
|
-
Retrieves the path to the Verible executable directory.
|
|
51
|
-
|
|
52
|
-
Returns:
|
|
53
|
-
path (str): The path.
|
|
54
|
-
"""
|
|
55
|
-
return os.path.join(os.path.dirname(self.root_cfg_path), self.path)
|
|
56
|
-
|
|
57
46
|
def get_exe_path(self, exe_name):
|
|
58
47
|
"""
|
|
59
|
-
Retrieves the path to
|
|
48
|
+
Retrieves the full path to a Verible executable.
|
|
60
49
|
|
|
61
50
|
Returns:
|
|
62
51
|
path (str): The path.
|
|
63
52
|
"""
|
|
64
|
-
return os.path.join(self.
|
|
53
|
+
return os.path.join(self.path, exe_name)
|
|
65
54
|
|
|
66
55
|
def __str__(self):
|
|
67
56
|
return pprint.pformat(self)
|
|
@@ -71,13 +60,13 @@ class VeribleConfigFile:
|
|
|
71
60
|
name: str
|
|
72
61
|
path: str
|
|
73
62
|
extra_args: dict[str, list[str]]
|
|
74
|
-
|
|
75
|
-
def initialise(self, root_cfg_path:str) -> VeribleConfig:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if not os.path.exists(
|
|
79
|
-
log_event(logger, logging.DEBUG, "verible.path_missing", name=res.get_name(), path=
|
|
63
|
+
|
|
64
|
+
def initialise(self, root_cfg_path: str) -> VeribleConfig:
|
|
65
|
+
resolved = str(Path(root_cfg_path).parent / self.path)
|
|
66
|
+
res = VeribleConfig(self.name, resolved, self.extra_args, False)
|
|
67
|
+
if not os.path.exists(resolved):
|
|
68
|
+
log_event(logger, logging.DEBUG, "verible.path_missing", name=res.get_name(), path=resolved)
|
|
80
69
|
else:
|
|
81
|
-
|
|
70
|
+
res.available = True
|
|
82
71
|
|
|
83
72
|
return res
|
|
@@ -295,10 +295,6 @@ def _human_message(event: str, fields: Mapping[str, Any]) -> str:
|
|
|
295
295
|
return "verible binaries unavailable"
|
|
296
296
|
case "verible.command_invalid":
|
|
297
297
|
return f'verible: invalid command "{fields.get("command")}"'
|
|
298
|
-
case "wcp.resolve_failed":
|
|
299
|
-
return f'WCP: could not find source for "{fields.get("variable")}" (searched {fields.get("searched")} files)'
|
|
300
|
-
case "wcp.connection_lost":
|
|
301
|
-
return f'WCP: connection lost ({fields.get("reason")}); waiting for Surfer to reconnect'
|
|
302
298
|
case "coverage.metric.failed":
|
|
303
299
|
return (
|
|
304
300
|
f'coverage metric "{fields.get("metric")}" failed'
|