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/connect-ddr-zq-ground.ts

/** Explicit bottom-layer ZQ support validation; DDR host layer policy is unchanged. */
import {readFileSync,writeFileSync,mkdirSync,copyFileSync} from 'node:fs'
import {resolve} from 'node:path'
import {createHash} from 'node:crypto'
import {checkPadPadClearance,checkPadTraceClearance,checkViaPadClearance,checkViaTraceClearance,checkPcbComponentOverlap} from '@tscircuit/checks'
import {planDdrGroundAntipads} from './ddr-ground-plane-antipads'
import {refreshDdrPlaneContacts} from './ddr-plane-contact-audit'
import {verifyDdrSystemCopper,auditDdrTraceJunctions} from './check-ddr-system-copper'
import {planeCoverageIntervals} from './audit-ddr-host-reference-coverage'
import {auditRouteAngles} from './check-route-angles'
import {auditCompositeHostTopology} from './ddr-composite-routing-context'
const [parentArg,zqArg,outArg]=process.argv.slice(2);if(!outArg)throw Error('Usage: parent zq-placement output')
const parentDir=resolve(parentArg!),zqDir=resolve(zqArg!),out=resolve(outArg),bound=new Map<string,string>(),fh=(p:string)=>createHash('sha256').update(readFileSync(p)).digest('hex'),hash=(v:any)=>createHash('sha256').update(JSON.stringify(v)).digest('hex'),read=(p:string)=>{bound.set(p,fh(p));return JSON.parse(readFileSync(p,'utf8'))},parent=read(parentDir+'/candidate.circuit.json'),prior=read(parentDir+'/report.json'),placement=read(zqDir+'/candidate.circuit.json'),zq=read(zqDir+'/report.json'),host=read(parentDir+'/host-bundle.json'),input=read(parentDir+'/routing-input.json'),parentPower=read(parentDir+'/ram-power-launch-audit.json')
if(hash(parent)!==prior.candidateCircuitSha256||zq.parentCircuitSha256!==hash(parent)||hash(placement)!==zq.candidateCircuitSha256||host.traces.length<21||hash(host.traces)!==prior.hostTracesSha256||host.traces.some((t:any)=>hash(parent.find((e:any)=>e.pcb_trace_id===t.pcb_trace_id))!==hash(t)))throw Error('Source provenance mismatch')
const originalPlanes=placement.filter((e:any)=>e.type==='pcb_copper_pour'),groundPlanes=originalPlanes.filter((e:any)=>e.layer==='inner1'||e.layer==='inner5');if(groundPlanes.length!==2||groundPlanes.some((e:any)=>e.source_net_id!=='source_net_346'))throw Error('Unexpected authoritative ground planes')
const vias=zq.connections.map((r:any)=>({x:-19.2,y:r.groundPad.y,net:'foreign-ground'})),plan=planDdrGroundAntipads(originalPlanes.filter((e:any)=>e.layer==='inner3'),vias),candidate=placement.map((e:any)=>e.type==='pcb_copper_pour'&&e.layer==='inner3'?plan.planes[0]:e),added:any[]=[],returns:any[]=[]
for(const r of zq.connections){const id=`ddr_zq_ground_${r.byte}`,pad=r.groundPad,v= vias[r.byte];if(pad.layer!=='bottom'||Math.abs(pad.x+18.57005)>1e-7||Math.abs(v.y-[-5.6999,7.3001][r.byte])>1e-7)throw Error('Unexpected resistor ground pad')
 added.push({type:'source_trace',source_trace_id:id,connected_source_port_ids:[r.resistorGroundPort],connected_source_net_ids:['source_net_346']})
 const trace={type:'pcb_trace',pcb_trace_id:id,source_trace_id:id,route:[{route_type:'wire',x:pad.x,y:pad.y,width:.12,layer:'bottom',start_pcb_port_id:pad.pcb_port_id},{route_type:'wire',x:v.x,y:v.y,width:.12,layer:'bottom'},{route_type:'via',x:v.x,y:v.y,from_layer:'bottom',to_layer:'top',via_diameter:.4572,via_hole_diameter:.254}]};added.push(trace);returns.push(trace)
}
const componentCleanup=candidate.filter((e:any)=>e.type==='source_component'&&String(e.source_component_id).startsWith('ddr_zq_')).map((before:any)=>{const after={...before};delete after.tolerance;delete after.supplier_part_numbers;return{before,after}});for(const r of componentCleanup)candidate[candidate.indexOf(r.before)]=r.after;candidate.push(...added)
const referenceGroundRow=parentPower.rows.find((r:any)=>r.byte===0&&r.ball==='B2'&&r.planeContact&&r.launchWithin1524Mm),referenceGroundPad=parent.find((e:any)=>e.type==='pcb_smtpad'&&e.pcb_smtpad_id===referenceGroundRow?.padId);if(!referenceGroundPad?.pcb_port_id)throw Error('Missing verified source-owned RAM ground reference')
const support=candidate.filter((e:any)=>e.type==='pcb_trace'&&String(e.pcb_trace_id).startsWith('ddr_zq_')),fresh=[...host.traces,...support],ids=new Set(fresh.map((e:any)=>e.pcb_trace_id)),physical=verifyDdrSystemCopper(candidate.filter((e:any)=>!ids.has(e.pcb_trace_id)),fresh,input.connections,{},50),hostTopology=auditCompositeHostTopology(candidate,host.traces,input.connections),angles=auditRouteAngles(candidate.filter((e:any)=>e.type==='pcb_trace')),junctions=auditDdrTraceJunctions(candidate,input.connections)
const official=[...checkPadPadClearance(candidate,{minClearance:.1016}),...checkPadTraceClearance(candidate,{minClearance:.1016}),...checkViaPadClearance(candidate,{minClearance:.1016}),...checkViaTraceClearance(candidate,{minClearance:.1016}),...checkPcbComponentOverlap(candidate)].filter((e:any)=>JSON.stringify(e).includes('ddr_zq_'))
const conductorErrors=physical.errors.filter((e:string)=>e!=='New signal on forbidden layer bottom'),planeAudit=refreshDdrPlaneContacts(prior.planeAudit,candidate.filter((e:any)=>e.type==='pcb_copper_pour'),candidate)
const groundAudit=refreshDdrPlaneContacts(groundPlanes.map((p:any)=>({layer:p.layer,source_net_id:p.source_net_id,viaContacts:returns.map((t:any)=>({id:t.pcb_trace_id,...t.route.at(-1)}))})),groundPlanes,candidate)
const padConnections=zq.connections.flatMap((r:any)=>[{name:r.sourceTraceId,source_trace_id:r.sourceTraceId,pointsToConnect:[{pointId:r.ramPcbPort},{pointId:r.resistorSignalPcbPort}]},{name:`ddr_zq_ground_${r.byte}`,source_trace_id:`ddr_zq_ground_${r.byte}`,pointsToConnect:[{pointId:r.groundPad.pcb_port_id},{pointId:referenceGroundPad.pcb_port_id}]}]),padAudit=verifyDdrSystemCopper(candidate,[],padConnections,{},4)
const allReferenceRegressions:any[]=[];let comparedReferenceSegments=0;const beforeSupply=originalPlanes.find((p:any)=>p.layer==='inner3'),afterSupply=plan.planes[0];for(const t of candidate.filter((e:any)=>e.type==='pcb_trace'))for(let i=1;i<t.route.length;i++){const a=t.route[i-1],b=t.route[i];if(a.route_type!=='wire'||b.route_type!=='wire'||a.layer!==b.layer||!['inner2','inner4'].includes(a.layer))continue;comparedReferenceSegments++;const missing=(p:any)=>planeCoverageIntervals(a,b,p.brep_shape).filter((v:any)=>!v.covered).reduce((n:number,v:any)=>n+v.lengthMm,0),delta=missing(afterSupply)-missing(beforeSupply);if(delta>1e-7)allReferenceRegressions.push({traceId:t.pcb_trace_id,index:i,addedUncoveredMm:delta})}
const valid=!allReferenceRegressions.length&&!official.length&&!conductorErrors.length&&!physical.violations.length&&hostTopology.valid&&angles.valid&&junctions.valid&&padAudit.connectivity.length===4&&padAudit.connectivity.every((c:any)=>c.connected)
mkdirSync(out,{recursive:true});const write=(n:string,v:any)=>writeFileSync(out+'/'+n,JSON.stringify(v,null,2)+'\n');for(const[p,h]of bound)if(fh(p)!==h)throw Error('Input changed')
write('candidate.circuit.json',candidate);write('report.json',{...prior,accepted:false,supportGeometryQualified:valid,parentDirectory:parentDir,parentCircuitSha256:hash(parent),candidateCircuitSha256:hash(candidate),planeAudit,groundAudit,physical,hostTopology,allReferenceRegressions,comparedReferenceSegments,retainedHostCount:host.traces.length,angles,junctions,officialNewSupportErrors:official,conductorErrors,padAudit,addedSupport:added,sourceHashes:Object.fromEntries(bound),zqConnections:zq.connections.map((r:any)=>({...r,groundConnected:valid,groundVia:vias[r.byte]})),scope:'Explicit ZQ bottom support candidate. DDR host forbidden-bottom policy unchanged; all other conductor errors and official new support clearance errors reject. Fresh power/reference audit required before integration; resistor tolerance/BOM procurement remains explicit.'});write('support-replacements.json',{parentDirectory:parentDir,parentCircuitSha256:hash(parent),placementDirectory:zqDir,placementSha256:hash(placement),candidateCircuitSha256:hash(candidate),planeReplacements:originalPlanes.filter((p:any)=>p.layer==='inner3').map((before:any)=>({before,after:plan.planes[0]})),additions:added,componentCleanup});for(const n of ['host-bundle.json','routing-input.json'])copyFileSync(parentDir+'/'+n,out+'/'+n)
console.log(JSON.stringify({supportGeometryQualified:valid,officialErrors:official.length,conductorErrors:conductorErrors.length,clearanceViolations:physical.violations.length,padConnections:padAudit.connectivity,groundAnnuli:groundAudit.map((a:any)=>({layer:a.layer,contacts:a.viaContacts.length})),hosts:hostTopology.valid}));if(!valid)process.exitCode=1
if(valid){
 const byId=(e:any)=>`${e.type}:${e[`${e.type}_id`]}`,parentMap=new Map(parent.map((e:any)=>[byId(e),e])),candidateMap=new Map(candidate.map((e:any)=>[byId(e),e])),replacements=parent.filter((e:any)=>hash(e)!==hash(candidateMap.get(byId(e)))).map((before:any)=>({before,after:candidateMap.get(byId(before))})),additions=candidate.filter((e:any)=>!parentMap.has(byId(e)));if(replacements.length!==3||replacements.some((r:any)=>!r.after||!(r.before.type==='source_trace'&&zq.connections.some((z:any)=>z.sourceTraceId===r.before.source_trace_id)||r.before.type==='pcb_copper_pour'&&r.before.layer==='inner3')))throw Error('Unexpected original element change');write('original-copper-replacements.json',{parentDirectory:parentDir,parentCircuitSha256:hash(parent),candidateCircuitSha256:hash(candidate),replacements,additions,removals:[]});
 for(const script of ['scripts/audit-ddr-global-power-launches.ts','scripts/audit-ddr-host-reference-coverage.ts']){const p=Bun.spawn(['bun',script,out],{stdout:'ignore',stderr:'inherit'});if(await p.exited)throw Error(`Audit failed: ${script}`)}
 const power=JSON.parse(readFileSync(out+'/ram-power-launch-audit.json','utf8')),reference=JSON.parse(readFileSync(out+'/host-reference-coverage.json','utf8')),beforeReference=read(parentDir+'/host-reference-coverage.json')
 if(power.launchQualified!==parentPower.launchQualified||power.planeConnected!==parentPower.planeConnected||hash(reference.rows)!==hash(beforeReference.rows))throw Error('Power or host reference projection regression')
 const final=JSON.parse(readFileSync(out+'/report.json','utf8'));for(const g of groundAudit)final.planeAudit.find((a:any)=>a.layer===g.layer).viaContacts.push(...g.viaContacts)
 final.sourceHashes=Object.fromEntries(bound);final.originalCopperReplacementsSha256=hash(JSON.parse(readFileSync(out+'/original-copper-replacements.json','utf8')));final.accepted=true;final.powerNoRegression={qualified:power.launchQualified,planeConnected:power.planeConnected,auditSha256:hash(power)};final.referenceNoRegression={rowsExactlyPreserved:true,auditSha256:hash(reference)};final.scope='Isolated ZQ resistor ground/support geometry and connectivity accepted: all parent hosts and prior RAM power qualification preserved, source-owned bottom support explicitly checked without changing DDR host policy. FullDDR electrical qualification and resistor procurement remain incomplete.';for(const[p,h]of bound)if(fh(p)!==h)throw Error('Input changed');write('report.json',final)
}