Skip to content

Commit

Permalink
Allow different indium bump types
Browse files Browse the repository at this point in the history
  • Loading branch information
theandyguthrie committed Jun 3, 2024
1 parent 08d7d8a commit ad33d0f
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 47 deletions.
12 changes: 8 additions & 4 deletions klayout_package/python/kqcircuits/chips/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@
from kqcircuits.test_structures.stripes_test import StripesTest
from kqcircuits.util.groundgrid import make_grid
from kqcircuits.elements.tsvs.tsv import Tsv
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector_dc import FlipChipConnectorDc
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector_rf import FlipChipConnectorRf
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector import FlipChipConnector


@add_parameters_from(Tsv, "tsv_type")
@add_parameters_from(FlipChipConnectorRf, "connector_type")
@add_parameters_from(FlipChipConnector, "bump_type")
@add_parameter(ChipFrame, "box", hidden=True)
@add_parameters_from(
ChipFrame,
Expand Down Expand Up @@ -403,6 +402,11 @@ def get_ground_bump_locations(self, bump_box):
"""
return self.make_grid_locations(bump_box, delta_x=self.bump_grid_spacing, delta_y=self.bump_grid_spacing)

@classmethod
def _get_ground_bump_element(cls):
"""Return the element which will be used for the ground bumps"""
return FlipChipConnector

def _produce_ground_bumps(self, faces=[0, 1]): # pylint: disable=dangerous-default-value
"""Produces a grid of indium bumps between given faces.
Expand All @@ -417,7 +421,7 @@ def _produce_ground_bumps(self, faces=[0, 1]): # pylint: disable=dangerous-defa
existing_bump_count = existing_bump_region.merged().count()

# Specify bump element, filter regions, and locations
bump = self.add_element(FlipChipConnectorDc, face_ids=[self.face_ids[face] for face in faces])
bump = self.add_element(self._get_ground_bump_element(), face_ids=[self.face_ids[face] for face in faces])
shape_layers = [("underbump_metallization", face) for face in faces]
filter_regions = self.get_filter_regions(
[("ground_grid_avoidance", face, 0) for face in faces]
Expand Down
2 changes: 2 additions & 0 deletions klayout_package/python/kqcircuits/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
default_marker_type = "Marker Standard"
default_junction_test_pads_type = "Junction Test Pads Simple"
default_tsv_type = "Tsv Standard"
default_bump_type = "Flip Chip Connector Dc"


# Default list of Elements to break down before netlist export.
default_netlist_breakdown = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,5 @@
"""PCell classes for flip-chip connectors."""

connector_type_choices = [
"Single",
"GSG",
"Coax",
"Flip Chip Connector Dc",
]
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
# and organizations (meetiqm.com/iqm-organization-contributor-license-agreement).

from kqcircuits.elements.element import Element
from kqcircuits.util.geometry_helper import circle_polygon
from kqcircuits.util.parameters import Param, pdt
from kqcircuits.defaults import default_bump_parameters
from kqcircuits.defaults import default_bump_type, default_bump_parameters
from kqcircuits.elements.flip_chip_connectors import connector_type_choices


class FlipChipConnector(Element):
Expand All @@ -29,20 +29,14 @@ class FlipChipConnector(Element):
Origin is at the geometric center.
"""

default_type = default_bump_type
ubm_diameter = Param(
pdt.TypeDouble, "Under-bump metalization diameter", default_bump_parameters["under_bump_diameter"], unit="μm"
)
bump_diameter = Param(pdt.TypeDouble, "Bump diameter", default_bump_parameters["bump_diameter"], unit="μm")
bump_type = Param(pdt.TypeString, "Bump type", default_bump_type, choices=connector_type_choices)

def create_bump_connector(self):
ubm_shape = circle_polygon(self.ubm_diameter / 2, self.n)
self.cell.shapes(self.get_layer("underbump_metallization", 0)).insert(ubm_shape)
self.cell.shapes(self.get_layer("underbump_metallization", 1)).insert(ubm_shape)

avoidance_shape = circle_polygon(self.ubm_diameter / 2 + self.margin, self.n)
self.cell.shapes(self.get_layer("ground_grid_avoidance", 0)).insert(avoidance_shape)
self.cell.shapes(self.get_layer("ground_grid_avoidance", 1)).insert(avoidance_shape)

bump_shape = circle_polygon(self.bump_diameter / 2, self.n)
self.cell.shapes(self.get_layer("indium_bump", 0)).insert(bump_shape) # bottom In bump
self.cell.shapes(self.get_layer("indium_bump", 1)).insert(bump_shape) # top In bump
@classmethod
def create(cls, layout, library=None, bump_type=None, **parameters):
"""Create a bump cell in layout."""
return cls.create_subtype(layout, library, bump_type, **parameters)[0]
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@


from kqcircuits.elements.flip_chip_connectors.flip_chip_connector import FlipChipConnector
from kqcircuits.util.geometry_helper import circle_polygon


class FlipChipConnectorDc(FlipChipConnector):
Expand All @@ -27,4 +28,15 @@ class FlipChipConnectorDc(FlipChipConnector):
"""

def build(self):
self.create_bump_connector()

ubm_shape = circle_polygon(self.ubm_diameter / 2, self.n)
self.cell.shapes(self.get_layer("underbump_metallization", 0)).insert(ubm_shape)
self.cell.shapes(self.get_layer("underbump_metallization", 1)).insert(ubm_shape)

avoidance_shape = circle_polygon(self.ubm_diameter / 2 + self.margin, self.n)
self.cell.shapes(self.get_layer("ground_grid_avoidance", 0)).insert(avoidance_shape)
self.cell.shapes(self.get_layer("ground_grid_avoidance", 1)).insert(avoidance_shape)

bump_shape = circle_polygon(self.bump_diameter / 2, self.n)
self.cell.shapes(self.get_layer("indium_bump", 0)).insert(bump_shape) # bottom In bump
self.cell.shapes(self.get_layer("indium_bump", 1)).insert(bump_shape) # top In bump
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,23 @@

from kqcircuits.elements.element import Element
from kqcircuits.elements.finger_capacitor_square import FingerCapacitorSquare
from kqcircuits.elements.flip_chip_connectors import connector_type_choices
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector import FlipChipConnector
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector_dc import FlipChipConnectorDc
from kqcircuits.elements.launcher import Launcher
from kqcircuits.pya_resolver import pya
from kqcircuits.util.parameters import Param, pdt, add_parameters_from


@add_parameters_from(FingerCapacitorSquare, "a2", "b2")
class FlipChipConnectorRf(FlipChipConnector):
@add_parameters_from(FlipChipConnector, bump_type="Flip Chip Connector Dc")
class FlipChipConnectorRf(Element):
"""PCell declaration for an inter-chip rf connector.
Flip chip connector with two coplanar waveguide connections and different ground bump configurations.
The input port is on the first face and on the left. The output port is on the second face and rotated as chosen.
About connector_type choices:
* ``Single``: the bump connects the two sides
* ``GSG``: ground-signal-ground indium bumps
* ``Coax``: signal transmitting bump is surrounded by four ground bumps
.. MARKERS_FOR_PNG 0,0 15,0 0,-40 -28,0
"""

connector_type = Param(pdt.TypeString, "Connector type", "Coax", choices=connector_type_choices)
inter_bump_distance = Param(pdt.TypeDouble, "Distance between In bumps", 100, unit="μm")
output_rotation = Param(pdt.TypeDouble, "Rotation of output port w.r.t. input port", 180, unit="degrees")
connector_a = Param(pdt.TypeDouble, "Conductor width at the connector area", 40, unit="μm")
Expand Down Expand Up @@ -120,15 +113,15 @@ def produce_shape(face, a, b, rotation, trace_rotation):

else:
# Taper geometry
s = self.ubm_diameter + (self.n_center_bumps - 1) * self.inter_bump_distance
trans = pya.DCplxTrans(1, 0, False, bump_ref["base"] + pya.DPoint(-self.ubm_diameter - s / 2, 0))
s = self.connector_a + (self.n_center_bumps - 1) * self.inter_bump_distance
trans = pya.DCplxTrans(1, 0, False, bump_ref["base"] + pya.DPoint(-self.connector_a - s / 2, 0))
tt = pya.DCplxTrans(1, self.output_rotation, False, 0, 0)
self.insert_cell(
Launcher,
trans,
self.face_ids[0],
s=s,
l=self.ubm_diameter,
l=self.connector_a,
a_launcher=self.connector_a,
b_launcher=self.connector_b,
launcher_frame_gap=self.connector_b,
Expand All @@ -141,7 +134,7 @@ def produce_shape(face, a, b, rotation, trace_rotation):
# Launcher's gap overlaps with the others center conductor.
add_metal = False
if int(self.output_rotation) not in (0, 180) and self.n_center_bumps > 1:
ubm = self.ubm_diameter
ubm = self.connector_a
ibm = self.inter_bump_distance
l = (self.n_center_bumps - 1) * ibm / 2
pts = [
Expand Down Expand Up @@ -177,7 +170,7 @@ def produce_shape(face, a, b, rotation, trace_rotation):
tt * trans,
self.face_ids[1],
s=s,
l=self.ubm_diameter,
l=self.connector_a,
a_launcher=self.connector_a,
b_launcher=self.connector_b,
launcher_frame_gap=self.connector_b,
Expand All @@ -191,19 +184,15 @@ def produce_shape(face, a, b, rotation, trace_rotation):

def _insert_ground_bumps(self, bump):
# Insert ground bumps
if self.connector_type == "GSG":
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, 0, self.inter_bump_distance))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, 0, -self.inter_bump_distance))
elif self.connector_type == "Coax":
dist_y = 0.5**0.5 * self.inter_bump_distance
dist_x = dist_y + self.inter_bump_distance * (self.n_center_bumps - 1) / 2
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, dist_x, dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, -dist_x, dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, dist_x, -dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, -dist_x, -dist_y))
dist_y = 0.5**0.5 * self.inter_bump_distance
dist_x = dist_y + self.inter_bump_distance * (self.n_center_bumps - 1) / 2
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, dist_x, dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, -dist_x, dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, dist_x, -dist_y))
self.insert_cell(bump, pya.DCplxTrans(1, 0, False, -dist_x, -dist_y))

def _get_bump(self):
return self.add_element(FlipChipConnectorDc, face_ids=self.face_ids)
return self.add_element(FlipChipConnector, face_ids=self.face_ids, bump_type=self.bump_type)

@classmethod
def get_sim_ports(cls, simulation):
Expand Down

0 comments on commit ad33d0f

Please sign in to comment.