0hmX/am3352

This code suite comprises TypeScript scripts that analyze, verify, and assemble complex DDR memory interface hardware, focusing on physical routing, via and pad placement, electrical clearance, and physical constraints, often involving precise geometric calculations and consistent provenance tracking.

Version
1.0.5
License
unset
Stars
0

docs/ddr-integration.md

# AM3352 to MT41K512M8DA-107 IT:P integration

Audit date: 2026-09-10. Memory input: `/Users/ankan/Documents/Codex/2026-09-10/what-x20/outputs/mt41k512m8da-107-it-p-fanout`. The memory project was inspected, not modified. Its four profiles are BGA escapes, not complete powered RAM modules. An exit contract does not certify a complete DDR interface.

## Exact memory and wiring

MT41K512M8DA-107 IT:P is **4 Gbit, 512M ×8 DDR3L**, 78-ball DA, industrial temperature, revision P. Two devices yield **1 GiB on a 16-bit bus**. A0–A15 are all needed (16 row bits); BA0–BA2 select eight banks. Column addressing uses A0–A9. The part supports 1.5 V compatibility; the present CPU module's `VCC_DDR_1V5` is therefore a deliberate DDR3 operating choice, not a 1.35 V DDR3L rail. The -107 speed grade does not make this controller a DDR3-1866 interface. [Micron manufacturer datasheet Rev. R, pages 1–2, 17–18, 25](https://atta.szlcsc.com/upload/public/pdf/source/20241017/DD693FFA66FA4C721D9CFF3534518DFE.pdf).

This table uses RAM0 for byte 0 and RAM1 for byte 1 with identity bit mapping. TI also permits explicit DQ permutations within each byte on AM335x DDR3/DDR3L; keep DM and DQS with their byte and validate any permuted mapping in the actual board netlist and copper. The table remains the default mapping, not a record of an experimental permutation. [TI guidance](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1223941/am3359-ddr3-swapping-data-lanes). Shared table entries mean one CPU net reaches both chips. `RESET_N` remains reset, outside the timed CA net class. The table is generated from the supplied memory pin map and this repository's CPU ball map. Physical ball `A1` must never be confused with address signal `A1` (RAM ball L7).

