README.md
# AM3352 reusable fanout for tscircuit
AM3352 ZCZ324 saved BGA escapes with **313 paths, 201 external signal exits and 82 fixed bottom-side capacitors**. Choose a directional DDR profile for a compatible ten-layer host, or the original six-layer `native` profile.
**DDR profiles address local routing geometry and reference-layer assignment. They are not a completed or electrically signed-off DDR3 board.** Complete CPU-to-memory timing, impedance, return-current transitions, termination and power delivery remain host-board checks. `bun run check:ddr` deliberately does not certify a complete interface from fanout geometry alone.

## Select a profile
Directions below use an **unrotated package**, A1 upper left, +X right and +Y up. Changing a profile changes saved routing; it does not rotate the chip.
| `layoutProfile` | DDR exit side | Outward direction | DDR exit layers | Boundary | Physical layers |
|---|---|---|---|---|---|
| `ddr_left` | Left | โX | top, inner2, inner4, inner6 | 17.78 ร 17.74 mm | 10 |
| `ddr_top` | Top | +Y | top, inner2, inner4, inner6 | 23.48 ร 17.94 mm | 10 |
| `ddr_bottom` | Bottom | โY | top, inner2, inner4, inner6 | 23.48 ร 21.33 mm | 10 |
| `native` | Mostly left; BA0, BA2, A6, A8 top | Mixed | top, inner2, inner3, inner4 | 17 ร 17 mm | 6 |
All **52 DDR-related terminals**, including RESETn, VREF and VTP, reach the selected DDR side. The timing audit treats the **49 CK/CA/DQ/DQS signals** separately from those three auxiliary signals. Other interfaces retain nearby-edge escapes; eight neighboring west-side auxiliary signals also turn with the DDR bus in the top/bottom profiles to keep that routing corridor open.
Padding is measured independently from each edge of the 15 ร 15 mm package:
| Profile | Left | Right | Top | Bottom | Area reduction from previous profile |
|---|---:|---:|---:|---:|---:|
| `ddr_left` | 1.81 mm | 0.97 mm | 1.86 mm | 0.88 mm | 49.5% |
| `ddr_top` | 7.51 mm | 0.97 mm | 2.06 mm | 0.88 mm | 73.7% |
| `ddr_bottom` | 7.51 mm | 0.97 mm | 1.86 mm | 4.47 mm | 68.7% |
| `native` | 1 mm | 1 mm | 1 mm | 1 mm | Unchanged |
DDR profiles use a tight rectangular enclosure on a **0.01 mm outward grid**, with 0.1016 mm reserve around internal copper. The left profile is re-solved in a smaller region; top/bottom channels are repacked and pair tuning rebuilt near their turns. Redundant final tails are shortened. Top/bottom padding includes the space needed for separated 45ยฐ bends and pair tuning; these bounds supersede the smaller sharp-corner versions. These are the tight bounds for the checked routing and fixed component placement, not a proof of the globally smallest possible layout. No track, clearance or via rules were relaxed.
The boundary is a host-routing handoff: terminal centers lie on it, and terminal end caps extend by half the trace width. It is not a fabrication board edge. `getAM3352Bounds(profile)` returns CPU-centered `minX/maxX/minY/maxY`; `LAYOUT_PROFILES[profile]` exposes `fanoutWidthMm`, `fanoutHeightMm` and `padding.{left,right,top,bottom}`. Legacy `fanoutSizeMm` and `paddingMm` are maximum values and must not be interpreted as symmetric dimensions. `pcbX/pcbY` still place the CPU center, including after rotation.
Top/bottom profiles consume more space and route length. Use the actual exported lengths when budgeting the remaining host connection; do not assume these profiles have equal delays.
**Every signal's exact ball, side, outward direction, source escape direction, final track tangent, layer, XY position, planar length and via spans are documented in [the generated exit tables](docs/signal-exits.md).** Machine-readable copies are `src/generated/<profile>.exits.json`.
## Install and use
```sh
tsci add 0hmX/am3352
```
```tsx
import {
AM3352Module,
getAM3352PowerPlanes,
getAM3352Bounds,
getAM3352Exits,
transformAM3352Exit,
} from '@tsci/0hmX.am3352'
// Inside a ten-layer board using the required reference/power copper:
<AM3352Module
name="SOC"
layoutProfile="ddr_left"
pcbX={0}
pcbY={0}
connections={{ UART0_TXD: '.DEBUG > .pin1' }}
/>
const planes = getAM3352PowerPlanes('ddr_left')
const exits = getAM3352Exits('ddr_left')
const placedExits = exits.map(exit => transformAM3352Exit(exit, {
pcbX: 10, pcbY: 0, pcbRotation: 90,
}))
```
`connections` accepts signal names or physical ball names and connects to host selectors. Direct selectors such as `.SOC .U1 > .DDR_D0` are also supported. Supply connections use the declared host copper regions, not the signal connection map. The module declares its own signal nets so cached copper remains instantiated when only a subset of signals is connected externally. Internal U1/C1โC82 names require one CPU instance per routing scope.
`pcbRotation` rotates the complete instance and saved routes. The exit helper rotates coordinates and vectors; its `side` field deliberately remains the **local** side. Copper layer names never rotate. `layoutProfile` still defaults to `native` for compatibility: specify a DDR profile explicitly.
The runtime remains pinned to tscircuit 0.0.2503 and props 0.0.650. Native `<fanout pcbTracePaths={โฆ}>` loads portable local-coordinate caches without running a solver on import. Do not move internal components or rewrite saved layer names without regenerating and validating the profile.
## Ten-layer DDR geometry
All four CPU profiles enforce **horizontal, vertical or 45ยฐ diagonal saved segments, with at most a 45ยฐ direction change at each same-layer bend**. A 45ยฐ direction change forms a 135ยฐ inside corner; two diagonal segments meeting in a sharp 90ยฐ corner are rejected. The bend limit covers saved signal and supply paths plus fixed support copper. Fixed pad-to-via support routes also use only these headings; their 126 formerly off-angle stubs now use 45ยฐ elbows with unchanged pad and via positions. Right-angle changes use two separated 45ยฐ bends, and differential-pair tuning uses flat-topped excursions. The same checks run after generation to prevent sharp corners from returning. Host routing must follow this rule separately.
DDR traces use **0.1016 mm width and clearance**, and DDR escape vias use **0.4572 mm pads / 0.254 mm drills**. All vias are plated through the complete ten-layer stack. Fixed capacitor and non-DDR copper retains its checked 0.4/0.2 mm vias and 0.0762 mm clearance; these are not the DDR track rules.
| Physical layer | Name | Role |
|---|---|---|
| 1 | top | Signal escapes and 3.3 V I/O copper |
| 2 | inner1 | GND reference |
| 3 | inner2 | Signal escapes |
| 4 | inner3 | 1.5 V DDR reference/power |
| 5 | inner4 | Signal escapes |
| 6 | inner5 | Additional GND reference |
| 7 | inner6 | Signal escapes |
| 8 | inner7 | 1.26 V MPU power |
| 9 | inner8 | 1.1 V core power |
| 10 | bottom | 1.8 V copper, local capacitor copper and other escapes |
Signal layers have adjacent GND or DDR reference layers. DDR routes no longer run laterally through their DDR power plane. The host must implement the actual reference copper throughout its DDR routing region. Layer names alone do not establish controlled impedance or reference continuity.
`getAM3352PowerPlanes(profile)` provides all required pour assignments, including both ground references. The legacy `AM3352_POWER_PLANES` export describes **native only**. I/O supply barrels contact the top pour while retaining a logical internal-layer transition; physical barrels always span the board.
The 82 capacitors remain within the original 17 ร 17 mm component area: 55 under the BGA body and 27 in its 1 mm perimeter. There are 117 processor supply/ground connections: 112 saved drops plus five fixed links. Four CAP_* outputs connect locally to capacitors; A3 RESERVED and M5 VPP remain intentionally unconnected. Processor DDR bypassing includes 20 ร 100 nF and 2 ร 10 ยตF; memory-device bypassing is additional.
## Supplied Micron memory
The intended part is **MT41K512M8DA-107 IT:P**, a ร8 DDR3L device with 1.5 V compatibility. Use **two devices for the AM3352's 16-bit interface**, one per byte lane. See [the integration and pin-mapping guide](docs/ddr-integration.md).
The supplied memory's original four-layer caches place signals on inner1, which conflicts with this CPU's GND layer. `DdrMemoryAdapter` accepts the caller's original memory paths, pin map and footprint, maps RAM inner1 โ inner2 and inner2 โ inner4, and enlarges its vias to 0.4572/0.254 mm. It supports all four supplied memory profiles: `outward_north`, `outward_south`, `inward_north` and `inward_south`. Their names describe local dogbone direction, independently of the CPU profiles above.
`getDdrMemoryConnections('SOC', 0)` and `(โฆ, 1)` expose the byte-specific DQ/DM/DQS and shared CK/address/control mapping. They do not provide VREF, ZQ, decoupling, termination or supply connections. The adapter intentionally accepts external assets rather than embedding machine-specific imports into the library.
## Validation and reproduction
```sh
bun install
bun run solve # original native profile
bun run solve:ddr # DDR left, then top/bottom directional caches
bun run build:ddr # render all DDR profiles
bun run document:exits
bun run check # native checks plus DDR profile checks
bun run check:ddr -- --profile=ddr_left --local-only
```
`check:ddr --local-only` checks timed-net coverage, minimum track/via dimensions, reference-layer adjacency and local differential skew. `check:ddr` without this flag is a strict **complete-interface gate**, which reports the missing host-level verification and exits nonzero. Reports separate local geometry from unverified full timing and electrical properties.
DDR generation preserves validated non-DDR copper and solves 51 DDR-related routes around it. DDR_A8 uses an explicit widened northward escape before turning west; it participates in obstacle handling and the final full-copper check. Directional variants add boundary routing with the chip held fixed. Generated geometry is rechecked independently after modifications. Full-copper DRC uses the legacy minimum; the DDR subset additionally uses the stricter DDR clearance against all other copper.
Rendered checks verify saved/fixed path preservation, actual full-depth via sizes, supply-pour contacts, rotation/translation and shorts. Netlist and assembly-placement checks cover the chip and capacitors. The preview's coincident edge contacts show the exit contract; they are **not evidence of complete memory routing**.
For the supplied memory project, run the explicit external-input checks:
```sh
bun scripts/check-ddr-integration.ts /path/to/mt41k512m8da-107-it-p-fanout
bun scripts/check-ddr-integration-render.tsx /path/to/mt41k512m8da-107-it-p-fanout
bun scripts/check-ddr-host.tsx /path/to/mt41k512m8da-107-it-p-fanout --direct
```
The host fixture checks one real CPU DDR_D0 โ RAM DQ0 connection, with noncoincident exits and both caches preserved. `--direct` uses an explicit 45ยฐ host route, independently checked for continuity and clearance. Omitting it runs a bounded capacity-router diagnostic. This is not proof that the stock router can automatically complete the DDR bus.
## Scope before DDR board signoff
Complete timing must include CPU escape + host copper + RAM escape, with layer/via delay. Pair skew alone does not prove byte-lane matching, impedance or coupling. Select the operating clock, fabrication dielectric stackup, two-device CK/CA topology, reference-transition treatment, DDR keepout, termination, VREF/VTT strategy, ZQ, memory power and controller settings before board signoff. The software audit explicitly retains these as unverified.
The original six-layer `native` profile remains a local fanout demonstration; it fails the DDR width/via/reference audit and must not be presented as a DDR-compliant alternative.
References: [TI AM335x datasheet SPRS717L](https://www.ti.com/lit/ds/sprs717l/sprs717l.pdf), [pinned fanout solver](https://github.com/tscircuit/fanout-solver/tree/3af2f35ee2bbd715059b725900c0f7f71e64bdd8), [processor support-circuit audit](docs/support-circuit-audit.md).
## Complete two-chip system work
A full **50-net / 78-branch** CPU-to-two-RAM signal fixture is under development. Its capture preserves all 457 saved CPU/RAM paths; it is still an unrouted, unpowered integration draft. See [reproduction commands and current evidence](docs/ddr-system-progress.md) and [full-board acceptance requirements](docs/real-ddr-acceptance.md). `auditDdrBoard` rejects missing full-board measurements and electrical evidence. It must not be replaced with the local breakout audit when deciding whether a DDR interface works.