ip.yml Reference
Complete field reference for the RouteRTL IP manifest file.
ip.yml is the single declaration point for an IP — its identity,
the HDL sources it ships, optional in-project build configuration, and
optional IP-XACT auto-packaging recipe. One file serves both registry
publishing and in-project consumption.
Run
rr ip initto scaffold a workingip.ymlinteractively. The template emits the canonical unified shape documented below.
Quick Reference
| Block | Required? | Purpose |
|---|---|---|
name, license | required | Identity + license declaration at the root |
namespace, version | publish-only | Required before rr pkg publish; omit for purely in-project IPs |
description | recommended | One-line summary shown in rr pkg search |
hdl | required | Canonical source manifest — language, library, and the file list |
dependencies | optional | Other published IPs this one depends on (by ns/name) |
build | optional | In-project build config — scan root, synth mode, child IPs |
packaging | optional | IP-XACT auto-packaging recipe (see RTL-P3.188) |
interfaces | optional | Bus interface declarations — surfaces in rr pkg info |
parameters | optional | Generic / parameter metadata |
fpga | optional | Vendor + resource compatibility hints |
The Canonical Shape
# ── Identity ────────────────────────────────────────────────────────
name: pulp_axis_stream_mux
namespace: sdi_claude # optional — publishable IPs only
version: "1.0.0" # optional — publishable IPs only
description: "AXIS 2→1 multiplexer (wrapper around PULP stream_mux_vec)."
license: Apache-2.0 # SPDX identifier
# ── HDL manifest ────────────────────────────────────────────────────
hdl:
language: systemverilog
library: work
files:
- hdl/pulp/stream_mux.sv
- hdl/pulp/stream_mux_vec.sv
- hdl/pulp_axis_stream_mux.sv
# ── Registry dependencies ───────────────────────────────────────────
dependencies: {}
# ── In-project build (optional) ────────────────────────────────────
build:
paths:
sources: hdl
synthesis:
mode: rtl
ips: []
# ── IP-XACT packaging (optional) ───────────────────────────────────
packaging:
recipe: tcl/package.tcl
vendor: sdi_claude
library: pulp
version: "1.0"
Identity is always at the root. The canonical position for license
is license: at the root — not nested under any wrapper block.
Section-by-Section
Identity
name: pulp_axis_stream_mux # required
namespace: sdi_claude # optional
version: "1.0.0" # optional
description: "AXIS 2→1 multiplexer." # recommended
license: Apache-2.0 # SPDX identifier
| Field | Required | Notes |
|---|---|---|
name | ✓ | The internal identifier. Must be unique within its namespace. Also used by build tooling and packaging recipes. |
namespace | publish-only | The publisher / org handle. Registry-lookup key is <namespace>/<name>. Omit for purely in-project IPs that will never be published. |
version | publish-only | Semver string. Must match the Git tag pushed at publish time. Omit for in-project IPs. |
description | recommended | Single line, shown in rr pkg search hit rows. Keep under ~80 chars. |
license | recommended | SPDX identifier. Compound expressions like MIT OR Apache-2.0 are accepted. rr pkg audit surfaces IPs with no license declaration. |
hdl
The canonical source manifest. Both the registry (when publishing) and the dependency resolver (when building) read this list.
hdl:
language: systemverilog # vhdl-2008 | vhdl-93 | verilog | systemverilog
library: work # VHDL library (empty → work)
files:
- rtl/alpha.vhd
- rtl/beta.vhd
| Field | Notes |
|---|---|
language | Primary HDL dialect. Mixed-language IPs use the dominant language here; the resolver infers per-file dialect from file extensions. |
library | VHDL library the files compile into. Only meaningful for VHDL; ignored for (System)Verilog. |
files | Required. Paths relative to this ip.yml. Order is advisory only — the dependency resolver computes the real compile order by walking use clauses and module instantiations. |
Never sort
files:alphabetically assuming the build will work — always let the dependency resolver figure out compile order from language-level references.
dependencies
Other registry-published IPs this one depends on. The package
resolver installs the transitive closure at rr pkg install.
dependencies:
open-logic/olo_base_pkg: "^2.5.0"
routertl/cdc_synchronizer: "~1.2"
Constraint syntax: ^X.Y.Z (caret, major-pinned), ~X.Y.Z (tilde,
minor-pinned), exact X.Y.Z, or local for a local path reference.
build (optional)
Include this block when the IP is consumed in-tree by rr synth run.
Purely registry-published IPs (installed under libs/<ns>/<name>/) do
not need it — the consumer's own project uses the registry metadata.
build:
paths:
sources: hdl # scan root — the resolver walks from here
synthesis:
mode: rtl # rtl | ooc | xci | qsys | netlist | ooc_dcp
ips: # child IP-XACT cores this build pulls in
- ../shared_pkg/ip.yml
| Field | Notes |
|---|---|
build.paths.sources | Scan root for the dependency resolver, relative to the IP dir. Typically hdl or src. |
build.synthesis.mode | How the vendor tool treats this IP. rtl = compile into the parent project. ooc = out-of-context synthesis. xci, qsys, netlist, ooc_dcp = pre-packaged artefacts. Some modes are vendor-specific and fail early on incompatible targets. |
build.ips | Paths to sibling ip.yml files whose IP-XACT cores this build depends on (e.g., a crossbar that references a mux core). Resolved depth-first. |
build.synthesisintentionally does not document asources:list. Compile order is always computed by the dependency resolver fromhdl.files+build.paths.sources. The escape-hatch list exists in the reader for edge cases but is not advertised — if you find yourself needing it, that's a signal the resolver has a gap worth filing.
Mini-project extensions (RTL-P2.431)
Optional sub-blocks under build: that let an ip.yml drive synth-smoke,
simulation, and contract-check workflows in isolation — without a
wrapping project.yml. Every field is optional; existing IPs parse
unchanged.
hdl:
top_module: pulp_axis_stream_mux # standalone synth entry point
top_sim: tb_pulp_axis_stream_mux # standalone cocotb testbench top
build:
simulation:
sources: # sim-only source list; if empty,
- hdl/sim/tb_stub.sv # falls back to synthesis sources
test_dir: tests # where @cocotb.test()s live
simulator: verilator # nvc | ghdl | verilator | riviera | questa | vcs | xcelium
waves:
formats: [fst] # fst | vcd
sources:
xdc: # constraints for standalone synth-smoke
- constraints/pinout.xdc
- constraints/timing.xdc
tcl_hooks: # standalone-synth hook chain
gen_project: [tcl/pre_gen.tcl]
synthesis: [tcl/pre_synth.tcl]
implementation: []
bitstream: []
hardware: # standalone synth-smoke target
vendor: xilinx # parent project.yml's hardware
part: xczu7ev-ffvc1156-2-i # wins when the IP is used inside a project
tool_version: "2024.1"
requirements: requirements.yml # explicit opt-in to contract-first
# verification (rr sim contract-check)
# absence = IP does not declare a contract
| Field | Notes |
|---|---|
hdl.top_module | Standalone synth-smoke entry point. Used by rr synth run --ip <dir>. |
hdl.top_sim | Standalone cocotb testbench top entity. Used by rr sim run --ip <dir>. |
build.simulation.sources | Simulation-only source list (relative paths from IP root). When empty, rr sim run falls back to the synthesis source list. |
build.simulation.test_dir | Where cocotb tests live for this IP. Relative to IP root. |
build.simulation.simulator | Per-IP sim backend. Pick according to your HDL mix: Verilator for pure-SystemVerilog, GHDL/NVC for pure-VHDL, commercial (Riviera-PRO / Questa / VCS / Xcelium) for mixed-language or encrypted-IP dependencies. |
build.simulation.waves.formats | Waveform dump format preference. fst is compact; vcd is ubiquitous. |
build.sources.xdc | Constraint files for standalone synth-smoke. Mirrors sources.xdc in project.yml. |
build.tcl_hooks.{stage} | Per-stage TCL hook lists for the IP's own synth-smoke. Stages match project.yml's: gen_project, synthesis, implementation, bitstream. |
build.hardware.{vendor,part,tool_version} | Standalone synth target. Ignored when the IP is consumed inside a project — the parent project.yml's hardware block wins. |
requirements | Path (relative to IP root) to a requirements.yml file declaring the IP's port contract + functional REQs. Absence = IP opts out of rr sim contract-check silently. Presence with a missing target file is a hard error. Pairs with the requirements: field on project.yml. |
The mini-project extensions do NOT change how the IP resolves its synthesis source list — that's still
hdl.files+ the dependency resolver walk frombuild.paths.sources. They only add workflows (sim, contract-check, standalone synth) that previously required a wrappingproject.yml.
packaging (optional, RTL-P3.188)
Declare this block to opt into rr synth run's pre-synth auto-package
step, which runs vivado -mode batch -source <recipe> when the IP's
component.xml is missing or stale.
packaging:
recipe: tcl/package.tcl # IP-dir-relative path (required)
vendor: sdi_claude # optional
library: pulp # optional
version: "1.0" # optional
recipeis relative to this IP's directory and must stay inside it —../escapes are rejected. IPs are self-contained.- Optional
vendor/library/versionare advertised as parameters the recipe may consume. The recipe owns the defaults when they're absent — these fields are de-duplication sugar, not a mandatory second source of truth.
An IP without a packaging block is silently skipped by
rr synth run. rr pkg audit stays quiet about its packaging state
(vendored primitives and WIP IPs don't need IP-XACT).
Registry metadata (interfaces, parameters, fpga)
Optional informational blocks. Surface in rr pkg search / rr pkg info
and can feed IP-XACT packaging when present.
interfaces:
- name: aclk
type: clock
freq_hz: 100000000
associated_reset: aresetn
- name: S_AXI
type: axi4-lite
role: slave
clock: aclk
parameters:
- name: Width_g
type: integer
default: 8
description: "Data bus width in bits"
fpga:
vendors: [xilinx, altera]
resources:
bram: true
dsp: false
pll: false
Interface type values: clock, reset, axi4, axi4-lite,
axi4-stream, wishbone, avalon, apb, gpio, custom.
Complete Examples
Minimal vendored IP (in-project, never published)
name: pulp_axis_stream_mux
license: Apache-2.0 # from upstream PULP (SHL-0.51 OR Apache-2.0)
hdl:
language: systemverilog
library: work
files:
- hdl/pulp/stream_mux.sv
- hdl/pulp/stream_mux_vec.sv
- hdl/pulp_axis_stream_mux.sv
build:
paths:
sources: hdl
synthesis:
mode: rtl
Minimal registry-publishable IP
name: olo_base_fifo_async
namespace: open-logic
version: "2.5.0"
description: "Asynchronous FIFO, configurable depth + width."
license: LGPL-2.1-or-later
hdl:
language: vhdl-2008
library: olo
files:
- hdl/olo_base_fifo_async.vhd
dependencies:
open-logic/olo_base_pkg: "^2.5.0"
Full dual-use IP (registry + in-tree + auto-packaging)
name: sdi_crossbar
namespace: sdi_claude
version: "1.0.0"
description: "N×M AXIS crossbar with VDMA passthrough support."
license: MIT
hdl:
language: systemverilog
library: work
files:
- hdl/sdi_crossbar.sv
- hdl/sdi_crossbar_route.sv
dependencies:
sdi_claude/pulp_axis_stream_mux: "^1.0.0"
build:
paths:
sources: hdl
synthesis:
mode: rtl
ips:
- ../pulp_axis_stream_mux/ip.yml
packaging:
recipe: tcl/package.tcl
vendor: sdi_claude
library: sdi
interfaces:
- name: aclk
type: clock
freq_hz: 148500000
- name: aresetn
type: reset
polarity: active_low
fpga:
vendors: [xilinx]
resources:
bram: true
Kitchen-sink template — every supported field
Copy-paste starting point that exercises every block and every field the canonical schema supports. Delete what you don't need.
# ═══════════════════════════════════════════════════════════════════════════
# ip.yml — canonical unified schema (RTL-P3.189 / D.58)
#
# Every field is shown. Required fields are called out inline. The rest
# is optional — strip anything you're not using.
# ═══════════════════════════════════════════════════════════════════════════
# ── Identity ─────────────────────────────────────────────────────────────────
name: example_ip # REQUIRED — internal name used everywhere
namespace: my_org # (publish-only) registry namespace
version: "1.2.3" # (publish-only) semver, matches git tag
description: "One-line summary of what this IP does."
license: MIT # SPDX — MIT, Apache-2.0, BSD-3-Clause,
# LGPL-2.1-or-later, "MIT OR Apache-2.0", …
# ── HDL sources (REQUIRED) ───────────────────────────────────────────────────
# Canonical manifest — registry + dependency resolver both read this.
# Do NOT hand-order files; let the resolver walk `use` / `import` /
# module instantiations to compute compile order.
hdl:
language: vhdl-2008 # vhdl-2008 | vhdl-93 | verilog | systemverilog
library: example_lib # VHDL library. Empty or omitted → "work".
files: # REQUIRED — paths relative to this ip.yml
- rtl/example_pkg.vhd
- rtl/example_top.vhd
- rtl/example_fsm.vhd
# ── Registry dependencies ────────────────────────────────────────────────────
# Other published IPs this one needs. Format: {<ns>/<name>: <semver-spec>}.
# Constraints: ^X.Y.Z (major-pinned), ~X.Y.Z (minor-pinned), exact X.Y.Z,
# or "local" for a local-path reference.
dependencies:
open-logic/olo_base_pkg: "^2.5.0"
routertl/cdc_synchronizer: "~1.2"
my_org/shared_constants: "local"
# ── In-project build (optional) ──────────────────────────────────────────────
# Present this block ONLY when the IP is consumed in-tree by `rr synth run`.
# Registry-only IPs (installed under libs/<ns>/<name>/) should omit it.
build:
paths:
sources: rtl # scan root for the dependency resolver,
# relative to this IP's directory.
synthesis:
mode: rtl # rtl — compile into parent project
# ooc — out-of-context synth
# xci — Xilinx pre-packaged IP
# qsys — Quartus / Platform Designer
# netlist — pre-synthesised netlist
# ooc_dcp — OOC design-checkpoint reuse
ips: # child IP-XACT cores this build pulls in
- ../pulp_axis_stream_mux/ip.yml
- ../crossbar/ip.yml
# ── IP-XACT auto-packaging (optional — RTL-P3.188) ──────────────────────────
# Declare this block to opt into `rr synth run`'s pre-synth auto-package
# step. When component.xml is missing or stale, Vivado is invoked in batch
# mode with the recipe below. Recipe path is IP-dir-relative; no `../`
# escapes (IPs must be self-contained).
packaging:
recipe: tcl/package.tcl # REQUIRED within this block
vendor: my_org # optional — recipe may read as parameter
library: example_lib # optional — recipe may read as parameter
version: "1.0" # optional — recipe may read as parameter
# ── Bus interfaces (optional) ───────────────────────────────────────────────
# Surfaces in `rr pkg info`. Feeds IP-XACT interface inference when the
# packaging recipe uses `ipx::associate_bus_interfaces`.
interfaces:
- name: aclk # clock
type: clock
freq_hz: 100000000
associated_reset: aresetn
associated_busif: S_AXI,M_AXIS # comma-separated associated interfaces
- name: aresetn # reset
type: reset
polarity: active_low # active_low | active_high
- name: S_AXI # AXI-Lite slave
type: axi4-lite
role: slave
clock: aclk
reset: aresetn
- name: M_AXIS # AXI-Stream master
type: axi4-stream
role: master
clock: aclk
# Other supported types:
# - type: axi4 (role: master|slave)
# - type: wishbone (role: master|slave)
# - type: avalon (role: master|slave)
# - type: apb (role: master|slave)
# - type: gpio
# - type: custom
# ── Parameters / generics (optional) ────────────────────────────────────────
parameters:
- name: DataWidth_g
type: integer # integer | boolean | string | real
default: 32
description: "Data bus width in bits."
- name: UseReset_g
type: boolean
default: true
description: "Instantiate the reset synchroniser."
- name: ModeName_g
type: string
default: "default"
- name: Threshold_g
type: real
default: 0.75
# ── FPGA compatibility (optional) ───────────────────────────────────────────
# Empty `vendors: []` = compatible with everything (default).
fpga:
vendors: [xilinx, altera] # [xilinx, lattice, altera, microchip]
resources:
bram: true
dsp: false
pll: false
Legacy shape migration
Before D.58 / RTL-P3.189, two ip.yml shapes existed in the wild:
| Legacy shape | Example field | Canonical equivalent |
|---|---|---|
| vendored / nested | ip.name, ip.library, ip.language | name, hdl.library, hdl.language |
| vendored / nested | paths.sources (top-level) | build.paths.sources |
| vendored / nested | synthesis.mode (top-level) | build.synthesis.mode |
| vendored / nested | ips (top-level) | build.ips |
| vendored / nested | ip.license | license (root) |
| registry / flat | everything already at root | unchanged — already canonical |
Readers transparently normalize legacy payloads into the canonical shape and log a one-time deprecation hint. No build breaks on the transition.
When to migrate: next time you edit an IP's ip.yml, promote it
to the canonical shape. No mass-migration is required; the adapter
stays in place for at least one release. New IPs scaffolded with
rr ip init already get the canonical shape.
Validation + tooling
rr pkg publishvalidates the identity block (name,namespace,version,license) and rejects files missing required fields.rr pkg auditwalks vendored IPs underhw/ip/,src/ip/,ip/and flags license gaps (LICENSE_MISSING), packaging gaps (UNPACKAGED,STALE_COMPONENT_XML), and registry regressions. SeePROJECT_YML_REFERENCE.mdfor thelicense_policyblock that makes audit a CI gate.rr synth runreadsbuild:+packaging:to drive auto-packaging and compile order. Userr synth run --dry-runto see the plan without invoking Vivado.- The canonical annotated template lives at
sdk/schemas/ip_yml_template.yml; the machine-readable field schema consumed byrr help ip.ymllives atsdk/schemas/ip_yml_schema.yml.