Source code for jitxlib.landpatterns.generators.bga
"""
The BGA Landpattern Generator
=============================
BGA (Ball Grid Array) packages use an array of solder balls on the bottom
surface instead of peripheral leads. This module provides generators for
creating BGA landpatterns with customizable grid configurations.
The BGA landpattern has three entry points:
- :py:class:`~BGA`: Complete generator with A1 alphanumeric numbering
(rows A-Z, columns 1-N, e.g., ``.p['A1']``, ``.p['B3']``)
- :py:class:`~BGADecorated`: With silkscreen but no numbering scheme
- :py:class:`~BGABase`: Basic pads only
Constructor Parameters:
num_rows: Number of rows in the ball grid (vertical)
num_cols: Number of columns in the ball grid (horizontal)
ball_diameter: Diameter of solder balls (typical: 0.3-0.6mm)
pitch: Center-to-center spacing between balls (typical: 0.4-1.27mm)
>>> from jitx import Component, Port
>>> from jitxlib.landpatterns.generators.bga import BGA
>>>
>>> class MyBGA(Component):
... # 10x10 BGA = 100 balls
... pins = {f'{chr(65+r)}{c+1}': Port() for r in range(10) for c in range(10)}
... def __init__(self):
... self.landpattern = BGA(
... num_rows=10,
... num_cols=10,
... ball_diameter=0.4, # 0.4mm balls
... pitch=0.8, # 0.8mm pitch
... )
Note:
BGA packages require careful PCB design for routing escape paths.
Consider via-in-pad or dog-bone patterns for dense arrays.
"""
from collections.abc import Iterable
from jitx.anchor import Anchor
from jitx.shapes.primitive import Circle
from jitx.transform import Transform
from ..courtyard import ExcessCourtyard
from ..grid_layout import A1, AlphaDictNumbering, GridLandpatternGenerator, GridPosition
from ..grid_planner import GridPlannerMixin
from ..pads import GridPadShapeGeneratorMixin
from ..silkscreen.labels import ReferenceDesignatorMixin
from ..silkscreen.marker import Pad1Marker
from ..silkscreen.outlines import SilkscreenOutline
[docs]
class BGABase(
GridPlannerMixin,
GridPadShapeGeneratorMixin,
GridLandpatternGenerator,
):
"""BGA Landpattern Generator Base"""
def __init__(
self,
num_rows: int,
num_cols: int,
ball_diameter: float,
pitch: float | tuple[float, float],
):
super().__init__()
self._num_rows = num_rows
self._num_cols = num_cols
# self.__ball_diameter = ball_diameter
if not isinstance(pitch, tuple):
pitch = (pitch, pitch)
assert len(pitch) == 2, "pitch must be a tuple of two values"
self.__pitch = pitch
self.pad_shape(Circle(diameter=ball_diameter))
def _generate_layout(self) -> Iterable[GridPosition]:
num_rows = self._num_rows
num_cols = self._num_cols
hpitch, vpitch = self.__pitch
center_row = (num_rows - 1) / 2.0
center_col = (num_cols - 1) / 2.0
# TODO: not sure how to handle this, anchoring is useful for creating
# sub-landpatterns that can be placed relative to an anchor; but I
# don't know what the anchor point should be. Center of the grid
# position at the appropriate corner?
# half_width = pitch * (num_cols - 1) / 2.0
# half_height = pitch * (num_rows - 1) / 2.0
# bounds = (-half_width, -half_height, half_width, half_height)
# center_x, center_y = self._get_anchor().flip().to_point(bounds)
center_x, center_y = 0, 0
for r in range(num_rows):
row_y = (center_row - r) * vpitch + center_y
for c in range(num_cols):
x = (c - center_col) * hpitch + center_x
yield GridPosition(r, c, Transform.translate(x, row_y))
[docs]
class BGADecorated(
SilkscreenOutline, Pad1Marker, ReferenceDesignatorMixin, ExcessCourtyard, BGABase
):
def __base_init__(self):
super().__base_init__()
self.pad_1_marker_direction(Anchor.W)
[docs]
class BGA(A1, AlphaDictNumbering, BGADecorated):
"""BGA Landpattern Generator"""