| RAM terminal | RAM ball | RAM0 CPU signal (ball) | RAM1 CPU signal (ball) | Original RAM exit direction | Original RAM exit layer |
|---|---|---|---|---|---|
| A0 | K3 | DDR_A0 (F3) | DDR_A0 (F3) | left (−X) | inner1 |
| A1 | L7 | DDR_A1 (H1) | DDR_A1 (H1) | right (+X) | inner1 |
| A10 | H7 | DDR_A10 (F4) | DDR_A10 (F4) | right (+X) | inner1 |
| A11 | M7 | DDR_A11 (F2) | DDR_A11 (F2) | right (+X) | inner1 |
| A12 | K7 | DDR_A12 (E3) | DDR_A12 (E3) | right (+X) | inner1 |
| A13 | N3 | DDR_A13 (H3) | DDR_A13 (H3) | left (−X) | inner1 |
| A14 | N7 | DDR_A14 (H4) | DDR_A14 (H4) | right (+X) | inner1 |
| A15 | J7 | DDR_A15 (D3) | DDR_A15 (D3) | right (+X) | inner1 |
| A2 | L3 | DDR_A2 (E4) | DDR_A2 (E4) | left (−X) | inner1 |
| A3 | K2 | DDR_A3 (C3) | DDR_A3 (C3) | left (−X) | inner2 |
| A4 | L8 | DDR_A4 (C2) | DDR_A4 (C2) | right (+X) | inner2 |
| A5 | L2 | DDR_A5 (B1) | DDR_A5 (B1) | left (−X) | inner2 |
| A6 | M8 | DDR_A6 (D5) | DDR_A6 (D5) | right (+X) | inner2 |
| A7 | M2 | DDR_A7 (E2) | DDR_A7 (E2) | left (−X) | inner2 |
| A8 | N8 | DDR_A8 (D4) | DDR_A8 (D4) | right (+X) | inner2 |
| A9 | M3 | DDR_A9 (C1) | DDR_A9 (C1) | left (−X) | inner1 |
| BA0 | J2 | DDR_BA0 (C4) | DDR_BA0 (C4) | left (−X) | inner2 |
| BA1 | K8 | DDR_BA1 (E1) | DDR_BA1 (E1) | right (+X) | inner2 |
| BA2 | J3 | DDR_BA2 (B3) | DDR_BA2 (B3) | left (−X) | inner1 |
| CAS_N | G3 | DDR_CASn (F1) | DDR_CASn (F1) | left (−X) | inner1 |
| CKE | G9 | DDR_CKE (G3) | DDR_CKE (G3) | right (+X) | top |
| CK_N | G7 | DDR_CKn (D1) | DDR_CKn (D1) | right (+X) | inner1 |
| CK_P | F7 | DDR_CK (D2) | DDR_CK (D2) | right (+X) | inner1 |
| CS_N | H2 | DDR_CSn0 (H2) | DDR_CSn0 (H2) | left (−X) | inner2 |
| DM | B7 | DDR_DQM0 (M2) | DDR_DQM1 (J2) | right (+X) | inner1 |
| DQ0 | B3 | DDR_D0 (M3) | DDR_D8 (J1) | left (−X) | inner1 |
| DQ1 | C7 | DDR_D1 (M4) | DDR_D9 (K1) | right (+X) | inner1 |
| DQ2 | C2 | DDR_D2 (N1) | DDR_D10 (K2) | left (−X) | inner2 |
| DQ3 | C8 | DDR_D3 (N2) | DDR_D11 (K3) | right (+X) | inner2 |
| DQ4 | E3 | DDR_D4 (N3) | DDR_D12 (K4) | left (−X) | inner1 |
| DQ5 | E8 | DDR_D5 (N4) | DDR_D13 (L3) | right (+X) | inner2 |
| DQ6 | D2 | DDR_D6 (P3) | DDR_D14 (L4) | left (−X) | inner2 |
| DQ7 | E7 | DDR_D7 (P4) | DDR_D15 (M1) | right (+X) | inner1 |
| DQS_N | D3 | DDR_DQSn0 (P2) | DDR_DQSn1 (L2) | left (−X) | inner1 |
| DQS_P | C3 | DDR_DQS0 (P1) | DDR_DQS1 (L1) | left (−X) | inner1 |
| ODT | G1 | DDR_ODT (G1) | DDR_ODT (G1) | left (−X) | top |
| RAS_N | F3 | DDR_RASn (G4) | DDR_RASn (G4) | left (−X) | inner1 |
| RESET_N | N2 | DDR_RESETn (G2) | DDR_RESETn (G2) | left (−X) | inner2 |
| WE_N | H3 | DDR_WEn (B2) | DDR_WEn (B2) | left (−X) | inner1 |

RAM exits are local to each unrotated package: A1 upper left, +Y north; boundaries X=±5 mm, Y=±6.25 mm. Left exits continue toward −X; right exits toward +X. Profile suffix north/south describes the **dogbone via offset**, not which package side has the external terminal. Inward/outward describes the via X offset. All four original profiles retain the side/layer assignments above. Rotation changes direction and position together; it does not remap copper layer names. Consult the CPU exit manifest for its separate local coordinates.

Connect every RAM `VDD_*`/`VDDQ_*` terminal to the selected DDR rail and every `VSS_*`/`VSSQ_*` terminal to ground. Provide VREFCA/VREFDQ filtering, individual ZQ calibration resistors, and local/bulk bypassing in the host design. The memory profile intentionally omits NC A3/F1/H1/F9/H9 and disabled TDQS# A7. Keep TDQS disabled so B7 remains DM. A raw copy of the memory module has no planes or bypass capacitors.

## Authoritative acceptance gates

TI's [SPRS717L DDR3 rules](https://www.ti.com/lit/ds/sprs717l/sprs717l.pdf#page=170) apply to the complete interconnect:

