0hmX/simplified-am62l-computer

This code defines components and scripts for physically representing and routing high-speed DDR memory signals, power lines, and ground planes on an 8-layer PCB with detailed pin assignments, copper pours, and precise via and trace layouts based on TI EVM reference data.

Version
1.0.16
License
unset
Stars
0

routing/fixed-target-bga-fanout-autorouter.ts

import { FixedTargetBgaFanoutSolver } from "@tscircuit/bga-fanout-solver"
import type {
  AutorouterCompleteEvent,
  AutorouterErrorEvent,
  AutorouterProgressEvent,
  GenericLocalAutorouter,
  SimpleRouteJson,
  SimplifiedPcbTrace,
} from "@tscircuit/core"

type ListenerMap = {
  complete: Array<(event: AutorouterCompleteEvent) => void>
  error: Array<(event: AutorouterErrorEvent) => void>
  progress: Array<(event: AutorouterProgressEvent) => void>
}

/** Adapts the synchronous fixed-target BGA solver to Core's autorouter API. */
class FixedTargetBgaFanoutAutorouter implements GenericLocalAutorouter {
  isRouting = false

  private stopped = false
  private outputSimpleRouteJson?: SimpleRouteJson
  private readonly listeners: ListenerMap = {
    complete: [],
    error: [],
    progress: [],
  }

  constructor(public readonly input: SimpleRouteJson) {}

  private solve() {
    const solver = new FixedTargetBgaFanoutSolver(this.input)
    solver.solve()
    if (solver.failed || !solver.solved) {
      throw new Error(solver.error ?? "Fixed-target BGA fanout failed")
    }
    const output = solver.getOutput()
    this.outputSimpleRouteJson = output.outputSimpleRouteJson
    return output.traces
  }

  start(): void {
    if (this.isRouting) {
      throw new Error("Fixed-target BGA fanout is already running")
    }

    this.isRouting = true
    this.stopped = false
    queueMicrotask(() => {
      if (this.stopped) return

      try {
        const traces = this.solve()
        if (this.stopped) return
        this.isRouting = false
        for (const listener of this.listeners.progress) {
          listener({
            type: "progress",
            steps: traces.length,
            progress: 1,
            phase: "fixed-target-bga-fanout",
          })
        }
        for (const listener of this.listeners.complete) {
          listener({ type: "complete", traces })
        }
      } catch (error) {
        this.isRouting = false
        const normalizedError =
          error instanceof Error ? error : new Error(String(error))
        for (const listener of this.listeners.error) {
          listener({ type: "error", error: normalizedError })
        }
      }
    })
  }

  stop(): void {
    this.stopped = true
    this.isRouting = false
  }

  on(
    event: "complete",
    callback: (event: AutorouterCompleteEvent) => void,
  ): void
  on(event: "error", callback: (event: AutorouterErrorEvent) => void): void
  on(
    event: "progress",
    callback: (event: AutorouterProgressEvent) => void,
  ): void
  on(
    event: keyof ListenerMap,
    callback:
      | ((event: AutorouterCompleteEvent) => void)
      | ((event: AutorouterErrorEvent) => void)
      | ((event: AutorouterProgressEvent) => void),
  ): void {
    this.listeners[event].push(callback as never)
  }

  solveSync(): SimplifiedPcbTrace[] {
    return this.solve()
  }

  getOutputSimpleRouteJson(): SimpleRouteJson | undefined {
    return this.outputSimpleRouteJson
  }
}

export const createFixedTargetBgaFanoutAutorouter = async (
  input: SimpleRouteJson,
): Promise<GenericLocalAutorouter> =>
  new FixedTargetBgaFanoutAutorouter(input)