astra/am3352-sbc
A 4-layer AM3352 single-board computer with 128‑MiB DDR3, PMIC power regulation, USB‑C 5‑V PD input, dual USB host ports, HDMI output with ESD protection, microSD/UART/JTAG interfaces, addressable RGB indicators, and a PWM-driven buzzer.
- Version
- 0.1.19
- License
- unset
- Stars
- 0
scripts/optimize-ddr-byte-pins.ts
/** Experimental candidate-only DQ permutation. Strobes, masks, bytes and all
* address/control pins are kept fixed. Acceptance must explicitly integrate the
* resulting RAM mapping into the netlist before native verification.
*/
export function optimizeBytePins(input:any,names:Record<string,string>,preserveFirstBit=false) {
const ramDqMap=Array.from({length:16},(_,i)=>i);
const orient=(p:any,q:any,r:any)=>(q.x-p.x)*(r.y-p.y)-(q.y-p.y)*(r.x-p.x);
const cross=(a:any,b:any,c:any,d:any)=>orient(a,b,c)*orient(a,b,d)<-1e-8&&orient(c,d,a)*orient(c,d,b)<-1e-8;
for(const byte of [0,1]){
const bits=Array.from({length:8},(_,i)=>input.connections.find((c:any)=>names[c.name]===`DDR_D${byte*8+i}`));
const fixed=input.connections.filter((c:any)=>[`DDR_DQM${byte}`,`DDR_DQS${byte}`,`DDR_DQSn${byte}`].includes(names[c.name]));
const terminals=bits.map(c=>structuredClone(c.pointsToConnect[1]));
let best:number[]=[],bestCost=Infinity;
const visit=(perm:number[],cost:number)=>{
if(cost>=bestCost)return;
if(perm.length===8){best=[...perm];bestCost=cost;return;}
const i=perm.length,a=bits[i].pointsToConnect[0];
for(let j=0;j<8;j++)if(!perm.includes(j)){
// Preserve DQ0 of each physical byte for conservative MPR/training compatibility.
if(preserveFirstBit&&((i===0)!==(j===0)))continue;
const b=terminals[j];let extra=Math.hypot(a.x-b.x,a.y-b.y);
for(const f of fixed)if(cross(a,b,...f.pointsToConnect as [any,any]))extra+=1000;
for(let k=0;k<i;k++)if(cross(a,b,bits[k].pointsToConnect[0],terminals[perm[k]]))extra+=1000;
visit([...perm,j],cost+extra);
}
};
visit([],0);
for(let i=0;i<8;i++){
bits[i].pointsToConnect[1]=terminals[best[i]];
ramDqMap[byte*8+best[i]]=byte*8+i;
const p=terminals[best[i]];
const pad=input.obstacles.find((o:any)=>o.circuitJsonMetadata?.pcb_port_id===p.pcb_port_id);
if(!pad)throw Error('DQ permutation lacks RAM pad');
pad.connectedTo=[pad.circuitJsonMetadata.pcb_smtpad_id,p.pcb_port_id,bits[i].name];
}
}
return ramDqMap;
}