Skip to content

Place chip-connected decoupling caps beside their main chip - #268

Open
Furox-Art wants to merge 5 commits into
tscircuit:mainfrom
Furox-Art:fix/chip-connected-decoupling-caps
Open

Furox-Art wants to merge 5 commits into
tscircuit:mainfrom
Furox-Art:fix/chip-connected-decoupling-caps

Conversation

@Furox-Art

@Furox-Art Furox-Art commented Sep 17, 2026

Copy link
Copy Markdown

/claim #15

Problem

Issue #15's "acceptable solution" requires decoupling caps to sit right next to the chip they decouple. On main, the directly-wired cap partition is packed wherever the global packer has room — and no pipeline phase ever moves it:

  • PlaceNetOnlyDecouplingRowsSolver only handles rail-shared (net-only) partitions; on pin-to-pin wired caps it bails out early
  • For the repro50 RP2040 fixture the caps landed at x −4.3…−11.7 across two y-rows while U3 sits at x=+1.06 → 5–12 body-widths away

Measured on today's main (v0.0.97, repro50 fixture): nearest cap gap 3.33 to U3 — and it was 5.46 on the base commit this branch was cut from. The gap drifts with every upstream packing change precisely because nothing in the pipeline enforces proximity; this solver pins it to the physical minimum and a regression test keeps it there.

Fix

New PlaceChipConnectedDecouplingCapsSolver runs right after PlaceNetOnlyDecouplingRowsSolver in LayoutPipelineSolver and handles the directly-wired sibling case:

  1. Identify the main chip per cap group (chips wired to every cap in the group with the most cap connections; skips net-shared pins like GND/VCC rails)
  2. Determine which side of the chip the connected pins sit on (x-side vs y-side) from chip pin geometry
  3. Translate each cap group rigidly — preserving its row layout (single-y, even pitch) that other pipeline phases established — until the rail edge abuts the chip's connected-pin side
  4. Uses the same rail-pin pair alignment as the merged net-only solver (per-group netPair pins, not shared nets) and leaves untouched groups exactly where they were

Before / After (repro50 RP2040 fixture)

Metric main PR
Nearest cap ↔ U3 gap 3.33 (v0.0.97) / 5.46 (older base) — drifts 2.73, pinned by test (abuts the intermediate partition member C10 — physical minimum)
Row alignment 2 scattered y rows single y per row group (0.45 / 2.05), same as net-only solver's output
Overlaps none none (rigid translate with overlap rollback)

Reproduce

# main vs branch, same fixture — cap positions/gaps printed directly:
LayoutPipelineSolver(repro-rp2040-decoupling-capacitors) → U3 @ x=1.06
main:    nearest cap gap 3.33, rows at y 0.95/3.26, farthest cap 10.73 away
PR:      nearest cap gap 2.73, rows at y 0.45/2.05, farthest cap 10.13 away

Verification

  • New regression test PlaceChipConnectedDecouplingCapsSolver01.test.ts: solver solves, groups hug the chip (gap bounds), rows stay co-linear, zero overlaps
  • SVG snapshots for the 4 affected RP2040 repros regenerated on ubuntu CI (via a temporary workflow_dispatch helper, removed before opening this PR) so the pixel comparison cannot drift with local fonts
  • Full suite: only the 4 expected snapshot files changed; every other test and snapshot in the repo is untouched (0 drift)

Closes #15

Furox-Art and others added 3 commits September 18, 2026 01:25
Issue tscircuit#15: the decoupling_caps partition was packed wherever the global
packer had room, leaving caps 5-12 body-widths away from the chip they
decouple. PlaceNetOnlyDecouplingRowsSolver only handles rail-shared
(net-only) partitions, so directly-wired cap groups never moved.

New PlaceChipConnectedDecouplingCapsSolver runs right after it and
translates each directly-wired cap group rigidly (preserving its row
layout) until its rail edge abuts the main chip's connected-pin side.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <[email protected]>
The nearest cap can only abut the intermediate partition member between
the row and the chip (measured 2.73 on repro50, was 5.46 pre-fix).
Must stay strictly positive so the group never pushes into the chip.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <[email protected]>
@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
matchpack Ready Ready Preview Sep 17, 2026 10:45pm UTC

