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-dq7-ordered-mask.ts

/** One bounded existing-template search for DQ7, reserving approved DQS0/DQ4 proposals. */
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{auditCompositeHostTopology}from'./ddr-composite-routing-context'
import{verifyDdrSystemCopper,auditDdrTraceJunctions}from'./check-ddr-system-copper'
import{auditRouteAngles}from'./check-route-angles'
import{checkHostTerminalContract}from'./route-ddr-sequential'
const dir=resolve('dist/ddr-dq7-ordered-host'),out=resolve('dist/ddr-dq7-ordered-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`),host=read(`${dir}/host-bundle.json`),input=read(`${dir}/routing-input.json`),beforeLengths=read(`${dir}/host-route-report.json`).lengths,dqs=read('dist/ddr-dqs0-shorter/replacements.json'),dqsReport=read('dist/ddr-dqs0-shorter/report.json'),dq4=read('dist/ddr-dq4-ordered-retuned/original-copper-replacements.json'),dq4Report=read('dist/ddr-dq4-ordered-retuned/report.json'),target=28.423158,delta=target-beforeLengths.fullPlanarMm,reserved=[...dqs,...dq4.replacements]
if(!dqsReport.accepted||!dq4Report.accepted||delta<=0||target>beforeLengths.nominalMm)throw Error('Invalid tuning target/reserved proposals')
let base=structuredClone(parent)
for(const r of reserved){const i=base.findIndex((e:any)=>e.type==='pcb_trace'&&e.pcb_trace_id===r.before.pcb_trace_id);if(objectHash(base[i])!==objectHash(r.before))throw Error('Reservation before witness mismatch');base[i]=r.after}
const before=parent.find((e:any)=>e.type==='pcb_trace'&&e.source_trace_id==='source_trace_582'),reversed={...before,route:[...before.route].reverse()},attempts:any[]=[],started=Date.now();let accepted:any=null
search:for(let index=0;index<reversed.route.length-1;index++)for(const sign of[-1,1])for(const entry of[2.2,1.8,1.4,1])for(const exit of[-.6,-.2,.2]){
 if(Date.now()-started>55000)break search
 let tuned:any;try{tuned=addWestwardTuningExcursion(reversed,index,entry,exit,delta,sign)}catch{continue}
 const after={...before,route:[...tuned.route].reverse()},fixed=base.filter((e:any)=>e.type!=='pcb_trace'||e.pcb_trace_id!==before.pcb_trace_id),r=verifyDdrSystemCopper(fixed,[after],[],{},0)
 const clean=!r.errors.length&&!r.violations.length&&r.angles.valid&&!r.joinedBends.length
 attempts.push({index,sign,entry,exit,clean,errors:r.errors,violations:r.violations.length})
 if(!clean)continue
 const candidate=base.map((e:any)=>e.type==='pcb_trace'&&e.pcb_trace_id===before.pcb_trace_id?after:e),ids=new Set(host.traces.map((t:any)=>t.pcb_trace_id)),traces=candidate.filter((e:any)=>e.type==='pcb_trace'&&ids.has(e.pcb_trace_id)),topology=auditCompositeHostTopology(candidate,traces,input.connections),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)))
 if(!topology.valid||!allAngles.valid||!allJunctions.valid||!terminal.valid)continue
 const planar=(route:any[])=>route.slice(1).reduce((n,p,i)=>n+(p.route_type==='wire'&&route[i].route_type==='wire'&&p.layer===route[i].layer?Math.hypot(p.x-route[i].x,p.y-route[i].y):0),0),measured=beforeLengths.ramMm+planar(after.route)+beforeLengths.cpuMm
 if(Math.abs(measured-target)>1e-7||objectHash(after.route[0])!==objectHash(before.route[0])||objectHash(after.route.at(-1))!==objectHash(before.route.at(-1))||after.route.some((p:any)=>p.route_type!=='wire'||p.layer!=='inner4'||p.width!==.12))throw Error('Template changed endpoint/layer/width/via or length')
 accepted={candidate,traces,after,topology,allAngles,allJunctions,terminal,measured,recipe:{index,sign,entry,exit,addedMm:delta,reversedForWestwardTemplate:true}};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('Input changed during search')
if(accepted){
 const replacements=[...reserved.map((r:any)=>({id:`pcb_trace:${r.before.pcb_trace_id}`,before:r.before,after:r.after,beforeSha256:objectHash(r.before),afterSha256:objectHash(r.after),reason:'Explicit approved DQS0/DQ4 reservation included in combined clearance check.'})),{id:`pcb_trace:${before.pcb_trace_id}`,before,after:accepted.after,beforeSha256:objectHash(before),afterSha256:objectHash(accepted.after),reason:'Add existing chamfered tuning template to DQ7 to match orderedDM0 target.'}],manifest={captureHash:host.captureHash,parentDirectory:dir,parentCircuitSha256:objectHash(parent),candidateCircuitSha256:objectHash(accepted.candidate),inputHashes:Object.fromEntries(hashes),replacements},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('dq7-replacement.json',replacements.at(-1));write('report.json',{captureHash:host.captureHash,accepted:true,beforeLengths,targetMm:target,measuredFullMm:accepted.measured,recipe:accepted.recipe,attempts,preservation,topology:accepted.topology,allAngles:accepted.allAngles,allJunctions:accepted.allJunctions,terminal:accepted.terminal,scope:'Combined DQS0/DQ4 proposals reserved; DQ7 only newly tuned. Other source geometry unchanged; remaining byte timing unqualified.'})
}else write('report.json',{accepted:false,attempts,inputHashes:Object.fromEntries(hashes)})
console.log(JSON.stringify({accepted:Boolean(accepted),attempts:attempts.length,beforeMm:beforeLengths.fullPlanarMm,afterMm:accepted?.measured,delta,hosts:accepted?.traces.length,candidateHash:accepted?objectHash(accepted.candidate):null}))