一键导入
pnr
Run ORFS make flow on sky130hd for synthesis, place-and-route, and GDS export. Produces timing/power/area reports and GDS file.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Run ORFS make flow on sky130hd for synthesis, place-and-route, and GDS export. Produces timing/power/area reports and GDS file.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | pnr |
| description | Run ORFS make flow on sky130hd for synthesis, place-and-route, and GDS export. Produces timing/power/area reports and GDS file. |
| disable-model-invocation | true |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob","mcp__chipagent-backend__check_environment","mcp__chipagent-backend__generate_config","mcp__chipagent-backend__run_stage","mcp__chipagent-backend__get_report","mcp__chipagent-backend__diagnose_failure","mcp__chipagent-backend__clean_design","mcp__chipagent-backend__compare_runs"] |
Physical implementation pipeline: synthesize compiled Verilog through ORFS make flow on sky130hd, run all PnR stages, and produce a formatted PPA verification report.
/chip-agent:pnr <ModuleName>
Example:
/chip-agent:pnr ALU8
Determine the project root directory by finding the nearest ancestor directory of .claude. Use that directory as the base for all relative paths below.
Set up variables:
PROJECT_ROOT="<project-root>"
RAW_MODULE="$ARGUMENTS" # first argument: module name (any case)
Normalize the module name so frontend and backend accept the same spelling. Rule (matches /chip-agent:chipyard): if the argument is all-lowercase, capitalize the first letter and append Config; otherwise take it as-is. If the resulting directory does not exist but a <Name>Config directory does, fall back to that.
if [ -z "$RAW_MODULE" ]; then
echo "Usage: /chip-agent:pnr <ModuleName>"; exit 1
fi
if echo "$RAW_MODULE" | grep -qE '[A-Z]'; then
MODULE="$RAW_MODULE"
else
FIRST=$(echo "${RAW_MODULE:0:1}" | tr '[:lower:]' '[:upper:]')
MODULE="${FIRST}${RAW_MODULE:1}Config"
fi
# Fallback: if normalized dir missing but bare-PascalCase Config variant exists, use it
if [ ! -d "$PROJECT_ROOT/MyDesign/$MODULE" ] && [ -d "$PROJECT_ROOT/MyDesign/${MODULE}Config" ]; then
MODULE="${MODULE}Config"
fi
# Final fallback: case-insensitive directory match in MyDesign/ (handles e.g. tinyrocket -> TinyRocketConfig)
if [ ! -d "$PROJECT_ROOT/MyDesign/$MODULE" ]; then
MATCH=$(ls "$PROJECT_ROOT/MyDesign" 2>/dev/null | grep -i "^${RAW_MODULE}\(Config\)\?$" | head -1)
if [ -n "$MATCH" ]; then MODULE="$MATCH"; fi
fi
echo "Resolved module: $MODULE"
Check that compiled Verilog exists:
test -f "$PROJECT_ROOT/MyDesign/$MODULE/workspace/generated/$MODULE.v"
No compiled Verilog found for <ModuleName>.
Run `/chip-agent:workflow <description>` first.
Chipyard detection: Check if this is a Chipyard-generated design:
test -f "$PROJECT_ROOT/MyDesign/$MODULE/workspace/generated/sram_mapping.json"
Also check spec.json:
grep -q '"source".*"chipyard"' "$PROJECT_ROOT/MyDesign/$MODULE/workspace/spec.json" 2>/dev/null
If either condition is true, this is a Chipyard+SRAM design. STOP and redirect:
Chipyard+SRAM design detected for <ModuleName>.
This requires the specialized chipyard-pnr flow (nosram preprocessing, SRAM override generation, ABC exclusion, OOM management).
Run: /chip-agent:chipyard-pnr <ModuleName>
Do NOT proceed with the standard-cell-only PnR pipeline below. The Chipyard flow has critical pitfalls (ABC SIGABRT, module redefinition, OOM) that this skill does not handle.
Call mcp__chipagent-backend__check_environment with no arguments.
Verify the response:
orfs.installed must be truesky130hd.installed must be trueIf either is false, STOP with message:
ORFS or sky130hd PDK not found.
Install OpenROAD-flow-scripts and ensure sky130hd platform is available.
See: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts
Extract and save for subsequent steps:
ORFS_FLOW_PATH = orfs.flow_pathRead MyDesign/$MODULE/workspace/spec.json if it exists. Extract:
clock_port (default: "clock" if absent)clock_period_ns (default: 10 if absent)top_module (default: use first module in Verilog if absent)source (optional, used for informational purposes)Call mcp__chipagent-backend__generate_config with:
module_name: top_module from spec.json (for Chipyard flows this will be ChipTop), or $MODULE if no top_module specifiedverilog_path: absolute path to MyDesign/$MODULE/workspace/generated/$MODULE.vworkspace_dir: absolute path to MyDesign/$MODULE/workspaceclock_port: from spec.json or "clock"clock_period_ns: from spec.json or 10Extract and save for subsequent steps:
CONFIG_MK = config_mk from responseDESIGN_NAME = design_name from responseInitialize comparison state:
comparison_round_count = // will be determined dynamically after synth in Step 3max_retries_per_round = 2round_plans =
{ clock_period_ns: <from spec.json or 10>, core_utilization: 40 }synth_cell_count = null (populated after Round 1 synth completes)Call mcp__chipagent-backend__compare_runs with:
action: "clear"workspace_dir: absolute path to MyDesign/$MODULE/workspaceThis resets the QoR history for a fresh run. Each /chip-agent:pnr invocation starts with an empty history.
MANDATORY: All rounds must run to completion. Do NOT skip remaining rounds even if an earlier round passes. Every round's result is needed for QoR comparison.
Set round_index = 0. While round_index < length of round_plans:
Set:
round = round_index + 1current_params = snapshot of round_plans[round_index]restart_from = "synth"retry_attempt = 1round_complete = falseBefore the first attempt in the round, call mcp__chipagent-backend__clean_design with:
config_mk_path: latest CONFIG_MKorfs_flow_path: ORFS_FLOW_PATHGenerate config for the round by calling mcp__chipagent-backend__generate_config with:
module_name: $MODULEverilog_path: absolute path to MyDesign/$MODULE/workspace/generated/$MODULE.vworkspace_dir: absolute path to MyDesign/$MODULE/workspaceclock_port: from spec.json or "clock"clock_period_ns: current_params.clock_period_nscore_utilization: current_params.core_utilizationplace_density: current_params.place_density (only if defined)gpl_timing_driven: current_params.gpl_timing_driven (only if defined)gpl_routability_driven: current_params.gpl_routability_driven (only if defined)Update CONFIG_MK from the response.
While retry_attempt <= max_retries_per_round and round_complete == false:
5a. Execute round via pnr-round-executor agent:
Spawn the pnr-round-executor agent (at agents/pnr-round-executor.md) with this input contract:
module: $MODULE
project_root: $PROJECT_ROOT
round_number: round
total_rounds: comparison_round_count
restart_from: restart_from
current_params: current_params
config_mk: CONFIG_MK
design_name: DESIGN_NAME
orfs_flow_path: ORFS_FLOW_PATH
clock_port: <from spec.json or "clock">
The agent runs all stages, displays per-stage metrics, diagnoses failures, and returns a structured JSON result.
5b. Parse the executor's JSON result:
Extract status, metrics, failed_stage, and diagnosis from the returned JSON block.
5c. Save run to QoR history:
status == "pass", save immediately.retry_attempt == max_retries_per_round, save the failing round.Use mcp__chipagent-backend__compare_runs with:
action: "save"workspace_dir: absolute path to MyDesign/$MODULE/workspacerun:
round: current round numberconfig: current_paramsmetrics: metrics from executor result (includes wns, tns, area, total_power_w, drc_violations, cell_count)status: "pass" or "fail"error_type: diagnosis.error_type if status is "fail", omit if "pass"5d. Finish or retry the round:
status == "pass": Display "Round {round}/{comparison_round_count} completed (PASSED). {comparison_round_count - round} rounds remaining." and set round_complete = true.retry_attempt == max_retries_per_round: Display "Round {round}/{comparison_round_count} completed (FAILED, retries exhausted). {comparison_round_count - round} rounds remaining." and set round_complete = true.5e. Check severity and prepare retry:
If diagnosis.severity == "critical":
"Critical error: {diagnosis.details}. Not fixable by parameter adjustment. Ending round {round}/{comparison_round_count}."round_complete = trueOtherwise, apply adjustments and retry:
diagnosis.suggested_params into current_params: overwrite matching keys, keep others unchanged."Round {round} diagnosed: {diagnosis.error_type}. Adjusting: {list changed params with old -> new values}. Restarting from {diagnosis.restart_from}."restart_from = diagnosis.restart_frommcp__chipagent-backend__clean_design with:
config_mk_path: CONFIG_MKorfs_flow_path: ORFS_FLOW_PATHmcp__chipagent-backend__generate_config with updated current_params (same arguments as step 3 above)CONFIG_MK from the new response.retry_attempt += 1Dynamic round expansion (after Round 1):
After the round completes (pass or retries exhausted), if round_index == 0 and round_plans has only 1 entry, expand based on metrics.cell_count (from synth):
{ clock_period_ns: max(1, <baseline clock> * 0.8), core_utilization: 40, gpl_timing_driven: true }{ clock_period_ns: max(1, <baseline clock> * 0.8), core_utilization: 35, gpl_timing_driven: true, gpl_routability_driven: true }cell_count > 1000:
{ clock_period_ns: max(1, <baseline clock> * 0.8), core_utilization: 35, place_density: 0.55, gpl_routability_driven: true }{ clock_period_ns: max(1, <baseline clock> * 0.7), core_utilization: 30, gpl_timing_driven: true }Append new entries to round_plans. Set comparison_round_count to the total number of rounds (3 or 5).
Increment round_index += 1
4a. Load all runs:
Call mcp__chipagent-backend__compare_runs with:
action: "load"workspace_dir: absolute path to MyDesign/$MODULE/workspace4b. Display comparison table:
Format the comparison table from all runs:
=== QoR Comparison: <ModuleName> ===
| Round | Clock (ns) | Utilization | Density | WNS (ns) | TNS (ns) | Area (um2) | Power (uW) | DRC | Status |
|-------|-----------|-------------|---------|----------|----------|------------|------------|-----|--------|
For each run in the history:
Clock (ns) = config.clock_period_nsUtilization = config.core_utilization with % suffixDensity = config.place_density or "-" if not setWNS (ns) = metrics.wns or "N/A" if unavailableTNS (ns) = metrics.tns or "N/A" if unavailableArea (um2) = metrics.area or "N/A" if unavailablePower (uW) = metrics.total_power_w * 1e6 or "N/A" if unavailableDRC = metrics.drc_violations or "N/A" if unavailableStatus = "PASS" or "FAIL"4c. Best-run recommendation:
Call mcp__chipagent-backend__compare_runs with:
action: "recommend"
workspace_dir: absolute path to MyDesign/$MODULE/workspace
If a best run is returned: Display "Recommendation: Round {N} (clock={X}ns, WNS={Y}ns, area={Z}um2, power={P}uW)" where {P} = best.metrics.total_power_w * 1e6 or "N/A" if unavailable
If no best run: Display "No passing run found. All rounds failed or had timing/DRC violations."
Only run this step if at least one passing round exists (i.e., compare_runs recommend returned a best run).
Use the best run's metrics for the report.
Run the agent pnr-report-formatter.md (relative to project root) and follow the agent's rules to format a PPA summary report.
Pass the agent these data accumulated from the best run's get_report responses:
cell_count, synth_areawns, tns, total_w, internal_pct, switching_pct, leakage_pct, area, utilizationviolationsclock_name and clock_period_ns from Step 2 (spec.json or defaults)design_name from Step 2orfs_flow_path from Step 1The agent formats and presents the PPA summary report directly in the conversation.
| # | Stage | Description |
|---|---|---|
| 0 | Verify Prerequisites | Check compiled Verilog exists for module |
| 1 | Check Environment | Verify ORFS + sky130hd via MCP |
| 2 | Generate Config | Create config.mk + constraint.sdc and initialize comparison-round presets |
| 2.5 | Clear QoR History | Reset qor_history.json for fresh run |
| 3 | Run Comparison Rounds | Baseline + alternative parameter rounds, with retries inside each round |
| 4 | QoR Comparison | Display comparison table + best-run recommendation |
| 5 | Format Report | PPA summary via pnr-report-formatter agent (best passing run only) |
$ARGUMENTS
A module name (PascalCase, e.g., ALU8, Counter8). The module must already have compiled Verilog at MyDesign/<ModuleName>/workspace/generated/<ModuleName>.v.
Upon pipeline completion, the following artifacts are produced:
{orfs_flow_path}/results/sky130hd/{design_name}/base/1_2_yosys.v{orfs_flow_path}/results/sky130hd/{design_name}/base/6_1_merged.gds{orfs_flow_path}/reports/sky130hd/{design_name}/base/{orfs_flow_path}/logs/sky130hd/{design_name}/base/scripts/synth.sh or scripts/pnr.sh -- they are migration stubs that exit with errormcp__chipagent-backend__get_report, which is responsible for resolving the correct ORFS/workspace artifact locationsmake commands -- use the MCP tools which handle ORFS make invocationclean_design between retries -- ORFS caches all stages; without cleaning, even partial restarts reuse stale cached results"critical" -- synthesis errors and combinational timing violations are not fixable by parameter adjustmentcurrent_params to original values between rounds -- build on previous adjustments to avoid parameter driftRun full Chipyard-to-ORFS PnR flow for large designs (SmallBOOM etc.) using All-Mock memory blackboxing in Docker: generate RTL, preprocess nosram, run multi-round ORFS synth->finish with mock SRAMs to avoid OOM.
Docker Chipyard flow: generate RTL from a Chipyard config via Docker, run SRAM mapping, stage artifacts into MyDesign, and hand off to PnR.
Run full Chipyard-to-ORFS PnR flow with multi-round parameter iteration in Docker: generate RTL from Chipyard Docker, preprocess nosram+SRAM override, run 3 rounds of ORFS synth→finish on sky130hd with progressive clock/utilization/density tuning for optimal PPA.
Run full Chipyard-to-ORFS PnR flow with multi-round parameter iteration: generate RTL from Chipyard with ENABLE_YOSYS_FLOW, preprocess nosram+SRAM override, run 3 rounds of ORFS synth→finish on sky130hd with progressive clock/utilization/density tuning for optimal PPA.
Unified Chipyard PnR flow: automatically routes to local or Docker workflow based on backend_mode setting.
Unified Chipyard flow: automatically routes to local or Docker workflow based on backend_mode setting.