AgentStack
SKILL verified MIT Self-run

Signoff Loop

skill-shenshan123-r2g-skills-signoff-loop · by ShenShan123

Drive an open-source EDA workflow from RTL to GDS with full signoff (DRC, LVS, RCX) using OpenROAD-flow-scripts (ORFS), Yosys, KLayout, Magic, Netgen, and OpenRCX — plus a self-improving observation→ingest→act loop that learns repair recipes to eliminate DRC/LVS violations and close timing at the best Fmax. Use when the user wants to turn a hardware spec or RTL into synthesis, place-and-route, GD…

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add skill-shenshan123-r2g-skills-signoff-loop

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Signoff Loop? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

signoff-loop Skill

Execute a staged, artifact-first open-source EDA flow from specification to GDSII with full signoff checks using OpenROAD-flow-scripts (ORFS), and close the loop by learning from every run (the two memory DBs + engineer_loop) so DRC/LVS violations are eliminated and timing closes at the best Fmax. Prefer deterministic scripts for execution, keeping the agent focused on planning, generation, diagnosis, and iteration.

> Dataset construction lives in the companion def-graph skill. This skill produces > the clean, signed-off 6_final.def/.odb/.spef; converting those into PyG graph > datasets (the five views b–f, tech-lib/LEF parser, feature + label extraction) is > def-graph's job — see its SKILL.md.

Environment Setup

Every flow script sources scripts/flow/_env.sh on entry, which autodetects ORFS + tool paths and lets the user override any single value. You do not need to source anything manually.

Resolution order (first hit wins, per value)

  1. Variable already set in the caller's environmentORFS_ROOT=... run_orfs.sh ... wins unconditionally.
  2. User env file — path in $R2G_ENV_FILE (if set).
  3. In-skill override filereferences/env.local.sh (copy from references/env.local.sh.template).
  4. ORFS-provided env$ORFS_ROOT/env.sh (once ORFS_ROOT is known).
  5. System-wide env/opt/openroad_tools_env.sh (if present).
  6. Autodetectcommand -v on $PATH, then a list of well-known install paths (e.g. $ORFS_ROOT/tools/install/OpenROAD/bin/openroad, $HOME/oss-cad-suite/bin/yosys, /usr/local/bin/klayout).

Checking what the skill found

bash scripts/flow/check_env.sh

Prints the resolved ORFS_ROOT, every tool binary it picked, and the platforms it can see. Exits non-zero if a required tool is missing.

Overriding just a few values

# One-off override for a single run
ORFS_ROOT=/opt/ORFS OPENROAD_EXE=/opt/openroad/bin/openroad \
  bash scripts/flow/run_orfs.sh design_cases/my_design nangate45

# Or persist overrides in a file
cp references/env.local.sh.template references/env.local.sh
# ...then edit the exports you care about; every subsequent flow picks them up.

Available platforms

nangate45, sky130hd, sky130hs, asap7, gf180, ihp-sg13g2 (default: asap7).

Workflow

1. Normalize the Specification First

  • Convert free-form requirements into a structured specification before writing RTL.
  • Read references/spec-template.md and produce input/normalized-spec.yaml.
  • If clock/reset, IO, target flow, or timing targets are missing, stop and ask the user or record explicit assumptions.

2. Initialize a Project Directory

  • Create a run folder under design_cases// using scripts/project/init_project.py.
  • The layout follows references/workflow.md.
  • Directories created: input/, rtl/, tb/, constraints/, lint/, sim/, synth/, backend/, drc/, lvs/, rcx/, reports/.

3. Generate RTL and Testbench Separately

  • Write RTL to rtl/design.v.
  • Write testbench to tb/testbench.v.
  • Keep assumptions and design notes in reports/rtl-notes.md.

4. Run Validation in Strict Order

  1. Run scripts/project/validate_config.py before ORFS backend to catch config/RTL issues early.
  2. Run lint/syntax checks before simulation.
  3. Run simulation before synthesis.
  4. Run synthesis before backend (ORFS).
  5. Do not skip failed stages unless the user explicitly requests it.

5. Run Backend with ORFS

  • Prepare constraints/config.mk and constraints/constraint.sdc.
  • Use scripts/flow/run_orfs.sh to invoke the ORFS Makefile.
  • ORFS runs place-and-route natively (no Docker required).
  • Collect results from the ORFS results directory.

