0hmX/am62l-lpddr4-breakout-repro
This code defines React components that instantiate circuits representing dedicated DDR address control and byte0 data lines.
- Version
- 1.0.11
- License
- unset
- Stars
- 0
scripts/verify-circuit-json.ts
import { readdir } from "node:fs/promises"
import { DDR_CONNECTIONS } from "../ddr-connections"
type CircuitJsonElement = Record<string, unknown> & { type: string }
const circuitJsonPath = process.argv[2] ?? "dist/index/circuit.json"
const circuitJson = (await Bun.file(circuitJsonPath).json()) as CircuitJsonElement[]
const elementsOfType = (type: string) =>
circuitJson.filter((element) => element.type === type)
const namesOf = (elements: CircuitJsonElement[]) =>
elements
.map((element) => element.name)
.filter((name): name is string => typeof name === "string")
.sort()
const expectedTraceNames = DDR_CONNECTIONS.map(({ traceName }) => traceName).sort()
const sourceTraces = elementsOfType("source_trace")
const sourceTraceNames = namesOf(sourceTraces)
const breakoutNames = ["RAM_BREAKOUT", "SOC_BREAKOUT"]
const sourceBreakoutGroups = elementsOfType("source_group").filter((element) =>
breakoutNames.includes(String(element.name)),
)
const pcbBreakoutGroups = elementsOfType("pcb_group").filter((element) =>
breakoutNames.includes(String(element.name)),
)
const breakoutPoints = elementsOfType("pcb_breakout_point")
const pcbTraces = elementsOfType("pcb_trace")
const pcbVias = elementsOfType("pcb_via")
const assert: (condition: unknown, message: string) => asserts condition = (
condition,
message,
) => {
if (!condition) throw new Error(message)
}
assert(sourceTraces.length === 33, `Expected 33 source traces, got ${sourceTraces.length}`)
assert(
JSON.stringify(sourceTraceNames) === JSON.stringify(expectedTraceNames),
`Source trace names differ:\nexpected ${expectedTraceNames.join(", ")}\nactual ${sourceTraceNames.join(", ")}`,
)
assert(
sourceBreakoutGroups.length === 2,
`Expected two source breakout groups, got ${sourceBreakoutGroups.length}`,
)
assert(
pcbBreakoutGroups.length === 2,
`Expected two breakout PCB groups, got ${pcbBreakoutGroups.length}`,
)
const source = await Bun.file("index.circuit.tsx").text()
const forbiddenSourcePatterns: Array<[RegExp, string]> = [
[/<via(?:\s|>)/i, "<via>"],
[/<breakoutpoint(?:\s|>)/i, "<breakoutpoint>"],
[/<pcbtrace(?:\s|>)/i, "manual PCB trace primitive"],
[/algorithmFn/, "algorithmFn"],
[/GenericLocalAutorouter/, "GenericLocalAutorouter"],
[/\broutingDisabled\b/, "routingDisabled"],
[/\bpcbRoutingDisabled\b/, "pcbRoutingDisabled"],
[/am62l-classified-autorouter/, "am62l-classified-autorouter"],
[/ti-am62l-evm-ddr-routes/, "ti-am62l-evm-ddr-routes"],
]
const forbiddenMatches = forbiddenSourcePatterns
.filter(([pattern]) => pattern.test(source))
.map(([, label]) => label)
assert(
forbiddenMatches.length === 0,
`Forbidden source-level routing constructs found: ${forbiddenMatches.join(", ")}`,
)
const breakoutPointCounts = Object.fromEntries(
pcbBreakoutGroups.map((group) => [
String(group.name),
breakoutPoints.filter(
(point) => point.pcb_group_id === group.pcb_group_id,
).length,
]),
)
const errorTypes = [
"pcb_autorouting_error",
"pcb_trace_error",
"pcb_pad_trace_clearance_error",
"pcb_via_clearance_error",
]
const errors = Object.fromEntries(
errorTypes.map((type) => [
type,
elementsOfType(type).map((error) => ({
id: error[`${type}_id`] ?? error.pcb_error_id,
message: error.message,
})),
]),
)
const debugDirectory = "dist/autorouter-debug"
let phaseInputs: Array<{
file: string
connectionCount: number
routingPcbGroupIds: string[]
}> = []
try {
const debugFiles = await readdir(debugDirectory)
const phaseInputFiles = debugFiles
.filter((file) => /^phase-\d+\.input\.simple-route\.json$/.test(file))
.sort((left, right) =>
left.localeCompare(right, undefined, { numeric: true }),
)
phaseInputs = await Promise.all(
phaseInputFiles.map(async (file) => {
const input = (await Bun.file(`${debugDirectory}/${file}`).json()) as {
connections?: Array<{ routingPcbGroupId?: string }>
}
const connections = input.connections ?? []
return {
file,
connectionCount: connections.length,
routingPcbGroupIds: [
...new Set(
connections
.map((connection) => connection.routingPcbGroupId)
.filter((id): id is string => Boolean(id)),
),
],
}
}),
)
} catch {
phaseInputs = []
}
const installedCorePackage = (await Bun.file(
"node_modules/@tscircuit/core/package.json",
).json()) as { version: string }
assert(
installedCorePackage.version === "0.0.1703",
`Expected installed @tscircuit/core 0.0.1703, got ${installedCorePackage.version}`,
)
let routingTiming: unknown = null
if (await Bun.file("dist/routing-timing.json").exists()) {
routingTiming = await Bun.file("dist/routing-timing.json").json()
}
const report = {
circuitJsonPath,
expectedCore: {
version: "0.0.1703",
gitHead: "23817c9f55dc36a1b647b52dd27152ee51e55ba5",
},
installedCoreVersion: installedCorePackage.version,
sourceTraceCount: sourceTraces.length,
sourceTraceNames,
sourceBreakoutGroupCount: sourceBreakoutGroups.length,
pcbBreakoutGroupCount: pcbBreakoutGroups.length,
breakoutPointCount: breakoutPoints.length,
breakoutPointCounts,
automaticPcbTraceCount: pcbTraces.length,
automaticPcbViaCount: pcbVias.length,
forbiddenSourceConstructs: forbiddenMatches,
phaseInputs,
errors,
routingTiming,
}
await Bun.write(
"dist/verification-report.json",
`${JSON.stringify(report, null, 2)}\n`,
)
console.log(JSON.stringify(report, null, 2))
if (breakoutPoints.length !== 66) {
console.warn(`Expected ideally 66 breakout points, got ${breakoutPoints.length}`)
}