Plan — GF180MCU PDK enablement (full sim path)
Status: Phases 0–6 shipped (2026-05-12 / 13). Phase 7
(wafer.space test-run-1 design integration) deferred pending design
availability. Subsequent follow-ups also landed (2026-05-14):
IO pad behavioural decomposition (__in_c, __in_s, __bi_24t,
plus filler classification for the wafer.space gf180mcu_ws_*
families) and bidir A/OE observability surfacing as
<port>__out / <port>__oe extra primary outputs — see commits
aa312b8, c23d583, 207cc80. These extended GF180MCU support
from "synthesized-core-only" to "full chip_top including pad ring",
validated end-to-end on a 227k-cell wafer.space chess chip_top
netlist. This document is now a recap of what landed; the
forward-looking deferred items are in § Follow-on cleanup at the
bottom.
Predecessors:
- SKY130 enablement (reference recipe in
docs/adding-a-pdk.md). - Multi-corner Liberty plumbing — WS2.4 + the sky130 multi-corner
integration test (
crates/opensta-to-ir/tests/opensta_integration.rs), shipped 2026-05-12.
ADRs: None new shipped. docs/adding-a-pdk.md is the canonical
integration-points checklist; this plan applied that recipe to
GF180MCU with both 7-track (gf180mcu_fd_sc_mcu7t5v0) and 9-track
(gf180mcu_fd_sc_mcu9t5v0) standard-cell libraries.
Goal (as shipped)
GF180MCU is now at the same support tier as SKY130:
- Timing path —
opensta-to-iraccepts GF180MCU Liberty files and emits IR; the multi-corner integration test atcrates/opensta-to-ir/tests/opensta_integration.rs::gf180mcu_multi_corner_emits_per_corner_valuesasserts per-corner setup/hold values differ correctly across tt/ss/ff PVT corners. - Simulation path —
jacquard simruns gate-level GF180MCU netlists on the GPU. Cell-type detection, pin direction tables, sequential/tie/multi-output classification, behavioural model parsing (with UDP support for sequential elements), and AIG decomposition are all wired throughAIG::from_netlistdb. - Validation — synthetic DFF+inverter fixture at
tests/timing_test/gf180mcu_timing/. Real wafer.space test-run-1 design integration is deferred (Phase 7, gated on design availability).
End state mirrors today's SKY130 support: CellLibrary::GF180MCU
detected, decomposed to AIG, simulated on Metal/CUDA/HIP, with a
golden-IR corpus entry covering the timing-IR side.
Why now
GF180MCU support was a release prerequisite per session 2026-05-12. The wafer.space ecosystem (https://github.com/wafer-space/gf180mcu) is the near-term commercial demand driver; the upstream google/gf180mcu-pdk is the canonical PDK that the wafer.space variant builds on.
Decisions (frozen 2026-05-12 session)
- One enum variant for GF180MCU.
CellLibrary::GF180MCUcovers both 7t5v0 and 9t5v0 prefixes. Matches the SKY130 precedent (CellLibrary::SKY130covers seven prefixes). - Both 7t and 9t fully supported. Unlike SKY130 (only hd is
decomposed), both GF180MCU standard-cell variants are first-class
for cell detection, pin direction, classification, and AIG
decomposition. Cell models for 7t and 9t are byte-identical per
cell type (verified at build time in
build.rs); decomposition reads from the 7t submodule and reuses for 9t. - Two separate submodules for vendoring cell models, mirroring
the per-library SKY130 split:
vendor/gf180mcu_fd_sc_mcu7t5v0/vendor/gf180mcu_fd_sc_mcu9t5v0/
- Install path:
volarepinned hash under[tool.jacquard.pdks.gf180mcu]inpyproject.tomlalongside the existing sky130 entry. Variant:gf180mcuC. - Reset polarity: GF180MCU uses active-low resets/sets
(pin names
RN,SETN) — same AIG formula shape as SKY130'sRESET_B/SET_B. The "n" prefix in cell names likedffnq/dffnrnq/icgtnindicates a negative-edge clock (pinCLKN), not reset polarity (resolving Open Q3 from the original plan).
Shipped phases
Phase 0 — Foundations (commit 6ae3e54)
pyproject.toml:[tool.jacquard.pdks.gf180mcu]withvolare_hash = "559a117b163cef2f920f33f30f6f690aa0b47e4c", variantgf180mcuC, separatedefault_lib_subdir_7t/default_lib_subdir_9tpaths.- Vendored submodules at
vendor/gf180mcu_fd_sc_mcu7t5v0/andvendor/gf180mcu_fd_sc_mcu9t5v0/. - Skeleton
src/gf180mcu.rs+src/gf180mcu_pdk.rsdeclared insrc/lib.rs.
Phase 1 — Library detection + cell-type extraction (commit 858dd70)
is_gf180mcu_cell(name) -> boolmatching both 7t5v0 and 9t5v0 prefixes.extract_cell_type(name)strips prefix + drive suffix.CellLibrary::GF180MCUenum value added;detect_library()/detect_library_from_file()extended;Mixedenforcement upgraded to three known libraries.
Phase 2 — Pin direction provider (commit e97e2d2)
GF180MCULeafPinsimplementingLeafPinProvider.- Generation strategy: build-time via
build.rs::generate_gf180mcu_pin_table, which scansvendor/gf180mcu_fd_sc_mcu{7,9}t5v0/cells/, parses.functional.v, cross-asserts 7t/9t pin layouts match, emits$OUT_DIR/gf180mcu_pins.rs. New precedent vs SKY130's hand-rolled match arms (see § Follow-on cleanup item 1). - Round-trip test instantiating every cell.
Phase 3 — Cell classification (commit 6969b90)
- Sequential / tie / filler / delay-cell whitelists in
src/gf180mcu_pdk.rsderived from behavioural models. - Unit tests asserting classification across the union of 7t5v0 and 9t5v0 cell catalogues.
Phase 4 — Combinational AIG decomposition
Sequenced as four commits:
92bb665— Phase 4 recon: confirmed SKY130 behavioural parser is PDK-neutral; identified shared infrastructure thatgf180mcu_pdkcould reuse.02da077— Phase 4 prep: introduced the PDK-neutralsrc/pdk_decomp.rsre-export module; exposedWireVal,GATE_MARKER,build_chain_gate,build_xor_chain,finalize_decomp_resultaspub(crate).32fb3b9— Phase 4 (combinational):decompose_combinationalfor GF180MCU + boolean equivalence test suite vs the vendored PDK models.d898343— Phase 4 (aig.rs integration): wired combinational decomposition throughAIG::from_netlistdb, end-to-end sim path for combinational GF180MCU netlists.
Phase 4b — Sequential cells (UDPs)
a7c0618— Phase 4b prep: UDP loader forgf180mcu_pdk(parsesUDP_GF018hv5v_mcu_sc7_TT_1P8V_25C_verilog_nonpg_*_FF_UDPand friends from the vendored PDK).459317e— Phase 4b: AIG hooks for sequential cells (DFFs, latches, scan-DFFs, clock-gating cellsicgtp/icgtn).gf180mcu_preprocesspre-creates DFF Q pins;gf180mcu_postprocessapplies async set/reset using the active-low RN/SETN convention via the same AIG formula as SKY130. Negative-edge clock cells useCLKNinstead ofCLK(handled intrace_clock_pin).3006f59— Phase 4b boolean-equivalence tests covering DFF, latch, scan-DFF, and clock-gating cells via multi-step truth-table evaluation.
Phase 5 — CLI / pipeline wiring audit (commit 57244d5)
Audit-only — no per-PDK branch was missing GF180MCU handling. The
auto-detection in AIG::from_netlistdb already covers every CLI
surface (sim / cosim / dump-paths all route through
setup::load_design). Cleanup: stale Phase 4b panic comments in
src/sim/setup.rs and src/aig.rs; field doc comments on CLI
arguments refreshed to mention GF180MCU alongside AIGPDK / SKY130.
Phase 6 — Validation fixture + multi-corner test
- Fixture (commit
4a7ee0e):tests/timing_test/gf180mcu_timing/mirroringsky130_timing/1:1. Syntheticinv_chain.v(DFF + 16-inverter chain + DFF) withgf180mcu_fd_sc_mcu7t5v0__{dffq,inv}_1cells, Liberty-only SDF generator, CVC testbench, sample stimulus, Makefile, README. - Integration test:
gf180mcu_multi_corner_emits_per_corner_valuesincrates/opensta-to-ir/tests/opensta_integration.rs. Loads three real PVT corners (typ=tt_025C_5v00, slow=ss_125C_4v50, fast=ff_n40C_5v50) at the 5.0 V operating point and asserts per-corner setup TimingValues differ correctly across PVT. Skips gracefully when the volare-installed PDK isn't present (gated onfind_gf180mcu_lib_dir()returningSome; matches the sky130 test's skip pattern).$GF180MCU_LIBERTY_DIRoverrides the volare default path.
Phase 7 — wafer.space test-run-1 design (deferred)
Gated on design availability. Scope:
- Vendor or pull a wafer.space test-run-1 gate-level netlist into
the
tests/timing_test/ordesigns/tree. - End-to-end pipeline: synth + PnR (or consume post-PnR output), opensta-to-ir, jacquard sim with Metal backend, golden-output VCD comparison.
- Promote to a corpus entry once stable.
Test inventory
Counts after Phase 6:
cargo test --lib: 212 passing (up from 166 at plan start).cargo test --lib gf180mcu: 45 passing (combinational + sequential equivalence + classification + detection + AIG-build).cargo test -p opensta-to-ir multi_corner: 2 passing (sky130 + gf180mcu), each gated on its respective volare PDK install.
Follow-on cleanup
These are nice-to-have refactors flagged during the GF180MCU work but deliberately out of scope for the enablement effort itself.
Update 2026-05-19: Items 1, 2, and 4 are now subsumed by
ADR 0010 — Declarative cell metadata
and its companion plan declarative-cell-metadata.md. The manifest
pathway converts these from "Rust refactor" projects into "move data
out of code as part of the migration to manifest-as-source-of-truth"
— happens once, gets all three at once.
-
Subsumed by ADR 0010 § "Deferred to a future ADR —build.rspin-table generator for SKY130 too.build.rspin-table scanner removal." Removed LAST in the manifest migration, after manifests cover the built-in PDKs. -
Physical relocation of shared PDK decomp infrastructureout ofsky130_pdk.rsintopdk_decomp.rs. Still relevant for the built-in (Rust-decomp) pathway, since ADR 0010 keeps that path load-bearing for cells with real AIG decomposition rules. Move when a third PDK exercises the surface. -
CellLibraryenum location. Currently lives insrc/sky130.rseven though it represents all PDKs. Moving to a neutral home (src/pdk.rsorsrc/lib.rs) is a trivial mechanical refactor. Independent of ADR 0010. -
IO and PR libraries.Now solved by the ADR 0010 manifest pathway.gf180mcu_fd_ioandgf180mcu_fd_prcells can be declared viakind = "io_pad_*"/kind = "filler"/kind = "tap"etc. in user-supplied manifests — no Jacquard PR needed. -
CI install strategy for GF180MCU Liberty. Both the sky130 and gf180mcu multi-corner tests currently skip when the PDK isn't installed locally. CI integration (volare-on-CI or a vendored minimal Liberty subset) is the same blocker that gates the
inv_chain_pnrsky130 corpus entry — out of scope for the GF180 enablement effort itself. Unrelated to ADR 0010.
Pitfalls (PDK-specific, for future readers)
- Reset polarity — GF180MCU is active-low (
RN/SETN); same AIG formula as SKY130'sRESET_B/SET_B. - Negative-edge clocks — cells like
dffnq/dffnrnq/icgtnuse pin nameCLKNinstead ofCLK. The "n" prefix is a clock marker, not a reset-polarity marker. - Power pins — GF180MCU operates at 5V nominal (vs SKY130's
1.8V). Both follow VDD/VSS naming. Corner names follow
tt_025C_5v00shape and parse cleanly through the genericTimingLibraryloader. - Cell pin names differ from SKY130 — inverter is
I/ZN(notA/Y); DFF isCLK/D/Q/notifier. Thenotifierport wires the UDP delay-model wrapper but is unused for logic simulation. - Cell-name collisions between 7t5v0 and 9t5v0 — both have
nand2_1etc. Detection keys on the full prefix, not the base type. Auto-handled byis_gf180mcu_cell. - Drive-strength suffixes — GF180MCU uses integer multipliers
(
inv_1,inv_2,inv_4, …) matching the SKY130 convention.
Links
docs/adding-a-pdk.md— canonical PDK integration recipe.src/sky130.rs,src/sky130_pdk.rs— SKY130 reference implementation.src/gf180mcu.rs,src/gf180mcu_pdk.rs— GF180MCU implementation.crates/opensta-to-ir/tests/opensta_integration.rs::{sky130,gf180mcu}_multi_corner_emits_per_corner_values— timing-side validation.tests/timing_test/{sky130,gf180mcu}_timing/— synthetic fixtures.pyproject.toml::[tool.jacquard.pdks.{sky130,gf180mcu}]— install pins.- Upstream PDK: https://github.com/google/gf180mcu-pdk
- wafer.space variant: https://github.com/wafer-space/gf180mcu