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/retune-ddr-dm1.ts

/** Small existing-template DM1 tuning with retained transition via. */
import{readFileSync,writeFileSync,mkdirSync}from'node:fs'
import{resolve}from'node:path'
import{createHash}from'node:crypto'
import{addWestwardTuningExcursion}from'./tune-ddr-data-mask'
import{objectHash,validateDeclaredDdrReplacements}from'./improve-ddr-a9-power-launches'
import{verifyDdrSystemCopper,auditDdrTraceJunctions}from'./check-ddr-system-copper'
import{auditCompositeHostTopology}from'./ddr-composite-routing-context'
import{auditHostSelfContacts}from'./audit-ddr-host-self-contacts'
import{auditRouteAngles}from'./check-route-angles'
import{checkHostTerminalContract}from'./route-ddr-sequential'
const dir=resolve(process.argv[2]??'dist/ddr-fourteen-shorter-strobes'),out=resolve(process.argv[3]??'dist/ddr-dm1-retuned'),hashes=new Map<string,string>(),fh=(p:string)=>createHash('sha256').update(readFileSync(p)).digest('hex'),read=(p:string)=>{hashes.set(p,fh(p));return JSON.parse(readFileSync(p,'utf8'))},parent=read(`${dir}/candidate.circuit.json`),prior=read(`${dir}/report.json`),target=27,host=read(`${dir}/host-bundle.json`),input=read(`${dir}/routing-input.json`),before=parent.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id==='source_trace_674'),connection=input.connections.find((c:any)=>c.name==='source_trace_674'),planar=(r:any[])=>r.slice(1).reduce((n,p,i)=>n+(p.route_type==='wire'&&r[i].route_type==='wire'&&p.layer===r[i].layer?Math.hypot(p.x-r[i].x,p.y-r[i].y):0),0)
if(prior.captureHash!==host.captureHash||before.route.filter((p:any)=>p.route_type==='via').length!==0||objectHash(before)!==objectHash(host.traces.find((t:any)=>t.pcb_trace_id===before.pcb_trace_id)))throw Error('Expected exact DM1host without a host via')
const fixedWitnesses=connection.pointsToConnect.map((p:any)=>{const exit=parent.find((e:any)=>e.type==='pcb_breakout_point'&&e.pcb_breakout_point_id===p.pointId),ts=parent.filter((e:any)=>e.type==='pcb_trace'&&e.source_trace_id===exit?.source_trace_id&&e.route.at(-1)?.layer===p.layer&&Math.hypot(e.route.at(-1).x-p.x,e.route.at(-1).y-p.y)<1e-7);if(ts.length!==1)throw Error('Expected unique actual CPU/RAM escape');return{exit,trace:ts[0],planarMm:planar(ts[0].route)}}),fixedMm=fixedWitnesses.reduce((n:number,w:any)=>n+w.planarMm,0),beforeMm=fixedMm+planar(before.route),delta=target-beforeMm
const actualStrobeLengths=['source_trace_675','source_trace_676'].map(name=>{const t=host.traces.find((t:any)=>t.connection_name===name),c=input.connections.find((c:any)=>c.name===name);return planar(t.route)+c.pointsToConnect.reduce((n:number,p:any)=>{const exit=parent.find((e:any)=>e.type==='pcb_breakout_point'&&e.pcb_breakout_point_id===p.pointId),saved=parent.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id===exit?.source_trace_id&&e.route.at(-1)?.layer===p.layer&&Math.hypot(e.route.at(-1).x-p.x,e.route.at(-1).y-p.y)<1e-7);if(!saved)throw Error('Missing actual strobe escape');return n+planar(saved.route)},0)}),actualStrobeMean=actualStrobeLengths.reduce((a,b)=>a+b,0)/2
if(!Number.isFinite(target)||Math.abs(actualStrobeMean-target)>1e-7)throw Error('Strobe target differs from actual copper')
if(Math.abs(beforeMm-22.054968859952975)>1e-6||delta<=0)throw Error('Actual DM1 length differs')
const rotated={...before,route:[...before.route].reverse()},attempts:any[]=[],started=Date.now();let accepted:any=null
search:for(const entry of[-1,-.5])for(const exit of[-2,-2.5])for(const sign of[1,-1]){
 if(Date.now()-started>55000)break
 let detour:any;try{detour=addWestwardTuningExcursion(rotated,1,entry,exit,delta,sign,.2)}catch{continue}
 const after={...before,route:[...detour.route].reverse()},fixed=parent.filter((e:any)=>e.type!=='pcb_trace'||e.pcb_trace_id!==before.pcb_trace_id),r=verifyDdrSystemCopper(fixed,[after],[],{},0),self=auditHostSelfContacts([after]),clean=!r.errors.length&&!r.violations.length&&r.angles.valid&&!r.joinedBends.length&&self.valid
 attempts.push({entry,exit,sign,clean,errors:r.errors,violations:r.violations.length,selfContacts:self.contacts.length})
 if(!clean)continue
 const candidate=parent.map((e:any)=>e===before?after:e),traces=host.traces.map((t:any)=>t.pcb_trace_id===before.pcb_trace_id?after:t),topology=auditCompositeHostTopology(candidate,traces,input.connections),selfContacts=auditHostSelfContacts(traces),allAngles=auditRouteAngles(candidate.filter((e:any)=>e.type==='pcb_trace')),allJunctions=auditDdrTraceJunctions(candidate,input.connections),terminal=checkHostTerminalContract(traces,input.connections.filter((c:any)=>traces.some((t:any)=>t.connection_name===c.name))),measuredMm=fixedMm+planar(after.route)
 if(!topology.valid||!selfContacts.valid||!allAngles.valid||!allJunctions.valid||!terminal.valid)continue
 if(Math.abs(measuredMm-target)>1e-7||objectHash(after.route[0])!==objectHash(before.route[0])||objectHash(after.route.at(-1))!==objectHash(before.route.at(-1))||objectHash(after.route.filter((p:any)=>p.route_type==='via'))!==objectHash(before.route.filter((p:any)=>p.route_type==='via'))||after.route.filter((p:any)=>p.route_type==='wire').some((p:any)=>p.width!==.12))throw Error('Template changed actual endpoints/vias/width or target')
 accepted={candidate,traces,after,measuredMm,topology,selfContacts,allAngles,allJunctions,terminal,recipe:{entry,exit,sign,addedMm:delta,reversedForWestwardHelper:true,bevelMm:.2}};break search
}
mkdirSync(out,{recursive:true});const write=(n:string,v:any)=>writeFileSync(`${out}/${n}`,JSON.stringify(v,null,2));for(const[p,h]of hashes)if(fh(p)!==h)throw Error('Parent inputs changed')
if(accepted){const manifest={captureHash:host.captureHash,parentDirectory:dir,parentCircuitSha256:objectHash(parent),candidateCircuitSha256:objectHash(accepted.candidate),inputHashes:Object.fromEntries(hashes),fixedWitnesses,replacements:[{id:`pcb_trace:${before.pcb_trace_id}`,before,after:accepted.after,beforeSha256:objectHash(before),afterSha256:objectHash(accepted.after),reason:'Existing45degree excursion on DM1 inner2 horizontal run; preserve the via-free host and actual endpoints.'}]},preservation=validateDeclaredDdrReplacements(parent,accepted.candidate,manifest);write('candidate.circuit.json',accepted.candidate);write('host-bundle.json',{...host,traces:accepted.traces});write('original-copper-replacements.json',manifest);write('report.json',{captureHash:host.captureHash,accepted:true,beforeMm,actualStrobeLengths,actualStrobeMean,targetMm:target,measuredMm:accepted.measuredMm,attempts,recipe:accepted.recipe,preservation,topology:accepted.topology,selfContacts:accepted.selfContacts,allAngles:accepted.allAngles,allJunctions:accepted.allJunctions,terminal:accepted.terminal,scope:'OneDM1host retuned, all other hosts/source copper exact. Planar matching only; viadelay/SI/fullbyte completeness remainunqualified.'})}else write('report.json',{accepted:false,attempts,inputHashes:Object.fromEntries(hashes)})
console.log(JSON.stringify({accepted:Boolean(accepted),attempts:attempts.length,beforeMm,targetMm:target,measuredMm:accepted?.measuredMm,candidateHash:accepted?objectHash(accepted.candidate):null}))