0hmX/am62l-lpddr4-breakout-repro
This code defines React components that instantiate circuits representing dedicated DDR address control and byte0 data lines.
- Version
- 1.0.11
- License
- unset
- Stars
- 0
single-ddr-bus-layout.tsx
import { MT53E1G16D1ZW, ballMap } from "@tsci/0hmX.mt53e1g16d1zw-footprint"
import { AM62L32, AM62L32BOGHAANBR } from "@tsci/tscircuit.ti"
import { Children, cloneElement, Fragment, isValidElement } from "react"
import { DDR_CONNECTIONS, type DdrBusName } from "./ddr-connections"
const AM62L_BALL_PITCH_MM = 0.5
const REQUIRED_ESCAPE_CHANNEL_MM = 0.24384
const AM62L_PAD_DIAMETER_MM =
AM62L_BALL_PITCH_MM - REQUIRED_ESCAPE_CHANNEL_MM
const AM62L_PAD_RADIUS_MM = AM62L_PAD_DIAMETER_MM / 2
const createAm62lEscapeFootprint = () => {
const defaultChip = AM62L32BOGHAANBR({} as any)
const defaultFootprint = defaultChip.props.footprint
return cloneElement(
defaultFootprint,
{},
Children.map(defaultFootprint.props.children, (child) =>
isValidElement(child) && child.type === "smtpad"
? cloneElement(child, { radius: `${AM62L_PAD_RADIUS_MM}mm` } as any)
: child,
),
)
}
const AM62L_ESCAPE_FOOTPRINT = createAm62lEscapeFootprint()
const SIGNAL_LAYERS = [
"top",
"inner1",
"inner2",
"inner3",
"inner4",
"inner5",
"inner6",
"bottom",
] as const
const BUS_CONFIGS = {
DDR_BYTE0: {
socPins: [76, 91, 92, 93, 94, 103, 104, 105, 121, 122, 123],
socDirection: "bottom_right",
ramDirection: "bottom_left",
fanoutGroups: [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
fanoutLayers: [undefined],
},
DDR_BYTE1: {
socPins: [236, 238, 255, 256, 257, 272, 273, 275, 276, 284, 285],
socDirection: "top_right",
ramDirection: "top_left",
// Group by physical AM62L ball row so each group can share one layer.
fanoutGroups: [
[1, 2],
[3, 4, 6],
[0, 5, 9, 10],
[7, 8],
],
fanoutLayers: ["inner2", "bottom", "inner3", "inner2"],
},
DDR_ADDR_CTRL: {
socPins: [124, 125, 139, 140, 149, 150, 162, 164, 165, 215, 216],
socDirection: "center_right",
ramDirection: "center_left",
fanoutGroups: [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
fanoutLayers: [undefined],
},
} as const
export const SingleDdrBusCircuit = ({ busName }: { busName: DdrBusName }) => {
const config = BUS_CONFIGS[busName]
const breakoutPadding = busName === "DDR_BYTE1" ? "2mm" : "1mm"
const connections = DDR_CONNECTIONS.filter(
(connection) => connection.busName === busName,
)
const fanoutBuses = config.fanoutGroups.map((connectionIndices, index) => ({
name: `${busName}_FANOUT_${index}`,
connections: connectionIndices.map(
(connectionIndex) => connections[connectionIndex]!.traceName,
),
preferredLayer: config.fanoutLayers[index],
routingPhaseIndex: index,
}))
const socFanoutDirections = Object.fromEntries(
fanoutBuses.map((fanoutBus) => [
fanoutBus.name,
config.socDirection,
]),
)
const ramFanoutDirections = Object.fromEntries(
fanoutBuses.map((fanoutBus) => [
fanoutBus.name,
config.ramDirection,
]),
)
const usedSocPins = new Set<number>(config.socPins)
const socNoConnect = Array.from({ length: 373 }, (_, index) => index + 1)
.filter((pin) => !usedSocPins.has(pin))
.map((pin) => `pin${pin}`)
const usedMemorySignals = new Set(
connections.map(({ memorySignal }) => memorySignal),
)
const memoryNoConnect = ballMap
.map(({ signal }, index) => ({ signal, selector: `pin${index + 1}` }))
.filter(({ signal }) => !usedMemorySignals.has(signal))
.map(({ selector }) => selector)
return (
<board
name={`AM62L_LPDDR4_${busName}_ONLY`}
width="45.2mm"
height="25mm"
layers={8}
defaultTraceWidth="0.08128mm"
minTraceWidth="0.08128mm"
minTraceToPadEdgeClearance="0.05mm"
minViaEdgeToPadEdgeClearance="0.08128mm"
minViaHoleEdgeToViaHoleEdgeClearance="0.1016mm"
minViaHoleDiameter="0.1mm"
minViaPadDiameter="0.24mm"
pcbStyle={{ viaHoleDiameter: "0.1mm", viaPadDiameter: "0.24mm" }}
autorouter="beta_pipeline9"
autorouterEffortLevel="1x"
>
<breakout
name="SOC_BREAKOUT"
pcbX={-10}
pcbY={0}
padding={breakoutPadding}
fanoutRoutingLayers={[...SIGNAL_LAYERS]}
busFanoutDirections={socFanoutDirections}
>
<AM62L32
name="U1"
footprintVariant="fccsp_373_anb"
footprint={AM62L_ESCAPE_FOOTPRINT}
pcbX={0}
pcbY={0}
pcbRotation={180}
noSchematicRepresentation
noConnect={socNoConnect as any}
/>
</breakout>
<breakout
name="RAM_BREAKOUT"
pcbX={10.116917}
pcbY={-0.050917}
padding={breakoutPadding}
fanoutRoutingLayers={[...SIGNAL_LAYERS]}
busFanoutDirections={ramFanoutDirections}
>
<MT53E1G16D1ZW
name="U2"
pcbX={0}
pcbY={0}
pcbRotation={90}
noSchematicRepresentation
noConnect={memoryNoConnect as any}
/>
</breakout>
{/* Each shared bus is consumed by both breakout phases, so this single
preference assigns matching SoC and RAM escape layers. */}
{fanoutBuses.map((fanoutBus) => (
<Fragment key={fanoutBus.name}>
<bus
name={fanoutBus.name}
connections={fanoutBus.connections}
preferredLayer={fanoutBus.preferredLayer}
routingPhaseIndex={fanoutBus.routingPhaseIndex}
/>
</Fragment>
))}
{connections.map(({ socSignal, memorySignal, traceName }) => (
<Fragment key={traceName}>
<trace
name={traceName}
from={`U1.${socSignal}`}
to={`U2.${memorySignal}`}
/>
</Fragment>
))}
</board>
)
}