From ad33d0f8081b83be0a24ce614d763ed0444ef893 Mon Sep 17 00:00:00 2001 From: Andrew Guthrie Date: Mon, 3 Jun 2024 12:10:10 +0000 Subject: [PATCH] Allow different indium bump types --- .../python/kqcircuits/chips/chip.py | 12 ++++-- klayout_package/python/kqcircuits/defaults.py | 2 + .../elements/flip_chip_connectors/__init__.py | 4 +- .../flip_chip_connector.py | 22 ++++------- .../flip_chip_connector_dc.py | 14 ++++++- .../flip_chip_connector_rf.py | 39 +++++++------------ 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/klayout_package/python/kqcircuits/chips/chip.py b/klayout_package/python/kqcircuits/chips/chip.py index 10babaf76..3f9cbebe6 100644 --- a/klayout_package/python/kqcircuits/chips/chip.py +++ b/klayout_package/python/kqcircuits/chips/chip.py @@ -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, @@ -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. @@ -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] diff --git a/klayout_package/python/kqcircuits/defaults.py b/klayout_package/python/kqcircuits/defaults.py index eb511cfcb..b8073403a 100644 --- a/klayout_package/python/kqcircuits/defaults.py +++ b/klayout_package/python/kqcircuits/defaults.py @@ -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 = [ diff --git a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/__init__.py b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/__init__.py index 580e3f7c8..773f17ac2 100644 --- a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/__init__.py +++ b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/__init__.py @@ -20,7 +20,5 @@ """PCell classes for flip-chip connectors.""" connector_type_choices = [ - "Single", - "GSG", - "Coax", + "Flip Chip Connector Dc", ] diff --git a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector.py b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector.py index 5ab954b3e..5774a507e 100644 --- a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector.py +++ b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector.py @@ -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): @@ -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] diff --git a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_dc.py b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_dc.py index 511c4e24c..d629c66fa 100644 --- a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_dc.py +++ b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_dc.py @@ -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): @@ -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 diff --git a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_rf.py b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_rf.py index 6ee228949..e9981f4f5 100644 --- a/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_rf.py +++ b/klayout_package/python/kqcircuits/elements/flip_chip_connectors/flip_chip_connector_rf.py @@ -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") @@ -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, @@ -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 = [ @@ -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, @@ -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):