5b. Check Timing Before Signoff (Tiered WNS + TNS)

After ORFS completes, extract PPA and run the timing gate:

  1. Run scripts/extract/extract_ppa.py reports/ppa.json to extract timing metrics.
  2. Run scripts/reports/check_timing.py to classify WNS and TNS and write reports/timing_check.json.
  3. The script independently classifies WNS and TNS, then takes the worse of the two as the combined tier. A design with small WNS but large TNS (many slightly-violating paths) is caught.
  4. Read reports/timing_check.json and act on the tier:

| Tier | Criteria | Agent Action | |------|----------|-------------| | clean | WNS >= 0, TNS >= 0 | Proceed to signoff. | | minor | WNS >= -2.0 AND TNS >= -10.0 | Auto-fix: update clk_period in constraint.sdc to suggested_clock_period from the JSON, then re-run backend. Report the fix to the user after the fact. | | moderate | WNS >= -5.0 AND TNS >= -100.0 (but not clean/minor) | Stop. Present the numbered options from the JSON to the user. Wait for their choice. | | severe | WNS 1e+30 | Stop. SDC clock port mismatch. Present options. Do NOT proceed. |

  1. The JSON includes wns_tier and tns_tier fields so the agent can explain which metric triggered the tier (e.g., "TNS escalated this from minor to moderate").
  2. Only proceed to signoff checks (step 6) after timing is resolved.

5a. (Optional) Fmax search — find the fastest closing period

Before committing to a clock period, you can characterize the design's Fmax:

python3 scripts/reports/fmax_search.py [platform] [--verify]

Loose-first search using cheap placement-stage timing (each probe runs only ORFS_STAGES="synth floorplan place"). It reports a predicted-signoff Fmax (reports/fmax_search.json), corrected by a learned per-family slack-deterioration model. The number is a proxy (UNVERIFIED) — post-place timing is optimistic vs signoff. Pass --verify to confirm the winner with one full flow (and feed the result back to tighten the model). This does NOT replace the step-8 check_timing gate, which still runs on the final backend.

Knobs: --probe-timeout, --place-fast (whole-search conservative lower bound for hang-prone designs), --keep-variants. The search is sequential; cross-design parallelism is achieved by running multiple invocations concurrently.

6. Run Signoff Checks (DRC, LVS, RCX)

After a successful backend run, run signoff checks in order:

DRC (Design Rule Check)

Two tool options are available:

  1. KLayout DRC (default) — scripts/flow/run_drc.sh [platform]
  • Uses ORFS make drc target with platform .lydrc rules
  • Outputs: drc/6_drc.lyrdb, drc/6_drc_count.rpt, drc/6_drc.log
  1. Magic DRC (sky130 only) — scripts/flow/run_magic_drc.sh [platform]
  • Uses Magic's built-in DRC engine with sky130A tech file
  • Requires the sky130A PDK; the script reads $PDK_ROOT/sky130A/libs.tech/magic/sky130A.tech

(set PDK_ROOT via references/env.local.sh/opt/pdks is only the fallback default).

  • Outputs: drc/magic_drc.rpt, drc/magic_drc_count.rpt, drc/magic_drc_result.json
  • Supported platforms: sky130hd, sky130hs
LVS (Layout vs Schematic)

Two tool options are available:

  1. KLayout LVS (default) — scripts/flow/run_lvs.sh [platform]
  • Uses ORFS make lvs target with platform .lylvs rules + CDL netlist
  • Gracefully skips platforms without LVS rules (produces lvs/lvs_result.json with status "skipped")
  • Outputs: lvs/6_lvs.lvsdb, lvs/6_lvs.log, lvs/6_final.cdl
  • nangate45: uses adapted FreePDK45 rules with connect_implicit("VDD"/"VSS") for bulk merging and schematic.purge for unused cell pins (e.g., QN on DFFR_X1)
  • Large design warning: KLayout LVS on designs >100K cells (black_parrot, swerv) takes >60 minutes. Use LVS_TIMEOUT=7200 for these designs. The default 3600s may not be enough.
  1. Netgen LVS (sky130 only) — scripts/flow/run_netgen_lvs.sh [platform]
  • Two-step flow: Magic extracts SPICE from GDS, then Netgen compares against Verilog netlist
  • Requires the sky130A PDK (Magic tech + $PDK_ROOT/sky130A/libs.tech/netgen/sky130A_setup.tcl).

