| name | rtl-ip-instantiate |
| description | Generate convention-compliant SV wrapper for third-party IP (memory, PLL, PHY, DSP) โ 'instantiate IP', 'IP wrapper', 'integrate third-party IP'. |
| user-invocable | true |
| argument-hint | [ip-name | path/to/ip-descriptor.xml] |
| allowed-tools | Bash, Read, Write, Edit, Task, Grep, Glob |
Generate a convention-compliant SystemVerilog wrapper module that instantiates a third-party IP with correct port connections, parameter settings, and explicit tie-offs. Output: `rtl/ip_wrappers/{ip_name}_wrapper.sv`.
<Use_When>
- Integrating a new third-party IP (memory, PLL, PHY, DSP block) with an IP-XACT descriptor or datasheet.
- A wrapper with standard AXI/APB or custom interface adaptation is needed.
- Vendor port names must be translated to project naming conventions.
</Use_When>
<Do_Not_Use_When>
- IP is already instantiated and only parameter changes are needed โ edit the file directly.
- IP is first-party RTL developed in this project โ no wrapper needed.
- Full IP integration with verification is needed โ run
rtl-p5s-func-verify after this skill.
</Do_Not_Use_When>
<Why_This_Exists>
IP instantiation is error-prone: wrong port widths, missing tie-offs, and parameter mismatches cause subtle bugs that survive lint. Automated wrapper generation from the authoritative IP descriptor eliminates transcription errors and documents every connection explicitly, making the mapping auditable.
</Why_This_Exists>
Prerequisites
- IP descriptor present at
docs/ip/{ip_name}.xml (IP-XACT) or equivalent datasheet.
- Project coding conventions readable from
rtl/ip_wrappers/ (existing wrappers) or .claude/rules/rtl-coding-conventions.md.
If missing: WARNING โ halt and ask user for IP descriptor location before generating.
| Path | Role |
|------|------|
| `templates/ip-wrapper-template.sv` | SV wrapper scaffold with `u_` instance, `logic`-only ports, `// TIED:` and `// PARAM:` comment patterns. |
| `scripts/gen_instantiation.py` | Deterministic wrapper skeleton generator: parses the vendor module header (ANSI ports/parameters, CamelCase/ALL-CAPS names allowed), emits a convention-compliant wrapper (`i_`/`o_`/`io_` prefixes, `clk`/`rst_n` naming, parameter pass-through with UPPER_SNAKE_CASE rename, `--tie PORT=VALUE[:reason]` tie-offs + documentation table). Stdlib-only. |
| `references/ip-instantiate-conventions.md` | Port-prefix rules, vendor-to-project mapping table, tie-off/param comment format, anti-patterns. |
| `examples/` | Worked example: `vendor_sram_2p/` (vendor 2-port SRAM stub + raw generated skeleton, regeneration-synced) and `sram_2p_wrapper/` (hand-tuned deliverable with clock merge, functional names, polarity adaptation, documented tie-offs). |
<Responsibility_Boundary>
- Scripts (
gen_instantiation.py) handle deterministic skeleton generation โ vendor-name translation, parameter pass-through, tie-off scaffolding; lint validation (Verible + slang) runs via Bash CLI.
- LLM handles port mapping design, tie-off decisions, clock-domain merging, polarity adaptation, and parameter documentation.
- Contract surface: every IP port either connects to a wrapper port or carries a
// TIED: reason comment; no silent unconnected ports.
</Responsibility_Boundary>
1. Spawn `rtl-explorer` to read existing `rtl/ip_wrappers/` and summarise current naming conventions (port prefixes, clock/reset style, instance prefix).
2. Spawn `rtl-architect` to read the IP descriptor โ list all ports, tie-off requirements, and parameter settings; design wrapper interface mapping vendor names to project conventions (`i_`/`o_`/`io_` prefixes, `{domain}_clk`, `{domain}_rst_n`).
3. If the vendor Verilog/SV header file is available, generate the deterministic skeleton first: `python3 {plugin_root}/skills/rtl-ip-instantiate/scripts/gen_instantiation.py -o rtl/ip_wrappers/{ip_name}_wrapper.sv --tie "PORT=VALUE:reason" ...` (`{plugin_root}` = plugin root resolved from `.rat/state/spawn-context.json`; one `--tie` per port the architect marked unused). If only a datasheet/IP-XACT exists, start from `templates/ip-wrapper-template.sv` instead.
4. Spawn `rtl-coder` to hand-tune `rtl/ip_wrappers/{ip_name}_wrapper.sv` per architect spec โ merge/rename clock domains, give mapped ports functional names, adapt polarities, resolve all TODO markers. `logic` types only, `u_{ip_name}` instance, all ports connected or `// TIED:`, parameters documented with `// PARAM:`.
5. Run lint: `verible-verilog-lint rtl/ip_wrappers/{ip_name}_wrapper.sv && slang rtl/ip_wrappers/{ip_name}_wrapper.sv` โ fix all errors before delivering.
6. Report wrapper path to the user.
Apply steps 1-6 to every requested IP โ do not stop after the first.
<Tool_Usage>
Task(subagent_type="rtl-agent-team:rtl-explorer",
prompt="Read rtl/ip_wrappers/ and docs/ for existing wrapper patterns. Summarise: "
"port naming convention (i_/o_/io_ prefixes), clock naming ({domain}_clk), "
"reset naming ({domain}_rst_n), instance naming (u_ prefix).")
Task(subagent_type="rtl-agent-team:rtl-architect",
prompt="Read IP descriptor at docs/ip/{ip_name}.xml (or datasheet). List all ports, "
"required tie-offs, and parameter settings. Design wrapper interface: map vendor "
"port names to project convention (i_/o_/io_ prefixes, {domain}_clk, {domain}_rst_n).")
Task(subagent_type="rtl-agent-team:rtl-coder",
prompt="Write rtl/ip_wrappers/{ip_name}_wrapper.sv. Instantiate {ip_name} as u_{ip_name} "
"with all ports connected per architect spec. Use logic only (no reg/wire). "
"Port prefixes: i_ input, o_ output, io_ bidirectional. "
"Clock: {domain}_clk, reset: {domain}_rst_n. "
"Tied ports: // TIED: reason. Parameters: // PARAM: description.")
</Tool_Usage>
SRAM IP with 32 vendor ports; IP-XACT at docs/ip/sram.xml; project uses AXI4-Lite.
rtl-explorer confirms i_/o_ prefix style; rtl-architect maps vendor clkโsys_clk, rst_nโsys_rst_n, dinโi_sram_din; rtl-coder writes wrapper with u_sram instance and logic types; lint passes.
PLL IP with test-mode ports that must be tied off.
All functional ports connected; test-mode ports tied to constants with `// TIED: unused test mode input` comments; parameter DATA_WIDTH documented with `// PARAM: AXI data bus width`.
IP has port width mismatch โ vendor provides 36-bit data bus, project interface is 32-bit.
rtl-architect flags mismatch to user; wrapper generation halted pending user resolution decision; no auto-truncation performed.
<Escalation_And_Stop_Conditions>
- IP descriptor not found โ halt immediately; ask user for datasheet or IP-XACT file path.
- Port width mismatch between IP and project interface โ flag to user; do not auto-resolve.
- Generated wrapper fails lint โ fix all errors before delivering; do not suppress warnings without documented rationale.
</Escalation_And_Stop_Conditions>
Output
rtl/ip_wrappers/{ip_name}_wrapper.sv โ convention-compliant wrapper module.
<Final_Checklist>