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

tests/ddr-directions.test.ts

import { expect, test } from 'bun:test'
import { readFileSync } from 'node:fs'
import { DDR_PROFILES, validateDdrProfile, assertTightDdrBounds } from '../scripts/validate-ddr-profiles'
for (const profile of DDR_PROFILES) {
  test(`${profile}: actual saved geometry preserves sources, exits on requested side and passes full copper DRC`, () => {
    const report = validateDdrProfile(profile)
    expect(report.localGeometryChecksPass).toBe(true)
    expect(report.tightEnclosureVerified).toBe(true)
    expect(report.widthMm).toBeLessThan(25)
    expect(report.heightMm).toBeLessThan(25)
    expect(report.routeAngles.saved.valid).toBe(true)
    expect(report.routeAngles.fixed.valid).toBe(true)
    expect(report.routeAngles.saved.maximumTurnDegrees).toBeLessThanOrEqual(45.0001)
    expect(report.allCopperDrc.valid).toBe(true)
    expect(report.pairs.every(p => p.localPlanarSkewMm <= .127)).toBe(true)
    expect(report.compliant).toBe(false)
  })
}
test('profile validation rejects a missing via and moved processor source', () => {
  const paths = JSON.parse(readFileSync('src/generated/ddr_top.trace-paths.json', 'utf8'))
  const missingVia = structuredClone(paths)
  const clock = missingVia.find((p: any) => p.connection === 'U1.D1')
  clock.route = clock.route.filter((p: any) => p.route_type !== 'via')
  expect(() => validateDdrProfile('ddr_top', missingVia)).toThrow()
  paths.find((p: any) => p.connection === 'U1.D1').route[0].x += .8
  expect(() => validateDdrProfile('ddr_top', paths)).toThrow('source must remain')
})

test('DDR strict clearance includes neighbouring non-DDR copper', async () => {
  const { validateDdrCopper } = await import('../scripts/ddr-copper-check')
  const makeTrace = (name: string, y: number, width: number) => ({
    type: 'pcb_trace', pcb_trace_id: name, connection_name: name,
    route: [{ route_type: 'wire', x: 0, y, layer: 'top', width }, { route_type: 'wire', x: 1, y, layer: 'top', width }],
  })
  const ddr = makeTrace('ddr', 0, .1016)
  // 0.09 mm copper gap passes global 0.0762 mm but fails DDR 0.1016 mm.
  const other = makeTrace('non-ddr', .18144, .08128)
  const input = { layerCount: 2, bounds: { minX: -2, maxX: 2, minY: -2, maxY: 2 }, obstacles: [], traces: [], connections: [ddr, other].map(t => ({ name: t.connection_name, pointsToConnect: t.route })) }
  for (const traces of [[ddr, other], [other, ddr]]) {
    const report = validateDdrCopper(input, traces, [ddr])
    expect(report.drc.valid).toBe(true)
    expect(report.ddrDrc.valid).toBe(false)
    expect(report.ddrDrc.issues.some(i => i.code === 'different-net-trace-clearance')).toBe(true)
  }
})


test('tight enclosure rejects redundant padding even when exits are extended to the enlarged edge', () => {
  const input = JSON.parse(readFileSync('scripts/fixtures/ddr_top.input.json', 'utf8')).input
  const traces = JSON.parse(readFileSync('src/generated/ddr_top.trace-paths.json', 'utf8')).map((p: any) => ({ connection_name: p.connection, route: p.route }))
  const expanded = { ...input.bounds, maxX: input.bounds.maxX + .5 }
  for (const t of traces) if (Math.abs(t.route.at(-1).x - input.bounds.maxX) < 1e-6) t.route.at(-1).x = expanded.maxX
  expect(() => assertTightDdrBounds(input, traces, expanded)).toThrow('tight')
})