Set PDK_ROOT via references/env.local.sh; /opt/pdks is only the fallback default.

  • Outputs: lvs/extracted.spice, lvs/netgen_lvs.rpt, lvs/netgen_lvs_result.json
  • Supported platforms: sky130hd, sky130hs
  • This is the production sky130 LVS path — prefer it over KLayout LVS on sky130 (the

ORFS KLayout sky130 rule deck is not production-grade; see references/failure-patterns.md, "sky130 LVS").

  • Antenna-diode designs are handled automatically: the script normalizes Magic's diode

X-subcircuit instances to D devices (perim=pj=) and runs netgen with MAGIC_EXT_USE_GDS=1, so sky130_fd_sc_hd__diode_2 matches instead of flattening.

  • Designs with port-to-port feedthroughs (assign out_port = in_port) need

export POST_GLOBAL_PLACE_TCL = /scripts/flow/orfs_hooks/buffer_port_feedthroughs.tcl in config.mk before the backend run — SPICE cannot express two top-level ports on one net, so without the hook LVS fails "Top level cell failed pin matching". The hook is a no-op for designs without feedthroughs (safe to set everywhere); a backend re-run is required when adding it. See references/failure-patterns.md, "sky130 LVS" cause 5.

RCX (Parasitic Extraction)
  1. RCXscripts/flow/run_rcx.sh [platform]
  • OpenRCX parasitic extraction via OpenROAD
  • Generates Tcl script (rcx/run_rcx.tcl) with define_process_corner, extract_parasitics, write_spef
  • Reads 6_final.odb from ORFS results, writes SPEF output
  • Outputs: rcx/6_final.spef, rcx/rcx.log, rcx/run_rcx.tcl

Extract results into JSON for reporting and dashboard:

  • scripts/extract/extract_drc.py reports/drc.json
  • scripts/extract/extract_lvs.py reports/lvs.json
  • scripts/extract/extract_rcx.py reports/rcx.json
  • If DRC/LVS is fail, attempt automated real-layout fixes:

scripts/flow/fix_signoff.sh [platform] [--check drc|lvs|both] (See references/signoff-fixing.md.)

  • If the backend aborted at route (congestion / DRT timeout, exit 124 — orfs_status=fail,

orfs_fail_stage=route), relieve it BEFORE signoff: scripts/flow/fix_signoff.sh sky130hd --check route (lowers CORE_UTILIZATION so DRT converges; learnable + A/B-validated route_relief). See references/failure-patterns.md "Routing Congestion".

Fix-Learning Loop

The skill learns from every fix attempt so candidate strategies are proposed in evidence-ranked order on the next similar violation.

  • Record. fix_signoff.sh and check_timing.py --journal append lossless,

session-keyed rows to reports/fix_log.jsonl (one per iteration: strategy, before/after counts, pre-fix violation class, verdict). fix_signoff.sh uses an adaptive budget (base 3 iters, hard cap 8, early-stop after 2 non-improving iters past the base).

  • Ingest. Step-10 ingest (knowledge/ingest_run.py) reads fix_log.jsonl into the

Tier-1 fix_events table and writes a run_violations snapshot for every run — clean or not (the full violation landscape). It then auto-runs fix_log_manager.manage() (toggle R2G_FIX_AUTOLEARN, default on).

  • Learn. learn_heuristics.py derives Tier-2 fix_trajectories (per-episode path,

including abandoned episodes and failed strategies — negative learning) and folds them into Tier-3 fix_recipes inside heuristics.json.

  • Apply. When a recipe exists for the design's family/platform/violation class,

diagnose_signoff_fix.py reorders the strategy list by empirical clearance — there is no hard gate, all real-fix strategies are always proposed, priority-ordered. diagnose_signoff_fix.py --check drc --list prints the evidence-ranked candidate set as JSON. Hard safety clamps are unchanged.

  • Symptom index. Learned repair experience is keyed by a symptom signature

