YAML Formats
This page is the canonical reference for all rtl_buddy configuration files. Use it when creating or updating configs for new designs, suites, and regressions.
root_config.yaml
The root config lives at the project root. It defines platforms, builders, Verible, coverage, synthesis tools, synthesis libraries, and the default regression config path.
Required keys:
rtl-buddy-filetype: project_root_configcfg-platformscfg-rtl-buildercfg-veriblecfg-rtl-reg
Full example:
rtl-buddy-filetype: project_root_config
cfg-platforms:
- os: "osx"
unames: ["Darwin"]
builder: "verilator"
verible: "verible-macos"
cfg-rtl-builder:
- name: "verilator"
builder: "verilator"
builder-simv: "obj_dir/simv"
sim-rand-seed: 31310
sim-rand-seed-prefix: "+verilator+seed+"
builder-opts:
debug:
compile-time: "--binary -sv -o simv"
run-time: "+verilator+rand+reset+2"
reg:
compile-time: "--binary -sv -o simv"
run-time: "+verilator+rand+reset+2"
cfg-verible:
- name: "verible-macos"
path: "/opt/homebrew/bin"
extra_args:
lint:
- "--rules=-module-filename"
cfg-coverage:
- name: "verilator"
use-lcov: true
cfg-coverview:
- name: "verilator"
generate-tables: "line"
config:
# inline Coverview JSON configuration values
cfg-surfer:
- name: "surfer-default"
path: "surfer" # bare name → found via PATH; or relative/absolute path
wcp-port: 0 # 0 = OS auto-assigns a free port
editor-cmd: "vim +%l %f" # %f = file path, %l = line number
editor-terminal: "tmux" # tmux | iterm2 | terminal | "" (empty = run cmd directly)
editor-sock: "~/.local/share/rtl-buddy/wave-nvim.sock" # optional: nvim remote reuse
ctrl-sock: "~/.local/share/rtl-buddy/wave-ctrl.sock" # optional: nvim → Surfer
cfg-synth-tools:
- name: "yosys"
tool: "yosys"
opts:
synth-args: ""
abc-args: ""
- name: "openroad"
tool: "openroad"
opts:
strategy: "AREA" # AREA | TIMING | TIMING_ANNEAL | TIMING_GENETIC
cfg-synth-libs:
- name: "sky130hd_tt"
path: "pdk/sky130hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
lef-paths: # required for OpenROAD backend
- "pdk/sky130hd/lef/sky130_fd_sc_hd_merged.lef"
cfg-synth-efforts:
- name: "quick"
yosys:
synth-args: "-flatten"
abc-args: "-fast"
openroad:
run: false # skip OpenROAD entirely → Yosys-only fast path
- name: "standard"
openroad:
run: true # current default behaviour: STA with ideal wires
- name: "accurate"
openroad:
run: true
pre-sta-tcl: |
initialize_floorplan -utilization 0.7 -aspect_ratio 1.0 \
-core_space 2.0 -site unithd
global_placement -density 0.7
estimate_parasitics -placement
cfg-cdc-tools:
- name: "rtl-buddy-cdc"
tool: "rtl-buddy-cdc"
opts:
sync-depth: 2 # forwarded as `--sync-depth N` (CDC-002 required depth)
extra-args: "" # appended verbatim to every invocation
cfg-rtl-reg:
reg-cfg-path: "design/regression.yaml"
Runtime effects:
- Platform is selected by matching
unameoutput againstcfg-platforms[].unames. --builderoverrides the platform-selected builder for the current run.--builder-modeselects which namedbuilder-optsentry to use for compile-time and run-time flags.cfg-coverageis keyed by simulator family (e.g.verilator).use-lcov: trueenables.infoexport and LCOV HTML generation when--coverage-htmlis used.cfg-coverviewis keyed by simulator family.generate-tablessets the coverage type for Coverview tables.configis a dict of inline Coverview JSON configuration values.cfg-surferconfigures the Surfer waveform viewer used byrb wave.pathis a bare executable name (resolved via PATH) or a relative/absolute path to the binary.editor-cmdsupports%f(file path) and%l(line number) placeholders.editor-terminalcontrols how the editor is launched:tmuxopens a new tmux window,iterm2andterminaluse AppleScript, empty string runs the command directly (suitable for GUI editors like VS Code).editor-sockis an optional Unix socket path that enables nvim remote reuse: rtl-buddy launches nvim with--listen <sock>on first use and reconnects for subsequent events.ctrl-sockis an optional Unix socket for the wave control server, which lets nvim send signals to Surfer — press<Space>wa(or your<leader>wa) on a signal name to add it to the waveform view. Install the bundled nvim plugin first withrb wave-install-nvim.cfg-synth-toolsdefines synthesis tool entries selected bysynth.yamltoolfields.toolis the executable name onPATH. For the Yosys backend,opts.synth-argsare appended to thesynthcommand andopts.abc-argsare used by the unmapped ABC step. For the OpenROAD backend,opts.strategycontrols optional resynthesis (AREA= none,TIMING/TIMING_ANNEAL=resynth_annealing,TIMING_GENETIC=resynth_genetic).cfg-synth-libsdefines named Liberty files for technology-mapped synthesis.pathis resolved relative toroot_config.yaml. The optionallef-pathslist specifies LEF files required by the OpenROAD backend for technology loading; ignored by the Yosys backend.cfg-synth-effortsdefines named synthesis effort levels referenced bysynth.yamleffortfields or the--effortCLI flag. Each entry has optionalyosys.synth-args/yosys.abc-args(merged into the Yosys stage) and anopenroadblock. Whenopenroad.run: false, the runner falls back to the Yosys-only backend even iftool: openroadwas selected — useful for a fast quick-look path that needs no LEF/STA.openroad.pre-sta-tclis a raw Tcl snippet injected intosynth.tclbetweenread_sdcandreport_checks; use it to insert floorplan/placement/parasitic-estimation steps before timing analysis. When nocfg-synth-effortsentries are configured or no effort is selected, a built-instandardeffort with all defaults is used. Precedence for the same knob: per-synthesistool_overrides>cfg-synth-efforts>cfg-synth-tools.cfg-cdc-toolsdefines CDC tool entries selected bycdc.yamltoolfields.toolis the executable name onPATH(or an absolute path).opts.sync-depthis forwarded as--sync-depth Nand controls CDC-002's required synchronizer depth.opts.extra-argsis appended verbatim to every analyzer invocation.cfg-rtl-reg.reg-cfg-pathis the fallback regression file forrtl-buddy regressionwhen no./regression.yamlexists in the cwd.cfg-verible[].pathis the directory containing Verible executables. Absolute paths are used as-is; relative paths are resolved from the directory containingroot_config.yaml.
regression.yaml
Required keys:
rtl-buddy-filetype: reg_configtest-configs
Example:
rtl-buddy-filetype: reg_config
test-configs:
- "design/example_block_a/verif/tests.yaml"
- "design/example_block_b/verif/tests.yaml"
Runtime effects:
rtl-buddy regressioniterates each listed suite and runs tests filtered by--start-level/--reg-level.regressionchanges directory into each suite directory before running.
models.yaml
Required keys:
rtl-buddy-filetype: model_configmodels
Example:
rtl-buddy-filetype: model_config
models:
- name: "my_design"
desc: "Optional human-readable description"
filelist:
- "-F my_design.f"
spec: "../../spec/my_design/specs.yaml"
Optional fields:
| Field | Type | Description |
|---|---|---|
desc | string | Human-readable model description |
spec | string | Path to the block's specs.yaml, relative to this models.yaml file. Used by rb spec check-design to link the design model to its specification. |
Runtime effects:
tests.yamlreferences a model bynameusing themodelandmodel_pathfields.- Model filelists are parsed by the filelist logic:
-Frecursion,+incdir+,+libext+,-v,-y, and plain source paths are all supported. specis not used at simulation time; it is only consumed by therb spectraceability commands.
tests.yaml
Required keys:
rtl-buddy-filetype: test_configtestbenchestests
Example:
rtl-buddy-filetype: test_config
testbenches:
- name: "tb_top"
filelist:
- "+incdir+../../../verif/tb"
- "tb_top.sv"
tests:
- name: "smoke"
desc: "sanity test"
reglvl: 0
model: "my_design"
model_path: "../src/models.yaml"
testbench: "tb_top"
plusargs:
test_cycles: "50"
lvm_verbosity: 1
plusdefines:
FEATURE_X: "1"
sim_timeout: 120
uvm:
max_warns: 0
max_errors: 0
- name: "sweep_case"
desc: "expands to many tests"
reglvl:
default: 2000
vcs: 3000
model: "my_design"
model_path: "../src/models.yaml"
testbench: "tb_top"
sweep:
path: "example_sweep.py"
Field reference:
| Field | Type | Description |
|---|---|---|
name | string | Test identifier; used in log file names |
desc | string | Human-readable description |
reglvl | int or dict | Regression level; int for all builders, dict for per-builder with default |
model | string | Model name from models.yaml |
model_path | string | Path to models.yaml; resolved relative to the suite directory |
testbench | string | Testbench name from testbenches list |
plusargs | dict | KEY: VALUE → +KEY=VALUE at sim runtime |
plusdefines | dict | KEY: VALUE → +define+KEY=VALUE at compile time |
sim_timeout | int | Timeout in seconds (default: 60) |
uvm.max_warns | int | UVM warning threshold; exceeding it fails the test |
uvm.max_errors | int | UVM error threshold; exceeding it fails the test |
sweep.path | string | Path to sweep expansion script |
preproc.path | string | Path to pre-processing script |
postproc.path | string | Path to post-processing script (parsed but not yet fully active) |
covers | list of strings | IDs of spec coverage items this test addresses (e.g. ["BLOCK-COV-01"]). Used by rb spec check-coverage; has no effect at simulation time. |
cocotb testbenches
Adding a cocotb: block to a testbench entry switches the runner to cocotb/VPI mode (Verilator only for now). toplevel: is required when cocotb: is present; omitting it raises a fatal error at config-load time.
Prerequisite: cocotb must be installed in the active Python environment (uv add cocotb or pip install cocotb). The runner invokes cocotb-config at compile time; a missing binary surfaces as a FatalRtlBuddyError with an actionable message.
testbenches:
- name: "tb_my_design"
filelist:
- "my_design.sv"
toplevel: my_design # DUT top-level module name — required for cocotb
cocotb:
module: test_my_design # Python module(s) containing @cocotb.test() coroutines
- name: "tb_multi"
filelist:
- "my_design.sv"
toplevel: my_design
cocotb:
module: # list form: all modules are loaded
- test_smoke
- test_corner_cases
Pass/fail detection for cocotb testbenches:
cocotb writes a JUnit XML results file (cocotb_results.xml) instead of PASS/FAIL stdout lines. rtl_buddy parses this file automatically after simulation; you do not need $display("PASS …") in cocotb tests. The desc field in the result reports the first three failure messages and a (+N more) suffix when there are more.
Testbench field reference (cocotb-specific additions):
| Field | Type | Required | Description |
|---|---|---|---|
toplevel | string | Yes (cocotb only) | Top-level DUT module name passed to COCOTB_TOPLEVEL |
cocotb.module | string or list | Yes | Python test module(s) passed to COCOTB_TEST_MODULES |
Runtime effects by field:
testbench: selects entry fromtestbenches; its filelist is appended to model sources for compilation.model_path: resolved relative to thetests.yamlfile's directory.reglvlas dict: usedefaultas the fallback for builders not listed.plusdefines: converted to+define+KEY(no value) or+define+KEY=VALUE.plusargs: converted to+KEY(no value) or+KEY=VALUE.sim_timeout: applies per test run, not per iteration inrandtest.sweep.path: Python script that expands one test entry into a list ofTestConfigobjects. See Plugins.preproc.path: Python script executed before compile; can mutatetest_cfgandroot_cfg, and receivessuite_dirplusartifact_dirin its execution namespace. See Plugins.
Path semantics and cwd
rtl_buddy.logand the convenience symlinks (test.log,test.err,test.randseed) are written to the suite root (the current working directory).- Per-test artifacts are written to
artefacts/{test_name}/under the suite root. Single runs writetest.log,test.err,test.randseed,compile.log,run.f, and (if enabled)coverage.datthere directly. Repeated runs (randtest) write sim outputs into numbered subdirectories:artefacts/{test_name}/run-0001/, etc. testandrandtestdo not automatically change into the suite directory. Run from the suite directory, or use--test-configwith a full path.regressiondoeschdirinto each suite directory before executing.- 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 underartefacts/{test_name}/. - For portable configs in multi-suite repos, make paths in
tests.yamlexplicit and verify they resolve correctly from the intended invocation directory.
synth.yaml
Required keys:
rtl-buddy-filetype: synth_configsyntheses
Example:
rtl-buddy-filetype: synth_config
syntheses:
- name: "smoke_synth"
desc: "Synthesize my_design with the default Yosys flow"
model: "my_design"
model_path: "../src/models.yaml"
tool: "yosys"
reglvl: 0
- name: "sky130_synth"
desc: "Technology-mapped synthesis for SKY130 (Yosys)"
model: "my_design"
model_path: "../src/models.yaml"
tool: "yosys"
constraints: "constraints.sdc"
libraries:
- "sky130hd_tt"
params:
WIDTH: 32
defines:
TARGET_SYNTH: 1
reglvl:
default: 0
dc: 1000
tool_overrides:
yosys:
synth_args: "-flatten"
- name: "sky130_openroad"
desc: "Technology-mapped synthesis with OpenROAD timing analysis"
model: "my_design"
model_path: "../src/models.yaml"
tool: "openroad"
constraints: "constraints.sdc"
libraries:
- "sky130hd_tt"
effort: "accurate" # references cfg-synth-efforts entry; overridable via --effort
reglvl: 0
Field reference:
| Field | Type | Description |
|---|---|---|
name | string | Synthesis identifier; used on the CLI and in artefacts/{name}/ |
desc | string | Human-readable synthesis description |
model | string | Model name from models.yaml; also used as the Yosys top module |
model_path | string | Path to models.yaml, resolved relative to the synth.yaml file |
tool | string | Synthesis tool name from root_config.yaml cfg-synth-tools |
constraints | string | Optional SDC file path, resolved relative to the synth.yaml file |
params | dict | Optional top-level parameter overrides passed through Yosys chparam -set |
defines | dict | Optional Verilog defines passed to read_verilog as -D KEY=VALUE |
libraries | list of strings | Optional Liberty library names from cfg-synth-libs; enables technology mapping |
reglvl | int or dict | Regression level; int for all tools, dict for per-tool with default |
tool_overrides | dict | Optional per-tool overrides for synth_args, abc_args, or strategy, keyed by synthesis tool name |
effort | string | Optional effort name from cfg-synth-efforts; controls Yosys synth/abc args and OpenROAD pre-sta-tcl. Overridable per invocation with rtl-buddy synth --effort <name>. Omitted ⇒ built-in standard defaults. |
Runtime effects:
rtl-buddy synthloadssynth.yaml, resolves sources viamodels.yaml, and dispatches to the backend selected bytool.- Yosys backend (
tool: "yosys"): writessynth.fandsynth.ys, runs Yosys, captures output insynth.log. Withoutlibraries, emits RTLIL; withlibraries, runsdfflibmap+abc -libertyand emitssynth_netlist.v. Reports Gates, Area (lib-mapped only), and WNS (lib-mapped with SDC). Passes when exit code is 0 andsynth.loghas noERROR:lines. - OpenROAD backend (
tool: "openroad"): requireslibrarieswithlef-pathsconfigured incfg-synth-libs. Stage 1 runs Yosys to producesynth_netlist.v(logged tosynth_yosys.log). Stage 2 runs OpenROAD withsynth.tclwhich callsread_lef,read_liberty,read_verilog,link_design,read_sdc(native multi-clock), and reports area/timing; output insynth.log. Reports Gates, Area, WNS (fromreport_checks -path_delay max), and TNS (fromreport_tns). Passes when both stages exit with code 0 and neither log contains errors. - If
constraintscontainscreate_clockentries, the Yosys backend uses the minimum period as ABC's-Dconstraint (multi-clock workaround). The OpenROAD backend passes the full SDC toread_sdcwithout modification. effortselects an entry fromroot_config.yamlcfg-synth-efforts. If the selected effort hasopenroad.run: false, a synthesis withtool: openroadfalls back to the Yosys-only backend (no LEF/STA required) — this is the recommended "quick" path for iteration. The--effortCLI flag onrtl-buddy synthandrtl-buddy synth-regressionoverrides whatever is set per-synthesis.
synth_regression.yaml
Required keys:
rtl-buddy-filetype: synth_reg_configsynth-configs
Example:
rtl-buddy-filetype: synth_reg_config
synth-configs:
- "design/example_block_a/synth/synth.yaml"
- "design/example_block_b/synth/synth.yaml"
Runtime effects:
rtl-buddy synth-regressioniterates each listedsynth.yamlfile and filters syntheses by--reg-level.- Paths in
synth-configsare resolved relative to thesynth_regression.yamlfile. synth-regressionchanges directory into each synthesis suite directory before executing its entries.
cdc.yaml
Required keys:
rtl-buddy-filetype: cdc_configanalyses
Example:
rtl-buddy-filetype: cdc_config
analyses:
- name: "ip_cdc_handshake_lint"
desc: "CDC lint of the request/ack handshake IP"
model: "ip_cdc_handshake"
model_path: "../../design/common/models.yaml"
tool: "rtl-buddy-cdc"
constraints: "ip_cdc_handshake.sdc"
waivers: "ip_cdc_handshake.waivers" # optional
reglvl: 0
- name: "alu_accel_lint"
desc: "CDC lint of the ALU accelerator"
model: "alu_accel_top"
model_path: "../../design/alu_accel/models.yaml"
tool: "rtl-buddy-cdc"
constraints: "alu_accel_top.sdc"
reglvl:
default: 0
rtl-buddy-cdc: 100
tool_overrides:
rtl-buddy-cdc:
sync_depth: 3
extra_args: "--strict"
Field reference:
| Field | Type | Description |
|---|---|---|
name | string | Analysis identifier; used on the CLI and in artefacts/{name}/ |
desc | string | Human-readable analysis description |
model | string | Model name from models.yaml; also used as the top module for elaboration |
model_path | string | Path to models.yaml, resolved relative to the cdc.yaml file |
tool | string | CDC tool name from root_config.yaml cfg-cdc-tools |
constraints | string | SDC file path, resolved relative to the cdc.yaml file |
waivers | string | Optional waiver file path, resolved relative to the cdc.yaml file |
reglvl | int or dict | Regression level; int for all tools, dict for per-tool with default |
tool_overrides | dict | Optional per-tool overrides for sync_depth or extra_args, keyed by CDC tool name |
Runtime effects:
rtl-buddy cdcloadscdc.yaml, resolves sources viamodels.yaml, and dispatches to the backend selected bytool.- The bundled
rtl-buddy-cdcbackend invokes the standalonertl-buddy-cdc lintCLI as a subprocess. The analysis receives the model's resolved filelist, the SDC, an optional waivers file, and the merged tool opts (rootcfg-cdc-toolsbaseline plus any matchingtool_overrides.<tool>). - Each analysis writes a text report and a machine-readable JSON report under
artefacts/{name}/; the JSON summary is parsed to populate the pass/fail/skip result for the CLI table. rtl-buddy cdc <name> --listlists configured analyses without running them.
cdc_regression.yaml
Required keys:
rtl-buddy-filetype: cdc_reg_configcdc-configs
Example:
rtl-buddy-filetype: cdc_reg_config
cdc-configs:
- "design/example_block_a/lint/cdc.yaml"
- "design/example_block_b/lint/cdc.yaml"
Runtime effects:
rtl-buddy cdc-regressioniterates each listedcdc.yamlfile and filters analyses by--reg-level.- Paths in
cdc-configsare resolved relative to thecdc_regression.yamlfile. cdc-regressionchanges directory into each CDC suite directory before executing its entries.
specs.yaml
specs.yaml lives in spec/<block>/ and defines the functional specification for one or more design blocks. It is consumed by the rb spec traceability commands and has no effect on simulation.
Required keys:
rtl-buddy-filetype: spec_configblocks
Example:
rtl-buddy-filetype: spec_config
blocks:
- name: "my_design"
desc: "Brief description of the block"
docs:
- "README.md"
- "behavior.md"
coverage-items:
- id: "MY-COV-01"
desc: "Normal operation path"
- id: "MY-COV-02"
desc: "Error handling and recovery"
Block field reference:
| Field | Type | Description |
|---|---|---|
name | string | Block identifier; matched against ModelConfig.name when resolving spec: links in models.yaml. For single-block files the name is matched unconditionally. |
desc | string | Human-readable block description |
docs | list of strings | Paths to markdown spec documents, relative to this specs.yaml file |
coverage-items | list | Functional coverage items for this block |
Coverage item fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique coverage item identifier, referenced by covers in tests.yaml |
desc | string | Human-readable description of what must be tested |
See Spec Traceability for the end-to-end workflow.
Authoring checklist for new suites
-
Add or verify the model entry in
models.yaml. -
Add a
testbenchentry and verify the filelist paths resolve correctly. -
Add at least one test entry with
model,model_path, andtestbench. -
Set
reglvlpolicy:0for must-run sanity tests, larger values for extended tests. -
Add the suite path to
regression.yaml. -
Run a smoke pass:
rtl-buddy --machine test <name> -c <suite>/tests.yamlrtl-buddy --machine regression -c <regression.yaml> -s 0 -l 0