ShiboSoftwareDev/am625sip-linux-board
This code defines the physical footprint and pin layout for an AM625 System-in-Package (SIP) component, detailing pad positions, pin labels, and package outline for hardware integration.
- Version
- 1.0.24
- License
- unset
- Stars
- 0
scripts/build-cap-vdds-cache.tsx
import { Circuit } from "@tscircuit/core"
import type { AnyCircuitElement } from "circuit-json"
import { mkdirSync, writeFileSync } from "node:fs"
import { Fragment } from "react"
import {
CAP_VDDS_LINKS,
CapVddsSubcircuit,
} from "../subcircuits/cap-vdds"
import { namespaceCachePcbTraceIds } from "./namespace-cache-pcb-trace-ids"
const CACHE_PATH = "subcircuits/cache/cap-vdds.circuit.json"
const INTERNAL_TRACE_COUNT = 18
const PARENT_LINK_COUNT = CAP_VDDS_LINKS.length
const BoardRules = ({
children,
placementDrcChecksDisabled = false,
}: {
children: React.ReactNode
placementDrcChecksDisabled?: boolean
}) => (
<board
width="140mm"
height="70mm"
layers={4}
autorouter="default"
schematicDisabled
placementDrcChecksDisabled={placementDrcChecksDisabled}
defaultTraceWidth="0.08128mm"
minTraceWidth="0.08128mm"
minTraceToPadEdgeClearance="0.05mm"
minPadEdgeToPadEdgeClearance="0.08128mm"
minViaEdgeToPadEdgeClearance="0.08128mm"
minViaHoleEdgeToViaHoleEdgeClearance="0.1016mm"
minViaHoleDiameter="0.1mm"
minViaPadDiameter="0.24mm"
pcbStyle={{ viaHoleDiameter: "0.1mm", viaPadDiameter: "0.24mm" }}
>
{children}
</board>
)
const LinkPad = ({ name, pcbX, pcbY, parentLayer }: {
name: string
pcbX: number
pcbY: number
parentLayer: "top" | "inner1" | "inner2" | "bottom"
}) => (
<chip
name={name}
pcbX={pcbX}
pcbY={pcbY}
noSchematicRepresentation
footprint={
<footprint>
<smtpad
portHints={["pin1"]}
layer={parentLayer}
shape="circle"
radius="0.12mm"
/>
</footprint>
}
/>
)
const getErrors = (circuitJson: AnyCircuitElement[]) =>
circuitJson.filter(
(element) =>
element.type.endsWith("_error") || element.type === "pcb_placement_error",
)
const getCacheJson = (sourceJson: AnyCircuitElement[]) => {
let cacheJson = sourceJson.filter((element) => {
const type = element.type
return (
(!type.startsWith("schematic_") || type === "schematic_component") &&
!type.startsWith("cad_") &&
!type.endsWith("_warning") &&
type !== "pcb_debug_object" &&
type !== "pcb_board" &&
type !== "source_project_metadata"
)
})
const schematicSourceComponentIds = new Set(
cacheJson.flatMap((element) =>
element.type === "schematic_component"
? [element.source_component_id]
: [],
),
)
const sourcePorts = cacheJson.filter(
(element) => element.type === "source_port",
)
for (const sourceComponent of cacheJson) {
if (
sourceComponent.type !== "source_component" ||
sourceComponent.ftype !== "simple_chip" ||
schematicSourceComponentIds.has(sourceComponent.source_component_id)
) {
continue
}
const portLabels = Object.fromEntries(
sourcePorts.flatMap((sourcePort) => {
if (
sourcePort.type !== "source_port" ||
sourcePort.source_component_id !== sourceComponent.source_component_id ||
sourcePort.pin_number == null
) {
return []
}
return [[`pin${sourcePort.pin_number}`, sourcePort.name]]
}),
)
if (Object.keys(portLabels).length === 0) continue
cacheJson.push({
type: "schematic_component",
schematic_component_id: `schematic_component_cache_${sourceComponent.source_component_id}`,
source_component_id: sourceComponent.source_component_id,
center: { x: 0, y: 0 },
size: { width: 2, height: 2 },
is_box_with_pins: true,
pin_spacing: 0.2,
port_labels: portLabels,
})
}
const routedSourceTraceIds = new Set(
cacheJson.flatMap((element) =>
element.type === "pcb_trace" && element.source_trace_id
? [element.source_trace_id]
: [],
),
)
cacheJson = cacheJson.filter(
(element) =>
element.type !== "source_trace" ||
routedSourceTraceIds.has(element.source_trace_id),
)
for (const element of cacheJson) {
if (element.type === "pcb_component") element.rotation = 0
}
return namespaceCachePcbTraceIds(cacheJson, "cap-vdds")
}
const main = async () => {
const sourceCircuit = new Circuit()
sourceCircuit.on("autorouting:start", (event: any) => {
console.log(
`source autorouting start: ${event.phaseName ?? "unphased"} (${event.simpleRouteJson.connections.length} connections)`,
)
})
sourceCircuit.on("autorouting:end", (event: any) => {
console.log(`source autorouting end: ${event.phaseName ?? "unphased"}`)
})
sourceCircuit.add(
<BoardRules>
<net name="GND" />
<copperpour
name="GND_PLANE"
layer="inner1"
connectsTo="net.GND"
clearance="0.15mm"
boardEdgeMargin="0.3mm"
/>
<CapVddsSubcircuit />
</BoardRules>,
)
await sourceCircuit.renderUntilSettled()
const sourceJson = sourceCircuit.getCircuitJson() as AnyCircuitElement[]
const sourceErrors = getErrors(sourceJson)
const sourceTraceCount = sourceJson.filter(
(element) => element.type === "pcb_trace",
).length
const cacheJson = getCacheJson(sourceJson)
if (sourceErrors.length > 0 || sourceTraceCount !== INTERNAL_TRACE_COUNT) {
console.error(
JSON.stringify({ sourceTraceCount, sourceErrors }, null, 2),
)
process.exitCode = 1
return
}
const parentCircuit = new Circuit()
parentCircuit.on("autorouting:start", (event: any) => {
console.log(
`parent autorouting start: ${event.phaseName ?? "unphased"} (${event.simpleRouteJson.connections.length} connections)`,
)
writeFileSync(
"/private/tmp/cap-vdds-parent-route-input.json",
`${JSON.stringify(event.simpleRouteJson, null, 2)}\n`,
)
})
parentCircuit.add(
<BoardRules placementDrcChecksDisabled>
<net name="GND" />
<copperpour
name="GND_PLANE"
layer="inner1"
connectsTo="net.GND"
clearance="0.15mm"
boardEdgeMargin="0.3mm"
/>
<subcircuit
name="CAP_VDDS_CACHE"
circuitJson={cacheJson}
pcbX={0}
pcbY={0}
exposedNets={["GND"]}
/>
{CAP_VDDS_LINKS.map(({ ball }, index) => (
<Fragment key={`CAP_VDDS_PARENT_PHASE_${ball}`}>
<autoroutingphase
name={`CAP_VDDS_PARENT_LINK_${ball}`}
phaseIndex={index}
autorouter="default"
/>
</Fragment>
))}
{CAP_VDDS_LINKS.map(
({ ball, exitX, exitY, parentLayer }, index) => (
<Fragment key={`CAP_VDDS_PARENT_LINK_${ball}`}>
<LinkPad
name={`L_${ball}`}
pcbX={exitX}
pcbY={exitY}
parentLayer={parentLayer}
/>
<trace
from={`.L_${ball} > .pin1`}
to={`.CAP_VDDS_CACHE .CAP_VDDS .X_${ball} > .pin1`}
routingPhaseIndex={index}
/>
</Fragment>
),
)}
</BoardRules>,
)
await parentCircuit.renderUntilSettled()
const parentJson = parentCircuit.getCircuitJson() as AnyCircuitElement[]
const parentErrors = getErrors(parentJson)
const parentTraceCount = parentJson.filter(
(element) => element.type === "pcb_trace",
).length
if (
parentErrors.length > 0 ||
parentTraceCount !== INTERNAL_TRACE_COUNT + PARENT_LINK_COUNT
) {
console.error(
JSON.stringify({ parentTraceCount, parentErrors }, null, 2),
)
process.exitCode = 1
return
}
mkdirSync("subcircuits/cache", { recursive: true })
writeFileSync(CACHE_PATH, `${JSON.stringify(cacheJson, null, 2)}\n`)
console.log(
JSON.stringify({
cachePath: CACHE_PATH,
sourceTraceCount,
parentTraceCount,
sourceElementCount: sourceJson.length,
cacheElementCount: cacheJson.length,
}, null, 2),
)
}
main().catch((error) => {
console.error(error)
process.exitCode = 1
})