(knowledge/symptom.py: {check, class, predicates} → a stable symptom_id), NOT the design-family name. learn_heuristics.py emits a top-level symptoms[symptom_id] projection in heuristics.json (pooled across families/platforms, with by_platform + evidence_designs provenance); diagnose_signoff_fix.py looks recipes up by symptom and seeds an informed cross-platform prior for untried strategies (so a fix learned on nangate45 transfers to e.g. sky130hd). It also surfaces the matching active prose lesson (via search_failures.lessons_for_symptom) at the fix-decision point. monitor_health.py (degradation alerts) and analyze_execution.py (fix-proposal triage) are operator-invoked CLIs over the same store.

See references/signoff-fixing.md ("Fix-Learning Loop") and knowledge/README.md.

Engineer Loop (campaign mode)

Use campaign mode when you need to run the full flow unattended across many designs — or when you want the A/B-gated recipe-learning cycle to run autonomously. The campaign orchestrator (scripts/loop/engineer_loop.py) drives the flow scripts, ingests results, triggers learning, and manages A/B trials without human gates.

# Add a project to the campaign ledger
python3 scripts/loop/engineer_loop.py add \
    --ledger design_cases/_batch/campaign.jsonl \
    --project design_cases/my_design [--platform nangate45]

# Run the campaign (optionally limit to N designs)
python3 scripts/loop/engineer_loop.py run \
    --ledger design_cases/_batch/campaign.jsonl [--max N]

# Inspect per-design state
python3 scripts/loop/engineer_loop.py status \
    --ledger design_cases/_batch/campaign.jsonl

The ledger is JSONL (last-state-wins); kill/restart is safe — the campaign resumes where it left off. States: pending → flow → signoff → fixing → clean | escalated | abandoned.

Hard rules for campaign mode:

  • Phase-1 runs workers=1 (single-process); do not run two campaigns sharing a DESIGN_NAME

concurrently.

  • Never run two configs with the same DESIGN_NAME + FLOW_VARIANT concurrently.
  • Never run more than one LVS job concurrently for designs > 100 K cells.
  • Only promoted recipes affect live strategy ranking; shadow and candidate recipes are

inert until their A/B trial completes.

When the loop opens an escalation (unknown symptom, exhausted catalog, unseen crash, or repeated regression), drain it following the agent runbook in references/engineer-loop.md ("Escalation Drain"). That document also covers provenance queries (trace_provenance.py) and the full safety-invariant list.

Platform Support Matrix

| Platform | KLayout DRC | KLayout LVS | Magic DRC | Netgen LVS | RCX | |----------|-------------|-------------|-----------|------------|-----| | nangate45 | Yes | Yes | No | No | Yes | | sky130hd | Yes | Yes | Yes | Yes | Yes | | sky130hs | Yes¹ | Yes | Yes | Yes² | Yes | | asap7 | Yes | No | No | No | Yes | | gf180 | Yes | Yes | No | No | Yes | | ihp-sg13g2 | Yes | Yes | No | No | Yes |

¹ sky130hs has no ORFS-shipped DRC deck; run_drc.sh deliberately reuses the sibling sky130hd.lydrc (pure sky130A tech-layer rules, no hd-specific content) via KLAYOUT_DRC_FILE= on the make command line (failure-patterns.md #32). ² Requires the sky130hs.lyt lefdef repair (tools/patch_sky130hs_lyt.py, applied by eda-install's platform-rules step) — the stock file makes def2stream drop ALL DEF geometry, turning every Netgen LVS into a false top-pin mismatch; run_netgen_lvs.sh guards portless extractions as infra errors (failure-patterns.md #33).

7. Treat Artifacts as Source of Truth

  • Save logs, reports, VCD waveforms, netlists, SPEF, configurations, and summary files.
  • Prefer file outputs over GUI tools. GUI viewers like GTKWave/KLayout are optional helpers.

8. Diagnose Before Editing

  • For failures, read references/failure-patterns.md.
  • Classify the failure: specification gap, RTL bug, testbench bug, synthesis issue, backend/configuration issue, DRC violation, LVS mismatch, or RCX extraction error.
  • Fix the smallest plausible cause first.

9. Summarize Each Stage Clearly

-

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.