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/route-ddr-dq5-inner6-host.ts
/** Same-layer host continuation from an explicitly revised RAM exit. */
import{readFileSync,writeFileSync,mkdirSync}from'node:fs'
import{resolve}from'node:path'
import{createHash}from'node:crypto'
import{verifyDdrCapture}from'./ddr-capture-provenance'
import{applyFacingExitReplacements}from'./ddr-facing-context'
import{terminalOnlyFixedObstacles}from'./ddr-terminal-copper-obstacles'
import{loadDdrCompositeRoutingContext,loadOrderedDdrCompositeSeed,loadAcceptedOrderedHostContext,auditCompositeHostTopology}from'./ddr-composite-routing-context'
import{auditRouteAngles}from'./check-route-angles'
import{auditDdrTraceJunctions}from'./check-ddr-system-copper'
import{objectHash}from'./improve-ddr-a9-power-launches'
import{checkHostTerminalContract}from'./route-ddr-sequential'
import{verifyDdrSystemCopper}from'./check-ddr-system-copper'
const[capture,facing,out,weightArg='1.2',statesArg='300000']=process.argv.slice(2),signal='DDR_D5',maximumSearchStates=Number(statesArg),heuristicWeight=Number(weightArg)
if(![1,1.2].includes(heuristicWeight)||!Number.isInteger(maximumSearchStates)||maximumSearchStates<1000||maximumSearchStates>1000000)throw Error('Invalid bounded search options')
if(!capture||!facing||!out)throw Error('Usage: capture validated-DQ5-escape output')
const bound=new Map<string,string>(),fh=(p:string)=>createHash('sha256').update(readFileSync(p)).digest('hex'),read=(p:string)=>{p=resolve(p);bound.set(p,fh(p));return JSON.parse(readFileSync(p,'utf8'))}
const {captureHash}=verifyDdrCapture(capture),candidate=read(resolve(facing,'candidate.circuit.json')),host=read(resolve(facing,'host-bundle.json')),input=read(resolve(facing,'routing-input.json')),report=read(resolve(facing,'report.json')),evidence=read(resolve(facing,'input-evidence.json')),changes=read(resolve(facing,'replacements.json')),map=read(resolve(capture,'signal-map.json'))
const parentPath=evidence.actualParentPath??Object.keys(evidence.actualInputHashes).find(p=>p.endsWith('/candidate.circuit.json'));if(!parentPath)throw Error('Missing exact parent')
for(const[p,h]of Object.entries(evidence.actualInputHashes))if(fh(p)!==h)throw Error('Stale input parent')
const parent=read(parentPath)
if(!report.accepted||report.captureHash!==captureHash||host.captureHash!==captureHash||host.layerSpace!=='physical'||host.traces.length!==12||objectHash(parent)!==report.parentCircuitSha256||objectHash(applyFacingExitReplacements(parent,changes))!==objectHash(candidate))throw Error('Unverified DQ5 escape replacement')
for(const t of host.traces)if(objectHash(candidate.find((e:any)=>e.pcb_trace_id===t.pcb_trace_id))!==objectHash(t))throw Error('Host differs')
for(const c of input.connections)for(const p of c.pointsToConnect){const e=candidate.find((e:any)=>e.pcb_breakout_point_id===p.pointId);if(!e||e.layer!==p.layer||Math.hypot(e.x-p.x,e.y-p.y)>1e-7)throw Error('Source-owned exit differs')}
const topology0=auditCompositeHostTopology(candidate,host.traces,input.connections)
if(!topology0.valid||!auditRouteAngles(candidate.filter((e:any)=>e.type==='pcb_trace')).valid||!auditDdrTraceJunctions(candidate,input.connections).valid)throw Error('Baseline validation failed')
const ids=new Set(host.traces.map((t:any)=>t.pcb_trace_id)),fixed=candidate.filter((e:any)=>!ids.has(e.pcb_trace_id)),context={topology:topology0,evidence:{inputHashes:Object.fromEntries(bound),escapeReport:report},invalidation:null,assertUnchanged:()=>{verifyDdrCapture(capture);for(const[p,h]of bound)if(fh(p)!==h)throw Error('Input changed during route')}},entry=map.find((m:any)=>m.cpuSignal===signal),connection=input.connections.find((c:any)=>c.source_trace_id===entry?.sourceTraceId)
input.traces=host.traces
if(!connection||connection.pointsToConnect.length!==2||host.traces.some((t:any)=>t.connection_name===connection.name))throw Error('Requires one unhosted two-terminal signal')
const[source,target]=[...connection.pointsToConnect].sort((a:any,b:any)=>a.x-b.x),layer=source.layer
if(layer!==target.layer||!['inner2','inner4','inner6'].includes(layer))throw Error('Requires same-layer signal terminals')
const terminalProjection=terminalOnlyFixedObstacles(fixed,connection);input.obstacles=terminalProjection.obstacles
const exit=candidate.find((e:any)=>e.pcb_breakout_point_id===source.pointId),saved=candidate.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id===exit.source_trace_id&&e.route.at(-1)?.layer===layer&&Math.hypot(e.route.at(-1).x-source.x,e.route.at(-1).y-source.y)<1e-7)
if(!saved)throw Error('Missing actual RAM endpoint copper')
const previous=[...saved.route].reverse().find((p:any)=>p.route_type==='wire'&&p.layer===layer&&Math.hypot(p.x-source.x,p.y-source.y)>1e-7),d=Math.hypot(source.x-previous.x,source.y-previous.y),collar={x:source.x+.2*(source.x-previous.x)/d,y:source.y+.2*(source.y-previous.y)/d}
const sourceObstacle=input.obstacles.find((o:any)=>o.connectedTo.includes(connection.name)&&o.layers.includes(layer)&&Math.hypot(o.center.x-source.x,o.center.y-source.y)<1e-7)
if(!sourceObstacle)throw Error('Missing source-owned endpoint obstacle')
const prepared:any={connection,connectionIndex:0,sourcePoint:{...source,pcb_port_id:source.pointId},sourcePointIndex:connection.pointsToConnect.indexOf(source),sourceLayer:layer,sourceObstacle,targetPoint:target},bounds={...input.bounds,maxX:4}
const bus:any={busId:signal,direction:'right',exitEdge:'right',termination:{type:'boundary'},connections:[prepared],componentId:'RAM-facing-exit',componentObstacles:[sourceObstacle],componentBounds:input.bounds,sharedBoundary:bounds,xCoordinates:[source.x],yCoordinates:[source.y],pitchX:.8,pitchY:.8}
const{routeViaMinimalWindingAlternativesSteps}=await import(resolve('node_modules/@tscircuit/fanout-solver/lib/route-via-minimal-winding.ts'))
const params:any={srj:input,bus,targetLayer:layer,terminals:[{connection:prepared,viaPoint:collar,exitPoint:target}],acceptedPlans:[],layerNames:['top',...Array.from({length:8},(_,i)=>`inner${i+1}`),'bottom'],traceWidth:.12,viaDiameter:.4572,viaHoleDiameter:.254,clearance:.1016,allowBlindAndBuriedVias:false,allowSourceLayerRouting:true,gridStep:.1,maximumRouteOrderAttempts:1,maximumSearchStates,heuristicWeight,sourceEscapePaths:new Map([[0,[source,collar]]])}
mkdirSync(out,{recursive:true});const write=(n:string,v:any)=>writeFileSync(resolve(out,n),JSON.stringify(v,null,2)+'\n');write('seed.circuit.json',candidate);write('seed-host-bundle.json',host);write('seed-topology.json',context.topology);write('input-evidence.json',{...context.evidence,signal,source,target,collar,bounds,maximumSearchStates,heuristicWeight,terminalProjectionWitnesses:terminalProjection.witnesses,invalidation:context.invalidation})
const started=Date.now(),steps=routeViaMinimalWindingAlternativesSteps(params,1),progress:any[]=[];let alternatives:any[]=[],finished=false
while(Date.now()-started<55000){const s=steps.next();if(s.done){alternatives=s.value;finished=true;break}progress.push({...s.value,visualization:undefined});write('progress.json',progress)}if(!finished)steps.return([])
const traces=(alternatives[0]??[]).map((p:any)=>({...p.trace,source_trace_id:connection.source_trace_id,connectsTo:connection.pointsToConnect.map((p:any)=>p.pointId)})),terminal=checkHostTerminalContract(traces,[connection]),physical=verifyDdrSystemCopper(fixed,[...host.traces,...traces],input.connections,{})
let lengths:any
if(traces.length===1){const planar=(route:any[])=>route.reduce((n:number,p:any,i:number)=>{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),cpuExit=candidate.find((e:any)=>e.pcb_breakout_point_id===target.pointId),cpu=candidate.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id===cpuExit.source_trace_id&&e.route.some((p:any)=>p.route_type==='wire'&&p.layer===layer&&Math.hypot(p.x-target.x,p.y-target.y)<1e-7));if(!cpu)throw Error('Missing actual CPU escape');lengths={ramMm:planar(saved.route),hostMm:planar(traces[0].route),cpuMm:planar(cpu.route),nominalMm:28.899838000000003};lengths.fullPlanarMm=lengths.ramMm+lengths.hostMm+lengths.cpuMm}
const allAngles=auditRouteAngles([...candidate,...traces].filter((e:any)=>e.type==='pcb_trace')),allJunctions=auditDdrTraceJunctions([...candidate,...traces],input.connections),allTerminal=checkHostTerminalContract([...host.traces,...traces],input.connections.filter((c:any)=>[...host.traces,...traces].some((t:any)=>t.connection_name===c.name)))
const topology=auditCompositeHostTopology([...candidate,...traces],[...host.traces,...traces],input.connections)
const accepted=topology.valid&&allAngles.valid&&allJunctions.valid&&allTerminal.valid&&physical.connectivity.filter((c:any)=>c.connected).length===host.traces.length+1&&traces.length===1&&traces[0].route.every((p:any)=>p.route_type==='wire'&&p.layer===layer)&&terminal.valid&&!physical.errors.length&&!physical.violations.length&&physical.angles.valid&&!physical.joinedBends.length&&physical.connectivity.some((c:any)=>c.name===connection.name&&c.connected)&&lengths.fullPlanarMm<=lengths.nominalMm+1e-7
context.assertUnchanged();write('report.json',{captureHash,accepted,finished,maximumSearchStates,heuristicWeight,expandedStateCount:progress.at(-1)?.expandedStateCount,elapsedSeconds:(Date.now()-started)/1000,physical,terminal,allTerminal,allAngles,allJunctions,topology,lengths,parentCandidateSha256:objectHash(candidate),sameNetTopologyStatus:'All12 prior hosts exact; every retained/new contact must be a source-owned endpoint.',scope:'Actual revised-exit host continuation; complete byte matching, references, impedance and remaining interface still unqualified.'});write('raw-traces.json',traces)
if(accepted){write('candidate.circuit.json',[...candidate,...traces]);write('routing-input.json',input);write('host-bundle.json',{...host,traces:[...host.traces,...traces]})}
console.log(JSON.stringify({accepted,alternatives:alternatives.length,errors:physical.errors.length,violations:physical.violations.length,angles:physical.angles.violations.length,joins:physical.joinedBends.length,lengths}));if(!accepted)process.exitCode=1