- §7.7.2.3.3.1: 16-bit interface, one x16 or two x8; DQ/DQS point-to-point. Shared CK/CA support two loads.
- Table 7-62: adjacent reference planes, uninterrupted ground and VDDS_DDR coverage; 4 mil minimum width/feature; 18–20 mil escape pads, 10 mil holes; Zo 50–75 Ω with ±5 Ω tolerance.
- §7.7.2.3.3.5: DDR region excludes unrelated signals unless separated by ground.
- §7.7.2.3.4.1: use the two-device CK/CA topology and termination. Same-side placement is supported; mirrored placement is optional.
- Table 7-68: preserve its A1/A2/A3/stub-specific lengths, skew, spacing and termination rules; source series termination is prohibited.
- Table 7-69: DQ/DM within each byte and relative to its strobe ≤25 mil (0.635 mm); DQS pair ≤5 mil (0.127 mm). Match bytes independently; use data ODT. Include both escapes and host traces.
- §§7.7.2.3.3.6–7: complete bulk/high-speed bypass requirements.

## Shared stackup blocker and resolution path

The original CPU `native` profile has six physical layers. Its `inner1` is ground; DDR signal escapes use top, inner2, inner3 and inner4. Its power pours share routing layers. The supplied RAM profile has four physical layers and places CK/DQS and several data/address signals on **inner1**. Importing these two profiles unchanged onto one board destroys the meaning of the CPU ground plane. Equal layer names are physical identities, not separate per-module stacks.

The implemented CPU profiles `ddr_left`, `ddr_top` and `ddr_bottom` separate DDR routing from the reference layers. Each uses an asymmetric rectangular boundary: the final left profile is 17.78 × 17.74 mm, with bounds X=−9.31…+8.47 and Y=−8.38…+9.36 mm. See [the exit contract](signal-exits.md) for all current profile bounds and side-specific padding. Their generated geometry, saved-path reuse, reference-pour continuity and shorts checks pass. The CPU caches enforce horizontal/vertical/45° segments. Saved and fixed support routes enforce at most 45° of same-layer direction change per bend; full 90° changes use two separated bends. Fixed capacitor-to-via routes also enforce these headings, using 45° elbows without moving pads or vias. This geometric constraint does not certify the caller-supplied RAM caches or the complete host route. These are geometric checks, not complete DDR electrical signoff. The ten-layer role assignment is:

| Physical layer | Role | Original CPU layer | Original RAM layer |
|---|---|---|---|
| L1 top | Signal | top | top |
| L2 inner1 | Ground | inner1 reference | — |
| L3 inner2 | Signal | inner2 signal | inner1 signal |
| L4 inner3 | DDR power reference, continuous throughout DDR area | relocate DDR supply drops | — |
| L5 inner4 | Signal | inner3 signal | inner2 signal |
| L6 inner5 | Ground | added | — |
| L7 inner6 | Signal | inner4 signal | — |
| L8 inner7 | MPU power | relocate MPU supply drops | — |
| L9 inner8 | Core power | relocate core supply drops | — |
| L10 bottom | Signal/support components | bottom | bottom via termination |

This is the implemented **layer-role assignment**, not a validated electrical stackup. Dielectric thicknesses, copper thicknesses, widths/gaps, stitching, power drops and all through-via spans require coordinated design. Each old signal layer remains separate, preserving planar ordering; the inserted planes address return-path adjacency. CPU supply drops must be reassigned to actual supply copper; merely renaming a saved signal layer does not relocate a supply correctly. The ten-layer board must physically contain the reference copper, not just metadata naming those planes. Parent pours cannot turn a split/obstructed region into an uninterrupted reference by declaration.

A six-layer alternative (top/GND/signal/DDR-power/GND/bottom) offers only three signal layers and requires **rerouting both escapes**, especially the CPU routes currently spread over four DDR signal layers. It is not achieved by reducing `layers` or aliasing two saved signal layers together. RAM inner1 can only be remapped to a signal layer. Enlarged vias also need fresh clearance checking on every layer.

## What remains outside a saved-exit guarantee

