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/assemble-ddr-dq0-timing.ts
/** Self-contained, exact-parent assembly of the independently verified DQ0 retune. */
import{readFileSync,writeFileSync,copyFileSync,mkdirSync}from'node:fs'
import{resolve}from'node:path'
import{createHash}from'node:crypto'
import{spawnSync}from'node:child_process'
import{verifyDdrCapture}from'./ddr-capture-provenance'
import{objectHash,validateDeclaredDdrReplacements}from'./improve-ddr-a9-power-launches'
import{auditCompositeHostTopology}from'./ddr-composite-routing-context'
import{auditHostSelfContacts}from'./audit-ddr-host-self-contacts'
import{auditDdrTraceJunctions}from'./check-ddr-system-copper'
import{auditRouteAngles}from'./check-route-angles'
import{checkHostTerminalContract}from'./route-ddr-sequential'
import{refreshDdrPlaneContacts}from'./ddr-plane-contact-audit'
import{convertCircuitJsonToPcbSvg}from'circuit-to-svg'
import{Resvg}from'@resvg/resvg-js'
const [parentArg='dist/ddr-eleven-byte0-partial-timing',trialArg='dist/ddr-dq0-retuned',outArg='dist/ddr-eleven-byte0-dq0-timing']=process.argv.slice(2),parentDir=resolve(parentArg),trialDir=resolve(trialArg),out=resolve(outArg),capture=resolve('dist/ddr-system/host-taps-54af3e346b5e'),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'))},{captureHash}=verifyDdrCapture(capture)
if(out===parentDir||out===trialDir)throw Error('Output must be isolated')
const parent=read(`${parentDir}/candidate.circuit.json`),prior=read(`${parentDir}/report.json`),priorManifest=read(`${parentDir}/original-copper-replacements.json`),priorHost=read(`${parentDir}/host-bundle.json`),input=read(`${parentDir}/routing-input.json`),priorPower=read(`${parentDir}/ram-power-launch-audit.json`),manifest=read(`${trialDir}/original-copper-replacements.json`),trial=read(`${trialDir}/report.json`),candidate=read(`${trialDir}/candidate.circuit.json`),host=read(`${trialDir}/host-bundle.json`)
if(!trial.accepted||[manifest,trial,host,prior].some(v=>v.captureHash!==captureHash)||manifest.replacements.length!==1||manifest.replacements[0].before.source_trace_id!=='source_trace_575'||prior.candidateCircuitSha256!==objectHash(parent)||prior.originalCopperReplacementsSha256!==objectHash(priorManifest)||priorPower.launchQualified!==56)throw Error('Parent/trial provenance differs')
for(const[p,h]of Object.entries(manifest.inputHashes)){if(fh(p)!==h)throw Error('Trial input hash changed');hashes.set(p,h as string)}
const preservation=validateDeclaredDdrReplacements(parent,candidate,manifest),change=manifest.replacements[0],expectedHost={...priorHost,traces:priorHost.traces.map((t:any)=>t.pcb_trace_id===change.before.pcb_trace_id?change.after:t)}
if(objectHash(host)!==objectHash(expectedHost)||host.traces.length!==11)throw Error('Unexpected host change')
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),fullLength=(name:string)=>{const connection=input.connections.find((c:any)=>c.name===name),t=host.traces.find((t:any)=>t.connection_name===name);if(!t||!connection)throw Error('Missing sourcehost');return planar(t.route)+connection.pointsToConnect.reduce((sum:number,p:any)=>{const exit=candidate.find((e:any)=>e.type==='pcb_breakout_point'&&e.pcb_breakout_point_id===p.pointId),saved=candidate.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(saved.length!==1)throw Error('Ambiguous actual sourceescape');return sum+planar(saved[0].route)},0)},strobeLengths=['source_trace_564','source_trace_565'].map(fullLength),strobeMean=strobeLengths.reduce((a,b)=>a+b,0)/2,dq0Mm=fullLength('source_trace_575')
if(Math.abs(strobeMean-prior.strobePair.meanMm)>1e-7||Math.abs(dq0Mm-strobeMean)>1e-7)throw Error('DQ0 does not match actual retained DQS0mean')
const topology=auditCompositeHostTopology(candidate,host.traces,input.connections),selfContacts=auditHostSelfContacts(host.traces),allAngles=auditRouteAngles(candidate.filter((e:any)=>e.type==='pcb_trace')),allJunctions=auditDdrTraceJunctions(candidate,input.connections),terminal=checkHostTerminalContract(host.traces,input.connections.filter((c:any)=>host.traces.some((t:any)=>t.connection_name===c.name))),planes=candidate.filter((e:any)=>e.type==='pcb_copper_pour'),planeAudit=refreshDdrPlaneContacts(prior.planeAudit,planes,candidate)
if(!topology.valid||!selfContacts.valid||!allAngles.valid||!allJunctions.valid||!terminal.valid||topology.physical.connectivity.filter(c=>c.connected).length!==11)throw Error('Full assembled host audit failed')
mkdirSync(out,{recursive:true});const write=(n:string,v:any)=>writeFileSync(`${out}/${n}`,JSON.stringify(v,null,2)+'\n'),copies=['ram-byte0-facing-progress.trace-paths.json','source-provenance.json','source-pair-report.json']
for(const n of copies){const p=`${parentDir}/${n}`;read(p);copyFileSync(p,`${out}/${n}`)}
const parentContract=read(`${parentDir}/exit-contract.json`),contract={...parentContract,...('candidateCircuitSha256' in parentContract?{candidateCircuitSha256:objectHash(candidate)}:{})},updatedInput={...input,traces:host.traces}
write('exit-contract.json',contract);write('routing-input.json',updatedInput);copyFileSync(`${parentDir}/routing-input.json`,`${out}/parent-routing-input.json`);copyFileSync(`${parentDir}/exit-contract.json`,`${out}/parent-exit-contract.json`)
copyFileSync(`${parentDir}/original-copper-replacements.json`,`${out}/parent-original-copper-replacements.json`)
const finalManifest={...manifest,inputHashes:Object.fromEntries(hashes)},finalReport={...prior,accepted:true,candidateCircuitSha256:objectHash(candidate),hostTracesSha256:objectHash(host.traces),hostBundleSha256:objectHash(host),supportCircuitSha256:objectHash(candidate),originalCopperReplacementsSha256:objectHash(finalManifest),parentReportSha256:objectHash(prior),parentAssemblyManifestSha256:objectHash(priorManifest),inheritedArtifacts:Object.fromEntries(copies.map(n=>[n,fh(`${parentDir}/${n}`)])),inputFileHashes:Object.fromEntries(hashes),dq0Evidence:{trial,change,preservation,actualFullPlanarMm:dq0Mm,actualDqs0LengthsMm:strobeLengths,actualDqs0MeanMm:strobeMean,skewMm:dq0Mm-strobeMean},physical:topology.physical,terminalContract:terminal,fullCandidateAngles:allAngles,fixedJunctionAudit:allJunctions,planeAudit,connectedHostCount:11,preservedHostCount:10,modifiedHostCount:1,exitContractProvenance:{parentSha256:objectHash(parentContract),currentSha256:objectHash(contract),geometryUnchanged:true,updatedFields:'candidateCircuitSha256' in parentContract?['candidateCircuitSha256']:[]},routingInputProvenance:{parentSha256:objectHash(input),currentSha256:objectHash(updatedInput),updatedFields:['traces']},scope:'Eleven actual topology-checked hosts; DQ0 retuned to retained DQS0mean. Parent cache/source provenance and prior assembly manifest preserved; routing-input host traces and exit-contract candidate hash refreshed with exact parent metadata copies.56RAMlaunches rechecked; fullDDR timing/SI incomplete.'}
write('candidate.circuit.json',candidate);write('host-bundle.json',host);write('original-copper-replacements.json',finalManifest);write('report.json',finalReport);write('topology-report.json',topology);write('host-self-contact-report.json',selfContacts)
const powerRun=spawnSync(process.execPath,[resolve('scripts/audit-ddr-global-power-launches.ts'),out,capture],{encoding:'utf8'});if(powerRun.status!==0)throw Error(powerRun.stderr)
const power=read(`${out}/ram-power-launch-audit.json`);if(power.total!==60||power.launchQualified!==56||power.planeConnected!==56||priorPower.rows.some((r:any)=>r.launchWithin1524Mm&&!power.rows.some((n:any)=>n.byte===r.byte&&n.ball===r.ball&&n.launchWithin1524Mm)))throw Error('Power audit changed')
Object.assign(finalReport,{launchAuditSha256:objectHash(power),launchQualified:56});write('report.json',finalReport)
for(const[p,h]of hashes)if(fh(p)!==h)throw Error(`Input changed ${p}`);if(verifyDdrCapture(capture).captureHash!==captureHash)throw Error('Capture changed')
for(const layer of['top','inner2','inner4']){const svg=convertCircuitJsonToPcbSvg(candidate,{layer:layer as any,width:1400,height:1000,viewport:{minX:-21,maxX:23,minY:-17,maxY:17},shouldDrawRatsNest:false});writeFileSync(`${out}/${layer}.svg`,svg);writeFileSync(`${out}/${layer}.png`,new Resvg(svg).render().asPng())}
console.log(JSON.stringify({out,candidateHash:objectHash(candidate),hosts:11,qualifiedPower:56,dq0Mm,strobeMean,skewMm:dq0Mm-strobeMean,topology:topology.valid,selfContacts:selfContacts.valid,allAngles:allAngles.valid,allJunctions:allJunctions.valid}))