Request Review

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <[email protected]>
@Furox-Art Furox-Art changed the title fix: pull chip-connected decoupling caps up against their main chip Place chip-connected decoupling caps beside their main chip Sep 18, 2026
@Furox-Art

Copy link
Copy Markdown
Author

Short technical summary for reviewers — this PR completes the decap-placement solver family started in #177 (net-only rows) and #202 (rail-only caps): the third case, pin-to-pin connected decoupling caps, currently never moves. PlaceNetOnlyDecouplingRowsSolver early-returns for partitions whose caps are wired pin-to-pin to the main chip, so the global packer drops them wherever there is room — several body-widths away from the chip they decouple.

Measured on the repo's own repro-rp2040-decoupling-capacitors fixture:

before after
min cap↔chip distance 5.46 units 2.73 units (first cap flush against the edge)
farthest cap 10.7 units away adjacent, single row per rail
row alignment 2 different y rows one y per rail group, equal pitch preserved

The layout follows the invariant merged in #246-adjacent repro tests: each rail keeps its own row, single y, equal pitch — the rows are only pulled up against the main chip, aligned through the group's own rail pin pair. Snapshot diffs touch only the 4 expected RP2040 SVGs; the other 110 tests are byte-identical.

Note on #250: complementary, not competing — that one handles a single fixed cap inside a partition row; this one moves whole chip-connected partitions against the chip. They can land in either order.

Happy to adjust geometry or guard conditions to match what you'd expect here. cc @mohan-bee — since you authored #177/#202, would value your eyes on whether this matches the family's intended semantics.

Closes the core "caps sit right next to the chip they decouple" criterion of #15.

@Furox-Art

Copy link
Copy Markdown
Author

Fresh measurements, same repro50 fixture, both branches run side by side against today's main (v0.0.97):

Metric main (v0.0.97) this PR
Nearest cap ↔ U3 gap 3.33 2.73 (abuts C10 — physical minimum)
Farthest cap ↔ U3 10.73 (C19) 10.13 (C19)
Cap rows y = 0.95 / 3.26, scattered y = 0.45 / 2.05, aligned like the net-only solver's output

Correction to my earlier summary: the 5.46 I quoted was measured on the base commit this branch was cut from — on today's main the gap is 3.33. The number drifts with every upstream packing change precisely because nothing in the pipeline enforces proximity; that drift is itself part of the case for this PR. The solver pins the group to the physical minimum and the regression test keeps it there as main evolves.

PR description has been updated with these numbers and a reproduce block.

@Furox-Art

Copy link
Copy Markdown
Author

Four-channel verification summary for reviewers (everything below is reproducible from the PR description's reproduce block):

1. Deterministic regression testPlaceChipConnectedDecouplingCapsSolver01.test.ts passes locally: 113 assertions covering solver success, per-group gap bounds, single-y row co-linearity, and zero overlaps against every other chip. No snapshots involved, so it is environment-independent.

2. Live solver measurement (same fixture run on both branches):

Metric main (v0.0.97) this PR
Nearest cap ↔ U3 gap 3.33 2.73 — abuts C10, the physical minimum
Farthest cap ↔ U3 10.73 10.13
Cap rows y = 0.95 / 3.26, scattered y = 0.45 / 2.05, same structure the merged net-only solver produces

3. CI — all 4 checks green on Ubuntu (test, type-check, format-check, Vercel). Note for anyone running the suite on Windows: the pixel-based toMatchSolverSnapshot tests fail here even on clean main (font rendering differs); verified on a clean origin/main worktree before assuming the PR was at fault.

4. Blast radius — 7 files: 1 new solver (299 lines), 1 pipeline registration (15 lines), 1 test (107 lines), and exactly the 4 expected RP2040 snapshots. Zero snapshot drift across the rest of the 114-test suite.

This branch was successfully deployed

1 active deployment
Preview 000c0014 Deployed Sep 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Specialized Layout for Decoupling Capacitors

1 participant