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}))