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/audit-ddr-90-placement.ts

/** Read-only alternative-placement audit; external files are hashed and untouched. */
import {readFileSync,writeFileSync} from 'node:fs'
import {resolve} from 'node:path'
import {createHash} from 'node:crypto'
import {verifyDdrCapture} from './ddr-capture-provenance'
const external=resolve(process.argv[2]??'/Users/ankan/Documents/Codex/2026-09-10/what-x20/outputs/mt41k512m8da-107-it-p-fanout/dist/am3352-routing-90'),out=resolve(process.argv[3]??'dist/ddr-integrated-ten/alternative-90-audit.json'),frozen='dist/ddr-system/host-taps-54af3e346b5e'
const read=(p:string)=>JSON.parse(readFileSync(p,'utf8')),hash=(p:string)=>createHash('sha256').update(readFileSync(p)).digest('hex'),files=['unrouted.circuit.json','forced-trunk-routing-input.json','length-floor-report.json','support-input-report.json'],sourceHashes=Object.fromEntries(files.map(f=>[f,hash(resolve(external,f))]))
const circuit=read(resolve(external,'unrouted.circuit.json')),input=read(resolve(external,'forced-trunk-routing-input.json')),reference=read(resolve(external,'length-floor-report.json')),{captureHash}=verifyDdrCapture(frozen),old=read(resolve(frozen,'unrouted.circuit.json'))
if(reference.fixedSha256!==sourceHashes['unrouted.circuit.json']||reference.inputSha256!==sourceHashes['forced-trunk-routing-input.json'])throw Error('External reference floor hashes stale')
const {getSourceNetOwnerForAudit}=await import(resolve('/Users/ankan/Documents/Codex/2026-09-10/what-x20/outputs/mt41k512m8da-107-it-p-fanout/scripts/audit-am3352-obstacle-ownership.ts')),owner=getSourceNetOwnerForAudit(circuit)
const planar=(route:any[])=>route.reduce((n,p,i)=>{const q=route[i-1];return n+(p.route_type==='wire'&&q?.route_type==='wire'&&p.layer===q.layer?Math.hypot(p.x-q.x,p.y-q.y):0)},0),octile=(a:any,b:any)=>{const x=Math.abs(a.x-b.x),y=Math.abs(a.y-b.y);return Math.max(x,y)+(Math.SQRT2-1)*Math.min(x,y)}
const members=input.connections.filter((c:any)=>/^DQ[0-7]$/.test(c.ramTerminal)||['DM','DQS_P','DQS_N'].includes(c.ramTerminal)).map((c:any)=>{
 const expected=owner(c.source_trace_id??c.name),balls=c.pointsToConnect.map((p:any)=>{
  const exit=circuit.find((e:any)=>e.type==='pcb_breakout_point'&&e.pcb_breakout_point_id===p.pointId),traces=circuit.filter((t:any)=>t.type==='pcb_trace'&&t.source_trace_id===exit?.source_trace_id&&t.route.some((q:any)=>q.route_type==='wire'&&q.layer===p.layer&&Math.hypot(q.x-p.x,q.y-p.y)<1e-7))
  if(!expected||owner(exit?.pcb_breakout_point_id)!==expected||traces.length!==1)throw Error('Invalid endpoint ownership')
  const trace=traces[0],ball=trace.route.find((p:any)=>p.route_type==='wire'),pads=circuit.filter((e:any)=>e.type==='pcb_smtpad'&&e.layer===ball.layer&&Math.hypot(e.x-ball.x,e.y-ball.y)<1e-7&&owner(e.pcb_smtpad_id)===expected)
  if(pads.length!==1)throw Error('Actual ball pad not unique')
  const group=circuit.find((e:any)=>e.type==='pcb_group'&&e.subcircuit_id===exit.subcircuit_id&&/^(RAM[01]|CPU)$/.test(e.name??''))
  return {x:pads[0].x,y:pads[0].y,padId:pads[0].pcb_smtpad_id,savedTraceId:trace.pcb_trace_id,fixedMm:planar(trace.route),exit:p,groupName:group?.name}
 })
 const ram=balls.find((b:any)=>/^RAM/.test(b.groupName??'')),cpu=balls.find((b:any)=>b!==ram)
 if(!ram||!cpu)throw Error('RAM/CPU identity ambiguous')
 const dx=Math.abs(cpu.x-ram.x),dy=Math.abs(cpu.y-ram.y),hostFloorMm=octile(cpu.exit,ram.exit),totalFloorMm=cpu.fixedMm+ram.fixedMm+hostFloorMm,floor=reference.bytes.find((b:any)=>b.byte===c.ramByte)?.nets.find((n:any)=>n.terminal===c.ramTerminal)
 if(!floor||Math.abs(floor.totalPlanarLowerBoundMm-totalFloorMm)>1e-6)throw Error('Independently computed floor differs')
 return {byte:c.ramByte,terminal:c.ramTerminal,name:c.name,ram,cpu,dxMm:dx,dyMm:dy,manhattanMm:dx+dy,hostFloorMm,totalFloorMm}
})
const bytes=[0,1].map(byte=>{const rows=members.filter((r:any)=>r.byte===byte);if(rows.length!==11)throw Error('Missing byte member');const data=rows.filter((r:any)=>r.terminal==='DM'||/^DQ[0-7]$/.test(r.terminal)),nominal=Math.max(...data.map((r:any)=>r.manhattanMm));return {byte,dqlmPairedDataMm:nominal,dqlmIncludingStrobesMm:Math.max(...rows.map((r:any)=>r.manhattanMm)),axisEnvelopeMm:Math.max(...data.map((r:any)=>r.dxMm))+Math.max(...data.map((r:any)=>r.dyMm)),maximumMemberFloorMm:Math.max(...rows.map((r:any)=>r.totalFloorMm)),nominalFloorBlockers:rows.filter((r:any)=>r.totalFloorMm>nominal+1e-7).map((r:any)=>({terminal:r.terminal,floorMm:r.totalFloorMm,excessMm:r.totalFloorMm-nominal})),members:rows.map((r:any)=>({...r,marginToNominalMm:nominal-r.totalFloorMm}))}})
const rigidComparisons:any[]=[]
for(const name of ['RAM0','RAM1']){
 const group=circuit.find((e:any)=>e.type==='pcb_group'&&e.name===name),prior=old.find((e:any)=>e.type==='pcb_group'&&e.name===name),transform=(p:any)=>({x:group.anchor_position.x+(p.y-prior.anchor_position.y),y:group.anchor_position.y-(p.x-prior.anchor_position.x)})
 let maxError=0,routeCount=0,pointCount=0,padCount=0,viaCount=0;const differences:any[]=[]
 for(const e of old.filter((e:any)=>e.subcircuit_id===prior.subcircuit_id&&['pcb_trace','pcb_smtpad','pcb_via'].includes(e.type))){
  const id=e[`${e.type}_id`],expectedPosition=e.type!=='pcb_trace'?transform(e):null,after=e.type==='pcb_via'?circuit.find((q:any)=>q.type===e.type&&q.subcircuit_id===group.subcircuit_id&&Math.hypot(q.x-expectedPosition!.x,q.y-expectedPosition!.y)<1e-6&&q.outer_diameter===e.outer_diameter&&q.hole_diameter===e.hole_diameter):circuit.find((q:any)=>q.type===e.type&&q[`${q.type}_id`]===id)
  if(!after){differences.push({id,reason:'missing'});continue}
  if(e.type==='pcb_trace'){routeCount++;if(e.route.length!==after.route.length){differences.push({id,reason:'point-count'});continue}for(const [i,p]of e.route.entries()){const q=after.route[i],expected=transform(p),error=Math.hypot(expected.x-q.x,expected.y-q.y);maxError=Math.max(maxError,error);pointCount++;if(error>1e-6||['route_type','layer','width','from_layer','to_layer','via_diameter','via_hole_diameter'].some(k=>p[k]!==q[k]))differences.push({id,index:i,error})}}
  else {if(e.type==='pcb_smtpad')padCount++;else viaCount++;const expected=transform(e),error=Math.hypot(expected.x-after.x,expected.y-after.y);maxError=Math.max(maxError,error);if(error>1e-6||['layer','shape','radius','outer_diameter','hole_diameter'].some(k=>e[k]!==after[k]))differences.push({id,error})}
 }
 const dataTraceIds=new Set(members.filter((m:any)=>m.ram.groupName===name).map((m:any)=>m.ram.savedTraceId)),dataDifferences=differences.filter(d=>dataTraceIds.has(d.id))
 rigidComparisons.push({dataTraceCount:dataTraceIds.size,dataProfilesRigidTransformOnly:dataDifferences.length===0,dataDifferences,name,fromAnchor:prior.anchor_position,toAnchor:group.anchor_position,rotationDeltaDegrees:-90,routeCount,pointCount,padCount,viaCount,maxErrorMm:maxError,differences})
}
const unchangedCurrentDataProfileComparison=bytes.map(b=>{
 const rows=b.members.map((m:any)=>{const prior=old.find((e:any)=>e.type==='pcb_trace'&&e.pcb_trace_id===m.ram.savedTraceId);if(!prior)throw Error('Missing original RAM data trace');const priorGroup=old.find((e:any)=>e.type==='pcb_group'&&e.name===m.ram.groupName),nextGroup=circuit.find((e:any)=>e.type==='pcb_group'&&e.name===m.ram.groupName),end=prior.route.at(-1),expectedEnd={x:nextGroup.anchor_position.x+(end.y-priorGroup.anchor_position.y),y:nextGroup.anchor_position.y-(end.x-priorGroup.anchor_position.x)};if(Math.hypot(expectedEnd.x-m.ram.exit.x,expectedEnd.y-m.ram.exit.y)>1e-6||end.layer!==m.ram.exit.layer)throw Error('Alternative data exit differs beyond placement');const priorLengthMm=planar(prior.route),adjustedFloorMm=m.totalFloorMm-m.ram.fixedMm+priorLengthMm;return {terminal:m.terminal,alternativeRamFixedMm:m.ram.fixedMm,currentRamFixedMm:priorLengthMm,adjustedFloorMm,excessOverNominalMm:adjustedFloorMm-b.dqlmPairedDataMm}})
 return {byte:b.byte,scope:'Same alternative placement with current RAM data escape lengths; data exit endpoints are identical under rigid rotation, while DQ4 internal path differs by0.8mm.',members:rows,nominalBlockers:rows.filter((r:any)=>r.excessOverNominalMm>1e-7).map((r:any)=>r.terminal)}
})
for(const file of files)if(hash(resolve(external,file))!==sourceHashes[file])throw Error('Read source changed during audit')
const report={sourceDirectory:external,sourceHashes,frozenComparisonCaptureHash:captureHash,unchangedCurrentDataProfileComparison,placement:circuit.filter((e:any)=>e.type==='pcb_group'&&/^(CPU|RAM[01])$/.test(e.name??'')).map((e:any)=>({name:e.name,anchor:e.anchor_position,center:e.center,width:e.width,height:e.height})),bytes,rigidComparisons,all22ReferenceFloorsIndependentlyReproduced:true,scope:'Read-only source-owned ball-pair nominal/frozen-planar-floor comparison. Positive lower-bound margin is necessary, not proof of obstacle-aware routing or timing. The MAX-column nominal-length interpretation and no invented overlength allowance remain unchanged.'}
writeFileSync(out,JSON.stringify(report,null,2)+'\n');console.log(JSON.stringify({bytes:bytes.map(({members,...b})=>b),rigidComparisons:rigidComparisons.map(({differences,...r})=>({...r,otherDifferenceCount:differences.length,changedIds:[...new Set(differences.map((d:any)=>d.id))]}))},null,2))