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-composite-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{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,signal='DDR_D7',statesArg,orderedDir,acceptedHostDir]=process.argv.slice(2)
if(!capture||!facing||!out)throw Error('Usage: capture composite-candidate output [signal]')
const maximumSearchStates=statesArg===undefined?300000:Number(statesArg);if(!Number.isInteger(maximumSearchStates)||maximumSearchStates<1000||maximumSearchStates>1000000)throw Error('Search state budget must be1000–1000000')
if(acceptedHostDir&&!orderedDir)throw Error('Accepted host directory requires ordered exit directory')
const context=await (acceptedHostDir?loadAcceptedOrderedHostContext(capture,facing,orderedDir!,acceptedHostDir):orderedDir?loadOrderedDdrCompositeSeed(capture,facing,orderedDir):loadDdrCompositeRoutingContext(capture,facing,{invalidateDq12:true})),{input,host,candidate,fixed,captureHash}=context,entry=context.map.find((m:any)=>m.cpuSignal===signal),connection=input.connections.find((c:any)=>c.source_trace_id===entry?.sourceTraceId)
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:1.2,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,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:context.nominal.bytes.find((b:any)=>b.byte===connection.ramByte)?.dqlmPairedDataMaximumMm};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,physical,terminal,allTerminal,allAngles,allJunctions,topology,lengths,parentCandidateSha256:objectHash(candidate),sameNetTopologyStatus:'DQ12 explicitly invalidated; every retained/new host contact must be an authoritative 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('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