0hmX/am3352-ddr-track-a-local-dfm-wip-20261007

Experimental RJ45-corrected board with isolated PG indication. 1005/1005 source joins pass; 15 expanded-guard physical errors, sourcing and qualification gates remain. Not fabrication-ready.

Version
0.0.14
License
unset
Stars
0

work/route-experiment.tsx

import { Circuit } from "@tscircuit/core"
import { Children, cloneElement, isValidElement } from "react"
import Board from "../index"
import { SavedRoutes } from "../layout/SavedRoutes"
import { SavedNativeVias } from "../data/saved-native-vias"
import { SavedNativePours } from "../data/saved-native-pours"
import { TimingConstraints } from "../design/timing-constraints"
import { writeFileSync } from "node:fs"
import { PowerPlanes } from "../layout/PowerPlanes"
import { savedRoutes } from "../data/saved-route-geometry"
import { checkRouting } from "./check-baseline"
import { analyzePcbStyle } from "@tscircuit/circuit-json-pcb-style-analysis"
import { AM3352 } from "../components/AM3352"
import { W631GG6MB_12 } from "../imports/W631GG6MB_12"

// Experimental native TSX rendering only. No circuit snapshots are written.
const original = Board()
const omitted = new Set([SavedRoutes, SavedNativeVias, SavedNativePours])
const relaxReferenceBound = (node: any): any => {
  if (!isValidElement(node)) return node
  const props = node.props as any
  return cloneElement(node as any, {
    ...(node.type === "bus" ? { maxLength: undefined } : {}),
    ...(props.children ? { children: Children.map(props.children, relaxReferenceBound) } : {}),
  })
}
const children = Children.toArray(original.props.children).filter(
  child => !isValidElement(child) || !omitted.has(child.type as any),
).map(child => {
  if (!isValidElement(child)) return child
  if (child.type === TimingConstraints) return relaxReferenceBound(TimingConstraints())
  if (child.type === AM3352 || child.type === W631GG6MB_12) return cloneElement(child as any, { viaInPad: true })
  return child
})
const placement = new Circuit()
placement.schematicDisabled = true
placement.add(cloneElement(original, { routingDisabled: true, children }))
await placement.renderUntilSettled()
const netNames = placement.db.source_net.list().map(net => net.name)
const nominalWidths = new Map<string, number>()
for (const [, nets, , points] of savedRoutes) {
  const width = Math.max(0.1, ...points.filter(point => typeof point[0] === "number").map(point => Number(point[3])))
  for (const net of nets) nominalWidths.set(net, Math.max(width, nominalWidths.get(net) ?? 0.1))
}
const circuit = new Circuit()
circuit.schematicDisabled = true
const started = Date.now()
const log = (kind: string, data: unknown) => console.log(`${((Date.now() - started) / 1000).toFixed(1)}s ${kind}`, JSON.stringify(data))
let previousProgress = 0
for (const event of ["autorouting:start", "autorouting:end", "autorouting:error"] as const) {
  circuit.on(event, (data: any) => log(event, {
    name: data?.displayName ?? data?.phaseName ?? data?.name,
    error: data?.error?.message,
    phase: data?.routingPhaseIndex,
    connections: data?.connectionCount,
    obstacles: data?.obstacleCount,
  }))
}
circuit.on("autorouting:end", (data: any) => {
  log("saved-path-availability", { phase: data?.routingPhaseIndex, count: data?.pcbTracePaths?.length, reason: data?.pcbTracePathsUnavailableReason })
  if (!data?.pcbTracePaths?.length) return
  writeFileSync(new URL(`./route-phase-${data.routingPhaseIndex}.tsx`, import.meta.url), `import type { FanoutTracePath } from "@tscircuit/props"\n\n// Native routing phase copper. Generated from TSX; no Circuit JSON snapshot.\nexport const paths: FanoutTracePath[] = ${JSON.stringify(data.pcbTracePaths, null, 2)}\n`)
})
circuit.on("solver:started", (data: any) => {
  const input = data?.solverParams?.input
  log("solver", { name: data?.solverName, connections: input?.connections?.length, obstacles: input?.obstacles?.length, layers: input?.layerCount, buses: input?.buses?.length, pairs: input?.differentialPairs?.length })
})
circuit.on("autorouting:progress", (data: any) => {
  if (Date.now() - previousProgress < 20000) return
  previousProgress = Date.now()
  log("progress", { phase: data?.phaseName, progress: data?.progress, order: data?._actualRoutingPhaseOrderIndex })
})
circuit.add(cloneElement(original, {
  routingDisabled: false,
  isViaInPadAllowed: true,
  autorouter: { preset: "auto_local", allowViaInPad: true },
  autorouterVersion: "latest",
  autorouterEffortLevel: "2x",
  preflightRoutingCheckPolicy: "none",
  routeRemaining: true,
  children: [...children,
    <PowerPlanes />,
    ...netNames.map(name => <net key={name} name={name} routingPhaseIndex={1} nominalTraceWidth={nominalWidths.get(name) ?? 0.1} />),
    <autoroutingphase key="route-main" name="full-board native routing" phaseIndex={1} autorouter={{ preset: "auto_local", allowViaInPad: true }} />,
    <autoroutingphase key="route-cleanup" name="45 degree route cleanup" phaseIndex={99} autorouter="simplify" reroute />,
  ],
}))
await circuit.renderUntilSettled()
const records = circuit.getCircuitJson()
const errors = records.filter(r => r.type.endsWith("_error"))
const counts = Object.fromEntries(["source_component", "source_trace", "pcb_trace", "pcb_via", "pcb_smtpad", "pcb_copper_pour"].map(type => [type, records.filter(r => r.type === type).length]))
const errorCounts = Object.fromEntries([...new Set(errors.map(e => e.type))].map(type => [type, errors.filter(e => e.type === type).length]))
log("complete", { counts, errorCounts, errors: errors.slice(0, 12).map((e: any) => ({ type: e.type, message: e.message })) })
if (!counts.pcb_trace) throw Error("Autorouter produced no traces; this is not a successful reroute")
log("route-style", { issues: analyzePcbStyle(records).issues.length })
await checkRouting(records)