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/normalize-ddr-capture.ts

/** Convert a provenance-bound raw host candidate into independently checked
 * partial copper. Only full-candidate physical predicates authorize shortcuts. */
import {readFileSync,writeFileSync,mkdirSync} from 'node:fs'
import {resolve} from 'node:path'
import {verifyDdrCapture} from './ddr-capture-provenance'
import {verifyDdrSystemCopper} from './check-ddr-system-copper'
import {normalizeDdrHostRoutes} from './normalize-ddr-host-routes'
import {anchorDdrHostEndpoints} from './anchor-ddr-host-endpoints'
import {selectVerifiedDdrSeed,resolveDdrTraceNet,ddrSeedTraceHash} from './ddr-verified-seed'
const args=process.argv.slice(2),[dir,source,output]=args.filter(a=>!a.startsWith('--'))
const seedPath=args.find(a=>a.startsWith('--seed-physical='))?.slice('--seed-physical='.length)
if(!dir||!source||!output)throw Error('Usage: capture-dir candidate-bundle.json output-dir [--seed-physical=path]')
const read=(p:string)=>JSON.parse(readFileSync(p,'utf8'))
const {captureHash,snapshot}=verifyDdrCapture(dir),bundle=read(source),input=read(resolve(dir,'merged-routing-input.json'))
if(bundle.captureHash!==captureHash||input.__ddrCaptureHash!==captureHash)throw Error('Mismatched capture')
if(!['virtual','physical'].includes(bundle.layerSpace))throw Error('Unknown layer space')
const mapping:Record<string,string>={top:'top',inner1:'inner2',inner2:'inner4',bottom:'inner6'}
const layer=(s:string)=>{const l=bundle.layerSpace==='virtual'?mapping[s]:s;if(!['top','inner2','inner4','inner6'].includes(l!))throw Error(`Illegal host layer ${s}`);return l}
const raw=bundle.traces.map((t:any,i:number)=>({...t,pcb_trace_id:t.pcb_trace_id??`host_${i}`,route:t.route.map((p:any)=>p.route_type==='wire'?{...p,layer:layer(p.layer)}:p.route_type==='via'?{...p,from_layer:layer(p.from_layer),to_layer:layer(p.to_layer),via_diameter:p.via_diameter??.4572,via_hole_diameter:p.via_hole_diameter??.254}:p)}))
const original=read(resolve(dir,'unrouted.circuit.json')),leads=snapshot.hostProfiles?[]:read(resolve(dir,'corridor-leads.json')),accepted:any[]=[],results:any[]=[]
const seed=seedPath?selectVerifiedDdrSeed({captureHash,bundle:read(seedPath),original,leads,connections:input.connections}):undefined
const seedNets=new Set(seed?.connectedNetNames??[]),seedTraces=seed?.traces??[],seedCount=seedTraces.length
accepted.push(...seedTraces)
const pending=raw.filter((t:any)=>!seedNets.has(resolveDdrTraceNet(t,input.connections)))
const seedEvidence=seed?{source:resolve(seedPath!),connectedNetNames:seed.connectedNetNames,traceCount:seedCount,traceHash:seed.seedTraceHash,discardedIncompleteTraceCount:seed.discardedIncompleteTraceCount}:null
const assertSeedPreserved=()=>{if(seed&&ddrSeedTraceHash(accepted.slice(0,seedCount))!==seed.seedTraceHash)throw Error('Immutable seed prefix changed')}
mkdirSync(output,{recursive:true})
writeFileSync(resolve(output,'seed-preservation.json'),JSON.stringify({captureHash,seed:seedEvidence,skippedRawTraceCount:raw.length-pending.length},null,2)+'\n')
writeFileSync(resolve(output,'candidate.physical.json'),JSON.stringify({captureHash,layerSpace:'physical',seed:seedEvidence,traces:accepted},null,2)+'\n')
const terminalDirections=leads.map((t:any)=>{const [a,b]=t.route;const length=Math.hypot(b.x-a.x,b.y-a.y);return {x:b.x,y:b.y,layer:b.layer,dx:(b.x-a.x)/length,dy:(b.y-a.y)/length}})
if(snapshot.hostProfiles){
 const seen=new Set<string>()
 for(const connection of input.connections.filter((c:any)=>/^DQ/.test(c.ramTerminal??'')||c.ramTerminal==='DM'))for(const point of connection.pointsToConnect){
  if(seen.has(point.pointId))continue;seen.add(point.pointId)
  const exit=original.find((e:any)=>e.type==='pcb_breakout_point'&&e.pcb_breakout_point_id===point.pointId)
  const trace=exit&&original.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id===exit.source_trace_id&&e.route.at(-1)?.layer===exit.layer&&Math.hypot(e.route.at(-1).x-exit.x,e.route.at(-1).y-exit.y)<1e-7)
  if(!trace)throw Error(`No actual saved data exit for ${point.pointId}`)
  const before=[...trace.route].reverse().find((p:any)=>p.route_type==='wire'&&p.layer===exit.layer&&Math.hypot(p.x-exit.x,p.y-exit.y)>1e-7)
  if(!before)throw Error('Data exit has no incoming tangent')
  const length=Math.hypot(exit.x-before.x,exit.y-before.y)
  terminalDirections.push({x:exit.x,y:exit.y,layer:exit.layer,dx:(exit.x-before.x)/length,dy:(exit.y-before.y)/length})
 }
}
let calls=0
for(const trace of pending){
 let last:any
 const anchored=anchorDdrHostEndpoints(trace,input.connections,original)
 const result=normalizeDdrHostRoutes([anchored.trace],{terminalDirections,acceptCandidate:candidate=>{
  calls++;const report=verifyDdrSystemCopper(original,[...leads,...accepted,candidate],input.connections)
  last={errors:report.errors.length,clearanceViolations:report.violations.length,angleViolations:report.angles.violations.length,joinedBends:report.joinedBends.length}
  return !last.errors&&!last.clearanceViolations&&!last.angleViolations&&!last.joinedBends
 }})
 accepted.push(...result.routes);assertSeedPreserved();results.push({traceId:trace.pcb_trace_id,endpointCorrections:anchored.corrections,candidateAccepted:result.routes.length===1,lastPhysicalCheck:last,rejected:result.rejected})
 writeFileSync(resolve(output,'candidate.physical.json'),JSON.stringify({captureHash,layerSpace:'physical',seed:seedEvidence,traces:accepted},null,2)+'\n')
 writeFileSync(resolve(output,'normalization-report.json'),JSON.stringify({captureHash,seed:seedEvidence,status:'partial-copper-unvalidated-connectivity',sourceTraceCount:raw.length,acceptedTraceCount:accepted.length,predicateCalls:calls,results},null,2)+'\n')
 console.log(JSON.stringify({processed:results.length,total:pending.length,accepted:accepted.length,predicateCalls:calls,lastPhysicalCheck:last}))
}
assertSeedPreserved()
const final=verifyDdrSystemCopper(original,[...leads,...accepted],input.connections)
writeFileSync(resolve(output,'physical-report.json'),JSON.stringify({captureHash,...final},null,2)+'\n')
console.log(JSON.stringify({valid:final.valid,connectedNets:final.connectivity.filter(c=>c.connected).length,totalNets:final.netCount,acceptedTraceCount:accepted.length}))
if(!final.valid)process.exitCode=1