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-facing-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{loadFacingContext}from'./ddr-facing-context'
import{objectHash}from'./improve-ddr-a9-power-launches'
import{checkHostTerminalContract}from'./route-ddr-sequential'
import{verifyDdrSystemCopper}from'./check-ddr-system-copper'
const[capture,support,facing,out,signal='DDR_DQM0']=process.argv.slice(2)
if(!capture||!support||!facing||!out)throw Error('Usage: capture support facing-candidate output [signal]')
const context=await loadFacingContext(capture,support,facing),{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 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:300000,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('input-evidence.json',{...context.evidence,signal,source,target,collar,bounds})
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.report.lengthBudget.nominalMm};lengths.fullPlanarMm=lengths.ramMm+lengths.hostMm+lengths.cpuMm}
const accepted=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,lengths,parentCandidateSha256:objectHash(candidate),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