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
scripts/ddr-interface-completeness.ts
import {readFileSync,writeFileSync} from 'node:fs'
import {createHash} from 'node:crypto'
import {resolve} from 'node:path'
type SignalBranch={sourceTraceId:string;cpuSignal:string;ramByte:number;ramTerminal:string}
type Connection={name:string;source_trace_id?:string}
type Connectivity={name:string;connected:boolean}
/** Count complete CPU signals, not routed host objects or individual RAM branches. */
export function auditDdrInterfaceCompleteness(map:SignalBranch[],connections:Connection[],connectivity:Connectivity[]){
const errors:string[]=[],groups=new Map<string,Array<SignalBranch&{connected:boolean}>>()
const seen=new Set<string>()
for(const branch of map){
if(seen.has(branch.sourceTraceId))errors.push(`Duplicate mapped branch ${branch.sourceTraceId}`)
seen.add(branch.sourceTraceId)
const matches=connections.filter(c=>c.source_trace_id===branch.sourceTraceId || c.name===branch.sourceTraceId)
const evidence=matches.length===1?connectivity.filter(c=>c.name===matches[0]!.name):[]
if(matches.length!==1)errors.push(`Expected one connection for ${branch.sourceTraceId}; found ${matches.length}`)
if(evidence.length!==1)errors.push(`Expected one physical result for ${branch.sourceTraceId}; found ${evidence.length}`)
const rows=groups.get(branch.cpuSignal)??[]
rows.push({...branch,connected:evidence.length===1&&evidence[0]!.connected===true})
groups.set(branch.cpuSignal,rows)
}
for(const c of connections)if(!map.some(b=>b.sourceTraceId===c.source_trace_id||b.sourceTraceId===c.name))errors.push(`Unmapped connection ${c.name}`)
for(const c of connectivity)if(!connections.some(x=>x.name===c.name))errors.push(`Unknown physical result ${c.name}`)
const signals=[...groups].map(([cpuSignal,branches])=>({cpuSignal,connected:branches.every(b=>b.connected),branches}))
return {valid:errors.length===0,complete:errors.length===0&&signals.length>0&&signals.every(s=>s.connected),errors,signalCount:signals.length,connectedSignalCount:signals.filter(s=>s.connected).length,branchCount:map.length,connectedBranchCount:signals.flatMap(s=>s.branches).filter(b=>b.connected).length,signals,scope:'Physical branch completeness only. Every mapped RAM branch must connect before a CPU signal counts as complete. Does not qualify shared-trunk topology, timing, termination, impedance, or electrical DDR compliance.'}
}
if(import.meta.main){
const [captureArg,boardArg]=process.argv.slice(2)
if(!captureArg||!boardArg)throw Error('Usage: capture-directory accepted-board-directory')
const capture=resolve(captureArg),board=resolve(boardArg),read=(p:string)=>JSON.parse(readFileSync(p,'utf8'))
const paths={map:`${capture}/signal-map.json`,input:`${board}/routing-input.json`,report:`${board}/report.json`,candidate:`${board}/candidate.circuit.json`}
const report=read(paths.report)
const manifest=read(`${board}/current-evidence-manifest.json`)
for(const key of ["input","report","candidate"] as const){
const file=paths[key].split("/").at(-1)!
const hash=createHash("sha256").update(JSON.stringify(read(paths[key]))).digest("hex")
if(manifest.files[file]!==hash)throw Error(`Stale evidence manifest for ${file}`)
}
const result={...auditDdrInterfaceCompleteness(read(paths.map),read(paths.input).connections,report.topology.physical.connectivity),inputFileHashes:Object.fromEntries(Object.entries(paths).map(([k,p])=>[k,{path:p,sha256:createHash('sha256').update(readFileSync(p)).digest('hex')}]))}
writeFileSync(`${board}/interface-completeness.json`,JSON.stringify(result,null,2)+'\n')
console.log(JSON.stringify({valid:result.valid,complete:result.complete,signals:`${result.connectedSignalCount}/${result.signalCount}`,branches:`${result.connectedBranchCount}/${result.branchCount}`}))
if(!result.valid)process.exitCode=1
}