The original CPU uses 0.08128 mm tracks and 0.4/0.2 mm vias; the supplied RAM uses 0.12 mm tracks and 0.45/0.2 mm vias. These dimensions are not automatically acceptable under the TI gate above. The regenerated DDR profiles widen DDR tracks and enlarge DDR vias, with fresh geometric checks; `native` retains its original dimensions. The adapter below enlarges the RAM drill/pad while preserving checked clearance. Its placeholder impedance still needs resolution before board signoff.

The RAM source contains tuned **planar** lengths and states its 1.6 mm, Er 4.2 stack is provisional. Neither cache contains extracted via delay or confirmed impedance. Moving traces between layer depths changes delay even when XY geometry is identical. Host tuning must sum CPU escape + host route + RAM escape and account for layer/via delay; it must not match only the free space between module boundaries.

The supplied RAM's existing host test covers selected top/inner1 continuations to headers, not a complete CPU-to-two-RAM route. Its original API does not expose a layer-remap or bottom-side placement option; the adapter below supplies the former. For a real two-device host fixture, use the compatible layer adapter with regenerated CPU profiles, then place the chips and termination, route all mapped nets, inspect all-layer copper for opens/shorts and return paths, and evaluate the full timing/topology gates. Do not label that integration tested based on matching coincident boundary pads or on `routingDisabled` renders.


## Portable memory adapter and checks

`src/ddr-memory.tsx` exports `adaptDdrMemoryPaths`, `DdrMemoryAdapter` and `getDdrMemoryConnections`. The caller supplies the original paths, `PIN_MAP` and footprint from their memory package. There are no absolute local imports, vendor copies or runtime solver calls. `getDdrMemoryConnections("CPU", 0)` provides the 39 byte-0/shared signal connections; byte 1 maps the second device. These mappings omit power/reference/calibration connections, which must be provided explicitly.

```tsx
<DdrMemoryAdapter
  name="RAM0"
  paths={getRamFanoutTracePaths("outward_north")}
  pins={PIN_MAP}
  footprint={<MicronJlcFootprint />}
  connections={getDdrMemoryConnections("CPU", 0)}
  pcbX={-20}
/>
```

The example assumes those symbols are imported by the host; the original memory package does not export its footprint from its root entrypoint. Import its footprint source or supply a matching footprint separately. Place on a ten-layer board with the layer roles above. This is a wiring example, not a validated CPU/RAM placement or board.

The adapter maps RAM inner1→inner2 and inner2→inner4, preserving top/bottom. It raises every via to **0.4572 mm copper / 0.254 mm drill**. All four supplied caches pass an all-layer saved-copper audit against their 78 original pads: **72 paths, 50 through-vias, minimum 0.111246 mm clearance**, exceeding the 0.1016 mm geometric threshold. Actual rendering of all four adapted profiles emits 78 pads, 72 paths/exits and 50 ten-layer vias with no Circuit JSON errors. CLI `check shorts` also reports no shorts for all four rendered adapter profiles. These are module-local geometry checks, not complete-board impedance or timing acceptance.

```sh
bun test tests/ddr-integration.test.tsx
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
```

The copper audit report and four rendered Circuit JSON files are written to `dist/ddr-integration/`. All ten physical via-barrel layers participate in the saved geometry clearance check. The focused render test also checks actual breakout-layer and via-span emission with routing enabled. It does not use `routingDisabled` as proof of saved copper.


## Real host continuation and remaining autorouter limitation

The integration fixture now places an actual `ddr_left` CPU and adapted `outward_north` RAM with separate, noncoincident exits. It connects **CPU M3 / DDR_D0 to RAM B3 / DQ0** through **8.328427 mm of new inner2 copper**. The explicit host route uses a 45-degree diagonal and straight segment. An independent geometry check measures **0.615407 mm minimum clearance** from that new copper to foreign traces/via barrels, above 0.1016 mm.

The assertions follow the physical pad→CPU saved path→host copper→RAM saved path→pad chain, and compare all **313 CPU + 72 RAM cached paths** point by point, including layers and widths. The result retains **559 traces** (385 saved, 173 fixed CPU support traces, one host trace), with zero emitted Circuit JSON errors; CLI `check shorts` also passes on the rendered host board. This demonstrates that saved exits can connect through real board space without changing their copper. It is not a complete routed DDR interface. The wiring helper defines both bytes and shared nets; this physical host test connects **only DQ0 of byte 0**, not both byte lanes or CK/CA.

