AnasSarkiz/am625sip-linux
An electronic component representing an AM625 system-in-package with mapped pins and physical footprint for PCB integration.
- Version
- 1.0.3
- License
- unset
- Stars
- 0
scripts/validate-artifact.mjs
import assert from "node:assert/strict"
import { readFileSync } from "node:fs"
const circuitJson = JSON.parse(readFileSync("dist/index/circuit.json", "utf8"))
const expectedBreakoutCount = Number(process.argv[2] ?? 2)
const errors = circuitJson.filter((element) => element.type.endsWith("_error"))
assert.equal(errors.length, 0, JSON.stringify(errors, null, 2))
const processor = circuitJson.find(
(element) => element.type === "source_component" && element.name === "U1",
)
assert.ok(processor, "Processor must be present")
const ports = circuitJson.filter(
(element) => element.type === "source_port" && element.source_component_id === processor.source_component_id,
)
assert.equal(ports.length, 425, "The full 425-ball processor must be present")
const traces = circuitJson.filter((element) => element.type === "pcb_trace")
const sourceTraces = circuitJson.filter((element) => element.type === "source_trace")
const breakoutPoints = circuitJson.filter((element) => element.type === "pcb_breakout_point")
assert.equal(sourceTraces.length, expectedBreakoutCount)
assert.equal(breakoutPoints.length, expectedBreakoutCount)
assert.equal(traces.length, 2 * expectedBreakoutCount, "Every connection needs fanout and downstream copper")
for (const sourceTrace of sourceTraces) {
const netTraces = traces.filter((trace) => trace.source_trace_id === sourceTrace.source_trace_id)
assert.equal(netTraces.length, 2)
const fanoutTrace = netTraces.find((trace) => trace.pcb_trace_id.startsWith("fanout:"))
const downstreamTrace = netTraces.find((trace) => !trace.pcb_trace_id.startsWith("fanout:"))
assert.ok(fanoutTrace && downstreamTrace, "Both routing phases must produce copper")
const breakoutPoint = breakoutPoints.find((point) => point.source_trace_id === sourceTrace.source_trace_id)
assert.ok(breakoutPoint)
const fanoutEnd = fanoutTrace.route.at(-1)
assert.equal(fanoutEnd.layer, breakoutPoint.layer, "Breakout layer must match actual copper")
assert.ok(Math.hypot(fanoutEnd.x - breakoutPoint.x, fanoutEnd.y - breakoutPoint.y) < 0.001)
const downstreamEnds = [downstreamTrace.route[0], downstreamTrace.route.at(-1)]
assert.ok(downstreamEnds.some((end) => end.layer === fanoutEnd.layer &&
Math.hypot(end.x - fanoutEnd.x, end.y - fanoutEnd.y) < 0.001), "Routing phases must join physically")
const pcbPorts = sourceTrace.connected_source_port_ids.map((sourcePortId) =>
circuitJson.find((element) => element.type === "pcb_port" && element.source_port_id === sourcePortId))
assert.ok(pcbPorts.every(Boolean))
for (const pcbPort of pcbPorts) {
assert.ok(netTraces.some((trace) => [trace.route[0], trace.route.at(-1)].some((end) =>
pcbPort.layers.includes(end.layer) && Math.hypot(end.x - pcbPort.x, end.y - pcbPort.y) < 0.001)),
"Both physical endpoints must be reached")
}
}
const schematicPorts = circuitJson.filter((element) => element.type === "schematic_port" &&
ports.some((port) => port.source_port_id === element.source_port_id))
assert.equal(schematicPorts.length, 425)
assert.equal(new Set(schematicPorts.map((port) => port.source_port_id)).size, 425,
"Schematic units must represent every processor ball exactly once")
assert.equal(circuitJson.filter((element) => element.type === "schematic_sheet").length, 2)
assert.ok(circuitJson.some((element) => element.type === "source_group" && element.is_subcircuit), "Processor must be a real subcircuit")
console.log(`PASS: 425 processor ports, ${traces.length} routed breakout traces, zero circuit JSON errors`)