```sh
bun scripts/check-ddr-host.tsx /path/to/mt41k512m8da-107-it-p-fanout --direct
bun test tests/ddr-host.test.tsx
```

The first command writes `dist/ddr-host/direct/circuit.json` and `report.json`. The regression test needs no external memory files: it uses one separate destination pad and verifies that all CPU saved paths survive a real noncoincident host connection. The helper creates its own output directory, so it also runs from a clean checkout.

**The general host autorouter is not proven for this layout.** On the earlier, larger profile, the unfiltered installed capacity router reported a topology overlap while processing CPU support networks. A signal-only run after the module's explicit signal-net declarations still exceeded a **30-second wall-clock diagnostic limit**. That capacity result predates the compact geometry; the compact profile has been verified with explicit host continuation, not a successful general-router run. The diagnostic runs in a separate subprocess so a long solver step cannot bypass the timeout. The signal-only adapter retains the full obstacle and preloaded-trace input but excludes power-network routing, which is covered by independent CPU plane-contact checks. It must not be advertised as a generally working stock router.

```sh
# Bounded diagnostic; exits nonzero on timeout, routing failure or missing target copper.
bun scripts/check-ddr-host.tsx /path/to/mt41k512m8da-107-it-p-fanout
```

Capacity diagnostics are kept separately under `dist/ddr-host/capacity/`, including `failure.json`; they do not overwrite the successful direct-continuation artifact. The supplied RAM remains unpowered in this one-signal fixture. Full two-device termination, supply/reference connections, complete routing, impedance and timing validation remain board integration work.

## Fixed-copper lower bound for compact profiles

The unchanged CPU/support geometry alone occupies **X = −8.2…+8.2 mm, Y = −8.2…+8.38 mm**. This includes all 324 BGA pads, 164 capacitor pads, 133 fixed supply/decoupling vias and 173 fixed support routes, measured to pad/via edges and trace half-widths. C33's upper pad sets the +Y edge; fixed via barrels set the other three edges. Preview receiver pads and board-wide pours are excluded.

Reserving a further 0.1016 mm around that copper requires at least **0.8016 mm left/right/bottom and 0.9816 mm top padding** beyond the 15 mm package body. This is a lower bound for the existing support geometry, not a proof that DDR routes can fit at those dimensions. Moving support parts would define a different optimization problem.

```sh
bun scripts/check-fixed-envelope.ts ddr_left
```

The command writes `dist/envelopes/ddr_left.fixed.json` with the exact witnesses. `getAM3352Bounds(profile)` describes the **terminal-center rectangle** in the CPU's coordinate frame. A terminal's round copper cap extends beyond its center by half the trace width; host board edges and unrelated copper must reserve that cap and the required clearance. The rectangle may have unequal padding on all four sides. Reference-plane validation checks the actual rectangle's corners and perimeter against the rendered outer polygon, not the area of an assumed centered square.

## Current six-layer grouped memory profile

The supplied project now also contains a six-layer `bus_grouped` cache. Its physical byte layer is `inner2` and its address/control/clock layer is `inner3`. Select this cache with **explicit** `DDR_MEMORY_SIX_LAYER_MAP`, its exported asymmetric boundary, and `traceWidthMm={0.1168}`. The width adjustment remains above the 0.1016 mm minimum and resolves the measured nominal clearance failures of the original 0.12 mm grouped cache. It changes the impedance geometry, so the host stackup must be evaluated with the adjusted width.

This configuration passes the complete saved-copper audit at **0.1019469 mm minimum nominal clearance**, including enlarged through-vias, and its rendered all-layer shorts check. It does not establish manufacturing tolerance or impedance. The original four compact profiles retain their widths and layer adapter. See [the source-hash and compatibility report](ddr-memory-compatibility.md) and [full-system work](ddr-system-progress.md).