diff --git a/sky130/cells/klayout/pymacros/README.md b/sky130/cells/klayout/pymacros/README.md
new file mode 100644
index 000000000..cd122659b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/README.md
@@ -0,0 +1,3 @@
+# Skywater130_PCells
+
+Contains klayout pcells generator.
diff --git a/sky130/cells/klayout/pymacros/cells/__init__.py b/sky130/cells/klayout/pymacros/cells/__init__.py
new file mode 100644
index 000000000..34a47f40a
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/__init__.py
@@ -0,0 +1,87 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+# ============================================================================
+# ---------------- Pcells Generators for Klayout of sky ----------------
+# ============================================================================
+
+import pya
+
+from cells.vias import vias_gen
+
+from .bjt import npn_bjt, pnp_bjt
+from .cap import cap_var, mim_cap
+from .diode import n_diode, p_diode, photo_diode
+from .fet import nfet, pfet
+from .gr import guard_ring_gen
+from .res_diff_klayout_panel import res_diff
+from .res_metal_klayout_panel import res_metal
+from .res_poly_klayout_panel import res_poly
+from .rf import rf_bjt, rf_coils, rf_mosfet
+from .vpp import cap_vpp
+
+
+# It's a Python class that inherits from the pya.Library class
+class sky130(pya.Library):
+ """
+ The library where we will put the PCell into
+ """
+
+ def __init__(self):
+ # Set the description
+ self.description = "sky130 Pcells"
+
+ # Create the PCell declarations
+ # MOS DEVICES
+ self.layout().register_pcell("pfet", pfet())
+ self.layout().register_pcell("nfet", nfet())
+
+ # BJT
+ self.layout().register_pcell(
+ "npn_bjt", npn_bjt()
+ ) # npn_05v5_1p00x1p00, npn_05v5_1p00x2p00 , npn_11v0_1p00x1p00
+ self.layout().register_pcell(
+ "pnp_bjt", pnp_bjt()
+ ) # pnp_05v5_0p68x0p68 , pnp_05v5_3p40x3p40
+
+ # CAP Devices
+ self.layout().register_pcell("cap_vpp", cap_vpp()) # VPP devices
+ self.layout().register_pcell("cap_var", cap_var()) # varactor devices
+ self.layout().register_pcell("mim_cap", mim_cap()) # mim cap devices
+
+ # DIODE DEVICES
+
+ self.layout().register_pcell("photodiode", photo_diode())
+ self.layout().register_pcell("n_diode", n_diode())
+ self.layout().register_pcell("p_diode", p_diode())
+
+ # RF Devices
+ self.layout().register_pcell("rf_mosfet", rf_mosfet()) # rf mosfets
+ self.layout().register_pcell("rf_bjt", rf_bjt()) # rf bjt
+ self.layout().register_pcell("rf_coils", rf_coils()) # rf coils
+
+ # vias
+ self.layout().register_pcell("vias_gen", vias_gen()) # vias generator
+ self.layout().register_pcell(
+ "guard_ring_gen", guard_ring_gen()
+ ) # vias generator
+
+ # Resistor
+ self.layout().register_pcell("res_diff", res_diff()) # Res diff generator
+ self.layout().register_pcell("res_poly", res_poly()) # Res poly generator
+ self.layout().register_pcell("res_metal", res_metal()) # Res metal generator
+
+ # Register us with the name "skywater130".
+ self.register("skywater130")
diff --git a/sky130/cells/klayout/pymacros/cells/bjt.py b/sky130/cells/klayout/pymacros/cells/bjt.py
new file mode 100644
index 000000000..f83986788
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/bjt.py
@@ -0,0 +1,112 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# BJT Generator for skywater130
+########################################################################################################################
+
+
+import pya
+
+from .draw_bjt import draw_npn, draw_pnp
+from .globals import BJT_NPN_DEV, BJT_PNP_DEV
+
+
+class npn_bjt(pya.PCellDeclarationHelper):
+ """
+ NPN BJT Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("type", self.TypeList, "type")
+
+ for i in BJT_NPN_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model",
+ self.TypeString,
+ "Model",
+ default="sky130_fd_pr__npn",
+ readonly=True,
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ # self.cell.flatten(1)
+ npn_instance = draw_npn(layout=self.layout, device_name=self.type)
+ write_cells = pya.CellInstArray(
+ npn_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+ self.layout.cleanup()
+
+
+class pnp_bjt(pya.PCellDeclarationHelper):
+ """
+ PNP BJT Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+
+ for i in BJT_PNP_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model",
+ self.TypeString,
+ "Model",
+ default="sky130_fd_pr__pnp",
+ readonly=True,
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ pnp_instance = draw_pnp(layout=self.layout, device_name=self.Type)
+ write_cells = pya.CellInstArray(
+ pnp_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+
+ self.layout.cleanup()
diff --git a/sky130/cells/klayout/pymacros/cells/cap.py b/sky130/cells/klayout/pymacros/cells/cap.py
new file mode 100644
index 000000000..1757b202b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/cap.py
@@ -0,0 +1,212 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# cap(Varactor-MIM) Generator for skywater130
+########################################################################################################################
+
+
+import pya
+
+from .draw_cap import draw_cap_var, draw_mim_cap
+
+l_min = 0.18
+w_min = 1
+grw_min = 0.17
+
+l_mim = 2
+l_mim2 = 2.16
+
+
+class cap_var(pya.PCellDeclarationHelper):
+ """
+ Cap(Varactor) Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__cap_var_lvt", "sky130_fd_pr__cap_var_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__cap_var_hvt", "sky130_fd_pr__cap_var_hvt"
+ )
+
+ self.param("l", self.TypeDouble, "length", default=l_min, unit="um")
+ self.param("w", self.TypeDouble, "width", default=w_min, unit="um")
+ self.param("tap_con_col", self.TypeInt, "tap Contacts Columns", default=1)
+
+ self.param("gr", self.TypeBoolean, "Gaurd Ring", default=0)
+ self.param(
+ "grw", self.TypeDouble, "Gaurd Ring Width", default=grw_min, unit="um"
+ )
+
+ self.param("nf", self.TypeDouble, "Number of Fingers", default=1)
+ # self.param("n", self.TypeDouble, "instance number", default=1)
+
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+ self.param("cap_value", self.TypeDouble, "Cap Value", readonly=True, unit="fF")
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "Varactor(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+ self.cap_value = 4.4 * self.area
+
+ if self.l < l_min:
+ self.l = l_min
+
+ if self.w < w_min:
+ self.w = w_min
+
+ if self.grw < grw_min:
+ self.grw = grw_min
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_cap_var(
+ layout=self.layout,
+ l_c=self.l,
+ w=self.w,
+ type=self.type,
+ tap_con_col=self.tap_con_col,
+ gr=self.gr,
+ grw=self.grw,
+ nf=self.nf,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
+
+
+class mim_cap(pya.PCellDeclarationHelper):
+ """
+ Cap(mim) Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__model__cap_mim", "sky130_fd_pr__model__cap_mim"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__model__cap_mim_m4", "sky130_fd_pr__model__cap_mim_m4"
+ )
+
+ self.param("l", self.TypeDouble, "length", default=l_mim, unit="um")
+ self.param("w", self.TypeDouble, "width", default=l_mim, unit="um")
+
+ # self.param("n", self.TypeInt, "instance number", default=1)
+
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+ self.param("cap_value", self.TypeDouble, "Cap Value", readonly=True, unit="fF")
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "mimcap(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+ self.cap_value = 2 * self.area
+
+ if self.type == "sky130_fd_pr__model__cap_mim_m4":
+ if self.l < l_mim2:
+ self.l = l_mim2
+
+ if self.w < l_mim2:
+ self.w = l_mim2
+ else:
+ if self.l < l_mim:
+ self.l = l_mim
+
+ if self.w < l_mim:
+ self.w = l_mim
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_mim_cap(
+ layout=self.layout, l_c=self.l, w=self.w, type=self.type
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/diode.py b/sky130/cells/klayout/pymacros/cells/diode.py
new file mode 100644
index 000000000..522ddba1c
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/diode.py
@@ -0,0 +1,268 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# DIODE Generator for skywater130
+########################################################################################################################
+
+
+import pya
+
+from .draw_diode import draw_diode, draw_photodiode
+from .globals import PHOTO_D_DEV
+
+
+class photo_diode(pya.PCellDeclarationHelper):
+ """
+ photo diode Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+
+ for i in PHOTO_D_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model",
+ self.TypeString,
+ "Model",
+ default="sky130_fd_pr__photodiode",
+ readonly=True,
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ ph_d_instance = draw_photodiode(layout=self.layout, device_name=self.Type)
+
+ write_cells = pya.CellInstArray(
+ ph_d_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+
+ self.layout.cleanup()
+
+
+d_min = 0.45
+grw_min = 0.17
+
+
+class n_diode(pya.PCellDeclarationHelper):
+ """
+ N-Diode Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pw2nd_05v5", "sky130_fd_pr__diode_pw2nd_05v5"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pw2nd_05v5_lvt", "sky130_fd_pr__diode_pw2nd_05v5_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pw2nd_05v5_nvt", "sky130_fd_pr__diode_pw2nd_05v5_nvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pw2nd_11v0", "sky130_fd_pr__diode_pw2nd_11v0"
+ )
+
+ self.param("w", self.TypeDouble, "width", default=d_min, unit="um")
+ self.param("l", self.TypeDouble, "length", default=d_min, unit="um")
+ self.param(
+ "cath_w", self.TypeDouble, "Cathode Width", default=grw_min, unit="um"
+ )
+
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+
+ # self.param("n", self.TypeInt, "n", default=1)
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "n_diode(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+
+ if self.l < d_min:
+ self.l = d_min
+
+ if self.w < d_min:
+ self.w = d_min
+
+ if self.cath_w < grw_min:
+ self.cath_w = grw_min
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_diode(
+ layout=self.layout,
+ d_type="n",
+ l_d=self.l,
+ w=self.w,
+ type=self.type,
+ cath_w=self.cath_w,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
+
+
+class p_diode(pya.PCellDeclarationHelper):
+ """
+ N-Diode Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pd2nw_05v5", "sky130_fd_pr__diode_pd2nw_05v5"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pd2nw_05v5_lvt", "sky130_fd_pr__diode_pd2nw_05v5_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pd2nw_05v5_hvt", "sky130_fd_pr__diode_pd2nw_05v5_hvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__diode_pd2nw_11v0", "sky130_fd_pr__diode_pd2nw_11v0"
+ )
+
+ self.param("w", self.TypeDouble, "width", default=d_min, unit="um")
+ self.param("l", self.TypeDouble, "length", default=d_min, unit="um")
+ self.param(
+ "cath_w", self.TypeDouble, "Cathode width", default=grw_min, unit="um"
+ )
+ self.param(
+ "grw", self.TypeDouble, "Gaurd Ring width", default=grw_min, unit="um"
+ )
+
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+
+ # self.param("n", self.TypeInt, "n", default=1)
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "p_diode(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+
+ if self.l < d_min:
+ self.l = d_min
+
+ if self.w < d_min:
+ self.w = d_min
+
+ if self.grw < grw_min:
+ self.grw = grw_min
+
+ if self.cath_w < grw_min:
+ self.cath_w = grw_min
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_diode(
+ layout=self.layout,
+ d_type="p",
+ l_d=self.l,
+ w=self.w,
+ type=self.type,
+ grw=self.grw,
+ cath_w=self.cath_w,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_bjt.py b/sky130/cells/klayout/pymacros/cells/draw_bjt.py
new file mode 100644
index 000000000..23955898e
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_bjt.py
@@ -0,0 +1,57 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## BJT Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+
+import os
+
+from .globals import BJT_NPN_DEV, BJT_PNP_DEV
+
+gds_p_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "fixed_devices/bjt"
+) # parent file path
+
+
+def draw_npn(layout, device_name):
+ """
+ drawing NPN devices
+ """
+ gds_path = f"{gds_p_path}/npn"
+
+ if device_name in BJT_NPN_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
+
+
+def draw_pnp(layout, device_name):
+ """
+ drawing PNP devices
+ """
+ gds_path = f"{gds_p_path}/pnp"
+
+ if device_name in BJT_PNP_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_cap.py b/sky130/cells/klayout/pymacros/cells/draw_cap.py
new file mode 100644
index 000000000..46d982f49
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_cap.py
@@ -0,0 +1,383 @@
+import gdsfactory as gf
+
+from .layers_def import (
+ cap2m_layer,
+ capm_layer,
+ hvtp_layer,
+ li_layer,
+ licon_layer,
+ m3_layer,
+ m4_layer,
+ m5_layer,
+ nsdm_layer,
+ nwell_layer,
+ poly_layer,
+ psdm_layer,
+ tap_layer,
+ via3_layer,
+ via4_layer,
+)
+from .via_generator import via_generator, via_stack
+
+
+def draw_cap_var(
+ layout,
+ type="sky130_fd_pr__cap_var_lvt",
+ l_c: float = 0.18,
+ w: float = 1,
+ tap_con_col: int = 1,
+ gr: int = 1,
+ grw: float = 0.17,
+ nf: int = 1,
+):
+ """
+ Retern varactor
+
+ Args:
+ layout : layout object
+ l_c : float of gate length
+ w : float of gate width
+ tap_con_col : int of tap contacts columns
+ gr : boolaen of having guard ring
+ grw : float of guard ring width
+ nf : integer of number of fingers
+
+
+ """
+
+ c = gf.Component("sky_cap_var_dev")
+
+ c_inst = gf.Component("dev inst")
+
+ # used dimensions and layers
+
+ end_cap = 0.15
+ con_size = (0.17, 0.17)
+ con_enc = (0.05, 0.08)
+ con_spacing = (0.17, 0.17)
+ con_t_enc = (0.06, 0.12)
+ gate_con_spacing = 0.195
+ tap_nsdm_enc = 0.125
+ nwell_enclosing = 0.18
+ tap_spacing = 0.27
+ hv_enc = 0.18
+ nwell_spacing = 1.27
+
+ # draw the channel tap and poly and thier contacts
+
+ tap_con = (
+ (tap_con_col * con_size[0])
+ + ((tap_con_col - 1) * con_size[0])
+ + 3 * con_t_enc[0]
+ )
+ tap_w = gate_con_spacing + tap_con
+
+ tap = c_inst.add_ref(
+ gf.components.rectangle(size=(l_c + 2 * tap_w, w), layer=tap_layer)
+ )
+
+ # adding nsdm
+ nsdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap.xmax - tap.xmin + 2 * tap_nsdm_enc,
+ tap.ymax - tap.ymin + 2 * tap_nsdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ nsdm.move((tap.xmin - tap_nsdm_enc, tap.ymin - tap_nsdm_enc))
+
+ tap_con = via_stack(
+ x_range=(0, tap_w - gate_con_spacing),
+ y_range=(0.06, w - 0.06),
+ base_layer=tap_layer,
+ metal_level=1,
+ )
+ c_inst.add_array(
+ component=tap_con,
+ columns=2,
+ rows=1,
+ spacing=(tap_w + l_c + gate_con_spacing, 0),
+ )
+
+ poly = c_inst.add_ref(
+ gf.components.rectangle(size=(l_c, w + 2 * end_cap), layer=poly_layer)
+ )
+ poly.move((tap_w, -end_cap))
+
+ if l_c < (con_size[0] + 2 * con_enc[0]):
+ pc_x = con_size[0] + 2 * con_enc[0]
+ else:
+ pc_x = l_c
+
+ pc_y = con_size[1] + 2 * con_enc[1]
+
+ c_pc = gf.Component("poly con")
+
+ rect_pc = c_pc.add_ref(gf.components.rectangle(size=(pc_x, pc_y), layer=poly_layer))
+
+ poly_con = via_stack(
+ x_range=(rect_pc.xmin, rect_pc.xmax),
+ y_range=(rect_pc.ymin, rect_pc.ymax),
+ base_layer=poly_layer,
+ metal_level=1,
+ li_enc_dir="H",
+ )
+ c_pc.add_ref(poly_con)
+
+ pc = c_inst.add_array(
+ component=c_pc, rows=2, columns=1, spacing=(0, pc_y + w + 2 * end_cap)
+ )
+ pc.move((tap_w - ((pc_x - l_c) / 2), -pc_y - end_cap))
+
+ # adding nwell
+ nwell = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(tap.xmax - tap.xmin + 2 * nwell_enclosing, pc.ymax - pc.ymin),
+ layer=nwell_layer,
+ )
+ )
+ nwell.move((tap.xmin - nwell_enclosing, pc.ymin))
+
+ # c.add_ref(c_inst)
+ c.add_array(
+ component=c_inst,
+ columns=1,
+ rows=nf,
+ spacing=(0, (c_inst.ymax - c_inst.ymin) + nwell_spacing),
+ )
+
+ if gr == 1:
+ c_temp = gf.Component("gr form")
+ g_r_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (c_inst.xmax - c_inst.xmin) + 2 * tap_spacing,
+ nf * (c_inst.ymax - c_inst.ymin)
+ + (nf - 1) * nwell_spacing
+ + 2 * tap_spacing,
+ ),
+ layer=tap_layer,
+ )
+ )
+ g_r_in.move((c_inst.xmin - tap_spacing, c_inst.ymin - tap_spacing))
+ g_r_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ g_r_in.xmax - g_r_in.xmin + 2 * grw,
+ g_r_in.ymax - g_r_in.ymin + 2 * grw,
+ ),
+ layer=tap_layer,
+ )
+ )
+ g_r_out.move((g_r_in.xmin - grw, g_r_in.ymin - grw))
+ c.add_ref(
+ gf.geometry.boolean(A=g_r_out, B=g_r_in, operation="A-B", layer=tap_layer)
+ )
+
+ c.add_ref(
+ gf.geometry.boolean(A=g_r_out, B=g_r_in, operation="A-B", layer=li_layer)
+ )
+
+ g_psdm_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ g_r_in.xmax - g_r_in.xmin - 2 * tap_nsdm_enc,
+ g_r_in.ymax - g_r_in.ymin - 2 * tap_nsdm_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ g_psdm_in.move((g_r_in.xmin + tap_nsdm_enc, g_r_in.ymin + tap_nsdm_enc))
+ g_psdm_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ g_r_out.xmax - g_r_out.xmin + 2 * tap_nsdm_enc,
+ g_r_out.ymax - g_r_out.ymin + 2 * tap_nsdm_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ g_psdm_out.move((g_r_out.xmin - tap_nsdm_enc, g_r_out.ymin - tap_nsdm_enc))
+
+ c.add_ref(
+ gf.geometry.boolean(
+ A=g_psdm_out, B=g_psdm_in, operation="A-B", layer=psdm_layer
+ )
+ )
+
+ if grw < con_size[0] + 2 * con_t_enc[0]:
+ g_con_range = (g_r_in.ymin, g_r_in.ymax)
+ else:
+ g_con_range = (g_r_out.ymin, g_r_out.ymax)
+
+ c.add_ref(
+ via_generator(
+ x_range=(g_r_in.xmin + 0.17, g_r_in.xmax - 0.17),
+ y_range=(g_r_in.ymax, g_r_out.ymax),
+ via_enclosure=con_t_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(g_r_in.xmin + 0.17, g_r_in.xmax - 0.17),
+ y_range=(g_r_out.ymin, g_r_in.ymin),
+ via_enclosure=con_t_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(g_r_out.xmin, g_r_in.xmin),
+ y_range=g_con_range,
+ via_enclosure=con_t_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(g_r_in.xmax, g_r_out.xmax),
+ y_range=g_con_range,
+ via_enclosure=con_t_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ if type == "sky130_fd_pr__cap_var_hvt":
+ hvtp = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_c + 2 * hv_enc, w + 2 * hv_enc), layer=hvtp_layer
+ )
+ )
+ hvtp.move((poly.xmin - hv_enc, tap.ymin - hv_enc))
+
+ c.write_gds("cap_var_temp.gds")
+ layout.read("cap_var_temp.gds")
+ cell_name = "sky_cap_var_dev"
+
+ return layout.cell(cell_name)
+
+
+def draw_mim_cap(
+ layout,
+ type="sky130_fd_pr__model__cap_mim",
+ l_c: float = 2,
+ w: float = 2,
+):
+ """
+ Retern mim cap
+
+ Args:
+ layout : layout object
+ l_c : float of capm length
+ w : float of capm width
+
+
+ """
+
+ c = gf.Component("sky_mim_cap_dev")
+
+ # used dimensions and layers
+
+ bottom_layer = m3_layer
+ upper_layer = m4_layer
+ via_layer = via3_layer
+ via_size = (0.2, 0.2)
+ via_enc = (0.09, 0.065)
+ via_spacing = (0.2, 0.2)
+ cap_layer = capm_layer
+ cap_enc = 0.195
+ m_dn_enc = 0.2
+ m_up_spacing = 1.355
+ m_up_w = 0.48
+
+ if type == "sky130_fd_pr__model__cap_mim_m4":
+ bottom_layer = m4_layer
+ upper_layer = m5_layer
+ via_layer = via4_layer
+ via_size = (0.8, 0.8)
+ via_enc = (0.31, 0.31)
+ via_spacing = (0.8, 0.8)
+ cap_layer = cap2m_layer
+ cap_enc = 0.08
+ m_dn_enc = 0.4
+ m_up_spacing = 1.68
+ m_up_w = 1.6
+
+ side_enc = (0.02, 0.06)
+
+ # drawing cap identifier and bottom , upper layers
+ cap = c.add_ref(gf.components.rectangle(size=(w, l_c), layer=cap_layer))
+
+ m_up1 = c.add_ref(
+ gf.components.rectangle(
+ size=(cap.xmax - cap.xmin - 2 * cap_enc, cap.ymax - cap.ymin - 2 * cap_enc),
+ layer=upper_layer,
+ )
+ )
+ m_up1.move((cap.xmin + cap_enc, cap.ymin + cap_enc))
+
+ m_dn = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ m_dn_enc
+ + cap_enc
+ + m_up1.xmax
+ - m_up1.xmin
+ + m_up_spacing
+ + m_up_w
+ + side_enc[0],
+ cap.ymax - cap.ymin + 2 * m_dn_enc,
+ ),
+ layer=bottom_layer,
+ )
+ )
+ m_dn.move((cap.xmin - m_dn_enc, cap.ymin - m_dn_enc))
+
+ m_up2 = c.add_ref(
+ gf.components.rectangle(
+ size=(m_up_w, m_dn.ymax - m_dn.ymin - 2 * side_enc[1]), layer=upper_layer
+ )
+ )
+ m_up2.move((m_up1.xmax + m_up_spacing, m_dn.ymin + side_enc[1]))
+
+ # generating vias
+
+ via_1 = via_generator(
+ x_range=(m_up1.xmin, m_up1.xmax),
+ y_range=(m_up1.ymin, m_up1.ymax),
+ via_enclosure=via_enc,
+ via_layer=via_layer,
+ via_size=via_size,
+ via_spacing=via_spacing,
+ )
+ c.add_ref(via_1)
+
+ via_2 = via_generator(
+ x_range=(m_up2.xmin, m_up2.xmax),
+ y_range=(m_up2.ymin, m_up2.ymax),
+ via_enclosure=via_enc,
+ via_layer=via_layer,
+ via_size=via_size,
+ via_spacing=via_spacing,
+ )
+ c.add_ref(via_2)
+
+ c.write_gds("mim_cap_temp.gds")
+ layout.read("mim_cap_temp.gds")
+ cell_name = "sky_mim_cap_dev"
+
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_diode.py b/sky130/cells/klayout/pymacros/cells/draw_diode.py
new file mode 100644
index 000000000..47b5f6d5c
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_diode.py
@@ -0,0 +1,455 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## Diode Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+
+import os
+
+import gdsfactory as gf
+
+from .globals import PHOTO_D_DEV
+from .layers_def import (
+ areaid_dio_layer,
+ diff_layer,
+ hvi_layer,
+ hvntm_layer,
+ hvtp_layer,
+ li_layer,
+ licon_layer,
+ lvtn_layer,
+ m1_layer,
+ mcon_layer,
+ nsdm_layer,
+ nwell_layer,
+ psdm_layer,
+ tap_layer,
+)
+from .via_generator import via_generator
+
+gds_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "fixed_devices/photodiode"
+) # parent file path
+
+
+def draw_photodiode(layout, device_name):
+ """
+ drawing photo diode device
+ """
+
+ if device_name in PHOTO_D_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
+
+
+def draw_diode(
+ layout,
+ d_type="n",
+ w: float = 0.45,
+ l_d: float = 0.45,
+ type="sky130_fd_pr__diode_pw2nd_05v5",
+ cath_w: float = 0.17,
+ grw: float = 0.17,
+):
+ """
+ Retern diode
+
+ Args:
+ layout : layout object
+ d_type : string of the diode type [n,p]
+ w : float of the diode width
+ l_d: float of the diode length
+ type : string of the device type
+ cath_w : float of cathode width in case of p_diode
+ grw : float of the gaurd ring width
+
+ """
+
+ c = gf.Component("sky_diode_dev")
+
+ c_inst = gf.Component("dev inst")
+
+ # used dimensions and layers
+
+ npsd_enc = 0.125
+ diff_tap_spacing: float = 0.37
+
+ con_size = (0.17, 0.17)
+ con_spacing = (0.19, 0.19)
+ d_con_enc = (0.06, 0.06)
+ t_con_enc = (0.12, 0.12)
+
+ li_enc = 0.08
+ m1_enc = 0.03
+
+ con_layer = [licon_layer, mcon_layer]
+
+ lvt_enc: float = 0.18
+
+ hv_enc = 0.185
+
+ nwell_enc = 0.185
+
+ if d_type == "n":
+ d_npsd_layer = nsdm_layer
+ t_npsd_layer = psdm_layer
+ elif d_type == "p":
+ d_npsd_layer = psdm_layer
+ t_npsd_layer = nsdm_layer
+
+ # generating diff and areaid_diode and its contacts
+ c_inst.add_ref(gf.components.rectangle(size=(w, l_d), layer=diff_layer))
+ diode = c_inst.add_ref(
+ gf.components.rectangle(size=(w, l_d), layer=areaid_dio_layer)
+ )
+
+ d_npsd = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * npsd_enc, l_d + 2 * npsd_enc), layer=d_npsd_layer
+ )
+ )
+ d_npsd.move((-npsd_enc, -npsd_enc))
+
+ for i in range(2):
+ d_con = c_inst.add_ref(
+ via_generator(
+ x_range=(0, w),
+ y_range=(0, l_d),
+ via_enclosure=d_con_enc,
+ via_layer=con_layer[i],
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ d_li = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ diode.xmax - diode.xmin + 2 * (li_enc - d_con_enc[0]),
+ d_con.ymax - d_con.ymin + 2 * li_enc,
+ ),
+ layer=li_layer,
+ )
+ )
+ d_li.move((-(li_enc - d_con_enc[0]), d_con.ymin - li_enc))
+ d_m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(w, d_li.ymax - d_li.ymin + 2 * m1_enc), layer=m1_layer
+ )
+ )
+ d_m1.movey(d_li.ymin - m1_enc)
+
+ # generating gaurd ring and its contacts
+ c_temp = gf.Component("temp store")
+ tap_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * diff_tap_spacing, l_d + 2 * diff_tap_spacing), layer=tap_layer
+ )
+ )
+ tap_in.move((-diff_tap_spacing, -diff_tap_spacing))
+ tap_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_in.xmax - tap_in.xmin + 2 * cath_w,
+ tap_in.ymax - tap_in.ymin + 2 * cath_w,
+ ),
+ layer=tap_layer,
+ )
+ )
+ tap_out.move((tap_in.xmin - cath_w, tap_in.ymin - cath_w))
+ c_inst.add_ref(
+ gf.geometry.boolean(A=tap_out, B=tap_in, operation="A-B", layer=tap_layer)
+ )
+
+ t_npsd_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_in.xmax - tap_in.xmin - 2 * npsd_enc,
+ tap_in.ymax - tap_in.ymin - 2 * npsd_enc,
+ ),
+ layer=t_npsd_layer,
+ )
+ )
+ t_npsd_in.move((tap_in.xmin + npsd_enc, tap_in.ymin + npsd_enc))
+ t_npsd_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_out.xmax - tap_out.xmin + 2 * npsd_enc,
+ tap_out.ymax - tap_out.ymin + 2 * npsd_enc,
+ ),
+ layer=t_npsd_layer,
+ )
+ )
+ t_npsd_out.move((tap_out.xmin - npsd_enc, tap_out.ymin - npsd_enc))
+ c_inst.add_ref(
+ gf.geometry.boolean(
+ A=t_npsd_out, B=t_npsd_in, operation="A-B", layer=t_npsd_layer
+ )
+ )
+
+ if cath_w < con_size[0] + 2 * t_con_enc[0]:
+ t_con_range = (tap_in.xmin, tap_in.xmax)
+ else:
+ t_con_range = (tap_out.xmin, tap_out.xmax)
+
+ c_inst.add_ref(
+ via_generator(
+ x_range=t_con_range,
+ y_range=(tap_in.ymax, tap_out.ymax),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c_inst.add_ref(
+ via_generator(
+ x_range=t_con_range,
+ y_range=(tap_out.ymin, tap_in.ymin),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c_inst.add_ref(
+ via_generator(
+ x_range=(tap_out.xmin, tap_in.xmin),
+ y_range=(tap_in.ymin + 0.17, tap_in.ymax - 0.17),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c_inst.add_ref(
+ via_generator(
+ x_range=(tap_in.xmax, tap_out.xmax),
+ y_range=(tap_in.ymin + 0.17, tap_in.ymax - 0.17),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ tap_li_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * diff_tap_spacing, l_d + 2 * diff_tap_spacing), layer=li_layer
+ )
+ )
+ tap_li_in.move((-diff_tap_spacing, -diff_tap_spacing))
+ tap_li_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_in.xmax - tap_in.xmin + 2 * cath_w,
+ tap_in.ymax - tap_in.ymin + 2 * cath_w,
+ ),
+ layer=li_layer,
+ )
+ )
+ tap_li_out.move((tap_in.xmin - cath_w, tap_in.ymin - cath_w))
+ c_inst.add_ref(
+ gf.geometry.boolean(A=tap_li_out, B=tap_li_in, operation="A-B", layer=li_layer)
+ )
+
+ if (
+ type == "sky130_fd_pr__diode_pw2nd_05v5_lvt"
+ or type == "sky130_fd_pr__diode_pw2nd_05v5_nvt"
+ or type == "sky130_fd_pr__diode_pd2nw_05v5_lvt"
+ ):
+ lvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * lvt_enc, l_d + 2 * lvt_enc), layer=lvtn_layer
+ )
+ )
+ lvt.move((-lvt_enc, -lvt_enc))
+
+ if (
+ type == "sky130_fd_pr__diode_pw2nd_05v5_nvt"
+ or type == "sky130_fd_pr__diode_pw2nd_11v0"
+ ):
+ hvntm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * hv_enc, l_d + 2 * hv_enc), layer=hvntm_layer
+ )
+ )
+ hvntm.move((diode.xmin - hv_enc, diode.ymin - hv_enc))
+
+ if type == "sky130_fd_pr__diode_pd2nw_05v5_hvt":
+ hvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(w + 2 * lvt_enc, l_d + 2 * lvt_enc), layer=hvtp_layer
+ )
+ )
+ hvt.move((-lvt_enc, -lvt_enc))
+
+ if (
+ type == "sky130_fd_pr__diode_pw2nd_05v5_nvt"
+ or type == "sky130_fd_pr__diode_pw2nd_11v0"
+ ):
+ hvi = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_out.xmax - tap_out.xmin + 2 * hv_enc,
+ tap_out.ymax - tap_out.ymin + 2 * hv_enc,
+ ),
+ layer=hvi_layer,
+ )
+ )
+ hvi.move((tap_out.xmin - hv_enc, tap_out.ymin - hv_enc))
+
+ # drawing nwell and outer gaurd ring in case of p-diode
+ if d_type == "p":
+ if type == "sky130_fd_pr__diode_pd2nw_11v0":
+ nwell_enc = 0.34
+
+ nwell = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ tap_out.xmax - tap_out.xmin + 2 * nwell_enc,
+ tap_out.ymax - tap_out.ymin + 2 * nwell_enc,
+ ),
+ layer=nwell_layer,
+ )
+ )
+ nwell.move((tap_out.xmin - nwell_enc, tap_out.ymin - nwell_enc))
+
+ gr_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ c_inst.xmax - c_inst.xmin + 2 * diff_tap_spacing,
+ c_inst.ymax - c_inst.ymin + 2 * diff_tap_spacing,
+ ),
+ layer=tap_layer,
+ )
+ )
+ gr_in.move((c_inst.xmin - diff_tap_spacing, c_inst.ymin - diff_tap_spacing))
+ gr_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ gr_in.xmax - gr_in.xmin + 2 * grw,
+ gr_in.ymax - gr_in.ymin + 2 * grw,
+ ),
+ layer=tap_layer,
+ )
+ )
+ gr_out.move((gr_in.xmin - grw, gr_in.ymin - grw))
+ c.add_ref(
+ gf.geometry.boolean(A=gr_out, B=gr_in, operation="A-B", layer=tap_layer)
+ )
+
+ c.add_ref(
+ gf.geometry.boolean(A=gr_out, B=gr_in, operation="A-B", layer=li_layer)
+ )
+
+ g_psdm_in = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ gr_in.xmax - gr_in.xmin - 2 * npsd_enc,
+ gr_in.ymax - gr_in.ymin - 2 * npsd_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ g_psdm_in.move((gr_in.xmin + npsd_enc, gr_in.ymin + npsd_enc))
+ g_psdm_out = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ gr_out.xmax - gr_out.xmin + 2 * npsd_enc,
+ gr_out.ymax - gr_out.ymin + 2 * npsd_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ g_psdm_out.move((gr_out.xmin - npsd_enc, gr_out.ymin - npsd_enc))
+
+ if grw < con_size[0] + 2 * t_con_enc[0]:
+ g_con_range = (gr_in.ymin, gr_in.ymax)
+ else:
+ g_con_range = (gr_out.ymin, gr_out.ymax)
+
+ c.add_ref(
+ via_generator(
+ x_range=(gr_in.xmin + 0.17, gr_in.xmax - 0.17),
+ y_range=(gr_in.ymax, gr_out.ymax),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(gr_in.xmin + 0.17, gr_in.xmax - 0.17),
+ y_range=(gr_out.ymin, gr_in.ymin),
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(gr_out.xmin, gr_in.xmin),
+ y_range=g_con_range,
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(gr_in.xmax, gr_out.xmax),
+ y_range=g_con_range,
+ via_enclosure=t_con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ if type == "sky130_fd_pr__diode_pd2nw_11v0":
+ hvi = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ gr_out.xmax - gr_out.xmin + 2 * hv_enc,
+ gr_out.ymax - gr_out.ymin + 2 * hv_enc,
+ ),
+ layer=hvi_layer,
+ )
+ )
+ hvi.move((gr_out.xmin - hv_enc, gr_out.ymin - hv_enc))
+
+ c.add_ref(c_inst)
+
+ c.write_gds("diode_temp.gds")
+ layout.read("diode_temp.gds")
+ cell_name = "sky_diode_dev"
+
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_fet.py b/sky130/cells/klayout/pymacros/cells/draw_fet.py
new file mode 100644
index 000000000..dcd2051a9
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_fet.py
@@ -0,0 +1,1793 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## Mosfets Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+from math import ceil, floor
+
+import gdsfactory as gf
+
+from .layers_def import (
+ areaid_lvn_layer,
+ diff_layer,
+ hvi_layer,
+ hvntm_layer,
+ hvtp_layer,
+ li_layer,
+ licon_layer,
+ lvtn_layer,
+ m1_layer,
+ m1_lbl,
+ m2_layer,
+ nsdm_layer,
+ nwell_layer,
+ poly_layer,
+ psdm_layer,
+ tap_layer,
+ via1_layer,
+)
+from .via_generator import via_generator, via_stack
+
+
+# @gf.cell
+def draw_nfet(
+ layout,
+ l_gate: float = 0.15,
+ w: float = 0.42,
+ sd_con_col: int = 1,
+ inter_sd_l: float = 0.3, # 0.21 ,
+ nf: int = 1,
+ grw: float = 0.17,
+ type="sky130_fd_pr__nfet_01v8",
+ bulk="None",
+ con_bet_fin: int = 1,
+ gate_con_pos="alternating",
+ interdig: int = 0,
+ patt="",
+ # n = 1
+): # -> gf.Component:
+ """
+ Retern nfet
+
+ Args:
+ layout : layout object
+ l : Float of gate length
+ w : Float of gate width
+ sd_l : Float of source and drain diffusion length
+ inter_sd_l : Float of source and drain diffusion length between fingers
+ nf : integer of number of fingers
+ M : integer of number of multipliers
+ grw : gaurd ring width when enabled
+ type : string of the device type
+ bulk : String of bulk connection type (None, Bulk Tie, Guard Ring)
+ con_bet_fin : boolean of having contacts for diffusion between fingers
+ gate_con_pos : string of choosing the gate contact position (bottom, top, alternating )
+
+ """
+ # used layers and dimensions
+
+ end_cap: float = 0.2
+ diff_tap_spacing: float = 0.32
+ poly_tap_spacing: float = 0.27
+
+ diff_nsdm_enc: float = 0.125
+ tap_psdm_enc: float = 0.125
+
+ gate_npc_ext = 0.11
+ npc_spacing = 0.27
+
+ gate_lvt_enc: float = 0.18
+
+ hv_enclosing: float = 0.185
+
+ areaid_lvn_enc: float = 0.1
+
+ # m1_m1lic_sp = 0.28+ mcon_enc[0] - end_cap
+
+ licon_size = (0.17, 0.17)
+ licon_spacing = (0.19, 0.19)
+ licon_dt_enc = (0.04, 0.06)
+
+ licon_p_enc = (0.05, 0.08)
+
+ sd_l_con = (
+ ((sd_con_col) * licon_size[0])
+ + ((sd_con_col - 1) * licon_spacing[0])
+ + 2 * licon_dt_enc[0]
+ )
+ sd_l = sd_l_con + 0.05
+
+ # gds components to store a single instance and the generated device
+ c = gf.Component("sky_nfet_dev")
+
+ c_inst = gf.Component("dev_temp")
+
+ # generating sd diffusion
+
+ if interdig == 1 and nf > 1 and nf != len(patt) and patt != "":
+ nf = len(patt)
+
+ l_d = sd_l + nf * l_gate + (nf - 1) * inter_sd_l + sd_l # diffution total length
+ rect_d = gf.components.rectangle(size=(l_d, w), layer=diff_layer)
+ sd_diff = c_inst.add_ref(rect_d)
+
+ # generatin sd contacts
+
+ sd_con = via_stack(
+ x_range=(0, sd_l), y_range=(0, w), base_layer=diff_layer, metal_level=1
+ )
+ c_inst.add_array(
+ component=sd_con,
+ columns=2,
+ rows=1,
+ spacing=(sd_l + nf * l_gate + (nf - 1) * inter_sd_l, 0),
+ )
+
+ if con_bet_fin == 1 and nf > 1:
+ inter_sd_con = via_stack(
+ x_range=(sd_l + l_gate, sd_l + l_gate + inter_sd_l),
+ y_range=(0, w),
+ base_layer=diff_layer,
+ metal_level=1,
+ )
+ c_inst.add_array(
+ component=inter_sd_con,
+ columns=nf - 1,
+ rows=1,
+ spacing=(l_gate + inter_sd_l, 0),
+ )
+
+ # generating poly
+
+ if l_gate <= licon_size[0] + 2 * licon_p_enc[0]:
+ pc_x = licon_p_enc[0] + licon_size[0] + licon_p_enc[0]
+
+ else:
+ pc_x = l_gate
+
+ pc_size = (pc_x, licon_p_enc[1] + licon_size[1] + licon_p_enc[1])
+
+ c_pc = gf.Component("poly con")
+
+ rect_pc = c_pc.add_ref(gf.components.rectangle(size=pc_size, layer=poly_layer))
+
+ poly_con = via_stack(
+ x_range=(rect_pc.xmin, rect_pc.xmax),
+ y_range=(rect_pc.ymin, rect_pc.ymax),
+ base_layer=poly_layer,
+ metal_level=1,
+ li_enc_dir="H",
+ )
+ c_pc.add_ref(poly_con)
+
+ if nf == 1:
+ poly = c_inst.add_ref(
+ gf.components.rectangle(size=(l_gate, w + 2 * end_cap), layer=poly_layer)
+ )
+ poly.move((sd_l, -end_cap))
+
+ if gate_con_pos == "bottom":
+ mv = 0
+ nr = 1
+ elif gate_con_pos == "top":
+ mv = pc_size[1] + w + 2 * end_cap
+ nr = 1
+ else:
+ mv = 0
+ nr = 2
+
+ pc = c_inst.add_array(
+ component=c_pc,
+ rows=nr,
+ columns=1,
+ spacing=(0, pc_size[1] + w + 2 * end_cap),
+ )
+ pc.move((sd_l - ((pc_x - l_gate) / 2), -pc_size[1] - end_cap + mv))
+
+ else:
+ w_p1 = end_cap + w + end_cap # poly total width
+
+ if inter_sd_l < (npc_spacing + 2 * gate_npc_ext):
+ if gate_con_pos == "alternating":
+ w_p1 += 0.2
+ w_p2 = w_p1
+ e_c = 0.2
+ else:
+ w_p2 = (
+ w_p1
+ + licon_p_enc[1]
+ + licon_size[1]
+ + licon_p_enc[1]
+ + npc_spacing
+ + 0.1
+ )
+ e_c = 0
+
+ if gate_con_pos == "bottom":
+ p_mv = -end_cap - (w_p2 - w_p1)
+ else:
+ p_mv = -end_cap
+
+ else:
+ w_p2 = w_p1
+ p_mv = -end_cap
+ e_c = 0
+
+ rect_p1 = gf.components.rectangle(size=(l_gate, w_p1), layer=poly_layer)
+ rect_p2 = gf.components.rectangle(size=(l_gate, w_p2), layer=poly_layer)
+ poly1 = c_inst.add_array(
+ rect_p1,
+ rows=1,
+ columns=ceil(nf / 2),
+ spacing=[2 * (inter_sd_l + l_gate), 0],
+ )
+ poly1.move((sd_l, -end_cap - e_c))
+
+ poly2 = c_inst.add_array(
+ rect_p2,
+ rows=1,
+ columns=floor(nf / 2),
+ spacing=[2 * (inter_sd_l + l_gate), 0],
+ )
+ poly2.move((sd_l + l_gate + inter_sd_l, p_mv))
+
+ # generating poly contacts setups
+
+ if gate_con_pos == "bottom":
+ mv_1 = 0
+ mv_2 = -(w_p2 - w_p1)
+ elif gate_con_pos == "top":
+ mv_1 = pc_size[1] + w_p1
+ mv_2 = pc_size[1] + w_p2
+ else:
+ mv_1 = -e_c
+ mv_2 = pc_size[1] + w_p2
+
+ nc1 = ceil(nf / 2)
+ nc2 = floor(nf / 2)
+
+ pc_spacing = 2 * (inter_sd_l + l_gate)
+
+ # generating poly contacts
+
+ pc1 = c_inst.add_array(
+ component=c_pc, rows=1, columns=nc1, spacing=(pc_spacing, 0)
+ )
+ pc1.move((sd_l - ((pc_x - l_gate) / 2), -pc_size[1] - end_cap + mv_1))
+
+ pc2 = c_inst.add_array(
+ component=c_pc, rows=1, columns=nc2, spacing=(pc_spacing, 0)
+ )
+ pc2.move(
+ (
+ sd_l - ((pc_x - l_gate) / 2) + (inter_sd_l + l_gate),
+ -pc_size[1] - end_cap + mv_2,
+ )
+ )
+
+ if interdig == 1:
+ if nf == len(patt):
+ pat = list(patt)
+ nt = (
+ []
+ ) # list to store the symbols of transistors and thier number nt(number of transistors)
+ [nt.append(x) for x in pat if x not in nt]
+ nl = int(len(nt))
+
+ m2_spacing = 0.14
+ via1_size = (0.15, 0.15)
+ via1_enc = (0.085, 0.055)
+ via1_spacing = (0.17, 0.17)
+ via2_size = (0.2, 0.2)
+ via2_enc = (0.085, 0.065)
+
+ m2_y = via1_size[1] + 2 * via1_enc[1]
+ m2 = gf.components.rectangle(
+ size=(sd_diff.xmax - sd_diff.xmin, m2_y), layer=m2_layer
+ )
+
+ if gate_con_pos == "alternating":
+ pat_o = []
+ pat_e = []
+
+ for i in range(int(nf)):
+ if i % 2 == 0:
+ pat_e.append(pat[i])
+ else:
+ pat_o.append(pat[i])
+
+ nt_o = []
+ [nt_o.append(x) for x in pat_o if x not in nt_o]
+
+ nt_e = []
+ [nt_e.append(x) for x in pat_e if x not in nt_e]
+
+ nl_b = len(nt_e)
+ nl_u = len(nt_o)
+
+ m2_y = via2_size[1] + 2 * via2_enc[1]
+ m2 = gf.components.rectangle(
+ size=(sd_diff.xmax - sd_diff.xmin, m2_y), layer=m2_layer
+ )
+
+ m2_arrb = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl_b,
+ spacing=(0, -m2_y - m2_spacing),
+ )
+ m2_arrb.movey(pc1.ymin - m2_spacing - m2_y)
+
+ m2_arru = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl_u,
+ spacing=(0, m2_y + m2_spacing),
+ )
+ m2_arru.movey(pc2.ymax + m2_spacing)
+
+ for i in range(nl_u):
+ for j in range(floor(nf / 2)):
+ if pat_o[j] == nt_o[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc2.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + (2 * j + 1) * (l_gate + inter_sd_l)
+ ),
+ (pc2.ymin + 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arru.ymin + i * (m2_y + m2_spacing),
+ m2_arru.ymin + i * (m2_y + m2_spacing) + m2_y,
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat_o[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+
+ for i in range(nl_b):
+ for j in range(ceil(nf / 2)):
+ if pat_e[j] == nt_e[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc1.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - pc1.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + (2 * j) * (l_gate + inter_sd_l)
+ ),
+ -(m1.ymax - m1.ymin) + (pc1.ymax - 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arrb.ymax - i * (m2_spacing + m2_y) - m2_y,
+ m2_arrb.ymax - i * (m2_spacing + m2_y),
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat_e[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+
+ m3_x = via2_size[0] + 2 * via2_enc[0]
+ m3_spacing = 0.3
+
+ for i in range(nl_b):
+ for j in range(nl_u):
+ if nt_e[i] == nt_o[j]:
+ m2_join_b = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ m2_y + (i + 1) * (m3_spacing + m3_x),
+ m2_y,
+ ),
+ layer=m2_layer,
+ ).move(
+ (
+ m2_arrb.xmin
+ - (m2_y + (i + 1) * (m3_spacing + m3_x)),
+ m2_arrb.ymax
+ - i * (m2_spacing + m2_y)
+ - m2_y,
+ )
+ )
+ )
+ m2_join_u = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ m2_y + (i + 1) * (m3_spacing + m3_x),
+ m2_y,
+ ),
+ layer=m2_layer,
+ ).move(
+ (
+ m2_arru.xmin
+ - (m2_y + (i + 1) * (m3_spacing + m3_x)),
+ m2_arru.ymin + j * (m2_spacing + m2_y),
+ )
+ )
+ )
+ m3 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(m3_x, m2_join_u.ymax - m2_join_b.ymin),
+ layer=m1_layer,
+ )
+ )
+ m3.move((m2_join_b.xmin, m2_join_b.ymin))
+ via2_dr = via_generator(
+ x_range=(m3.xmin, m3.xmax),
+ y_range=(m2_join_b.ymin, m2_join_b.ymax),
+ via_enclosure=via1_enc,
+ via_size=via1_size,
+ via_layer=via1_layer,
+ via_spacing=via1_spacing,
+ )
+ c_inst.add_array(
+ component=via2_dr,
+ columns=1,
+ rows=2,
+ spacing=(0, m2_join_u.ymin - m2_join_b.ymin),
+ )
+
+ elif gate_con_pos == "top":
+ m2_arr = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl,
+ spacing=(0, m2.ymax - m2.ymin + m2_spacing),
+ )
+ m2_arr.movey(pc2.ymax + m2_spacing)
+
+ for i in range(nl):
+ for j in range(int(nf)):
+ if pat[j] == nt[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc2.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - ((1 - j % 2) * pc1.ymin)
+ - (j % 2) * pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + j * (l_gate + inter_sd_l)
+ ),
+ (1 - j % 2) * (pc1.ymin + 0.06)
+ + (j % 2) * (pc2.ymin + 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arr.ymin + i * (m2_spacing + m2_y),
+ m2_arr.ymin + i * (m2_spacing + m2_y) + m2_y,
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+
+ elif gate_con_pos == "bottom":
+ m2_arr = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl,
+ spacing=(0, -m2_y - m2_spacing),
+ )
+ m2_arr.movey(pc2.ymin - m2_spacing - m2_y)
+
+ for i in range(nl):
+ for j in range(int(nf)):
+ if pat[j] == nt[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc1.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - (j % 2) * pc1.ymin
+ - (1 - j % 2) * pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + j * (l_gate + inter_sd_l)
+ ),
+ -(m1.ymax - m1.ymin)
+ + (1 - j % 2) * (pc1.ymax - 0.06)
+ + (j % 2) * (pc2.ymax - 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arr.ymax - i * (m2_spacing + m2_y) - m2_y,
+ m2_arr.ymax - i * (m2_spacing + m2_y),
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+
+ # generating bulk
+ if bulk == "None":
+ nsdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * diff_nsdm_enc, w + 2 * diff_nsdm_enc), layer=nsdm_layer
+ )
+ )
+ nsdm.move((-diff_nsdm_enc, -diff_nsdm_enc))
+
+ if (
+ type == "sky130_fd_pr__nfet_g5v0d10v5"
+ or type == "sky130_fd_pr__nfet_05v0_nvt"
+ or type == "sky130_fd_pr__nfet_03v3_nvt"
+ ):
+ hvntm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * hv_enclosing, w + 2 * hv_enclosing),
+ layer=hvntm_layer,
+ )
+ )
+ hvntm.move((sd_diff.xmin - hv_enclosing, sd_diff.ymin - hv_enclosing))
+
+ elif bulk == "bulk tie":
+ rect_bulk = c_inst.add_ref(
+ gf.components.rectangle(size=(sd_l * 1.5, w), layer=tap_layer)
+ )
+ rect_bulk.connect("e1", destination=sd_diff.ports["e3"])
+ nsdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ sd_diff.xmax - sd_diff.xmin + diff_nsdm_enc,
+ w + 2 * diff_nsdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ nsdm.move((-diff_nsdm_enc, -diff_nsdm_enc))
+ psdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ rect_bulk.xmax - rect_bulk.xmin + tap_psdm_enc,
+ w + 2 * tap_psdm_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ psdm.connect("e1", destination=nsdm.ports["e3"])
+
+ bulk_con = via_stack(
+ x_range=(rect_bulk.xmin + 0.1, rect_bulk.xmax - 0.1),
+ y_range=(rect_bulk.ymin, rect_bulk.ymax),
+ base_layer=tap_layer,
+ metal_level=0,
+ )
+ c_inst.add_ref(bulk_con)
+
+ if (
+ type == "sky130_fd_pr__nfet_g5v0d10v5"
+ or type == "sky130_fd_pr__nfet_05v0_nvt"
+ or type == "sky130_fd_pr__nfet_03v3_nvt"
+ ):
+ hvntm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + hv_enclosing, w + 2 * hv_enclosing), layer=hvntm_layer
+ )
+ )
+ hvntm.move((sd_diff.xmin - hv_enclosing, sd_diff.ymin - hv_enclosing))
+
+ elif bulk == "Gaurd Ring":
+ nsdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * diff_nsdm_enc, w + 2 * diff_nsdm_enc), layer=nsdm_layer
+ )
+ )
+ nsdm.move((-diff_nsdm_enc, -diff_nsdm_enc))
+ c.add_ref(c_inst)
+
+ c_temp = gf.Component("temp_store")
+ rect_bulk_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (c_inst.xmax - c_inst.xmin) + 2 * diff_tap_spacing,
+ (c_inst.ymax - c_inst.ymin) + 2 * poly_tap_spacing,
+ ),
+ layer=tap_layer,
+ )
+ )
+ rect_bulk_in.move(
+ (c_inst.xmin - diff_tap_spacing, c_inst.ymin - poly_tap_spacing)
+ )
+ rect_bulk_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) + 2 * grw,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) + 2 * grw,
+ ),
+ layer=tap_layer,
+ )
+ )
+ rect_bulk_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw))
+ c.add_ref(
+ gf.geometry.boolean(
+ A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=tap_layer
+ )
+ )
+
+ psdm_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) - 2 * tap_psdm_enc,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) - 2 * tap_psdm_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ psdm_in.move(
+ (rect_bulk_in.xmin + tap_psdm_enc, rect_bulk_in.ymin + tap_psdm_enc)
+ )
+ psdm_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_out.xmax - rect_bulk_out.xmin) + 2 * tap_psdm_enc,
+ (rect_bulk_out.ymax - rect_bulk_out.ymin) + 2 * tap_psdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ psdm_out.move(
+ (rect_bulk_out.xmin - tap_psdm_enc, rect_bulk_out.ymin - tap_psdm_enc)
+ )
+ psdm = c.add_ref(
+ gf.geometry.boolean(
+ A=psdm_out, B=psdm_in, operation="A-B", layer=psdm_layer
+ )
+ )
+
+ # generating contacts
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmin + 0.17, rect_bulk_in.xmax - 0.17),
+ y_range=(rect_bulk_out.ymin, rect_bulk_in.ymin),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmin + 0.17, rect_bulk_in.xmax - 0.17),
+ y_range=(rect_bulk_in.ymax, rect_bulk_out.ymax),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_out.xmin, rect_bulk_in.xmin),
+ y_range=(rect_bulk_in.ymin + 0.17, rect_bulk_in.ymax - 0.17),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmax, rect_bulk_out.xmax),
+ y_range=(rect_bulk_in.ymin + 0.17, rect_bulk_in.ymax - 0.17),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ tap_li_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (l_d) + 2 * diff_tap_spacing,
+ (c_inst.ymax - c_inst.ymin) + 2 * poly_tap_spacing,
+ ),
+ layer=li_layer,
+ )
+ )
+ tap_li_in.move((-diff_tap_spacing, c_inst.ymin - poly_tap_spacing))
+ tap_li_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) + 2 * grw,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) + 2 * grw,
+ ),
+ layer=li_layer,
+ )
+ )
+ tap_li_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw))
+ c.add_ref(
+ gf.geometry.boolean(
+ A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=li_layer
+ )
+ )
+
+ # generating hvi for high voltage
+ if (
+ type == "sky130_fd_pr__nfet_g5v0d10v5"
+ or type == "sky130_fd_pr__nfet_05v0_nvt"
+ or type == "sky130_fd_pr__nfet_03v3_nvt"
+ ):
+ hvi = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ rect_bulk_out.xmax - rect_bulk_out.xmin + 2 * hv_enclosing,
+ rect_bulk_out.ymax - rect_bulk_out.ymin + 2 * hv_enclosing,
+ ),
+ layer=hvi_layer,
+ )
+ )
+ hvi.move(
+ (rect_bulk_out.xmin - hv_enclosing, rect_bulk_out.ymin - hv_enclosing)
+ )
+
+ hvntm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * hv_enclosing, w + 2 * hv_enclosing),
+ layer=hvntm_layer,
+ )
+ )
+ hvntm.move((sd_diff.xmin - hv_enclosing, sd_diff.ymin - hv_enclosing))
+
+ if bulk != "Gaurd Ring":
+ c.add_ref(c_inst)
+
+ # generating hvi and hvntm for high voltage
+ if (
+ type == "sky130_fd_pr__nfet_g5v0d10v5"
+ or type == "sky130_fd_pr__nfet_05v0_nvt"
+ or type == "sky130_fd_pr__nfet_03v3_nvt"
+ ):
+ hvi = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ c_inst.xmax - c_inst.xmin + 2 * hv_enclosing,
+ (c_inst.ymax - c_inst.ymin) + 2 * hv_enclosing,
+ ),
+ layer=hvi_layer,
+ )
+ )
+ hvi.move((c_inst.xmin - hv_enclosing, c_inst.ymin - hv_enclosing))
+
+ if type == "sky130_fd_pr__nfet_01v8_lvt":
+ lvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ nf * l_gate + (nf - 1) * inter_sd_l + 2 * gate_lvt_enc,
+ w + 2 * gate_lvt_enc,
+ ),
+ layer=lvtn_layer,
+ )
+ )
+ lvt.move((sd_l - gate_lvt_enc, -gate_lvt_enc))
+
+ if type == "sky130_fd_pr__nfet_03v3_nvt" or type == "sky130_fd_pr__nfet_05v0_nvt":
+ nvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ nf * l_gate + (nf - 1) * inter_sd_l + 2 * gate_lvt_enc,
+ w + 2 * gate_lvt_enc,
+ ),
+ layer=lvtn_layer,
+ )
+ )
+ nvt.move((sd_l - gate_lvt_enc, -gate_lvt_enc))
+
+ if type == "sky130_fd_pr__nfet_03v3_nvt":
+ areaid_lvn = gf.components.rectangle(
+ size=(l_gate + 2 * areaid_lvn_enc, w + 2 * areaid_lvn_enc),
+ layer=areaid_lvn_layer,
+ )
+ areaid_lvn_arr = c_inst.add_array(
+ component=areaid_lvn,
+ columns=nf,
+ rows=1,
+ spacing=[l_gate + inter_sd_l, 0],
+ )
+ areaid_lvn_arr.move((sd_l - areaid_lvn_enc, sd_diff.ymin - areaid_lvn_enc))
+
+ # creating layout and cell in klayout
+ c.write_gds("nfet_temp.gds")
+ layout.read("nfet_temp.gds")
+ cell_name = "sky_nfet_dev"
+
+ return layout.cell(cell_name)
+ # return c
+
+
+# @gf.cell
+def draw_pfet(
+ layout,
+ l_gate: float = 0.15,
+ w: float = 0.42,
+ sd_con_col: int = 1,
+ inter_sd_l: float = 0.5, # 0.21 ,
+ nf: int = 5,
+ grw: float = 0.17,
+ type="sky130_fd_pr__pfet_01v8",
+ bulk="None",
+ con_bet_fin: int = 1,
+ gate_con_pos="alternating",
+ interdig: int = 1,
+ patt="",
+ # n = 1
+) -> gf.Component:
+ """
+ Retern pfet
+
+ Args:
+ layout : layout object
+ l : Float of gate length
+ w : Float of gate width
+ sd_con_col : integer of number of contacts columns contained in source and drain area
+ inter_sd_l : Float of source and drain diffusion length between fingers
+ nf : integer of number of fingers
+ M : integer of number of multipliers
+ grw : gaurd ring width when enabled
+ type : string of the device type
+ bulk : String of bulk connection type (None, Bulk Tie, Guard Ring)
+ con_bet_fin : boolean of having contacts for diffusion between fingers
+ gate_con_pos : string of choosing the gate contact position (bottom, top, alternating )
+
+
+ """
+
+ # used layers and dimensions
+
+ end_cap: float = 0.2 # may be increases to solve the met1 drc prob
+ diff_tap_spacing: float = 0.32
+ poly_tap_spacing: float = 0.27
+
+ diff_psdm_enc: float = 0.125
+ tap_nsdm_enc: float = 0.125
+
+ nwell_enclosing: float = 0.18
+
+ if type == "sky130_fd_pr__pfet_g5v0d10v5":
+ nwell_enclosing = 0.34
+
+ gate_npc_ext = 0.11
+ npc_spacing = 0.27
+
+ gate_lvt_enc: float = 0.18
+
+ gate_hvt_enc: float = 0.18
+
+ licon_size = (0.17, 0.17)
+ licon_spacing = (0.19, 0.19)
+ licon_dt_enc = (0.04, 0.06)
+
+ licon_t_enc = 0.12
+
+ licon_p_enc = (0.05, 0.08)
+
+ # m1_m1lic_sp = 0.28+ mcon_enc[0] - end_cap
+
+ sd_l_con = (
+ ((sd_con_col) * licon_size[0])
+ + ((sd_con_col - 1) * licon_spacing[0])
+ + 2 * licon_dt_enc[0]
+ )
+ sd_l = sd_l_con + 0.05
+
+ # gds components to store a single instance and the generated device
+ c = gf.Component("sky_pfet_dev")
+
+ c_inst = gf.Component("dev_temp")
+
+ # generating sd diffusion
+
+ if interdig == 1 and nf > 1 and nf != len(patt) and patt != "":
+ nf = len(patt)
+
+ l_d = sd_l + nf * l_gate + (nf - 1) * inter_sd_l + sd_l # diffution total length
+ rect_d = gf.components.rectangle(size=(l_d, w), layer=diff_layer)
+ sd_diff = c_inst.add_ref(rect_d)
+
+ # generatin sd contacts
+
+ sd_con = via_stack(
+ x_range=(0, sd_l), y_range=(0, w), base_layer=diff_layer, metal_level=1
+ )
+ c_inst.add_array(
+ component=sd_con,
+ columns=2,
+ rows=1,
+ spacing=(sd_l + nf * l_gate + (nf - 1) * inter_sd_l, 0),
+ )
+
+ if con_bet_fin == 1 and nf > 1:
+ inter_sd_con = via_stack(
+ x_range=(sd_l + l_gate, sd_l + l_gate + inter_sd_l),
+ y_range=(0, w),
+ base_layer=diff_layer,
+ metal_level=1,
+ )
+ c_inst.add_array(
+ component=inter_sd_con,
+ columns=nf - 1,
+ rows=1,
+ spacing=(l_gate + inter_sd_l, 0),
+ )
+
+ # generating poly
+
+ if l_gate <= licon_size[0] + 2 * licon_p_enc[0]:
+ pc_x = licon_p_enc[0] + licon_size[0] + licon_p_enc[0]
+
+ else:
+ pc_x = l_gate
+
+ pc_size = (pc_x, licon_p_enc[1] + licon_size[1] + licon_p_enc[1])
+
+ c_pc = gf.Component("poly con")
+
+ rect_pc = c_pc.add_ref(gf.components.rectangle(size=pc_size, layer=poly_layer))
+
+ poly_con = via_stack(
+ x_range=(rect_pc.xmin, rect_pc.xmax),
+ y_range=(rect_pc.ymin, rect_pc.ymax),
+ base_layer=poly_layer,
+ metal_level=1,
+ li_enc_dir="H",
+ )
+ c_pc.add_ref(poly_con)
+
+ if nf == 1:
+ poly = c_inst.add_ref(
+ gf.components.rectangle(size=(l_gate, w + 2 * end_cap), layer=poly_layer)
+ )
+ poly.move((sd_l, -end_cap))
+
+ if gate_con_pos == "bottom":
+ mv = 0
+ nr = 1
+ elif gate_con_pos == "top":
+ mv = pc_size[1] + w + 2 * end_cap
+ nr = 1
+ else:
+ mv = 0
+ nr = 2
+
+ pc = c_inst.add_array(
+ component=c_pc,
+ rows=nr,
+ columns=1,
+ spacing=(0, pc_size[1] + w + 2 * end_cap),
+ )
+ pc.move((sd_l - ((pc_x - l_gate) / 2), -pc_size[1] - end_cap + mv))
+
+ else:
+ w_p1 = end_cap + w + end_cap # poly total width
+
+ if inter_sd_l < (npc_spacing + 2 * gate_npc_ext):
+ if gate_con_pos == "alternating":
+ w_p1 += 0.2
+ w_p2 = w_p1
+ e_c = 0.2
+ else:
+ w_p2 = (
+ w_p1
+ + licon_p_enc[1]
+ + licon_size[1]
+ + licon_p_enc[1]
+ + npc_spacing
+ + 0.1
+ )
+ e_c = 0
+
+ if gate_con_pos == "bottom":
+ p_mv = -end_cap - (w_p2 - w_p1)
+ else:
+ p_mv = -end_cap
+
+ else:
+ w_p2 = w_p1
+ p_mv = -end_cap
+ e_c = 0
+
+ rect_p1 = gf.components.rectangle(size=(l_gate, w_p1), layer=poly_layer)
+ rect_p2 = gf.components.rectangle(size=(l_gate, w_p2), layer=poly_layer)
+ poly1 = c_inst.add_array(
+ rect_p1,
+ rows=1,
+ columns=ceil(nf / 2),
+ spacing=[2 * (inter_sd_l + l_gate), 0],
+ )
+ poly1.move((sd_l, -end_cap - e_c))
+
+ poly2 = c_inst.add_array(
+ rect_p2,
+ rows=1,
+ columns=floor(nf / 2),
+ spacing=[2 * (inter_sd_l + l_gate), 0],
+ )
+ poly2.move((sd_l + l_gate + inter_sd_l, p_mv))
+
+ # generating poly contacts setups
+
+ if gate_con_pos == "bottom":
+ mv_1 = 0
+ mv_2 = -(w_p2 - w_p1)
+ elif gate_con_pos == "top":
+ mv_1 = pc_size[1] + w_p1
+ mv_2 = pc_size[1] + w_p2
+ else:
+ mv_1 = -e_c
+ mv_2 = pc_size[1] + w_p2
+
+ nc1 = ceil(nf / 2)
+ nc2 = floor(nf / 2)
+
+ pc_spacing = 2 * (inter_sd_l + l_gate)
+
+ # generating poly contacts
+
+ pc1 = c_inst.add_array(
+ component=c_pc, rows=1, columns=nc1, spacing=(pc_spacing, 0)
+ )
+ pc1.move((sd_l - ((pc_x - l_gate) / 2), -pc_size[1] - end_cap + mv_1))
+
+ pc2 = c_inst.add_array(
+ component=c_pc, rows=1, columns=nc2, spacing=(pc_spacing, 0)
+ )
+ pc2.move(
+ (
+ sd_l - ((pc_x - l_gate) / 2) + (inter_sd_l + l_gate),
+ -pc_size[1] - end_cap + mv_2,
+ )
+ )
+
+ if interdig == 1:
+ if nf == len(patt):
+ pat = list(patt)
+ nt = (
+ []
+ ) # list to store the symbols of transistors and thier number nt(number of transistors)
+ [nt.append(x) for x in pat if x not in nt]
+ nl = len(nt)
+
+ m2_spacing = 0.14
+ via1_size = (0.15, 0.15)
+ via1_enc = (0.085, 0.055)
+ via1_spacing = (0.17, 0.17)
+ via2_size = (0.2, 0.2)
+ via2_enc = (0.085, 0.065)
+
+ m2_y = via1_size[1] + 2 * via1_enc[1]
+ m2 = gf.components.rectangle(
+ size=(sd_diff.xmax - sd_diff.xmin, m2_y), layer=m2_layer
+ )
+
+ if gate_con_pos == "alternating":
+ pat_o = []
+ pat_e = []
+
+ for i in range(int(nf)):
+ if i % 2 == 0:
+ pat_e.append(pat[i])
+ else:
+ pat_o.append(pat[i])
+
+ nt_o = []
+ [nt_o.append(x) for x in pat_o if x not in nt_o]
+
+ nt_e = []
+ [nt_e.append(x) for x in pat_e if x not in nt_e]
+
+ nl_b = len(nt_e)
+ nl_u = len(nt_o)
+
+ m2_y = via2_size[1] + 2 * via2_enc[1]
+ m2 = gf.components.rectangle(
+ size=(sd_diff.xmax - sd_diff.xmin, m2_y), layer=m2_layer
+ )
+
+ m2_arrb = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl_b,
+ spacing=(0, -m2_y - m2_spacing),
+ )
+ m2_arrb.movey(pc1.ymin - m2_spacing - m2_y)
+
+ m2_arru = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl_u,
+ spacing=(0, m2_y + m2_spacing),
+ )
+ m2_arru.movey(pc2.ymax + m2_spacing)
+
+ for i in range(nl_u):
+ for j in range(floor(nf / 2)):
+ if pat_o[j] == nt_o[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc2.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + (2 * j + 1) * (l_gate + inter_sd_l)
+ ),
+ (pc2.ymin + 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arru.ymin + i * (m2_y + m2_spacing),
+ m2_arru.ymin + i * (m2_y + m2_spacing) + m2_y,
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat_o[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+ # c_inst.add_label(f'G_{pat_o[j]}{n}',position=((via1.xmax+via1.xmin)/2, (pc2.ymin + pc2.ymax)/2),layer=m1_lbl)
+
+ for i in range(nl_b):
+ for j in range(ceil(nf / 2)):
+ if pat_e[j] == nt_e[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc1.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - pc1.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + (2 * j) * (l_gate + inter_sd_l)
+ ),
+ -(m1.ymax - m1.ymin) + (pc1.ymax - 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arrb.ymax - i * (m2_spacing + m2_y) - m2_y,
+ m2_arrb.ymax - i * (m2_spacing + m2_y),
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat_e[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+ # c_inst.add_label(f'G_{pat_e[j]}{n}',position=((via1.xmax+via1.xmin)/2, (pc1.ymin + pc1.ymax)/2),layer=m1_lbl)
+
+ m3_x = via2_size[0] + 2 * via2_enc[0]
+ m3_spacing = 0.3
+
+ for i in range(nl_b):
+ for j in range(nl_u):
+ if nt_e[i] == nt_o[j]:
+ m2_join_b = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ m2_y + (i + 1) * (m3_spacing + m3_x),
+ m2_y,
+ ),
+ layer=m2_layer,
+ ).move(
+ (
+ m2_arrb.xmin
+ - (m2_y + (i + 1) * (m3_spacing + m3_x)),
+ m2_arrb.ymax
+ - i * (m2_spacing + m2_y)
+ - m2_y,
+ )
+ )
+ )
+ m2_join_u = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ m2_y + (i + 1) * (m3_spacing + m3_x),
+ m2_y,
+ ),
+ layer=m2_layer,
+ ).move(
+ (
+ m2_arru.xmin
+ - (m2_y + (i + 1) * (m3_spacing + m3_x)),
+ m2_arru.ymin + j * (m2_spacing + m2_y),
+ )
+ )
+ )
+ m3 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(m3_x, m2_join_u.ymax - m2_join_b.ymin),
+ layer=m1_layer,
+ )
+ )
+ m3.move((m2_join_b.xmin, m2_join_b.ymin))
+ via2_dr = via_generator(
+ x_range=(m3.xmin, m3.xmax),
+ y_range=(m2_join_b.ymin, m2_join_b.ymax),
+ via_enclosure=via1_enc,
+ via_size=via1_size,
+ via_layer=via1_layer,
+ via_spacing=via1_spacing,
+ )
+ c_inst.add_array(
+ component=via2_dr,
+ columns=1,
+ rows=2,
+ spacing=(0, m2_join_u.ymin - m2_join_b.ymin),
+ )
+
+ elif gate_con_pos == "top":
+ m2_arr = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl,
+ spacing=(0, m2.ymax - m2.ymin + m2_spacing),
+ )
+ m2_arr.movey(pc2.ymax + m2_spacing)
+
+ for i in range(nl):
+ for j in range(int(nf)):
+ if pat[j] == nt[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc2.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - ((1 - j % 2) * pc1.ymin)
+ - (j % 2) * pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + j * (l_gate + inter_sd_l)
+ ),
+ (1 - j % 2) * (pc1.ymin + 0.06)
+ + (j % 2) * (pc2.ymin + 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arr.ymin + i * (m2_spacing + m2_y),
+ m2_arr.ymin + i * (m2_spacing + m2_y) + m2_y,
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+ # c_inst.add_label(f'G_{pat[j]}{n}',position=((via1.xmax+via1.xmin)/2, (pc2.ymin + pc2.ymax)/2),layer=m1_lbl)
+
+ elif gate_con_pos == "bottom":
+ m2_arr = c_inst.add_array(
+ component=m2,
+ columns=1,
+ rows=nl,
+ spacing=(0, -m2_y - m2_spacing),
+ )
+ m2_arr.movey(pc2.ymin - m2_spacing - m2_y)
+
+ for i in range(nl):
+ for j in range(int(nf)):
+ if pat[j] == nt[i]:
+ m1 = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ poly_con.xmax - poly_con.xmin,
+ (
+ (
+ pc1.ymax
+ + (i + 1) * (m2_spacing + m2_y)
+ )
+ - (j % 2) * pc1.ymin
+ - (1 - j % 2) * pc2.ymin
+ ),
+ ),
+ layer=m1_layer,
+ )
+ )
+ m1.move(
+ (
+ (
+ sd_l
+ - (
+ (poly_con.xmax - poly_con.xmin - l_gate)
+ / 2
+ )
+ + j * (l_gate + inter_sd_l)
+ ),
+ -(m1.ymax - m1.ymin)
+ + (1 - j % 2) * (pc1.ymax - 0.06)
+ + (j % 2) * (pc2.ymax - 0.06),
+ )
+ )
+ via1_dr = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(
+ m2_arr.ymax - i * (m2_spacing + m2_y) - m2_y,
+ m2_arr.ymax - i * (m2_spacing + m2_y),
+ ),
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_size=via1_size,
+ via_spacing=via1_spacing,
+ )
+ via1 = c_inst.add_ref(via1_dr)
+ c_inst.add_label(
+ f"{pat[j]}",
+ position=(
+ (via1.xmax + via1.xmin) / 2,
+ (via1.ymax + via1.ymin) / 2,
+ ),
+ layer=m1_lbl,
+ )
+ # c_inst.add_label(f'G_{pat[j]}{n}',position=((via1.xmax+via1.xmin)/2, (pc2.ymin + pc2.ymax)/2),layer=m1_lbl)
+
+ # generating bulk
+ if bulk == "None":
+ psdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * diff_psdm_enc, w + 2 * diff_psdm_enc), layer=psdm_layer
+ )
+ )
+ psdm.move((-diff_psdm_enc, -diff_psdm_enc))
+
+ elif bulk == "bulk tie":
+ rect_bulk = c_inst.add_ref(
+ gf.components.rectangle(size=(1.3 * sd_l, w), layer=tap_layer)
+ )
+ rect_bulk.connect("e1", destination=sd_diff.ports["e3"])
+ psdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ sd_diff.xmax - sd_diff.xmin + diff_psdm_enc,
+ w + 2 * diff_psdm_enc,
+ ),
+ layer=psdm_layer,
+ )
+ )
+ psdm.move((-diff_psdm_enc, -diff_psdm_enc))
+ nsdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ rect_bulk.xmax - rect_bulk.xmin + tap_nsdm_enc,
+ w + 2 * tap_nsdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ nsdm.move((rect_bulk.xmin, rect_bulk.ymin - tap_nsdm_enc))
+
+ bulk_con = via_stack(
+ x_range=(rect_bulk.xmin + 0.1, rect_bulk.xmax - 0.1),
+ y_range=(rect_bulk.ymin, rect_bulk.ymax),
+ base_layer=tap_layer,
+ metal_level=0,
+ )
+ c_inst.add_ref(bulk_con)
+
+ elif bulk == "Gaurd Ring":
+ psdm = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(l_d + 2 * diff_psdm_enc, w + 2 * diff_psdm_enc), layer=psdm_layer
+ )
+ )
+ psdm.move((-diff_psdm_enc, -diff_psdm_enc))
+ c.add_ref(c_inst)
+
+ c_temp = gf.Component("temp_store")
+ rect_bulk_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (c_inst.xmax - c_inst.xmin) + 2 * diff_tap_spacing,
+ (c_inst.ymax - c_inst.ymin) + 2 * poly_tap_spacing,
+ ),
+ layer=tap_layer,
+ )
+ )
+
+ rect_bulk_in.move(
+ (c_inst.xmin - diff_tap_spacing, c_inst.ymin - poly_tap_spacing)
+ )
+ rect_bulk_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) + 2 * grw,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) + 2 * grw,
+ ),
+ layer=tap_layer,
+ )
+ )
+ rect_bulk_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw))
+ B = c.add_ref(
+ gf.geometry.boolean(
+ A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=tap_layer
+ )
+ )
+
+ nsdm_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) - 2 * tap_nsdm_enc,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) - 2 * tap_nsdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ nsdm_in.move(
+ (rect_bulk_in.xmin + tap_nsdm_enc, rect_bulk_in.ymin + tap_nsdm_enc)
+ )
+ nsdm_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_out.xmax - rect_bulk_out.xmin) + 2 * tap_nsdm_enc,
+ (rect_bulk_out.ymax - rect_bulk_out.ymin) + 2 * tap_nsdm_enc,
+ ),
+ layer=nsdm_layer,
+ )
+ )
+ nsdm_out.move(
+ (rect_bulk_out.xmin - tap_nsdm_enc, rect_bulk_out.ymin - tap_nsdm_enc)
+ )
+ nsdm = c.add_ref(
+ gf.geometry.boolean(
+ A=nsdm_out, B=nsdm_in, operation="A-B", layer=nsdm_layer
+ )
+ )
+
+ # adding contacts
+
+ if grw < licon_size[0] + 2 * licon_t_enc:
+ g_con_range = (B.ymin, B.ymax)
+ else:
+ g_con_range = (B.ymin, B.ymax)
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmin + 0.17, rect_bulk_in.xmax - 0.17),
+ y_range=(rect_bulk_out.ymin, rect_bulk_in.ymin),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmin + 0.17, rect_bulk_in.xmax - 0.17),
+ y_range=(rect_bulk_in.ymax, rect_bulk_out.ymax),
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_out.xmin, rect_bulk_in.xmin),
+ y_range=g_con_range,
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(rect_bulk_in.xmax, rect_bulk_out.xmax),
+ y_range=g_con_range,
+ via_enclosure=licon_dt_enc,
+ via_layer=licon_layer,
+ via_size=licon_size,
+ via_spacing=licon_spacing,
+ )
+ )
+
+ tap_li_in = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (l_d) + 2 * diff_tap_spacing,
+ (c_inst.ymax - c_inst.ymin) + 2 * poly_tap_spacing,
+ ),
+ layer=li_layer,
+ )
+ )
+ tap_li_in.move((-diff_tap_spacing, c_inst.ymin - poly_tap_spacing))
+ tap_li_out = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(
+ (rect_bulk_in.xmax - rect_bulk_in.xmin) + 2 * grw,
+ (rect_bulk_in.ymax - rect_bulk_in.ymin) + 2 * grw,
+ ),
+ layer=li_layer,
+ )
+ )
+ tap_li_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw))
+ c.add_ref(
+ gf.geometry.boolean(
+ A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=li_layer
+ )
+ )
+
+ # generating nwell
+ nwell = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ nsdm_out.xmax - nsdm_out.xmin + 2 * nwell_enclosing,
+ nsdm_out.ymax - nsdm_out.ymin + 2 * nwell_enclosing,
+ ),
+ layer=nwell_layer,
+ )
+ )
+ nwell.move((nsdm_out.xmin - nwell_enclosing, nsdm_out.ymin - nwell_enclosing))
+
+ if bulk != "Gaurd Ring":
+ c.add_ref(c_inst)
+
+ # nwell generation
+ nwell = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ c_inst.xmax - c_inst.xmin + 2 * nwell_enclosing,
+ (c_inst.ymax - c_inst.ymin) + 2 * nwell_enclosing,
+ ),
+ layer=nwell_layer,
+ )
+ )
+ nwell.move((c_inst.xmin - nwell_enclosing, c_inst.ymin - nwell_enclosing))
+
+ if type == "sky130_fd_pr__pfet_01v8_lvt":
+ lvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ nf * l_gate + (nf - 1) * inter_sd_l + 2 * gate_lvt_enc,
+ w + 2 * gate_lvt_enc,
+ ),
+ layer=lvtn_layer,
+ )
+ )
+ lvt.move((sd_l - gate_lvt_enc, -gate_lvt_enc))
+
+ if type == "sky130_fd_pr__pfet_01v8_hvt":
+ hvt = c_inst.add_ref(
+ gf.components.rectangle(
+ size=(
+ nf * l_gate + (nf - 1) * inter_sd_l + 2 * gate_hvt_enc,
+ w + 2 * gate_hvt_enc,
+ ),
+ layer=hvtp_layer,
+ )
+ )
+ hvt.move((sd_l - gate_hvt_enc, -gate_hvt_enc))
+
+ if type == "sky130_fd_pr__pfet_g5v0d10v5":
+ hvi = c.add_ref(
+ gf.components.rectangle(
+ size=(nwell.xmax - nwell.xmin, nwell.ymax - nwell.ymin), layer=hvi_layer
+ )
+ )
+ hvi.move((nwell.xmin, nwell.ymin))
+
+ # creating layout and cell in klayout
+ c.write_gds("pfet_temp.gds")
+ layout.read("pfet_temp.gds")
+ cell_name = "sky_pfet_dev"
+
+ return layout.cell(cell_name)
+ # return c
+
+
+if __name__ == "__main__":
+ c = draw_pfet()
+ c.show()
diff --git a/sky130/cells/klayout/pymacros/cells/draw_guard_ring.py b/sky130/cells/klayout/pymacros/cells/draw_guard_ring.py
new file mode 100644
index 000000000..0566bc190
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_guard_ring.py
@@ -0,0 +1,156 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## Guard Ring Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+
+import gdsfactory as gf
+
+from .layers_def import li_layer, licon_layer, m1_layer, mcon_layer, tap_layer
+from .via_generator import via_generator
+
+
+def draw_gr(layout, in_l: float = 1, in_w: float = 1, grw: float = 0.17, con_lev="li"):
+ """
+ layout : layout object
+ in_l : float of the inner length of the ring
+ in_w : float of the inner width of the ring
+ grw : float of the guard ring width
+ con_lev : connection level of (li, metal1)
+
+ """
+
+ con_size = (0.17, 0.17)
+ con_spacing = (0.19, 0.19)
+ con_enc = (0.12, 0.12)
+
+ c = gf.Component("sky_ring_gen")
+ c_temp = gf.Component("temp_store")
+
+ inner = c_temp.add_ref(gf.components.rectangle(size=(in_w, in_l), layer=tap_layer))
+ outer = c_temp.add_ref(
+ gf.components.rectangle(
+ size=(inner.xmax - inner.xmin + 2 * grw, inner.ymax - inner.ymin + 2 * grw),
+ layer=tap_layer,
+ )
+ )
+ outer.move((-grw, -grw))
+
+ c.add_ref(gf.geometry.boolean(A=outer, B=inner, operation="A-B", layer=tap_layer))
+
+ if con_lev == "li" or con_lev == "metal1":
+ c.add_ref(
+ gf.geometry.boolean(A=outer, B=inner, operation="A-B", layer=li_layer)
+ )
+
+ if grw < con_size[0] + 2 * con_enc[0]:
+ con_range = (inner.xmin, inner.xmax)
+ else:
+ con_range = (outer.xmin, outer.xmax)
+
+ c.add_ref(
+ via_generator(
+ x_range=(outer.xmin, inner.xmin),
+ y_range=(inner.ymin + 0.17, inner.ymax - 0.17),
+ via_enclosure=con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=(inner.xmax, outer.xmax),
+ y_range=(inner.ymin + 0.17, inner.ymax - 0.17),
+ via_enclosure=con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=con_range,
+ y_range=(inner.ymax, outer.ymax),
+ via_enclosure=con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=con_range,
+ y_range=(outer.ymin, inner.ymin),
+ via_enclosure=con_enc,
+ via_layer=licon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ if con_lev == "metal1":
+ c.add_ref(
+ gf.geometry.boolean(A=outer, B=inner, operation="A-B", layer=m1_layer)
+ )
+
+ c.add_ref(
+ via_generator(
+ x_range=(outer.xmin, inner.xmin),
+ y_range=(inner.ymin + 0.17, inner.ymax - 0.17),
+ via_enclosure=con_enc,
+ via_layer=mcon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=(inner.xmax, outer.xmax),
+ y_range=(inner.ymin + 0.17, inner.ymax - 0.17),
+ via_enclosure=con_enc,
+ via_layer=mcon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=con_range,
+ y_range=(inner.ymax, outer.ymax),
+ via_enclosure=con_enc,
+ via_layer=mcon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+ c.add_ref(
+ via_generator(
+ x_range=con_range,
+ y_range=(outer.ymin, inner.ymin),
+ via_enclosure=con_enc,
+ via_layer=mcon_layer,
+ via_size=con_size,
+ via_spacing=con_spacing,
+ )
+ )
+
+ c.write_gds("ring_temp.gds")
+ layout.read("ring_temp.gds")
+ cell_name = "sky_ring_gen"
+
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_rf.py b/sky130/cells/klayout/pymacros/cells/draw_rf.py
new file mode 100644
index 000000000..04cc7a820
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_rf.py
@@ -0,0 +1,74 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## RF Devices Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+
+import os
+
+from .globals import RF_BJT_DEV, RF_COILS_DEV, RF_MOSFET_DEV
+
+gds_p_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "fixed_devices/rf"
+) # parent file path
+
+
+def draw_rf_mosfet(layout, device_name):
+ """
+ drawing rf mosfet devices
+ """
+ gds_path = f"{gds_p_path}/rf_mosfet" # gds file path
+
+ if device_name in RF_MOSFET_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
+
+
+def draw_rf_bjt(layout, device_name):
+ """
+ drawing rf mosfet devices
+ """
+
+ gds_path = f"{gds_p_path}/rf_bjt" # gds file path
+
+ if device_name in RF_BJT_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
+
+
+def draw_rf_coils(layout, device_name):
+ """
+ drawing rf coils devices
+ """
+
+ gds_path = f"{gds_p_path}/rf_coils" # gds file path
+
+ if device_name in RF_COILS_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/draw_vpp.py b/sky130/cells/klayout/pymacros/cells/draw_vpp.py
new file mode 100644
index 000000000..4b364d91a
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/draw_vpp.py
@@ -0,0 +1,38 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+## VPP CAP Pcells Generators for Klayout of skywater130
+########################################################################################################################
+
+
+import os
+
+from .globals import VPP_CAP_DEV
+
+gds_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixed_devices/VPP")
+
+
+def draw_vpp(layout, device_name):
+ """
+ drawing VPP Capacitors devices
+ """
+
+ if device_name in VPP_CAP_DEV:
+ layout.read(f"{gds_path}/{device_name}.gds")
+ cell_name = device_name
+ else:
+ cell_name = device_name
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/fet.py b/sky130/cells/klayout/pymacros/cells/fet.py
new file mode 100644
index 000000000..d4c217afb
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fet.py
@@ -0,0 +1,349 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# MOSFET (PFET) Generator for skywater130
+########################################################################################################################
+
+import pya
+
+from .draw_fet import draw_nfet, draw_pfet
+
+fet_01v8_l = 0.15
+fet_g5v0_l = 0.5
+
+fet_w = 0.42
+
+fet_ld = 0.3
+fet_inter_ld = 0.3
+fet_01v8_grw = 0.17
+pfet_g5v0_grw = 0.3
+
+pfet_01v8_lvt_l = 0.35
+nfet_g5v0_nvt_l = 0.9
+
+
+class pfet(pya.PCellDeclarationHelper):
+ """
+ PMOS Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.param(
+ "con_bet_fin", self.TypeBoolean, "Contact Between Fingers", default=1
+ )
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__pfet_01v8", "sky130_fd_pr__pfet_01v8"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__pfet_01v8_lvt", "sky130_fd_pr__pfet_01v8_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__pfet_01v8_hvt", "sky130_fd_pr__pfet_01v8_hvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__pfet_g5v0d10v5", "sky130_fd_pr__pfet_g5v0d10v5"
+ )
+ self.Type_handle = self.param("bulk", self.TypeList, "Bulk Type")
+ self.Type_handle.add_choice("None", "None")
+ self.Type_handle.add_choice("bulk tie", "bulk tie")
+ self.Type_handle.add_choice("Gaurd Ring", "Gaurd Ring")
+ self.Type_handle = self.param(
+ "gate_con_pos", self.TypeList, "Gate Contact Position"
+ )
+ self.Type_handle.add_choice("top", "top")
+ self.Type_handle.add_choice("bottom", "bottom")
+ self.Type_handle.add_choice("alternating", "alternating")
+
+ self.param("l", self.TypeDouble, "length", default=fet_01v8_l, unit="um")
+ self.param("w", self.TypeDouble, "Width", default=fet_w, unit="um")
+ self.param("sd_con_col", self.TypeInt, "Diffusion Contacts Columns", default=1)
+ self.param(
+ "inter_sd_l",
+ self.TypeDouble,
+ "Between Fingers Diffusion Length",
+ default=fet_inter_ld,
+ unit="um",
+ )
+ self.param("nf", self.TypeInt, "Number of Fingers", default=1)
+ self.param(
+ "grw", self.TypeDouble, "Guard Ring Width", default=fet_01v8_grw, unit="um"
+ )
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+
+ self.param("interdig", self.TypeBoolean, "Interdigitation", default=0)
+ self.param(
+ "patt", self.TypeString, "Pattern in case of Interdigitation", default=""
+ )
+
+ # self.param("n", self.TypeInt, "inst_num", default=1)
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "pfet(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+ # w,l must be larger or equal than min. values.
+ if self.type == "sky130_fd_pr__pfet_g5v0d10v5":
+ if (self.l) < fet_g5v0_l:
+ self.l = fet_g5v0_l
+ if (self.w) < fet_w:
+ self.w = fet_w
+ if (self.grw) < pfet_g5v0_grw:
+ self.grw = pfet_g5v0_grw
+ else:
+ if (self.l) < fet_01v8_l:
+ self.l = fet_01v8_l
+ if (self.w) < fet_w:
+ self.w = fet_w
+ if (self.grw) < fet_01v8_grw:
+ self.grw = fet_01v8_grw
+
+ if self.type == "sky130_fd_pr__pfet_01v8_lvt":
+ if (self.l) < pfet_01v8_lvt_l:
+ self.l = pfet_01v8_lvt_l
+ else:
+ if (self.l) < fet_01v8_l:
+ self.l = fet_01v8_l
+
+ if (self.sd_con_col) < 1:
+ self.sd_con_col = 1
+
+ if (self.inter_sd_l) < fet_inter_ld and self.con_bet_fin == 1:
+ self.inter_sd_l = fet_inter_ld
+ elif (self.inter_sd_l) < 0.21 and self.con_bet_fin == 0:
+ self.inter_sd_l = 0.21
+
+ if self.interdig == 1 and self.gate_con_pos != "alternating":
+ self.inter_sd_l = 0.5
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_pfet(
+ layout=self.layout,
+ l_gate=self.l,
+ w=self.w,
+ sd_con_col=self.sd_con_col,
+ inter_sd_l=self.inter_sd_l,
+ nf=self.nf,
+ grw=self.grw,
+ type=self.type,
+ bulk=self.bulk,
+ con_bet_fin=self.con_bet_fin,
+ gate_con_pos=self.gate_con_pos,
+ interdig=self.interdig,
+ patt=self.patt,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
+
+
+class nfet(pya.PCellDeclarationHelper):
+ """
+ NMOS Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.param(
+ "con_bet_fin", self.TypeBoolean, "Contact Between Fingers", default=1
+ )
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__nfet_01v8", "sky130_fd_pr__nfet_01v8"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__nfet_01v8_lvt", "sky130_fd_pr__nfet_01v8_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__nfet_03v3_nvt", "sky130_fd_pr__nfet_03v3_nvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__nfet_05v0_nvt", "sky130_fd_pr__nfet_05v0_nvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__nfet_g5v0d10v5", "sky130_fd_pr__nfet_g5v0d10v5"
+ )
+ self.Type_handle = self.param("bulk", self.TypeList, "Bulk Type")
+ self.Type_handle.add_choice("None", "None")
+ self.Type_handle.add_choice("bulk tie", "bulk tie")
+ self.Type_handle.add_choice("Gaurd Ring", "Gaurd Ring")
+ self.Type_handle = self.param(
+ "gate_con_pos", self.TypeList, "Gate Contact Position"
+ )
+ self.Type_handle.add_choice("top", "top")
+ self.Type_handle.add_choice("bottom", "bottom")
+ self.Type_handle.add_choice("alternating", "alternating")
+
+ self.param("l", self.TypeDouble, "length", default=fet_01v8_l, unit="um")
+ self.param("w", self.TypeDouble, "Width", default=fet_w, unit="um")
+ self.param(
+ "sd_con_col",
+ self.TypeDouble,
+ "Diffusion Contacts Columns",
+ default=fet_ld,
+ unit="um",
+ )
+ self.param(
+ "inter_sd_l",
+ self.TypeDouble,
+ "Between Fingers Diffusion Length",
+ default=fet_inter_ld,
+ unit="um",
+ )
+ self.param("nf", self.TypeInt, "Number of Fingers", default=1)
+ self.param(
+ "grw", self.TypeDouble, "Guard Ring Width", default=fet_01v8_grw, unit="um"
+ )
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param("perim", self.TypeDouble, "Perimeter", readonly=True, unit="um")
+
+ self.param("interdig", self.TypeBoolean, "Interdigitation", default=0)
+ self.param(
+ "patt", self.TypeString, "Pattern in case of Interdigitation", default=""
+ )
+
+ # self.param("n", self.TypeInt, "inst_num", default=1)
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "nfet(L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ self.area = self.w * self.l
+ self.perim = 2 * (self.w + self.l)
+ # w,l must be larger or equal than min. values.
+ if (
+ self.type == "sky130_fd_pr__nfet_03v3_nvt"
+ or self.type == "sky130_fd_pr__nfet_05v0_nvt"
+ or self.type == "sky130_fd_pr__nfet_g5v0d10v5"
+ ):
+ if (self.l) < fet_g5v0_l:
+ self.l = fet_g5v0_l
+ if (self.w) < fet_w:
+ self.w = fet_w
+ if (self.grw) < pfet_g5v0_grw:
+ self.grw = pfet_g5v0_grw
+
+ if self.type == "sky130_fd_pr__nfet_05v0_nvt":
+ if (self.l) < nfet_g5v0_nvt_l:
+ self.l = nfet_g5v0_nvt_l
+
+ else:
+ if (self.l) < fet_01v8_l:
+ self.l = fet_01v8_l
+ if (self.w) < fet_w:
+ self.w = fet_w
+ if (self.grw) < fet_01v8_grw:
+ self.grw = fet_01v8_grw
+
+ if (self.sd_con_col) < 1:
+ self.sd_con_col = 1
+
+ if (self.inter_sd_l) < fet_inter_ld and self.con_bet_fin == 1:
+ self.inter_sd_l = fet_inter_ld
+ elif self.inter_sd_l < 0.21 and self.con_bet_fin == 0:
+ self.inter_sd_l = 0.21
+
+ if self.interdig == 1 and self.gate_con_pos != "alternating":
+ self.inter_sd_l = 0.5
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_nfet(
+ layout=self.layout,
+ l_gate=self.l,
+ w=self.w,
+ sd_con_col=self.sd_con_col,
+ inter_sd_l=self.inter_sd_l,
+ nf=self.nf,
+ grw=self.grw,
+ type=self.type,
+ bulk=self.bulk,
+ con_bet_fin=self.con_bet_fin,
+ gate_con_pos=self.gate_con_pos,
+ interdig=self.interdig,
+ patt=self.patt,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.cdl
new file mode 100644
index 000000000..11eeba181
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield C0 C1 SUB cap_1 cap_2
+
+Cx C0 C1 SUB cap_1 cap_2 sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.gds
new file mode 100644
index 000000000..ff5d63ec9
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.cdl
new file mode 100644
index 000000000..518ce4d4e
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.gds
new file mode 100644
index 000000000..9cb3a10fe
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.cdl
new file mode 100644
index 000000000..dd2386ea1
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.gds
new file mode 100644
index 000000000..79d364830
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.cdl
new file mode 100644
index 000000000..c0967eccd
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.gds
new file mode 100644
index 000000000..71a2bdae5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.cdl
new file mode 100644
index 000000000..54f76bfff
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.gds
new file mode 100644
index 000000000..fd71f1faa
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.cdl
new file mode 100644
index 000000000..9d2c3bd40
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.gds
new file mode 100644
index 000000000..2787b9974
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.cdl
new file mode 100644
index 000000000..99f60b116
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3 C0 C1 MET3 SUB
+
+Cx C0 C1 MET3 SUB sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.gds
new file mode 100644
index 000000000..daf9bb77a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.cdl
new file mode 100644
index 000000000..111459af2
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.gds
new file mode 100644
index 000000000..d683bc6c1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.cdl
new file mode 100644
index 000000000..fca65f021
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell
+
+Cx sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.gds
new file mode 100644
index 000000000..9183233d7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield_o2subcell.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.cdl
new file mode 100644
index 000000000..27c980304
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3 C0 C1 MET3 SUB
+
+Cx C0 C1 MET3 SUB sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.gds
new file mode 100644
index 000000000..0e9f487d7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.cdl
new file mode 100644
index 000000000..7f414f417
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.gds
new file mode 100644
index 000000000..efe5c5e4d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.cdl
new file mode 100644
index 000000000..2fc44f5b1
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.gds
new file mode 100644
index 000000000..acfdf465c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.cdl
new file mode 100644
index 000000000..fa4e6b86f
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.gds
new file mode 100644
index 000000000..1de0ae822
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.cdl
new file mode 100644
index 000000000..136d1fc4e
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.gds
new file mode 100644
index 000000000..828d52138
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.cdl
new file mode 100644
index 000000000..ed0cacadf
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.gds
new file mode 100644
index 000000000..dce4d90f0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.cdl
new file mode 100644
index 000000000..a938dd141
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.gds
new file mode 100644
index 000000000..477b1d893
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.cdl
new file mode 100644
index 000000000..0b6348eb8
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.gds
new file mode 100644
index 000000000..6ca8d242d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.cdl
new file mode 100644
index 000000000..01b50a16a
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4 C0 C1 MET4 SUB
+
+Cx C0 C1 MET4 SUB sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.gds
new file mode 100644
index 000000000..2f410580c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.cdl
new file mode 100644
index 000000000..4646039fa
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top C0 C1 M4 SUB
+
+Cx C0 C1 M4 SUB sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.gds
new file mode 100644
index 000000000..b2a769291
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.cdl
new file mode 100644
index 000000000..2668d2879
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4 C0 C1 MET4 SUB
+
+Cx C0 C1 MET4 SUB sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.gds
new file mode 100644
index 000000000..ce99b1d15
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.cdl
new file mode 100644
index 000000000..5fa88d550
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top C0 C1 M4 SUB
+
+Cx C0 C1 M4 SUB sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.gds
new file mode 100644
index 000000000..66baf8adf
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.cdl
new file mode 100644
index 000000000..d1b88291b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.gds
new file mode 100644
index 000000000..778513d36
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.cdl
new file mode 100644
index 000000000..52d9efdd9
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell
+
+Cx sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.gds
new file mode 100644
index 000000000..289ba6859
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield_o2subcell.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.cdl
new file mode 100644
index 000000000..c25671d11
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3 C0 C1 MET3 SUB
+
+Cx C0 C1 MET3 SUB sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.gds
new file mode 100644
index 000000000..90b53a02c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.cdl
new file mode 100644
index 000000000..be024e591
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.gds
new file mode 100644
index 000000000..23972c594
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.cdl
new file mode 100644
index 000000000..d371ed437
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.gds
new file mode 100644
index 000000000..b7a848e2a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.cdl
new file mode 100644
index 000000000..ee42d6c67
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.gds
new file mode 100644
index 000000000..0005588f4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.cdl
new file mode 100644
index 000000000..ef3855f80
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.gds
new file mode 100644
index 000000000..ca8a1c088
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.cdl
new file mode 100644
index 000000000..4396a41e3
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.gds
new file mode 100644
index 000000000..5f0abce6a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.cdl
new file mode 100644
index 000000000..efc1a7b40
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.gds
new file mode 100644
index 000000000..f36bda0d6
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.cdl
new file mode 100644
index 000000000..e5fbb6aeb
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv C0 C1 MET5
+
+Cx C0 C1 MET5 sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.gds
new file mode 100644
index 000000000..976d3a154
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.cdl
new file mode 100644
index 000000000..e8351cf70
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop C0 M5 SUB
+
+Cx C0 M5 SUB sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.gds
new file mode 100644
index 000000000..53c24fe96
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.cdl
new file mode 100644
index 000000000..800d32907
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.gds
new file mode 100644
index 000000000..ba7a488e3
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.cdl
new file mode 100644
index 000000000..e2fe693ab
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3 C0 C1 MET3 SUB
+
+Cx C0 C1 MET3 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.gds
new file mode 100644
index 000000000..afe2c605e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.cdl
new file mode 100644
index 000000000..5a8acc878
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4 C0 C1 MET4 SUB
+
+Cx C0 C1 MET4 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.gds
new file mode 100644
index 000000000..1ee3f03f3
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.cdl
new file mode 100644
index 000000000..d4d0ba68e
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top C0 C1 M4 SUB
+
+Cx C0 C1 M4 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.gds
new file mode 100644
index 000000000..3c4097bba
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.cdl
new file mode 100644
index 000000000..44119b570
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4 C0 C1 MET4 SUB
+
+Cx C0 C1 MET4 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.gds
new file mode 100644
index 000000000..06e53e0bb
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.cdl
new file mode 100644
index 000000000..1920407f4
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top C0 C1 M4 SUB
+
+Cx C0 C1 M4 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.gds
new file mode 100644
index 000000000..999555559
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.cdl
new file mode 100644
index 000000000..da38c67bd
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.gds
new file mode 100644
index 000000000..08df3df80
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.cdl
new file mode 100644
index 000000000..814c371da
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.gds
new file mode 100644
index 000000000..2f3b2c69e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.cdl
new file mode 100644
index 000000000..48627283b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.gds
new file mode 100644
index 000000000..464efc253
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.cdl
new file mode 100644
index 000000000..f0c0cb0ed
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.gds
new file mode 100644
index 000000000..d5cb6b9fd
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.cdl
new file mode 100644
index 000000000..0c50a9ec9
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.gds
new file mode 100644
index 000000000..0bc8a95f3
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.cdl
new file mode 100644
index 000000000..6b3e7a551
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6 C0 C1 M5A SUB
+
+Cx C0 C1 M5A SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.gds
new file mode 100644
index 000000000..1847eb88b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x6.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.cdl
new file mode 100644
index 000000000..88080e11d
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7 C0 C1 M5A SUB
+
+Cx C0 C1 M5A SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.gds
new file mode 100644
index 000000000..b772653dc
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x7.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.cdl
new file mode 100644
index 000000000..b1e5188c8
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8 C0 C1 M5A SUB
+
+Cx C0 C1 M5A SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.gds
new file mode 100644
index 000000000..4fbabaed7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x8.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.cdl
new file mode 100644
index 000000000..14d8a0a64
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9 C0 C1 M5A SUB
+
+Cx C0 C1 M5A SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.gds
new file mode 100644
index 000000000..25a469b89
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x9.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.cdl
new file mode 100644
index 000000000..898cfd780
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.gds
new file mode 100644
index 000000000..05dc89273
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_xtop.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.cdl
new file mode 100644
index 000000000..3941b7713
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.gds
new file mode 100644
index 000000000..c2bbe1c31
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.cdl
new file mode 100644
index 000000000..54be7e2f5
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.gds
new file mode 100644
index 000000000..82c08aaff
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.cdl
new file mode 100644
index 000000000..999d41fa8
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1 C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.gds
new file mode 100644
index 000000000..a392bff05
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.cdl
new file mode 100644
index 000000000..8e1964500
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.gds
new file mode 100644
index 000000000..c30af6608
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.cdl
new file mode 100644
index 000000000..da62a0dea
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.gds
new file mode 100644
index 000000000..77e58a667
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.cdl
new file mode 100644
index 000000000..7ab4718a2
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.gds
new file mode 100644
index 000000000..448b149b1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.cdl
new file mode 100644
index 000000000..7cbe7504a
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top C0 C1 M5 SUB
+
+Cx C0 C1 M5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.gds
new file mode 100644
index 000000000..94e311f4e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_top.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.cdl
new file mode 100644
index 000000000..0149bf1f8
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5 C0 C1 MET5 SUB
+
+Cx C0 C1 MET5 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.gds
new file mode 100644
index 000000000..d9df5b26f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.cdl
new file mode 100644
index 000000000..33184d9a0
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.gds
new file mode 100644
index 000000000..cb054bd04
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..a0fd54a09
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..0c1209f89
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x11p7_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..1b24bd6ee
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..39e57a1d5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_11p5x23p1_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..b7ddf7ad7
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..f03feb88f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x11p7_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..b2989951b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..36e3b6569
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_22p5x23p1_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..eef7614b6
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..582d6c439
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x11p7_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..5a966c42e
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..8c4f3a7f0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_33p6x23p1_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..9c615a309
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..83286101d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x11p7_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..80ec3c196
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield C0 C1 SUB
+
+Cx C0 C1 SUB sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..e0dddea6d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..269a677dd
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..f67ba8ab2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.cdl
new file mode 100644
index 000000000..b4da70ef8
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin
+
+Cx sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.gds
new file mode 100644
index 000000000..afec93bc2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x11p7_pol1m1m2m3m4m5_noshield_m5pullin.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.cdl
new file mode 100644
index 000000000..1913ea38a
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield
+
+Cx sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.gds
new file mode 100644
index 000000000..9f8737da4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.cdl
new file mode 100644
index 000000000..242509984
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin
+
+Cx sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.gds
new file mode 100644
index 000000000..847336aa2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_m5pullin.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.cdl b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.cdl
new file mode 100644
index 000000000..1005a491c
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.cdl
@@ -0,0 +1,22 @@
+
+# Copyright 2022 SkyWater PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+.SUBCKT sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test
+
+Cx sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test
+
+.ENDS
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.gds
new file mode 100644
index 000000000..61ce4db39
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/VPP/sky130_fd_pr__cap_vpp_55p8x23p1_pol1m1m2m3m4m5_noshield_test.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L1p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L1p00.gds
new file mode 100644
index 000000000..c9f225525
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L1p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L2p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L2p00.gds
new file mode 100644
index 000000000..614b8448e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_05v5_W1p00L2p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_11v0_W1p00L1p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_11v0_W1p00L1p00.gds
new file mode 100644
index 000000000..ff1993b9a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/npn/sky130_fd_pr__npn_11v0_W1p00L1p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds
new file mode 100644
index 000000000..a92674ad6
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds
new file mode 100644
index 000000000..72fdc7e8f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/bjt/pnp/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/photodiode/sky130_fd_pr__photodiode.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/photodiode/sky130_fd_pr__photodiode.gds
new file mode 100644
index 000000000..90127dfe9
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/photodiode/sky130_fd_pr__photodiode.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L4p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L4p00.gds
new file mode 100644
index 000000000..c8267e53e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L4p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L8p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L8p00.gds
new file mode 100644
index 000000000..a6cff017e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W1p00L8p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L2p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L2p00.gds
new file mode 100644
index 000000000..ce598ddf5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L2p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L4p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L4p00.gds
new file mode 100644
index 000000000..536749acb
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L4p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L8p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L8p00.gds
new file mode 100644
index 000000000..58d2f193c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W2p00L8p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W5p00L5p00.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W5p00L5p00.gds
new file mode 100644
index 000000000..9316015a3
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_bjt/sky130_fd_pr__rf_npn_05v5_W5p00L5p00.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil1.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil1.gds
new file mode 100644
index 000000000..3890733b5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil1.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil2.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil2.gds
new file mode 100644
index 000000000..909999b16
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil2.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil3.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil3.gds
new file mode 100644
index 000000000..0537acb06
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_coils/sky130_fd_pr__rf_test_coil3.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p15.gds
new file mode 100644
index 000000000..46e89059d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p18.gds
new file mode 100644
index 000000000..0694b18e8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p25.gds
new file mode 100644
index 000000000..88d7d19a6
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p15.gds
new file mode 100644
index 000000000..39214c448
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p18.gds
new file mode 100644
index 000000000..7a6d1a41a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p25.gds
new file mode 100644
index 000000000..9b159cc15
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p15.gds
new file mode 100644
index 000000000..b04f2b648
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p18.gds
new file mode 100644
index 000000000..273792844
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p25.gds
new file mode 100644
index 000000000..c5fc66677
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p15.gds
new file mode 100644
index 000000000..0e73812f4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p18.gds
new file mode 100644
index 000000000..29c52903e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p25.gds
new file mode 100644
index 000000000..c38358f88
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p15.gds
new file mode 100644
index 000000000..3ce81e362
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p18.gds
new file mode 100644
index 000000000..99b4c7003
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p25.gds
new file mode 100644
index 000000000..db95070b8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p15.gds
new file mode 100644
index 000000000..a8caafca8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p18.gds
new file mode 100644
index 000000000..bf1123df9
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p25.gds
new file mode 100644
index 000000000..5e100d47e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_aM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p15.gds
new file mode 100644
index 000000000..d9e272a50
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p18.gds
new file mode 100644
index 000000000..9b8a81ab9
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p25.gds
new file mode 100644
index 000000000..142407f69
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p15.gds
new file mode 100644
index 000000000..921d9a2ab
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p18.gds
new file mode 100644
index 000000000..f35f99dd8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p25.gds
new file mode 100644
index 000000000..836a8db7a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p15.gds
new file mode 100644
index 000000000..720d0b722
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p18.gds
new file mode 100644
index 000000000..3e7aae964
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p25.gds
new file mode 100644
index 000000000..055bf2fd7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p15.gds
new file mode 100644
index 000000000..f1d88dd84
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p18.gds
new file mode 100644
index 000000000..3f155c08d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p25.gds
new file mode 100644
index 000000000..2f0734932
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p15.gds
new file mode 100644
index 000000000..c88c13402
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p18.gds
new file mode 100644
index 000000000..ad4c754ce
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p25.gds
new file mode 100644
index 000000000..be3552b73
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p15.gds
new file mode 100644
index 000000000..dd06de89c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p18.gds
new file mode 100644
index 000000000..a146eb954
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p25.gds
new file mode 100644
index 000000000..93452aac2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W3p00L0p15.gds
new file mode 100644
index 000000000..c078a534c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W5p00L0p15.gds
new file mode 100644
index 000000000..04080d383
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_hcM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p42L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p42L0p15.gds
new file mode 100644
index 000000000..6c72f6f9b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p42L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p84L0p15.gds
new file mode 100644
index 000000000..3865c6620
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W1p65L0p15.gds
new file mode 100644
index 000000000..26ba4259a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W3p00L0p15.gds
new file mode 100644
index 000000000..2724636bc
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p42L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p42L0p15.gds
new file mode 100644
index 000000000..f89297119
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p42L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p84L0p15.gds
new file mode 100644
index 000000000..d36481549
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W1p65L0p15.gds
new file mode 100644
index 000000000..f4691dc99
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W3p00L0p15.gds
new file mode 100644
index 000000000..ad8cf001e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p42L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p42L0p15.gds
new file mode 100644
index 000000000..975fec49b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p42L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p84L0p15.gds
new file mode 100644
index 000000000..c7b17d400
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W1p65L0p15.gds
new file mode 100644
index 000000000..4b8d694db
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W3p00L0p15.gds
new file mode 100644
index 000000000..4ab700db7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF06W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p42L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p42L0p15.gds
new file mode 100644
index 000000000..dab8d1d9c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p42L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p84L0p15.gds
new file mode 100644
index 000000000..fc13c9400
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W1p65L0p15.gds
new file mode 100644
index 000000000..95998b68b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W3p00L0p15.gds
new file mode 100644
index 000000000..97fa4c9ac
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aF08W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p15.gds
new file mode 100644
index 000000000..b180e26e4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p18.gds
new file mode 100644
index 000000000..75359b314
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p25.gds
new file mode 100644
index 000000000..846a45def
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p15.gds
new file mode 100644
index 000000000..de74f0acd
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p18.gds
new file mode 100644
index 000000000..6af0911d4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p25.gds
new file mode 100644
index 000000000..3c4564704
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p15.gds
new file mode 100644
index 000000000..1e123aec1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p18.gds
new file mode 100644
index 000000000..26db4da66
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p25.gds
new file mode 100644
index 000000000..63bd88901
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p15.gds
new file mode 100644
index 000000000..385e1c89e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p18.gds
new file mode 100644
index 000000000..db5ae74ed
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p25.gds
new file mode 100644
index 000000000..b5b0be4f0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p15.gds
new file mode 100644
index 000000000..1e6e93044
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p18.gds
new file mode 100644
index 000000000..a60ab13b7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p25.gds
new file mode 100644
index 000000000..d16e55ee0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p15.gds
new file mode 100644
index 000000000..10b041647
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p18.gds
new file mode 100644
index 000000000..682cf326b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p25.gds
new file mode 100644
index 000000000..d9430b110
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_aM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p15.gds
new file mode 100644
index 000000000..c98b3952e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p18.gds
new file mode 100644
index 000000000..98b5d0e49
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p25.gds
new file mode 100644
index 000000000..7c0bfe365
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p15.gds
new file mode 100644
index 000000000..2deec9f4e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p18.gds
new file mode 100644
index 000000000..760010e26
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p25.gds
new file mode 100644
index 000000000..92455d1ec
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p15.gds
new file mode 100644
index 000000000..dda05ae26
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p18.gds
new file mode 100644
index 000000000..d7b46b954
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p25.gds
new file mode 100644
index 000000000..0d5c60722
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p15.gds
new file mode 100644
index 000000000..20430de63
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p18.gds
new file mode 100644
index 000000000..3fda62577
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p25.gds
new file mode 100644
index 000000000..1c381b26c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p15.gds
new file mode 100644
index 000000000..c5bd736e1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p18.gds
new file mode 100644
index 000000000..48d78026e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p25.gds
new file mode 100644
index 000000000..796ca9de4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p15.gds
new file mode 100644
index 000000000..86684842b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p18.gds
new file mode 100644
index 000000000..865e272b4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p25.gds
new file mode 100644
index 000000000..e4452a38b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p15.gds
new file mode 100644
index 000000000..dbeae6f26
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p18.gds
new file mode 100644
index 000000000..3e7d706bc
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p25.gds
new file mode 100644
index 000000000..137c5dcf8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p15.gds
new file mode 100644
index 000000000..864d14532
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p18.gds
new file mode 100644
index 000000000..c60f58b92
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p25.gds
new file mode 100644
index 000000000..fe96bbc4f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p15.gds
new file mode 100644
index 000000000..e8333d6f0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p18.gds
new file mode 100644
index 000000000..18ace17a0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p25.gds
new file mode 100644
index 000000000..61bb2fb2c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p15.gds
new file mode 100644
index 000000000..7fa16fd67
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p18.gds
new file mode 100644
index 000000000..8db8dc8e1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p25.gds
new file mode 100644
index 000000000..601647e0f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p15.gds
new file mode 100644
index 000000000..147ff9ed2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p18.gds
new file mode 100644
index 000000000..3dd649484
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p25.gds
new file mode 100644
index 000000000..2384728d0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p15.gds
new file mode 100644
index 000000000..226adae74
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p18.gds
new file mode 100644
index 000000000..9c5b695a6
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p25.gds
new file mode 100644
index 000000000..989f7d15f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_lvt_cM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W3p00L0p15.gds
new file mode 100644
index 000000000..8d2560679
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W5p00L0p15.gds
new file mode 100644
index 000000000..4e78a32c4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_01v8_mcM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_aup.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_aup.gds
new file mode 100644
index 000000000..35572c5b2
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_aup.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_noptap_iso.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_noptap_iso.gds
new file mode 100644
index 000000000..fab064b94
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_noptap_iso.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_aup.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_aup.gds
new file mode 100644
index 000000000..d119d3a9d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_aup.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_noptap_iso.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_noptap_iso.gds
new file mode 100644
index 000000000..86f739cac
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_noptap_iso.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap.gds
new file mode 100644
index 000000000..7ac0f31ae
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap_iso.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap_iso.gds
new file mode 100644
index 000000000..e5a6bc9c8
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_nvt_withptap_iso.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap.gds
new file mode 100644
index 000000000..d7e764420
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap_iso.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap_iso.gds
new file mode 100644
index 000000000..460d362f9
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_withptap_iso.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_zvt_withptap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_zvt_withptap.gds
new file mode 100644
index 000000000..8f2fee391
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_20v0_zvt_withptap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W3p00L0p50.gds
new file mode 100644
index 000000000..5b133cac1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W5p00L0p50.gds
new file mode 100644
index 000000000..7aa37b834
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W7p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W7p00L0p50.gds
new file mode 100644
index 000000000..b46ca3601
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM04W7p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W3p00L0p50.gds
new file mode 100644
index 000000000..5b0f9c818
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W5p00L0p50.gds
new file mode 100644
index 000000000..bee7bcbfe
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W7p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W7p00L0p50.gds
new file mode 100644
index 000000000..c51df25d7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_aM10W7p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W3p00L0p50.gds
new file mode 100644
index 000000000..75b3cbdee
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W5p00L0p50.gds
new file mode 100644
index 000000000..a2261d7a0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W3p00L0p50.gds
new file mode 100644
index 000000000..04acce1fe
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W5p00L0p50.gds
new file mode 100644
index 000000000..35fc5aab5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W7p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W7p00L0p50.gds
new file mode 100644
index 000000000..bbae5f44e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W7p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W3p00L0p50.gds
new file mode 100644
index 000000000..7048b1a47
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W5p00L0p50.gds
new file mode 100644
index 000000000..da538f9fb
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W7p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W7p00L0p50.gds
new file mode 100644
index 000000000..9cd4349cc
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W7p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W0p84L0p15.gds
new file mode 100644
index 000000000..164f5dbb6
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W1p68L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W1p68L0p15.gds
new file mode 100644
index 000000000..4d8f4726e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W1p68L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W2p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W2p00L0p15.gds
new file mode 100644
index 000000000..bda29caee
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W2p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W3p00L0p15.gds
new file mode 100644
index 000000000..ab46016e0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W5p00L0p15.gds
new file mode 100644
index 000000000..d5caeab8f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W0p84L0p15.gds
new file mode 100644
index 000000000..09d6c83b1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W1p68L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W1p68L0p15.gds
new file mode 100644
index 000000000..2c8d2debd
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W1p68L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W2p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W2p00L0p15.gds
new file mode 100644
index 000000000..f492228ad
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W2p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W3p00L0p15.gds
new file mode 100644
index 000000000..b579ee867
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W5p00L0p15.gds
new file mode 100644
index 000000000..031c6714d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W0p84L0p15.gds
new file mode 100644
index 000000000..aa1552eed
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W1p68L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W1p68L0p15.gds
new file mode 100644
index 000000000..060ab5492
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W1p68L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W2p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W2p00L0p15.gds
new file mode 100644
index 000000000..b093affda
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W2p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W3p00L0p15.gds
new file mode 100644
index 000000000..039409717
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF06W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W0p84L0p15.gds
new file mode 100644
index 000000000..33dd7319b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W1p68L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W1p68L0p15.gds
new file mode 100644
index 000000000..2e77923fc
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aF08W1p68L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p15.gds
new file mode 100644
index 000000000..12a117346
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p18.gds
new file mode 100644
index 000000000..cf292a858
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p25.gds
new file mode 100644
index 000000000..bfad7972e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p15.gds
new file mode 100644
index 000000000..6e78aa646
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p18.gds
new file mode 100644
index 000000000..8673c5f79
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p25.gds
new file mode 100644
index 000000000..1ab9a7986
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p15.gds
new file mode 100644
index 000000000..08f29ea95
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p18.gds
new file mode 100644
index 000000000..151b7ef46
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p25.gds
new file mode 100644
index 000000000..13b1e1a4f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p15.gds
new file mode 100644
index 000000000..a84ab8cb7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p18.gds
new file mode 100644
index 000000000..5804fa99d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p25.gds
new file mode 100644
index 000000000..ed76274fb
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p15.gds
new file mode 100644
index 000000000..5768cba7c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p18.gds
new file mode 100644
index 000000000..4cde6f452
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p25.gds
new file mode 100644
index 000000000..9c27d27f4
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p15.gds
new file mode 100644
index 000000000..5d8be3d3d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p18.gds
new file mode 100644
index 000000000..22ba8e45e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p25.gds
new file mode 100644
index 000000000..2c74ff7ff
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_aM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p15.gds
new file mode 100644
index 000000000..13ee963a1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p18.gds
new file mode 100644
index 000000000..21c707f1b
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p25.gds
new file mode 100644
index 000000000..c3f3da09d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p15.gds
new file mode 100644
index 000000000..e3f25c3d1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p18.gds
new file mode 100644
index 000000000..ca8b60c2f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p25.gds
new file mode 100644
index 000000000..0fd2689bf
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p15.gds
new file mode 100644
index 000000000..c3adafb04
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p18.gds
new file mode 100644
index 000000000..630bcd276
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p25.gds
new file mode 100644
index 000000000..1ef07a6b0
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p15.gds
new file mode 100644
index 000000000..be2aa5efa
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p18.gds
new file mode 100644
index 000000000..b39e1dc95
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p25.gds
new file mode 100644
index 000000000..52569a07a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p15.gds
new file mode 100644
index 000000000..f8e37b56a
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p18.gds
new file mode 100644
index 000000000..3b09a5785
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p25.gds
new file mode 100644
index 000000000..bed909209
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p15.gds
new file mode 100644
index 000000000..f2d6f3cd7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p18.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p18.gds
new file mode 100644
index 000000000..c446cff91
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p18.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p25.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p25.gds
new file mode 100644
index 000000000..374b61592
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p25.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W3p00L0p15.gds
new file mode 100644
index 000000000..ca613fa4f
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W5p00L0p15.gds
new file mode 100644
index 000000000..c29d732e3
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_hcM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p35.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p35.gds
new file mode 100644
index 000000000..6c8cea017
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p35.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p50.gds
new file mode 100644
index 000000000..93ffc1b5e
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p35.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p35.gds
new file mode 100644
index 000000000..96e15e41c
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p35.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p50.gds
new file mode 100644
index 000000000..cf01787d5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM02W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p35.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p35.gds
new file mode 100644
index 000000000..6ed07a1d1
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p35.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p50.gds
new file mode 100644
index 000000000..28e4e5372
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W3p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p35.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p35.gds
new file mode 100644
index 000000000..fe1176eb7
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p35.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p50.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p50.gds
new file mode 100644
index 000000000..1ea7b4c3d
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_lvt_aM04W5p00L0p50.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W3p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W3p00L0p15.gds
new file mode 100644
index 000000000..d176a8914
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W3p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W5p00L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W5p00L0p15.gds
new file mode 100644
index 000000000..675a65206
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mcM04W5p00L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mvt_aF02W0p84L0p15.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mvt_aF02W0p84L0p15.gds
new file mode 100644
index 000000000..9358e6aee
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_01v8_mvt_aF02W0p84L0p15.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_20v0_withptap.gds b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_20v0_withptap.gds
new file mode 100644
index 000000000..8e8762cf5
Binary files /dev/null and b/sky130/cells/klayout/pymacros/cells/fixed_devices/rf/rf_mosfet/sky130_fd_pr__rf_pfet_20v0_withptap.gds differ
diff --git a/sky130/cells/klayout/pymacros/cells/globals.py b/sky130/cells/klayout/pymacros/cells/globals.py
new file mode 100644
index 000000000..7c8c5ed40
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/globals.py
@@ -0,0 +1,70 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# Global parameters generation
+########################################################################################################################
+
+import glob
+import os
+
+# Listing device names
+
+fixed_dev_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "fixed_devices"
+) # parent file path
+
+BJT_NPN_DEV = glob.glob(f"{fixed_dev_path}/bjt/npn/*")
+
+for i in range(len(BJT_NPN_DEV)):
+ BJT_NPN_DEV[i] = BJT_NPN_DEV[i].split("/")[-1]
+ BJT_NPN_DEV[i] = BJT_NPN_DEV[i][:-4]
+
+
+BJT_PNP_DEV = glob.glob(f"{fixed_dev_path}/bjt/pnp/*")
+
+for i in range(len(BJT_PNP_DEV)):
+ BJT_PNP_DEV[i] = BJT_PNP_DEV[i].split("/")[-1]
+ BJT_PNP_DEV[i] = BJT_PNP_DEV[i][:-4]
+
+
+VPP_CAP_DEV = glob.glob(f"{fixed_dev_path}/VPP/*")
+
+for i in range(len(VPP_CAP_DEV)):
+ VPP_CAP_DEV[i] = VPP_CAP_DEV[i].split("/")[-1]
+ VPP_CAP_DEV[i] = VPP_CAP_DEV[i][:-4]
+
+
+PHOTO_D_DEV = glob.glob(f"{fixed_dev_path}/photodiode/*")
+for i in range(len(PHOTO_D_DEV)):
+ PHOTO_D_DEV[i] = PHOTO_D_DEV[i].split("/")[-1]
+ PHOTO_D_DEV[i] = PHOTO_D_DEV[i][:-4]
+
+RF_MOSFET_DEV = glob.glob(f"{fixed_dev_path}/rf/rf_mosfet/*")
+for i in range(len(RF_MOSFET_DEV)):
+ RF_MOSFET_DEV[i] = RF_MOSFET_DEV[i].split("/")[-1]
+ RF_MOSFET_DEV[i] = RF_MOSFET_DEV[i][:-4]
+
+RF_BJT_DEV = glob.glob(f"{fixed_dev_path}/rf/rf_bjt/*")
+for i in range(len(RF_BJT_DEV)):
+ RF_BJT_DEV[i] = RF_BJT_DEV[i].split("/")[-1]
+ RF_BJT_DEV[i] = RF_BJT_DEV[i][:-4]
+
+RF_COILS_DEV = glob.glob(f"{fixed_dev_path}/rf/rf_coils/*")
+for i in range(len(RF_COILS_DEV)):
+ RF_COILS_DEV[i] = RF_COILS_DEV[i].split("/")[-1]
+ RF_COILS_DEV[i] = RF_COILS_DEV[i][:-4]
+
+# print (VPP_CAP_DEV)
diff --git a/sky130/cells/klayout/pymacros/cells/gr.py b/sky130/cells/klayout/pymacros/cells/gr.py
new file mode 100644
index 000000000..6aee3af27
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/gr.py
@@ -0,0 +1,113 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# Guard Ring Generator for skywater130
+########################################################################################################################
+
+import pya
+
+from .draw_guard_ring import draw_gr
+
+min_s = 0.27
+min_w = 0.17
+min_w_m1 = 0.23
+min_s_m1 = 0.38
+
+
+class guard_ring_gen(pya.PCellDeclarationHelper):
+ """
+ Guard Ring Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.param("in_w", self.TypeDouble, "Inner Width", default=min_s, unit="um")
+ self.param("in_l", self.TypeDouble, "Inner Length", default=min_s, unit="um")
+ self.param("grw", self.TypeDouble, "Guard Ring Width", default=min_w, unit="um")
+
+ self.Type_handle = self.param("con_lev", self.TypeList, "Connection Level")
+ self.Type_handle.add_choice("None", "None")
+ self.Type_handle.add_choice("li", "li")
+ self.Type_handle.add_choice("metal1", "metal1")
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return f"Guard Ring(Ring Width = {self.grw})"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+ # w,l must be larger or equal than min. values.
+
+ if self.con_lev == "metal1":
+ if self.grw < min_w_m1:
+ self.grw = min_w_m1
+
+ if self.in_l < min_s_m1:
+ self.in_l = min_s_m1
+
+ if self.in_w < min_s_m1:
+ self.in_w = min_s_m1
+ else:
+ if self.grw < min_w:
+ self.grw = min_w
+
+ if self.in_l < min_s:
+ self.in_l = min_s
+
+ if self.in_w < min_s:
+ self.in_w = min_s
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = draw_gr(
+ layout=self.layout,
+ in_l=self.in_l,
+ in_w=self.in_w,
+ grw=self.grw,
+ con_lev=self.con_lev,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/layers_def.py b/sky130/cells/klayout/pymacros/cells/layers_def.py
new file mode 100644
index 000000000..c5fb15bfc
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/layers_def.py
@@ -0,0 +1,100 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# Skywater 130nm Layers parameters generation
+########################################################################################################################
+
+from gdsfactory.types import LayerSpec
+
+diff_layer: LayerSpec = (65, 20)
+diff_lbl: LayerSpec = (65, 6)
+
+tap_layer: LayerSpec = (65, 44)
+tap_lbl: LayerSpec = (65, 5)
+
+nwell_layer: LayerSpec = (64, 20)
+
+dnwell_layer: LayerSpec = (64, 18)
+
+hvtp_layer: LayerSpec = (78, 44) # high_vt PMOS
+
+hvi_layer: LayerSpec = (75, 20) # high voltage layer for voltages higher than 1.8v
+
+lvtn_layer: LayerSpec = (125, 44) # low_vt NMOS
+
+poly_layer: LayerSpec = (66, 20)
+
+hvntm_layer: LayerSpec = (125, 20) # high voltage n-implant
+
+nsdm_layer: LayerSpec = (93, 44)
+
+psdm_layer: LayerSpec = (94, 20)
+
+npc_layer: LayerSpec = (95, 20)
+
+licon_layer: LayerSpec = (66, 44)
+
+li_layer: LayerSpec = (67, 20)
+li_lbl: LayerSpec = (67, 5)
+
+mcon_layer: LayerSpec = (67, 44)
+
+m1_layer: LayerSpec = (68, 20)
+m1_lbl: LayerSpec = (68, 5)
+
+via1_layer: LayerSpec = (68, 44)
+
+m2_layer: LayerSpec = (69, 20)
+m2_lbl: LayerSpec = (69, 5)
+
+via2_layer: LayerSpec = (69, 44)
+
+m3_layer: LayerSpec = (70, 20)
+m3_lbl: LayerSpec = (70, 5)
+
+via3_layer: LayerSpec = (70, 44)
+
+m4_layer: LayerSpec = (71, 20)
+m4_lbl: LayerSpec = (71, 5)
+
+via4_layer: LayerSpec = (71, 44)
+
+m5_layer: LayerSpec = (72, 20)
+m5_lbl: LayerSpec = (72, 5)
+
+pr_bound_layer: LayerSpec = (235, 4)
+
+areaid_lvn_layer: LayerSpec = (81, 60)
+
+areaid_dio_layer: LayerSpec = (81, 23)
+
+capm_layer: LayerSpec = (89, 44)
+
+cap2m_layer: LayerSpec = (97, 44)
+
+
+######res
+diff_res: LayerSpec = (65, 13)
+poly_res: LayerSpec = (66, 13)
+rpm_drawing: LayerSpec = (86, 20)
+rpm_high_drawing: LayerSpec = (79, 20)
+pwell_res: LayerSpec = (64, 13)
+li1_res: LayerSpec = (67, 13)
+met1_res: LayerSpec = (68, 13)
+met2_res: LayerSpec = (69, 13)
+met3_res: LayerSpec = (70, 13)
+met4_res: LayerSpec = (71, 13)
+met5_res: LayerSpec = (72, 13)
diff --git a/sky130/cells/klayout/pymacros/cells/parent_res.py b/sky130/cells/klayout/pymacros/cells/parent_res.py
new file mode 100644
index 000000000..a1d4ba83b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/parent_res.py
@@ -0,0 +1,265 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+# res Generator for skywater130
+
+import math
+from abc import ABC, abstractmethod
+
+import gdsfactory as gf
+
+# ##############CONSTANT############3
+
+
+CONTACT_SPACE = 0.19
+CONTACT_S = 0.18
+CONTACT_N = 10
+
+
+############################3
+class draw_res(ABC):
+ """parent abstracted class for the backend of the res
+ Args:
+ type (str): type of the res
+ """
+
+ def __init__(self, type):
+ self.type_ = type
+ self.c = gf.Component(self.type_)
+
+ def set_l_w(self, len, wid):
+ """set the length and width of the res
+ Args:
+ len(float): length of the resistor
+ wid(float): width of the resistor
+ """
+ self.l_res = len
+ self.w_res = wid
+
+ def draw_rect_layer(self, layer_names, l_space, w_space):
+ """draw the rect layers of the res
+ Args:
+ layer_names(list[layers]):
+ list of the layer names
+ l_space(list[float]):
+ [0.5*length of the layers - 0.5*length of the marked layer]
+ w_space(list[float]):
+ [0.5*width of the layers - 0.5*width of the marked layer]
+
+ """
+ for layer_, l_rect, w in zip(layer_names, l_space, w_space):
+ self.c.add_ref(
+ gf.components.rectangle(
+ size=(self.w_res + 2 * w, self.l_res + 2 * l_rect),
+ layer=layer_,
+ centered=True,
+ )
+ )
+
+ def draw_frame_layer(self, lay_nm, l_sp, w_sp, thi):
+ """draw the frame layers of the res
+ Args:
+ lay_nm(list[layers]):
+ list of the layer names
+ l_sp(list[float]):
+ [0.5*length of the layers - 0.5*length of the marked layer]
+ w_sp(list[float]):
+ [0.5*width of the layers - 0.5*width of the marked layer]
+ thi(list[float]):
+ list of the thickness of the frame
+
+ """
+ for layer_, l_frame, w, thick in zip(lay_nm, l_sp, w_sp, thi):
+ l_h = thick
+ w_h = self.w_res + 2 * w
+
+ l_v = self.l_res + 2 * l_frame - 2 * thick
+ w_v = thick
+
+ res1 = self.c.add_ref(
+ gf.components.rectangle(size=(w_h, l_h), layer=layer_, centered=True)
+ )
+ res2 = self.c.add_ref(
+ gf.components.rectangle(size=(w_h, l_h), layer=layer_, centered=True)
+ )
+
+ res1.movey(0.5 * l_v + 0.5 * l_h)
+ res2.movey(-1 * (0.5 * l_v + 0.5 * l_h))
+
+ res1 = self.c.add_ref(
+ gf.components.rectangle(size=(w_v, l_v), layer=layer_, centered=True)
+ )
+ res2 = self.c.add_ref(
+ gf.components.rectangle(size=(w_v, l_v), layer=layer_, centered=True)
+ )
+
+ res1.movex(0.5 * w_h - 0.5 * w_v)
+ res2.movex(-1 * (0.5 * w_h - 0.5 * w_v))
+
+ def draw_contact_layer_h(
+ self, layer_names, l_space, sizes_w, sizes_l, s_fit_in, s_btw
+ ):
+ """draw the horizontal contact layers of the res
+ Args:
+ layer_names(list[layers]):
+ list of the layer names
+ l_space(list[float]):
+ [0.5*length of the layers - 0.5*length of the marked layer]
+ sizes_w(list[float]):
+ list of contacts width
+ sizes_l(list[float]):
+ list of contacts length
+ s_fit_in(list[float]):
+ list of total length to fit contacts in
+ s_btw(list[float]):
+ list of the spaces btw the contacts
+
+ """
+ for layer_, l_h, size_l, size_w, space_fit, space_btw in zip(
+ layer_names, l_space, sizes_l, sizes_w, s_fit_in, s_btw
+ ):
+ counts = math.floor((space_fit) / (size_w + space_btw))
+ if counts < 1:
+ counts = 1
+ res = gf.components.rectangle(
+ size=(size_w, size_l), layer=layer_, centered=True
+ )
+ res_ar1 = self.c.add_array(
+ res,
+ rows=1,
+ columns=counts,
+ spacing=(size_w + space_btw, size_w + space_btw),
+ )
+ res_ar2 = self.c.add_array(
+ res,
+ rows=1,
+ columns=counts,
+ spacing=(size_w + space_btw, size_w + space_btw),
+ )
+
+ res_ar1.movey(size_l * 0.5 + l_h + self.l_res * 0.5)
+ res_ar2.movey(-1 * (size_l * 0.5 + l_h + self.l_res * 0.5))
+
+ res_ar1.movex(-(counts - 1) * (size_w + space_btw) * 0.5)
+ res_ar2.movex(-(counts - 1) * (size_w + space_btw) * 0.5)
+
+ def draw_contact_layer_v(
+ self,
+ layer_names,
+ l_space,
+ sizes_w,
+ sizes_l,
+ space_fit_in,
+ spaces_btw=None,
+ ):
+ """draw the vertical contact layers of the res
+ Args:
+ layer_names(list[layers]):
+ list of the layer names
+ l_space(list[float]):
+ [0.5*length of the layers - 0.5*length of the marked layer]
+ sizes_w(list[float]):
+ list of contacts width
+ sizes_l(list[float]):
+ list of contacts length
+ space_fit_in(list[float]):
+ list of total length to fit contacts in
+ spaces_btw(list[float]):
+ list of the spaces btw the contacts
+ """
+ if spaces_btw is None:
+ spaces_btw = sizes_w
+ for layer_, l_v, size_l, size_w, space_fit, space_btw in zip(
+ layer_names,
+ l_space,
+ sizes_l,
+ sizes_w,
+ space_fit_in,
+ spaces_btw,
+ ):
+ counts = math.floor((space_fit) / (size_w + space_btw))
+ res = gf.components.rectangle(
+ size=(size_w, size_l), layer=layer_, centered=True
+ )
+ res_ar1 = self.c.add_array(
+ res,
+ rows=counts,
+ columns=1,
+ spacing=(size_l + space_btw, size_l + space_btw),
+ )
+ res_ar2 = self.c.add_array(
+ res,
+ rows=counts,
+ columns=1,
+ spacing=(size_l + space_btw, size_l + space_btw),
+ )
+
+ res_ar1.movey(-(counts - 1) * size_l)
+ res_ar2.movey(-(counts - 1) * size_l)
+
+ res_ar1.movex(0.5 * self.w_res + l_v + 0.5 * size_w)
+ res_ar2.movex(-(0.5 * self.w_res + l_v + 0.5 * size_w))
+
+ def draw_2dArr_layer(self, layer_names, mcon_d, l_up=0, l_down=0, n=0):
+ """draw the 2d contact layers of the res
+ Args:
+ layer_names(list[layers]): list of the layer names
+ mcon_d(list[float]): list of contacts thickness
+ l_up(list[float]): upper contacts array space from marked layer
+ l_down(list[float]): down contacts array space from marked layer
+ n(list[float]): list of the 1 for 2d arr and 0 for 1d arr
+ """
+ res = gf.components.rectangle(
+ size=(mcon_d, mcon_d), layer=layer_names, centered=True
+ )
+
+ counts_arr = math.floor(self.w_res / (2 * CONTACT_S))
+ if counts_arr <= 0:
+ counts_arr = 1
+ if counts_arr % 2 == 0 and counts_arr > CONTACT_N:
+ counts_arr = counts_arr - 1
+ res_ar1 = self.c.add_array(
+ res,
+ rows=6,
+ columns=counts_arr + n,
+ spacing=(mcon_d + CONTACT_SPACE, mcon_d + CONTACT_SPACE),
+ )
+ res_ar2 = self.c.add_array(
+ res,
+ rows=6,
+ columns=counts_arr + n,
+ spacing=(mcon_d + CONTACT_SPACE, mcon_d + CONTACT_SPACE),
+ )
+
+ res_ar1.movey(mcon_d * 0.5 + l_up + (self.l_res) * 0.5)
+ res_ar2.movey(-1 * (mcon_d * 0.5 + l_down + (self.l_res) * 0.5))
+ if (counts_arr + n) != 1:
+ # res_ar1.movex(-1*(mcon_d * 0.5 + 0.5*self.w_res))
+ # res_ar2.movex(-1 * (mcon_d * 0.5 +0.5*self.w_res))
+ res_ar1.movex(-(counts_arr + n - 1) * CONTACT_S)
+ res_ar2.movex(-(counts_arr + n - 1) * CONTACT_S)
+
+ def get_c(self):
+ """get component
+
+ Returns:
+ c(gf.component): layout creates
+ """
+ return self.c
+
+ @abstractmethod
+ def your_res():
+ """must override in the child class"""
+ pass
diff --git a/sky130/cells/klayout/pymacros/cells/res_diff_child.py b/sky130/cells/klayout/pymacros/cells/res_diff_child.py
new file mode 100644
index 000000000..757f2dd9b
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_diff_child.py
@@ -0,0 +1,723 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+# res Generator for skywater130
+
+from .layers_def import (
+ diff_layer,
+ diff_res,
+ hvi_layer,
+ hvntm_layer,
+ li_layer,
+ licon_layer,
+ m1_layer,
+ mcon_layer,
+ nsdm_layer,
+ nwell_layer,
+ psdm_layer,
+ tap_layer,
+)
+from .parent_res import draw_res
+
+# ##########constant#################
+# [l,w]
+# react
+DIFF_RES = 0
+DIFF_LAYER_ND = [0.515, 0]
+NSDM_LAYER_ND = [0.64, 0.125]
+# HVT
+HVI_ND = [1.43, 0.915, 0.7, 0.21]
+HVNTM_ND = [0.7, 0.185]
+# [l,w,thickness]
+# frame
+TAP_ND_LVT = [1.125, 0.61, 0.17]
+PSDM_ND_LVT = [1.25, 0.735, 0.42]
+LI_ND_LVT = [1.125, 0.61, 0.17]
+# HVT
+TAP_ND_HVT = [1.245, 0.73, 0.29]
+PSDM_ND_HVT = [1.37, 0.855, 0.54]
+LI_ND_HVT = [1.185, 0.67, 0.17]
+# [l,w,thickness_l,thickness_w,space]
+# CONTACT H
+LICON1_ND_LVT = [0.285, 0.17, 0.17, 0, 0.17]
+LICON2_ND_LVT = [0.955, 0.17, 0.17, 0, 0.17]
+MCON_ND_LVT = [0.185, 0.17, 0.17, 0, 0.19]
+M1_ND_LVT = [0.025, 0.49, 0, 0, 0]
+LI1_ND_LVT = [0.085, 0.2, 0, 0, 0]
+LI2_ND_LVT = [0.285, 0.17, 0, 0, 0]
+# HVT
+LICON2_ND_HVT = 1.015
+
+# CONTACT V
+LICON3_ND_LVT = [0.44, 0.17, 0.17, 1.37, 0.17]
+# HVT
+LICON3_ND_HVT = 0.5
+
+# #####PD
+NWELL_PD = [1.305, 0.79]
+# HVT
+NWELL_PD_HVT = [1.575, 1.06]
+HVI_PD_HVT = [1.575, 1.06]
+# frame
+TAP_PD_HVT = [1.245, 0.73, 0.29]
+PSDM_PD_HVT = [1.37, 0.855, 0.54]
+LI_PD_HVT = [1.185, 0.67, 0.17]
+
+
+#################################
+
+
+class res_diff_draw(draw_res):
+ """child class for the backend of the diff res
+ Args:
+ type_ (str): type of the res
+ """
+
+ def __init__(self, type_):
+ super().__init__(type_)
+
+ def your_res(
+ self,
+ layout,
+ type="sky130_fd_pr__res_nd_lvt",
+ l_res: float = 2.1,
+ w: float = 0.42,
+ gr: int = 1,
+ ):
+ """draw the res with calling the parent func with right data
+
+ Args:
+ layout(layout): drawing layout
+ type(float): type of the resistor
+ l_res(float): length of the resistor
+ w(float): width of the resistor
+ gr(int): guard ring of the resistor
+
+ """
+ self.set_l_w(l_res, w)
+ if type == "sky130_fd_pr__res_nd_lvt":
+ # rects
+ layer_names = [diff_res, diff_layer, nsdm_layer]
+ l1 = [DIFF_RES, DIFF_LAYER_ND[0], NSDM_LAYER_ND[0]]
+ w1 = [DIFF_RES, DIFF_LAYER_ND[1], NSDM_LAYER_ND[1]]
+
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, psdm_layer, li_layer]
+ l1 = [TAP_ND_LVT[0], PSDM_ND_LVT[0], LI_ND_LVT[0]]
+ w1 = [TAP_ND_LVT[1], PSDM_ND_LVT[1], LI_ND_LVT[1]]
+ thick = [TAP_ND_LVT[2], PSDM_ND_LVT[2], LI_ND_LVT[2]]
+
+ if gr == 1:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ LICON2_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ LICON2_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ LICON2_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w + 0.34,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ LICON2_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+ if gr:
+ layer_names = [licon_layer]
+ l1 = [LICON3_ND_LVT[0]]
+ sizes_l = [LICON3_ND_LVT[1]]
+ sizes_w = [LICON3_ND_LVT[2]]
+ space_fit_in = [l_res + LICON3_ND_LVT[3]]
+ spaces = [LICON3_ND_LVT[4]]
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
+ elif type == "sky130_fd_pr__res_nd_hvt":
+ # rects
+ layer_names = [
+ diff_res,
+ diff_layer,
+ nsdm_layer,
+ hvi_layer,
+ hvntm_layer,
+ ]
+ l1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[0],
+ NSDM_LAYER_ND[0],
+ HVI_ND[0],
+ HVNTM_ND[0],
+ ]
+ w1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[1],
+ NSDM_LAYER_ND[1],
+ HVI_ND[1],
+ HVNTM_ND[1],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ diff_res,
+ diff_layer,
+ nsdm_layer,
+ hvi_layer,
+ hvntm_layer,
+ ]
+ l1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[0],
+ NSDM_LAYER_ND[0],
+ HVI_ND[2],
+ HVNTM_ND[0],
+ ]
+ w1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[1],
+ NSDM_LAYER_ND[1],
+ HVI_ND[3],
+ HVNTM_ND[1],
+ ]
+
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, psdm_layer, li_layer]
+
+ l1 = [TAP_ND_HVT[0], PSDM_ND_HVT[0], LI_ND_HVT[0]]
+ w1 = [TAP_ND_HVT[1], PSDM_ND_HVT[1], LI_ND_HVT[1]]
+ thick = [TAP_ND_HVT[2], PSDM_ND_HVT[2], LI_ND_HVT[2]]
+
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+
+ l1 = [
+ LICON1_ND_LVT[0],
+ LICON2_ND_HVT,
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ LICON2_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ LICON2_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w + 0.34,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ LICON2_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+
+ l1 = [
+ LICON1_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ layer_names = [licon_layer]
+ l1 = [LICON3_ND_HVT]
+ sizes_l = [LICON3_ND_LVT[1]]
+ sizes_w = [LICON3_ND_LVT[2]]
+ space_fit_in = [l_res + LICON3_ND_LVT[3]]
+ spaces = [LICON3_ND_LVT[4]]
+
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
+ elif type == "sky130_fd_pr__res_pd_lvt":
+ # rects
+ layer_names = [
+ diff_res,
+ diff_layer,
+ psdm_layer,
+ nwell_layer,
+ ]
+
+ l1 = [DIFF_RES, DIFF_LAYER_ND[0], NSDM_LAYER_ND[0], NWELL_PD[0]]
+ w1 = [DIFF_RES, DIFF_LAYER_ND[1], NSDM_LAYER_ND[1], NWELL_PD[1]]
+
+ if gr == 0:
+ layer_names = [
+ diff_res,
+ diff_layer,
+ psdm_layer,
+ ]
+ l1 = [DIFF_RES, DIFF_LAYER_ND[0], NSDM_LAYER_ND[0]]
+ w1 = [DIFF_RES, DIFF_LAYER_ND[1], NSDM_LAYER_ND[1]]
+
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, nsdm_layer, li_layer]
+ l1 = [TAP_ND_LVT[0], PSDM_ND_LVT[0], LI_ND_LVT[0]]
+ w1 = [TAP_ND_LVT[1], PSDM_ND_LVT[1], LI_ND_LVT[1]]
+ thick = [TAP_ND_LVT[2], PSDM_ND_LVT[2], LI_ND_LVT[2]]
+
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ LICON2_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ LICON2_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ LICON2_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w + 0.34,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ LICON2_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ layer_names = [licon_layer]
+ l1 = [LICON3_ND_LVT[0]]
+ sizes_l = [LICON3_ND_LVT[1]]
+ sizes_w = [LICON3_ND_LVT[2]]
+ space_fit_in = [l_res + LICON3_ND_LVT[3]]
+ spaces = [LICON3_ND_LVT[4]]
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
+ elif type == "sky130_fd_pr__res_pd_hvt":
+ # rects
+ layer_names = [
+ diff_res,
+ diff_layer,
+ psdm_layer,
+ hvi_layer,
+ nwell_layer,
+ ]
+ l1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[0],
+ NSDM_LAYER_ND[0],
+ HVI_PD_HVT[0],
+ NWELL_PD_HVT[0],
+ ]
+ w1 = [
+ DIFF_RES,
+ DIFF_LAYER_ND[1],
+ NSDM_LAYER_ND[1],
+ HVI_PD_HVT[1],
+ NWELL_PD_HVT[1],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ diff_res,
+ diff_layer,
+ psdm_layer,
+ hvi_layer,
+ ]
+ l1 = [DIFF_RES, DIFF_LAYER_ND[0], NSDM_LAYER_ND[0], HVI_ND[2]]
+ w1 = [DIFF_RES, DIFF_LAYER_ND[1], NSDM_LAYER_ND[1], HVI_ND[3]]
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, nsdm_layer, li_layer]
+ l1 = [TAP_PD_HVT[0], PSDM_PD_HVT[0], LI_PD_HVT[0]]
+ w1 = [TAP_PD_HVT[1], PSDM_PD_HVT[1], LI_PD_HVT[1]]
+ thick = [TAP_PD_HVT[2], PSDM_PD_HVT[2], LI_PD_HVT[2]]
+
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ LICON2_ND_HVT,
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ LICON2_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ LICON2_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w + 0.34,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ LICON2_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ licon_layer,
+ mcon_layer,
+ m1_layer,
+ li_layer,
+ li_layer,
+ ]
+ l1 = [
+ LICON1_ND_LVT[0],
+ MCON_ND_LVT[0],
+ M1_ND_LVT[0],
+ LI1_ND_LVT[0],
+ LI2_ND_LVT[0],
+ ]
+ sizes_l = [
+ LICON1_ND_LVT[1],
+ MCON_ND_LVT[1],
+ M1_ND_LVT[1],
+ LI1_ND_LVT[1],
+ LI2_ND_LVT[1],
+ ]
+ sizes_w = [
+ LICON1_ND_LVT[2],
+ MCON_ND_LVT[2],
+ w - 0.05,
+ w - 0.12,
+ w + 0.04,
+ ]
+ space_fit_in = [
+ w,
+ w - 0.12,
+ M1_ND_LVT[3],
+ LI1_ND_LVT[3],
+ LI2_ND_LVT[3],
+ ]
+ spaces = [
+ LICON1_ND_LVT[4],
+ MCON_ND_LVT[4],
+ M1_ND_LVT[4],
+ LI1_ND_LVT[4],
+ LI2_ND_LVT[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+ layer_names = [licon_layer]
+ l1 = [LICON3_ND_HVT]
+ sizes_l = [LICON3_ND_LVT[1]]
+ sizes_w = [LICON3_ND_LVT[2]]
+ space_fit_in = [l_res + LICON3_ND_LVT[3]]
+ spaces = [LICON3_ND_LVT[4]]
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/res_diff_klayout_panel.py b/sky130/cells/klayout/pymacros/cells/res_diff_klayout_panel.py
new file mode 100644
index 000000000..f60422013
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_diff_klayout_panel.py
@@ -0,0 +1,87 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+from .res_diff_child import res_diff_draw
+from .res_klayout_panel import res
+
+# ################constants################
+L_MIN = 2.1
+W_MIN = 0.42
+# ##############sheet resistances
+RES_ND_LVT = 772.2 # sheet res for sky130_fd_pr__res_nd_lvt
+RES_ND_HVT = 714.28 # sheet res for sky130_fd_pr__res_nd_hvt
+RES_PD = 1172.33 # sheet res for sky130_fd_pr__res_pd_lvt,hvt
+##########################################
+
+
+class res_diff(res):
+ """child class for the front end of the diff res (klayout panel)
+ Args:
+ res(class): parent class for all types of resistors
+ l_min(float): minimum length of the resistor
+ w_min(float): minimum width of the resistor
+
+ """
+
+ def __init__(self):
+ super().__init__(L_MIN, W_MIN) # (l_min,w_min)
+
+ # types of resistor you need to add
+ # it goes in var self.type
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_nd_lvt", "sky130_fd_pr__res_nd_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_nd_hvt", "sky130_fd_pr__res_nd_hvt"
+ )
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_pd_lvt", "sky130_fd_pr__res_pd_lvt"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_pd_hvt", "sky130_fd_pr__res_pd_hvt"
+ )
+
+ def coerce_parameters_impl(self):
+ """(override func) check the minimum values of l and w
+
+ decide whether the handle or the numeric parameter has
+ changed (by comparing against the effective
+ radius ru) and set ru to the effective radius. We also update the
+ numerical value or the shape, depending on which on has not changed
+
+
+ """
+ super().coerce_parameters_impl(L_MIN, W_MIN) # (l_min,w_min)
+ # res_value = sheet res * area
+ if self.type == "sky130_fd_pr__res_nd_lvt":
+ self.res_value = RES_ND_LVT * self.area
+ elif self.type == "sky130_fd_pr__res_nd_hvt":
+ self.res_value = RES_ND_HVT * self.area
+ else:
+ self.res_value = RES_PD * self.area
+
+ def produce_impl(self):
+ """(override func)call the implementation backend code
+ create instance and pass it to the parent func
+
+ instance(layout): the result layout to show
+
+ """
+ drw = res_diff_draw(self.type)
+ instance = drw.your_res(
+ self.layout, l_res=self.len, w=self.w, type=self.type, gr=self.gr
+ )
+ super().produce_impl(instance)
diff --git a/sky130/cells/klayout/pymacros/cells/res_klayout_panel.py b/sky130/cells/klayout/pymacros/cells/res_klayout_panel.py
new file mode 100644
index 000000000..61d899a38
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_klayout_panel.py
@@ -0,0 +1,126 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+# res Generator for skywater130
+
+import pya
+
+
+class res(pya.PCellDeclarationHelper):
+ """parent class for the front end of the res (klayout panel)
+ Args:
+ l_min(float): minimum length of the resistor
+ w_min(float): minimum width of the resistor
+ """
+
+ def __init__(self, l_min, w_min):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.Type_handle = self.param("type", self.TypeList, "Device Type")
+
+ self.param("len", self.TypeDouble, "length", default=l_min, unit="um")
+ self.param("w", self.TypeDouble, "width", default=w_min, unit="um")
+
+ self.param("gr", self.TypeBoolean, "Gaurd Ring", default=1)
+ self.param("area", self.TypeDouble, "Area", readonly=True, unit="um^2")
+ self.param(
+ "res_value",
+ self.TypeDouble,
+ "Res Value",
+ readonly=True,
+ unit="ohms",
+ )
+
+ def display_text_impl(self):
+ """Provide a descriptive text for the cell
+ Return:
+ (str):the res name with len and w
+ """
+
+ # Provide a descriptive text for the cell
+ return (
+ "Resistor_"
+ + str(self.type)
+ + "(L="
+ + ("%.3f" % self.len)
+ + ",W="
+ + ("%.3f" % self.w)
+ + ")"
+ )
+
+ def coerce_parameters_impl(self, l_min, w_min):
+ """check the minimum values of l and w
+
+ decide whether the handle or the numeric parameter has
+ changed (by comparing against the effective
+ radius ru) and set ru to the effective radius. We also update the
+ numerical value or the shape, depending on which on has not changed
+ Args:
+ l_min(float): minimum length of the resistor
+ w_min(float): minimum width of the resistor
+
+ """
+
+ self.area = self.w * self.len
+
+ if self.len < l_min:
+ self.len = l_min
+
+ if self.w < w_min:
+ self.w = w_min
+
+ def can_create_from_shape_impl(self):
+ """Implement the Create PCell
+
+ we can use any shape which has a finite bounding box
+ """
+
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ """Implement the "Create PCell from shape" protocol:
+
+ we set r and l from the shape's bounding box width and layer
+ """
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.len = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ """Implement the "Create PCell from shape" protocol:
+
+ we use the center of the shape's bounding box
+ to determine the transformation
+ """
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self, instance):
+ """call the implementation backend code
+ Args:
+ instance(layout): the result layout to show
+
+ """
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/res_metal_child.py b/sky130/cells/klayout/pymacros/cells/res_metal_child.py
new file mode 100644
index 000000000..7838ac397
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_metal_child.py
@@ -0,0 +1,110 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+# res Generator for skywater130
+
+from gdsfactory.types import LayerSpec
+
+from .layers_def import (
+ li1_res,
+ li_layer,
+ m1_layer,
+ m2_layer,
+ m3_layer,
+ m4_layer,
+ m5_layer,
+ met1_res,
+ met2_res,
+ met3_res,
+ met4_res,
+ met5_res,
+)
+from .parent_res import draw_res
+
+# ########constants##########
+# ONLY FOR GENERIC RES
+L_MIN_G = 0.17
+W_MIN_G = 0.17
+# REACT
+LI_LYAER_G = [0.285, 0]
+
+
+# ##########################
+class res_metal_draw(draw_res):
+ """child class for the backend of the metal res
+ Args:
+ type_ (str): type of the res
+ """
+
+ def __init__(self, type_):
+ super().__init__(type_)
+ # self.l=l
+ # self.w=w
+ # self.your_res()
+
+ def gen_res(self, ly1: LayerSpec, ly2: LayerSpec):
+ """draw the different metal res
+
+ Args:
+ ly1(LayerSpec): marked layer
+ ly2(LayerSpec): overlapping layer
+
+ """
+ layer_names = [ly1, ly2]
+ l1 = [0, LI_LYAER_G[0]]
+ w1 = [0, LI_LYAER_G[1]]
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ def your_res(
+ self,
+ layout,
+ type="sky130_fd_pr__res_generic_l1",
+ l_res: float = L_MIN_G,
+ w: float = W_MIN_G,
+ ):
+ """draw the res with calling the parent func with right data
+
+ Args:
+ layout(layout): drawing layout
+ type(str): type of the resistor
+ l(float): length of the resistor
+ w(float): width of the resistor
+
+ """
+ self.set_l_w(l_res, w)
+
+ if type == "sky130_fd_pr__res_generic_l1":
+ self.gen_res(li1_res, li_layer)
+
+ elif type == "sky130_fd_pr__res_generic_m1":
+ self.gen_res(met1_res, m1_layer)
+
+ elif type == "sky130_fd_pr__res_generic_m2":
+ self.gen_res(met2_res, m2_layer)
+
+ elif type == "sky130_fd_pr__res_generic_m3":
+ self.gen_res(met3_res, m3_layer)
+
+ elif type == "sky130_fd_pr__res_generic_m4":
+ self.gen_res(met4_res, m4_layer)
+
+ elif type == "sky130_fd_pr__res_generic_m5":
+ self.gen_res(met5_res, m5_layer)
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/res_metal_klayout_panel.py b/sky130/cells/klayout/pymacros/cells/res_metal_klayout_panel.py
new file mode 100644
index 000000000..32169d2d4
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_metal_klayout_panel.py
@@ -0,0 +1,117 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+from .res_klayout_panel import res
+from .res_metal_child import res_metal_draw
+
+# ################constants################
+L_MIN = 0.17
+W_MIN = 0.17
+
+L_MIN_M1 = 0.14
+L_MIN_M2 = 0.14
+L_MIN_M3 = 0.3
+L_MIN_M4 = 0.3
+L_MIN_M5 = 1.6
+
+# ##############sheet resistances
+RES_GEN = 442.9 # sheet res for sky130_fd_pr__res_generic_l1
+
+
+RES_M1 = 6.377 # sheet res for sky130_fd_pr__res_generic_m1
+RES_M2 = 6.377 # sheet res for sky130_fd_pr__res_generic_m2
+RES_M3 = 0.522 # sheet res for sky130_fd_pr__res_generic_m3
+RES_M4 = 0.522 # sheet res for sky130_fd_pr__res_generic_m4
+RES_M5 = 0.0113 # sheet res for sky130_fd_pr__res_generic_m5
+
+##########################################
+
+
+class res_metal(res):
+ """child class for the front end of the poly res (klayout panel)
+ Args:
+ res(class): parent class for all types of resistors
+ l_min(float): minimum length of the resistor
+ w_min(float): minimum width of the resistor
+
+ """
+
+ def __init__(self):
+ super().__init__(L_MIN, W_MIN) # (l_min,w_min)
+
+ # types of resistor you need to add
+ # it goes in var self.type
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_l1", "sky130_fd_pr__res_generic_l1"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_m1", "sky130_fd_pr__res_generic_m1"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_m2", "sky130_fd_pr__res_generic_m2"
+ )
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_m3", "sky130_fd_pr__res_generic_m3"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_m4", "sky130_fd_pr__res_generic_m4"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_m5", "sky130_fd_pr__res_generic_m5"
+ )
+
+ def coerce_parameters_impl(self):
+ """(override func) check the minimum values of l and w
+
+ decide whether the handle or the numeric parameter has
+ changed (by comparing against the effective
+ radius ru) and set ru to the effective radius. We also update the
+ numerical value or the shape, depending on which on has not changed
+
+
+ """
+
+ # res_value = sheet res * area
+ if self.type == "sky130_fd_pr__res_generic_l1":
+ super().coerce_parameters_impl(L_MIN, W_MIN) # (l_min,w_min)
+ self.res_value = RES_GEN * self.area
+
+ elif self.type == "sky130_fd_pr__res_generic_m1":
+ super().coerce_parameters_impl(L_MIN_M1, L_MIN_M1)
+ self.res_value = RES_M1 * self.area
+ elif self.type == "sky130_fd_pr__res_generic_m2":
+ super().coerce_parameters_impl(L_MIN_M2, L_MIN_M2)
+ self.res_value = RES_M2 * self.area
+ elif self.type == "sky130_fd_pr__res_generic_m3":
+ super().coerce_parameters_impl(L_MIN_M3, L_MIN_M3)
+ self.res_value = RES_M3 * self.area
+ elif self.type == "sky130_fd_pr__res_generic_m4":
+ super().coerce_parameters_impl(L_MIN_M4, L_MIN_M4)
+ self.res_value = RES_M4 * self.area
+ elif self.type == "sky130_fd_pr__res_generic_m5":
+ super().coerce_parameters_impl(L_MIN_M5, L_MIN_M5)
+ self.res_value = RES_M5 * self.area
+
+ def produce_impl(self):
+ """(override func)call the implementation backend code
+ create instance and pass it to the parent func
+
+ instance(layout): the result layout to show
+
+ """
+ drw = res_metal_draw(self.type)
+ instance = drw.your_res(self.layout, l_res=self.len, w=self.w, type=self.type)
+ super().produce_impl(instance)
diff --git a/sky130/cells/klayout/pymacros/cells/res_poly_child.py b/sky130/cells/klayout/pymacros/cells/res_poly_child.py
new file mode 100644
index 000000000..91f943732
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_poly_child.py
@@ -0,0 +1,571 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+# res Generator for skywater130
+
+import math
+
+from .layers_def import (
+ dnwell_layer,
+ li_layer,
+ licon_layer,
+ m1_layer,
+ mcon_layer,
+ npc_layer,
+ nsdm_layer,
+ nwell_layer,
+ poly_layer,
+ poly_res,
+ psdm_layer,
+ pwell_res,
+ rpm_drawing,
+ rpm_high_drawing,
+ tap_layer,
+)
+from .parent_res import draw_res
+
+# ########constants##########
+# ONLY FOR GENERIC RES
+L_MIN_G = 1.65
+W_MIN_G = 0.42
+
+# react
+POLY_LAYER_G = [2.15, 0]
+# FRAME
+TAP_LI_LAYER_G = [2.8, 0.65, 0.17]
+PSDM_LAYER_G = [2.925, 0.775, 0.42]
+
+# CONTACTS H
+LICON1_LAYER_G = [1.9, 0.17, 0.17, 0, 0.17]
+LICON2_LAYER_G = [2.63, 0.17, 0.17, 0, 0.17]
+NPC_LAYER_G = [1.8, 0.37, 0, 0, 0]
+LI1_LAYER_G = [0.085, 1.815, 0, 0, 0]
+LI2_LAYER_G = [1.9, 0.17, 0, 0, 0]
+M1_LAYER_G = [0.025, 2.105, 0, 0, 0]
+# CONTACT V
+LICON_LAYER_G = [0.48, 0.17, 0.17, 4.98, 0.17]
+# 2D ARRAY
+MCON_LAYER_G = [0.17, 0.09, 1.89]
+# ###################################
+
+
+# ONLY FOR ISO RES
+L_MIN_ISO = 26.5
+W_MIN_ISO = 2.65
+
+# react
+DNWELL = [1.82, 1.03]
+# FRAME
+NWELL = [2.22, 1.43, 1.43]
+TAP_LI_LAYER_ISO = [1.59, 0.8, 0.17]
+NSDM_LAYER_ISO = [1.715, 0.925, 0.42]
+# CONTACTS H
+TAP_ISO = [0, 0.53, 0, 0, 0]
+PSDM_ISO = [-0.125, 0.78, 0, 0, 0]
+LI_ISO = [0, 0.53, 0, 0, 0]
+M1_ISO = [0.055, 0.325, 0, 0, 0]
+LICON_ISO = [0.01, 0.17, 0.17, 0, 0.17]
+LICON_ISO2 = 0.35
+LICON_ISO3 = 1.42
+MCON_ISO = [0.13, 0.17, 0.17, 0, 0.19]
+# CONTACTS H
+LICON_ISO_H = [0.63, 0.17, 0.17, 2.1, 0.17]
+# ###############################
+# THE REST OF THE RES
+L_MIN = 0.5
+W_MIN = 0.35
+W_MIN_0P35 = 0.35
+W_MIN_0P69 = 0.69
+W_MIN_1P41 = 1.41
+W_MIN_2P85 = 2.85
+W_MIN_5P73 = 5.73
+GR = 1
+RPM_LAYER = 0.29
+EXTRA_LEN = 0.12
+
+# REACT
+POLY_RES = [0, 0]
+POLY_LAYER = [2.1, 0]
+PSDM_LAYER = [2.875, 0.775]
+PSDM_LAYER_NO_GR = [2.21, 0.11]
+NPC_LAYER = [2.195, 0.095]
+RPM_LAUER = [2.3, 0]
+RPM_FOR_LAYERS = [0.46, 0.29, 0.2, 0.2, 0.2]
+# FRAME
+TAP_LI_LAYER = [2.75, 0.65, 0.17]
+# CONTACTS H
+LICON1_LAYER = [0.02, 2, 0.19, 0, 0.52]
+LICON2_LAYER = [2.58, 0.17, 0.17, 0, 0.17]
+LI_LAYER = [-0.06, 2.16, 0, 0, 0]
+M1_LAYER = [-0.035, 2.105, 0, 0, 0]
+LICON1_LAYER_NO_GR = 2
+
+# CONTACT V
+LICON_LAYER = [0.48, 0.17, 0.17, 4.31, 0.17]
+# 2D ARRAY
+MCON_LAYER = [0.17, 0.035, 1.83]
+
+
+# ##########################
+class res_poly_draw(draw_res):
+ """child class for the backend of the poly res
+ Args:
+ type_ (str): type of the res
+ """
+
+ def __init__(self, type_):
+ super().__init__(type_)
+ # self.l=l
+ # self.w=w
+ # self.your_res()
+
+ def poly_res(
+ self,
+ l_res: float = L_MIN,
+ w: float = W_MIN,
+ gr: int = GR,
+ n_mcon: int = 0,
+ rpm: float = RPM_LAYER,
+ xhigh: int = 0,
+ ):
+ """draw the res the specific res with right data
+
+ Args:
+ l_res(float): length of the resistor
+ w(float): width of the resistor
+ gr(int): guard ring of the resistor
+ n_mcon(float): mcon_layer number of columns
+ rpm(float): rpm layer width
+ xhigh(int): select high or xhigh poly res
+
+ """
+ # rects
+ self.set_l_w(l_res + EXTRA_LEN, w)
+ rpm_layer = rpm_drawing
+ if xhigh:
+ rpm_layer = rpm_high_drawing
+ layer_names = [poly_res, poly_layer, psdm_layer, npc_layer, rpm_layer]
+ l1 = [POLY_RES[0], POLY_LAYER[0], PSDM_LAYER[0], NPC_LAYER[0], RPM_LAUER[0]]
+ w1 = [POLY_RES[1], POLY_LAYER[1], PSDM_LAYER[1], NPC_LAYER[1], rpm]
+ if gr == 0:
+ layer_names = [poly_res, poly_layer, psdm_layer, npc_layer, rpm_layer]
+ l1 = [
+ POLY_RES[0],
+ POLY_LAYER[0],
+ PSDM_LAYER_NO_GR[0],
+ NPC_LAYER[0],
+ RPM_LAUER[0],
+ ]
+ w1 = [POLY_RES[1], POLY_LAYER[1], PSDM_LAYER_NO_GR[1], NPC_LAYER[1], rpm]
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, li_layer]
+ l1 = [TAP_LI_LAYER[0], TAP_LI_LAYER[0]]
+ w1 = [TAP_LI_LAYER[1], TAP_LI_LAYER[1]]
+ thick = [TAP_LI_LAYER[2], TAP_LI_LAYER[2]]
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [licon_layer, licon_layer, li_layer, m1_layer]
+ l1 = [LICON1_LAYER[0], LICON2_LAYER[0], LI_LAYER[0], M1_LAYER[0]]
+ sizes_l = [LICON1_LAYER[1], LICON2_LAYER[1], LI_LAYER[1], M1_LAYER[1]]
+ sizes_w = [LICON1_LAYER[2], LICON2_LAYER[2], w, w - 0.1]
+ space_fit_in = [w + 0.1, w + 0.34, LI_LAYER[3], M1_LAYER[3]]
+ spaces = [LICON1_LAYER[4], LICON2_LAYER[4], LI_LAYER[4], M1_LAYER[4]]
+
+ if gr == 0:
+ layer_names = [licon_layer, li_layer, m1_layer]
+ l1 = [LICON1_LAYER[0], LI_LAYER[0], M1_LAYER[0]]
+ sizes_l = [LICON1_LAYER_NO_GR, LI_LAYER[1], M1_LAYER[1]]
+ sizes_w = [LICON1_LAYER[2], w, w - 0.1]
+ space_fit_in = [w + 0.1, LI_LAYER[3], M1_LAYER[3]]
+ spaces = [LICON1_LAYER[4], LI_LAYER[4], M1_LAYER[4]]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ # vertical contacts
+
+ layer_names = [licon_layer]
+ l1 = [LICON_LAYER[0]]
+ sizes_l = [LICON_LAYER[1]]
+ sizes_w = [LICON_LAYER[2]]
+ space_fit_in = [l_res + LICON_LAYER[3]]
+ spaces = [LICON_LAYER[4]]
+
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ # 2d arr
+ self.draw_2dArr_layer(
+ mcon_layer, MCON_LAYER[0], MCON_LAYER[1], MCON_LAYER[2], n_mcon
+ )
+
+ def your_res(
+ self,
+ layout,
+ type="sky130_fd_pr__res_generic_po",
+ l_res: float = L_MIN_G,
+ w: float = W_MIN_G,
+ gr: int = GR,
+ ):
+ """draw the res with calling the parent func with right data
+
+ Args:
+ layout(layout): drawing layout
+ type(str): type of the resistor
+ l_res(float): length of the resistor
+ w(float): width of the resistor
+ gr(int): guard ring of the resistor
+
+ """
+ self.set_l_w(l_res, w)
+
+ if type == "sky130_fd_pr__res_generic_po":
+ # rects
+ layer_names = [poly_res, poly_layer]
+ l1 = [POLY_RES[0], POLY_LAYER_G[0]]
+ w1 = [POLY_RES[1], POLY_LAYER_G[1]]
+
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [tap_layer, psdm_layer, li_layer]
+ l1 = [TAP_LI_LAYER_G[0], PSDM_LAYER_G[0], TAP_LI_LAYER_G[0]]
+ w1 = [TAP_LI_LAYER_G[1], PSDM_LAYER_G[1], TAP_LI_LAYER_G[1]]
+ thick = [TAP_LI_LAYER_G[2], PSDM_LAYER_G[2], TAP_LI_LAYER_G[2]]
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ licon_layer,
+ licon_layer,
+ npc_layer,
+ li_layer,
+ li_layer,
+ m1_layer,
+ ]
+ # npc
+ counts_arr = math.floor(w / 0.36)
+ if counts_arr <= 0:
+ counts_arr = 1
+ w_met = w - 0.21
+ if counts_arr == 1:
+ w_met = 0.37
+ ##
+ l1 = [
+ LICON1_LAYER_G[0],
+ LICON2_LAYER_G[0],
+ NPC_LAYER_G[0],
+ LI1_LAYER_G[0],
+ LI2_LAYER_G[0],
+ M1_LAYER_G[0],
+ ]
+ sizes_l = [
+ LICON1_LAYER_G[1],
+ LICON2_LAYER_G[1],
+ NPC_LAYER_G[1],
+ LI1_LAYER_G[1],
+ LI2_LAYER_G[1],
+ M1_LAYER_G[1],
+ ]
+ sizes_w = [LICON1_LAYER_G[2], LICON2_LAYER_G[2], w_met, w - 0.16, w, w]
+ space_fit_in = [
+ w,
+ w + 0.68,
+ NPC_LAYER_G[3],
+ LI1_LAYER_G[3],
+ LI2_LAYER_G[3],
+ M1_LAYER_G[3],
+ ]
+ spaces = [
+ LICON1_LAYER_G[4],
+ LICON2_LAYER_G[4],
+ NPC_LAYER_G[4],
+ LI1_LAYER_G[4],
+ LI2_LAYER_G[4],
+ M1_LAYER_G[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ licon_layer,
+ npc_layer,
+ li_layer,
+ li_layer,
+ m1_layer,
+ ]
+ l1 = [
+ LICON1_LAYER_G[0],
+ NPC_LAYER_G[0],
+ LI1_LAYER_G[0],
+ LI2_LAYER_G[0],
+ M1_LAYER_G[0],
+ ]
+ sizes_l = [
+ LICON1_LAYER_G[1],
+ NPC_LAYER_G[1],
+ LI1_LAYER_G[1],
+ LI2_LAYER_G[1],
+ M1_LAYER_G[1],
+ ]
+ sizes_w = [LICON1_LAYER_G[2], w_met, w - 0.16, w, w]
+ space_fit_in = [
+ w,
+ w + 0.68,
+ LI1_LAYER_G[3],
+ LI2_LAYER_G[3],
+ M1_LAYER_G[3],
+ ]
+ spaces = [
+ LICON1_LAYER_G[4],
+ NPC_LAYER_G[4],
+ LI1_LAYER_G[4],
+ LI2_LAYER_G[4],
+ M1_LAYER_G[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ layer_names = [licon_layer]
+ l1 = [LICON_LAYER_G[0]]
+ sizes_l = [LICON_LAYER_G[1]]
+ sizes_w = [LICON_LAYER_G[2]]
+ space_fit_in = [l_res + LICON_LAYER_G[3]]
+ spaces = [LICON_LAYER_G[4]]
+
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ # 2d arr
+ self.draw_2dArr_layer(
+ mcon_layer, MCON_LAYER_G[0], MCON_LAYER_G[1], MCON_LAYER_G[2]
+ ) # 0.09,1.9
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
+
+ elif type == "sky130_fd_pr__res_iso_pw":
+ # rects
+ layer_names = [pwell_res, dnwell_layer]
+ l1 = [0, DNWELL[0]]
+ w1 = [0, DNWELL[1]]
+ if gr == 0:
+ layer_names = [pwell_res]
+ l1 = [0]
+ w1 = [0]
+
+ self.draw_rect_layer(layer_names, l1, w1)
+
+ # frams
+ layer_names = [nwell_layer, tap_layer, nsdm_layer, li_layer]
+ l1 = [NWELL[0], TAP_LI_LAYER_ISO[0], NSDM_LAYER_ISO[0], TAP_LI_LAYER_ISO[0]]
+ w1 = [NWELL[1], TAP_LI_LAYER_ISO[1], NSDM_LAYER_ISO[1], TAP_LI_LAYER_ISO[1]]
+ thick = [
+ NWELL[2],
+ TAP_LI_LAYER_ISO[2],
+ NSDM_LAYER_ISO[2],
+ TAP_LI_LAYER_ISO[2],
+ ]
+
+ if gr:
+ self.draw_frame_layer(layer_names, l1, w1, thick)
+
+ # countacts
+
+ layer_names = [
+ tap_layer,
+ psdm_layer,
+ li_layer,
+ m1_layer,
+ licon_layer,
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ ]
+
+ l1 = [
+ TAP_ISO[0],
+ PSDM_ISO[0],
+ LI_ISO[0],
+ M1_ISO[0],
+ LICON_ISO[0],
+ LICON_ISO2,
+ LICON_ISO3,
+ MCON_ISO[0],
+ ]
+ sizes_l = [
+ TAP_ISO[1],
+ PSDM_ISO[1],
+ LI_ISO[1],
+ M1_ISO[1],
+ LICON_ISO[1],
+ LICON_ISO[1],
+ LICON_ISO[1],
+ MCON_ISO[1],
+ ]
+ sizes_w = [
+ w - 0.4,
+ w - 0.15,
+ w - 0.48,
+ w - 0.4,
+ LICON_ISO[2],
+ LICON_ISO[2],
+ LICON_ISO[2],
+ MCON_ISO[2],
+ ]
+ space_fit_in = [
+ TAP_ISO[3],
+ PSDM_ISO[3],
+ LI_ISO[3],
+ M1_ISO[3],
+ w - 0.6,
+ w - 0.6,
+ w + 0.76,
+ w - 0.49,
+ ]
+ spaces = [
+ TAP_ISO[4],
+ PSDM_ISO[4],
+ LI_ISO[4],
+ M1_ISO[4],
+ LICON_ISO[4],
+ LICON_ISO[4],
+ LICON_ISO[4],
+ MCON_ISO[4],
+ ]
+
+ if gr == 0:
+ layer_names = [
+ tap_layer,
+ psdm_layer,
+ li_layer,
+ m1_layer,
+ licon_layer,
+ licon_layer,
+ mcon_layer,
+ ]
+
+ l1 = [
+ TAP_ISO[0],
+ PSDM_ISO[0],
+ LI_ISO[0],
+ M1_ISO[0],
+ LICON_ISO[0],
+ LICON_ISO2,
+ MCON_ISO[0],
+ ]
+ sizes_l = [
+ TAP_ISO[1],
+ PSDM_ISO[1],
+ LI_ISO[1],
+ M1_ISO[1],
+ LICON_ISO[1],
+ LICON_ISO[1],
+ MCON_ISO[1],
+ ]
+ sizes_w = [
+ w - 0.4,
+ w - 0.15,
+ w - 0.48,
+ w - 0.4,
+ LICON_ISO[2],
+ LICON_ISO[2],
+ MCON_ISO[2],
+ ]
+ space_fit_in = [
+ TAP_ISO[3],
+ PSDM_ISO[3],
+ LI_ISO[3],
+ M1_ISO[3],
+ w - 0.6,
+ w - 0.6,
+ w - 0.49,
+ ]
+ spaces = [
+ TAP_ISO[4],
+ PSDM_ISO[4],
+ LI_ISO[4],
+ M1_ISO[4],
+ LICON_ISO[4],
+ LICON_ISO[4],
+ MCON_ISO[4],
+ ]
+
+ self.draw_contact_layer_h(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ layer_names = [licon_layer]
+ l1 = [LICON_ISO_H[0]]
+ sizes_l = [LICON_ISO_H[1]]
+ sizes_w = [LICON_ISO_H[2]]
+ space_fit_in = [l_res + LICON_ISO_H[3]]
+ spaces = [LICON_ISO_H[4]]
+
+ if gr:
+ self.draw_contact_layer_v(
+ layer_names, l1, sizes_w, sizes_l, space_fit_in, spaces
+ )
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
+
+ elif type == "sky130_fd_pr__res_high_po_0p35":
+ self.poly_res(l_res, W_MIN_0P35, gr, 0, RPM_FOR_LAYERS[0])
+ elif type == "sky130_fd_pr__res_high_po_0p69":
+ self.poly_res(l_res, W_MIN_0P69, gr, 1, RPM_FOR_LAYERS[1])
+ elif type == "sky130_fd_pr__res_high_po_1p41":
+ self.poly_res(l_res, W_MIN_1P41, gr, 1, RPM_FOR_LAYERS[2])
+ elif type == "sky130_fd_pr__res_high_po_2p85":
+ self.poly_res(l_res, W_MIN_2P85, gr, 1, RPM_FOR_LAYERS[3])
+ elif type == "sky130_fd_pr__res_high_po_5p73":
+ self.poly_res(l_res, W_MIN_5P73, gr, 1, RPM_FOR_LAYERS[4])
+ # high
+
+ elif type == "sky130_fd_pr__res_xhigh_po_0p35":
+ self.poly_res(l_res, W_MIN_0P35, gr, 0, RPM_FOR_LAYERS[0], 1)
+ elif type == "sky130_fd_pr__res_xhigh_po_0p69":
+ self.poly_res(l_res, W_MIN_0P69, gr, 1, RPM_FOR_LAYERS[1], 1)
+ elif type == "sky130_fd_pr__res_xhigh_po_1p41":
+ self.poly_res(l_res, W_MIN_1P41, gr, 1, RPM_FOR_LAYERS[2], 1)
+ elif type == "sky130_fd_pr__res_xhigh_po_2p85":
+ self.poly_res(l_res, W_MIN_2P85, gr, 1, RPM_FOR_LAYERS[3], 1)
+ elif type == "sky130_fd_pr__res_xhigh_po_5p73":
+ self.poly_res(l_res, W_MIN_5P73, gr, 1, RPM_FOR_LAYERS[4], 1)
+
+ c = self.get_c()
+ c.write_gds("res_temp.gds")
+ layout.read("res_temp.gds")
+ cell_name = type
+ return layout.cell(cell_name)
diff --git a/sky130/cells/klayout/pymacros/cells/res_poly_klayout_panel.py b/sky130/cells/klayout/pymacros/cells/res_poly_klayout_panel.py
new file mode 100644
index 000000000..696c23345
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/res_poly_klayout_panel.py
@@ -0,0 +1,173 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+from .res_klayout_panel import res
+from .res_poly_child import res_poly_draw
+
+# ################constants################
+L_MIN = 1.65
+W_MIN = 0.33
+L_MIN_ISO = 26.5
+W_MIN_ISO = 2.65
+L_MIN_PO = 0.5
+W_MIN_0P35 = 0.35
+W_MIN_0P69 = 0.69
+W_MIN_1P41 = 1.41
+W_MIN_2P85 = 2.85
+W_MIN_5P73 = 5.73
+
+# ##############sheet resistances
+RES_GEN = 442.6 # sheet res for sky130_fd_pr__res_generic_po
+
+RES_ISO = 153.3 # sheet res for sky130_fd_pr__res_iso_pw
+
+RES_0P35 = 8971.42 # sheet res for sky130_fd_pr__res_high_po_0p35
+RES_0P69 = 2308.5 # sheet res for sky130_fd_pr__res_high_po_0p69
+RES_1P41 = 552.76 # sheet res for sky130_fd_pr__res_high_po_1p41
+RES_2P85 = 135.3 # sheet res for sky130_fd_pr__res_high_po_2p85
+RES_5P73 = 33.47 # sheet res for sky130_fd_pr__res_high_po_5p73
+# XHIGH
+RES_XH_0P35 = 22468.57 # sheet res for sky130_fd_pr__res_xhigh_po_0p35
+RES_XH_0P69 = 5779.7 # sheet res for sky130_fd_pr__res_xhigh_po_0p69
+RES_XH_1P41 = 1384.63 # sheet res for sky130_fd_pr__res_xhigh_po_1p41
+RES_XH_2P85 = 338.87 # sheet res for sky130_fd_pr__res_xhigh_po_2p85
+RES_XH_5P73 = 83.8 # sheet res for sky130_fd_pr__res_xhigh_po_5p73
+##########################################
+
+
+class res_poly(res):
+ """child class for the front end of the poly res (klayout panel)
+ Args:
+ res(class): parent class for all types of resistors
+ l_min(float): minimum length of the resistor
+ w_min(float): minimum width of the resistor
+
+ """
+
+ def __init__(self):
+ super().__init__(L_MIN_PO, W_MIN) # (l_min,w_min)
+
+ # types of resistor you need to add
+ # it goes in var self.type
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_generic_po", "sky130_fd_pr__res_generic_po"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_iso_pw", "sky130_fd_pr__res_iso_pw"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_high_po_0p35", "sky130_fd_pr__res_high_po_0p35"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_high_po_0p69", "sky130_fd_pr__res_high_po_0p69"
+ )
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_high_po_1p41", "sky130_fd_pr__res_high_po_1p41"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_high_po_2p85", "sky130_fd_pr__res_high_po_2p85"
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_high_po_5p73", "sky130_fd_pr__res_high_po_5p73"
+ )
+
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_xhigh_po_0p35",
+ "sky130_fd_pr__res_xhigh_po_0p35",
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_xhigh_po_0p69",
+ "sky130_fd_pr__res_xhigh_po_0p69",
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_xhigh_po_1p41",
+ "sky130_fd_pr__res_xhigh_po_1p41",
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_xhigh_po_2p85",
+ "sky130_fd_pr__res_xhigh_po_2p85",
+ )
+ self.Type_handle.add_choice(
+ "sky130_fd_pr__res_xhigh_po_5p73",
+ "sky130_fd_pr__res_xhigh_po_5p73",
+ )
+
+ def coerce_parameters_impl(self):
+ """(override func) check the minimum values of l and w
+
+ decide whether the handle or the numeric parameter has
+ changed (by comparing against the effective
+ radius ru) and set ru to the effective radius. We also update the
+ numerical value or the shape, depending on which on has not changed
+
+
+ """
+
+ # res_value = sheet res * area
+ if self.type == "sky130_fd_pr__res_generic_po":
+ super().coerce_parameters_impl(L_MIN, W_MIN) # (l_min,w_min)
+ self.res_value = RES_GEN * self.area
+
+ elif self.type == "sky130_fd_pr__res_iso_pw":
+ super().coerce_parameters_impl(L_MIN_ISO, W_MIN_ISO)
+ self.res_value = RES_ISO * self.area
+
+ elif self.type == "sky130_fd_pr__res_high_po_0p35":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_0P35)
+ self.res_value = RES_0P35 * self.area
+
+ elif self.type == "sky130_fd_pr__res_high_po_0p69":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_0P69)
+ self.res_value = RES_0P69 * self.area
+ elif self.type == "sky130_fd_pr__res_high_po_1p41":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_1P41)
+ self.res_value = RES_1P41 * self.area
+ elif self.type == "sky130_fd_pr__res_high_po_2p85":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_2P85)
+ self.res_value = RES_2P85 * self.area
+
+ elif self.type == "sky130_fd_pr__res_high_po_5p73":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_5P73)
+ self.res_value = RES_5P73 * self.area
+
+ elif self.type == "sky130_fd_pr__res_xhigh_po_0p35":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_0P35)
+ self.res_value = RES_XH_0P35 * self.area
+ elif self.type == "sky130_fd_pr__res_xhigh_po_0p69":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_0P69)
+ self.res_value = RES_XH_0P69 * self.area
+ elif self.type == "sky130_fd_pr__res_xhigh_po_1p41":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_1P41)
+ self.res_value = RES_XH_1P41 * self.area
+ elif self.type == "sky130_fd_pr__res_xhigh_po_2p85":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_2P85)
+ self.res_value = RES_XH_2P85 * self.area
+ elif self.type == "sky130_fd_pr__res_xhigh_po_5p73":
+ super().coerce_parameters_impl(L_MIN_PO, W_MIN_5P73)
+ self.res_value = RES_XH_5P73 * self.area
+
+ def produce_impl(self):
+ """(override func)call the implementation backend code
+ create instance and pass it to the parent func
+
+ instance(layout): the result layout to show
+
+ """
+ drw = res_poly_draw(self.type)
+ instance = drw.your_res(
+ self.layout, l_res=self.len, w=self.w, type=self.type, gr=self.gr
+ )
+ super().produce_impl(instance)
diff --git a/sky130/cells/klayout/pymacros/cells/rf.py b/sky130/cells/klayout/pymacros/cells/rf.py
new file mode 100644
index 000000000..0de2ddfe7
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/rf.py
@@ -0,0 +1,144 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# RF DEVICES Generator for skywater130
+########################################################################################################################
+
+import pya
+
+from .draw_rf import draw_rf_bjt, draw_rf_coils, draw_rf_mosfet
+from .globals import RF_BJT_DEV, RF_COILS_DEV, RF_MOSFET_DEV
+
+
+class rf_mosfet(pya.PCellDeclarationHelper):
+ """
+ rf mosfet Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+
+ for i in RF_MOSFET_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model", self.TypeString, "Model", default="sky130_fd_pr__", readonly=True
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ rf_mos_instance = draw_rf_mosfet(layout=self.layout, device_name=self.Type)
+
+ write_cells = pya.CellInstArray(
+ rf_mos_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+
+ self.layout.cleanup()
+
+
+class rf_bjt(pya.PCellDeclarationHelper):
+ """
+ rf bjt Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+ for i in RF_BJT_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model", self.TypeString, "Model", default="sky130_fd_pr__", readonly=True
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ rf_bjt_instance = draw_rf_bjt(layout=self.layout, device_name=self.Type)
+
+ write_cells = pya.CellInstArray(
+ rf_bjt_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+
+ self.layout.cleanup()
+
+
+class rf_coils(pya.PCellDeclarationHelper):
+ """
+ rf coils Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+ for i in RF_COILS_DEV:
+ self.Type_handle.add_choice(i, i)
+
+ self.param(
+ "Model", self.TypeString, "Model", default="sky130_fd_pr__", readonly=True
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ rf_coils_instance = draw_rf_coils(layout=self.layout, device_name=self.Type)
+
+ write_cells = pya.CellInstArray(
+ rf_coils_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+
+ self.layout.cleanup()
diff --git a/sky130/cells/klayout/pymacros/cells/via_generator.py b/sky130/cells/klayout/pymacros/cells/via_generator.py
new file mode 100644
index 000000000..59c5bdfd7
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/via_generator.py
@@ -0,0 +1,598 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# via Generator for skywater130
+########################################################################################################################
+
+
+from math import ceil, floor
+
+import gdsfactory as gf
+from gdsfactory.types import Float2, LayerSpec
+
+from .layers_def import (
+ diff_layer,
+ li_layer,
+ licon_layer,
+ m1_layer,
+ m2_layer,
+ m3_layer,
+ m4_layer,
+ m5_layer,
+ mcon_layer,
+ npc_layer,
+ nsdm_layer,
+ nwell_layer,
+ poly_layer,
+ psdm_layer,
+ tap_layer,
+ via1_layer,
+ via2_layer,
+ via3_layer,
+ via4_layer,
+)
+
+
+@gf.cell
+def via_generator(
+ x_range: Float2 = (0, 1),
+ y_range: Float2 = (0, 1),
+ via_size: Float2 = (0.17, 0.17),
+ via_layer: LayerSpec = (66, 44),
+ via_enclosure: Float2 = (0.06, 0.06),
+ via_spacing: Float2 = (0.17, 0.17),
+) -> gf.Component():
+ """
+ return only vias withen the range xrange and yrange while enclosing by via_enclosure
+ and set number of rows and number of coloumns according to ranges and via size and spacing
+
+ """
+
+ c = gf.Component()
+
+ width = x_range[1] - x_range[0]
+ length = y_range[1] - y_range[0]
+ nr = floor(length / (via_size[1] + via_spacing[1]))
+ if (length - nr * via_size[1] - (nr - 1) * via_spacing[1]) / 2 < via_enclosure[1]:
+ nr -= 1
+
+ if nr < 1:
+ nr = 1
+
+ nc = ceil(width / (via_size[0] + via_spacing[0]))
+
+ if (
+ round(width - nc * via_size[0] - (nc - 1) * via_spacing[0], 2)
+ ) / 2 < via_enclosure[0]:
+ nc -= 1
+
+ if nc < 1:
+ nc = 1
+
+ via_sp = (via_size[0] + via_spacing[0], via_size[1] + via_spacing[1])
+
+ rect_via = gf.components.rectangle(size=via_size, layer=via_layer)
+
+ via_arr = c.add_array(rect_via, rows=nr, columns=nc, spacing=via_sp)
+
+ via_arr.move((x_range[0], y_range[0]))
+
+ via_arr.movex((width - nc * via_size[0] - (nc - 1) * via_spacing[0]) / 2)
+ via_arr.movey((length - nr * via_size[1] - (nr - 1) * via_spacing[1]) / 2)
+
+ return c
+
+
+@gf.cell
+def via_stack(
+ x_range: Float2 = (0, 1),
+ y_range: Float2 = (0, 1),
+ base_layer: LayerSpec = diff_layer,
+ slotted_licon: int = 0,
+ metal_level: int = 1,
+ li_enc_dir="V",
+) -> gf.Component:
+ """
+ return via stack till the metal level indicated where :
+ metal_level 0 : till li
+ metal_level 1 : till m1
+ metal_level 2 : till m2
+ metal_level 3 : till m3
+ metal_level 4 : till m4
+ metal_level 5 : till m5
+ withen the range xrange and yrange and expecting the base_layer to be drawen
+
+ """
+
+ c = gf.Component()
+
+ # vias dimensions
+
+ if slotted_licon == 1:
+ licon_size = (0.19, 2)
+
+ else:
+ licon_size = (0.17, 0.17)
+
+ mcon_size = (0.17, 0.17)
+
+ if base_layer == diff_layer or base_layer == tap_layer:
+ con_enc = (0.06, 0.06)
+
+ # elif base_layer == tap_layer:
+ # con_enc = (0.1,0.06)
+
+ elif base_layer == poly_layer:
+ con_enc = (0.05, 0.08)
+ npc_enc = 0.01
+ npc = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ x_range[1] - x_range[0] + 2 * npc_enc,
+ y_range[1] - y_range[0] + 2 * npc_enc,
+ ),
+ layer=npc_layer,
+ )
+ )
+ npc.move((x_range[0] - npc_enc, y_range[0] - npc_enc))
+
+ else:
+ pass
+
+ if li_enc_dir == "H":
+ li_enc = (0.08, 0)
+ m1_enc = (0.06, 0.03)
+ elif li_enc_dir == "V":
+ li_enc = (0, 0.08)
+ m1_enc = (0.03, 0.06)
+
+ con_spacing = (0.19, 0.19)
+
+ via1_size = (0.15, 0.15)
+ via1_spacing = (0.17, 0.17)
+ via1_enc = (0.055, 0.085)
+
+ via2_size = (0.2, 0.2)
+ via2_enc = (0.04, 0.085)
+ via2_spacing = (0.2, 0.2)
+
+ via3_size = (0.2, 0.2)
+ via3_enc = (0.06, 0.09)
+ via3_spacing = (0.2, 0.2)
+
+ via4_size = (0.8, 0.8)
+ via4_enc = (0.19, 0.19)
+ via4_spacing = (0.8, 0.8)
+
+ if metal_level >= 0:
+ licon_gen = via_generator(
+ x_range=x_range,
+ y_range=y_range,
+ via_size=licon_size,
+ via_enclosure=con_enc,
+ via_layer=licon_layer,
+ via_spacing=con_spacing,
+ )
+ licon = c.add_ref(licon_gen)
+
+ li = c.add_ref(
+ gf.components.rectangle(
+ size=(
+ licon.xmax - licon.xmin + (2 * li_enc[0]),
+ licon.ymax - licon.ymin + (2 * li_enc[1]),
+ ),
+ layer=li_layer,
+ )
+ )
+ li.move((licon.xmin - li_enc[0], licon.ymin - li_enc[1]))
+
+ if metal_level >= 1:
+ mcon_gen = via_generator(
+ x_range=x_range,
+ y_range=y_range,
+ via_size=mcon_size,
+ via_enclosure=con_enc,
+ via_layer=mcon_layer,
+ via_spacing=con_spacing,
+ )
+ mcon = c.add_ref(mcon_gen)
+
+ if (mcon.xmax - mcon.xmin + 2 * m1_enc[0]) < (
+ via1_size[0] + 2 * via1_enc[0]
+ ) and metal_level >= 2:
+ m1_x = via1_size[0] + 2 * via1_enc[0]
+
+ else:
+ m1_x = mcon.xmax - mcon.xmin + 2 * m1_enc[0]
+
+ if (mcon.ymax - mcon.ymin + 2 * m1_enc[1]) < (
+ via1_size[1] + 2 * via1_enc[1]
+ ) and metal_level >= 2:
+ m1_y = via1_size[1] + 2 * via1_enc[1]
+
+ else:
+ m1_y = mcon.ymax - mcon.ymin + 2 * m1_enc[1]
+
+ m1_a = 0.084
+
+ if (m1_x * m1_y) < m1_a:
+ m1_x = m1_a / m1_y
+
+ m1_mx = (m1_x - (mcon.xmax - mcon.xmin)) / 2
+ m1_my = (m1_y - (mcon.ymax - mcon.ymin)) / 2
+
+ m1 = c.add_ref(gf.components.rectangle(size=(m1_x, m1_y), layer=m1_layer))
+ m1.move((mcon.xmin - m1_mx, mcon.ymin - m1_my))
+
+ if metal_level >= 2:
+ via1_gen = via_generator(
+ x_range=(m1.xmin, m1.xmax),
+ y_range=(m1.ymin, m1.ymax),
+ via_size=via1_size,
+ via_enclosure=via1_enc,
+ via_layer=via1_layer,
+ via_spacing=via1_spacing,
+ )
+ via1 = c.add_ref(via1_gen)
+
+ if (via1.xmax - via1.xmin) > (via1.ymax - via1.ymin):
+ m2_enc = (0.055, 0.085)
+ else:
+ m2_enc = (0.085, 0.055)
+
+ if (via1.xmax - via1.xmin + 2 * m2_enc[0]) < (
+ via2_size[0] + 2 * via2_enc[0]
+ ) and metal_level >= 3:
+ m2_x = via2_size[0] + 2 * via2_enc[0]
+
+ else:
+ m2_x = via1.xmax - via1.xmin + 2 * m2_enc[0]
+
+ if (via1.ymax - via1.ymin + 2 * m2_enc[1]) < (
+ via2_size[1] + 2 * via2_enc[1]
+ ) and metal_level >= 3:
+ m2_y = via2_size[1] + 2 * via2_enc[1]
+
+ else:
+ m2_y = via1.ymax - via1.ymin + 2 * m2_enc[1]
+
+ m2_mx = (m2_x - (via1.xmax - via1.xmin)) / 2
+ m2_my = (m2_y - (via1.ymax - via1.ymin)) / 2
+
+ m2 = c.add_ref(gf.components.rectangle(size=(m2_x, m2_y), layer=m2_layer))
+ m2.move((via1.xmin - m2_mx, via1.ymin - m2_my))
+
+ if metal_level >= 3:
+ via2_gen = via_generator(
+ x_range=(m2.xmin, m2.xmax),
+ y_range=(m2.ymin, m2.ymax),
+ via_size=via2_size,
+ via_enclosure=via2_enc,
+ via_layer=via2_layer,
+ via_spacing=via2_spacing,
+ )
+ via2 = c.add_ref(via2_gen)
+
+ m3_enc = (0.065, 0.065)
+
+ if (via2.xmax - via2.xmin + 2 * m3_enc[0]) < (
+ via3_size[0] + 2 * via3_enc[0]
+ ) and metal_level >= 4:
+ m3_x = via3_size[0] + 2 * via3_enc[0]
+
+ else:
+ m3_x = via2.xmax - via2.xmin + 2 * m3_enc[0]
+
+ if (via2.ymax - via2.ymin + 2 * m3_enc[1]) < (
+ via3_size[1] + 2 * via3_enc[1]
+ ) and metal_level >= 4:
+ m3_y = via3_size[1] + 2 * via3_enc[1]
+
+ else:
+ m3_y = via2.ymax - via2.ymin + 2 * m3_enc[1]
+
+ m3_mx = (m3_x - (via2.xmax - via2.xmin)) / 2
+ m3_my = (m3_y - (via2.ymax - via2.ymin)) / 2
+
+ m3 = c.add_ref(gf.components.rectangle(size=(m3_x, m3_y), layer=m3_layer))
+ m3.move((via2.xmin - m3_mx, via2.ymin - m3_my))
+
+ if metal_level >= 4:
+ via3_gen = via_generator(
+ x_range=(m3.xmin, m3.xmax),
+ y_range=(m3.ymin, m3.ymax),
+ via_size=via3_size,
+ via_enclosure=via3_enc,
+ via_layer=via3_layer,
+ via_spacing=via3_spacing,
+ )
+ via3 = c.add_ref(via3_gen)
+
+ m4_enc = (0.065, 0.065)
+
+ if (via3.xmax - via3.xmin + 2 * m4_enc[0]) < (
+ via4_size[0] + 2 * via4_enc[0]
+ ) and metal_level >= 5:
+ m4_x = via4_size[0] + 2 * via4_enc[0]
+
+ else:
+ m4_x = via3.xmax - via3.xmin + 2 * m4_enc[0]
+
+ if (via3.ymax - via3.ymin + 2 * m4_enc[1]) < (
+ via4_size[1] + 2 * via4_enc[1]
+ ) and metal_level >= 5:
+ m4_y = via4_size[1] + 2 * via4_enc[1]
+
+ else:
+ m4_y = via3.ymax - via3.ymin + 2 * m4_enc[1]
+
+ m4_mx = (m4_x - (via3.xmax - via3.xmin)) / 2
+ m4_my = (m4_y - (via3.ymax - via3.ymin)) / 2
+
+ m4 = c.add_ref(gf.components.rectangle(size=(m4_x, m4_y), layer=m4_layer))
+ m4.move((via3.xmin - m4_mx, via3.ymin - m4_my))
+
+ if metal_level >= 5:
+ via4_gen = via_generator(
+ x_range=(m4.xmin, m4.xmax),
+ y_range=(m4.ymin, m4.ymax),
+ via_size=via4_size,
+ via_enclosure=via4_enc,
+ via_layer=via4_layer,
+ via_spacing=via4_spacing,
+ )
+ via4 = c.add_ref(via4_gen)
+
+ m5_enc = (0.31, 0.31)
+ m5_min_w = 1.6
+ if (via4.xmax - via4.xmin + 2 * m5_enc[0]) < m5_min_w:
+ m5_x = m5_min_w
+
+ else:
+ m5_x = via4.xmax - via4.xmin + 2 * m5_enc[0]
+
+ if (via4.ymax - via4.ymin + 2 * m5_enc[1]) < m5_min_w:
+ m5_y = m5_min_w
+
+ else:
+ m5_y = via4.ymax - via4.ymin + 2 * m5_enc[1]
+
+ m5_a = 4
+ if (m5_x * m5_y) < m5_a:
+ m5_x = m5_a / m5_y
+
+ m5_mx = (m5_x - (via4.xmax - via4.xmin)) / 2
+ m5_my = (m5_y - (via4.ymax - via4.ymin)) / 2
+
+ m5 = c.add_ref(gf.components.rectangle(size=(m5_x, m5_y), layer=m5_layer))
+ m5.move((via4.xmin - m5_mx, via4.ymin - m5_my))
+
+ return c
+
+
+# @gf.cell
+def vias_gen_draw(
+ layout, l_vias: float = 1.0, w: float = 1.0, start_layer="poly", end_layer="metal5"
+): # -> gf.Component :
+ """
+ draws a vias stack from the start_layer to the end_layer and also draws the start and end layers where :
+ l_vias : float of the length that vias will be drawn in
+ w : float of the width that vias will drawn in
+ start_layer : string of the first layer to be drawn that takes input of (poly,p_tap,n_tap,p_diff,n_diff,li,metal1:5)
+ end_layer : string of the last layer to be drawn that takes input of (poly,p_tap,n_tap,p_diff,n_diff,li,metal1:5)
+
+ """
+ c = gf.Component("via")
+
+ base_layers = ["poly", "n_diff", "p_diff", "n_tap", "p_tap"]
+ metal_layers = ["li", "metal1", "metal2", "metal3", "metal4", "metal5"]
+
+ if start_layer in base_layers:
+ level_1 = -1
+ else:
+ for i in range(len(metal_layers)):
+ if start_layer == metal_layers[i]:
+ level_1 = i
+
+ if end_layer in base_layers:
+ level_2 = -1
+ else:
+ for i in range(len(metal_layers)):
+ if end_layer == metal_layers[i]:
+ level_2 = i
+
+ if level_1 <= -1 and level_2 >= -1:
+ if start_layer == "poly" or end_layer == "poly":
+ npc_enc = 0.05
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=poly_layer))
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * npc_enc, w + 2 * npc_enc), layer=npc_layer
+ )
+ ).move((-npc_enc, -npc_enc))
+ if "diff" in start_layer or "diff" in end_layer:
+ n_p_enc = 0.125
+ nwell_enc = 0.18
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=diff_layer))
+ if "n_" in start_layer or "n_" in end_layer:
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * n_p_enc, w + 2 * n_p_enc), layer=nsdm_layer
+ )
+ ).move((-n_p_enc, -n_p_enc))
+ else:
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * n_p_enc, w + 2 * n_p_enc), layer=psdm_layer
+ )
+ ).move((-n_p_enc, -n_p_enc))
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * nwell_enc, w + 2 * nwell_enc),
+ layer=nwell_layer,
+ )
+ ).move((-nwell_enc, -nwell_enc))
+ if "tap" in start_layer or "tap" in end_layer:
+ n_p_enc = 0.125
+ nwell_enc = 0.18
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=tap_layer))
+ if "n_" in start_layer or "n_" in end_layer:
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * n_p_enc, w + 2 * n_p_enc), layer=nsdm_layer
+ )
+ ).move((-n_p_enc, -n_p_enc))
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * nwell_enc, w + 2 * nwell_enc),
+ layer=nwell_layer,
+ )
+ ).move((-nwell_enc, -nwell_enc))
+ else:
+ c.add_ref(
+ gf.components.rectangle(
+ size=(l_vias + 2 * n_p_enc, w + 2 * n_p_enc), layer=psdm_layer
+ )
+ ).move((-n_p_enc, -n_p_enc))
+
+ if level_1 <= 0 and level_2 >= 0:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=li_layer))
+
+ if level_1 <= 1 and level_2 >= 1:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=m1_layer))
+
+ if level_1 <= 2 and level_2 >= 2:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=m2_layer))
+
+ if level_1 <= 3 and level_2 >= 3:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=m3_layer))
+
+ if level_1 <= 4 and level_2 >= 4:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=m4_layer))
+
+ if level_1 <= 5 and level_2 >= 5:
+ c.add_ref(gf.components.rectangle(size=(l_vias, w), layer=m5_layer))
+
+ if level_1 <= -1 and level_2 > -1:
+ licon_size = (0.17, 0.17)
+
+ licon_spacing = (0.17, 0.17)
+
+ if start_layer == "poly":
+ licon_enc = (0.08, 0.05)
+ elif "diff" in start_layer:
+ licon_enc = (0.12, 0.06) # (0.06,0.04)
+ elif "tap" in start_layer:
+ licon_enc = (0.12, 0.06)
+
+ licon = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=licon_size,
+ via_layer=licon_layer,
+ via_enclosure=licon_enc,
+ via_spacing=licon_spacing,
+ )
+ c.add_ref(licon)
+
+ if level_1 <= 0 and level_2 > 0:
+ mcon_size = (0.17, 0.17)
+ mcon_enc = (0.06, 0.03)
+ mcon_spacing = (0.19, 0.19)
+
+ mcon = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=mcon_size,
+ via_layer=mcon_layer,
+ via_enclosure=mcon_enc,
+ via_spacing=mcon_spacing,
+ )
+ c.add_ref(mcon)
+
+ if level_1 <= 1 and level_2 > 1:
+ via1_size = (0.15, 0.15)
+ via1_enc = (0.085, 0.055)
+ via1_spacing = (0.17, 0.17)
+
+ via1 = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=via1_size,
+ via_layer=via1_layer,
+ via_enclosure=via1_enc,
+ via_spacing=via1_spacing,
+ )
+ c.add_ref(via1)
+
+ if level_1 <= 2 and level_2 > 2:
+ via2_size = (0.2, 0.2)
+ via2_enc = (0.085, 0.065)
+ via2_spacing = (0.2, 0.2)
+
+ via2 = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=via2_size,
+ via_layer=via2_layer,
+ via_enclosure=via2_enc,
+ via_spacing=via2_spacing,
+ )
+ c.add_ref(via2)
+
+ if level_1 <= 3 and level_2 > 3:
+ via3_size = (0.2, 0.2)
+ via3_enc = (0.09, 0.065)
+ via3_spacing = (0.2, 0.2)
+
+ via3 = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=via3_size,
+ via_layer=via3_layer,
+ via_enclosure=via3_enc,
+ via_spacing=via3_spacing,
+ )
+ c.add_ref(via3)
+
+ if level_1 <= 4 and level_2 > 4:
+ via4_size = (0.8, 0.8)
+ via4_enc = (0.31, 0.31)
+ via4_spacing = (0.8, 0.8)
+
+ via4 = via_generator(
+ x_range=(0, l_vias),
+ y_range=(0, w),
+ via_size=via4_size,
+ via_layer=via4_layer,
+ via_enclosure=via4_enc,
+ via_spacing=via4_spacing,
+ )
+ c.add_ref(via4)
+
+ # creating layout and cell in klayout
+ c.write_gds("vias_temp.gds")
+ layout.read("vias_temp.gds")
+ cell_name = "via"
+
+ return layout.cell(cell_name)
+ # return c
+
+
+# testing the generated methods
+if __name__ == "__main__":
+ c = vias_gen_draw(start_layer="li", end_layer="poly")
+ c.show()
diff --git a/sky130/cells/klayout/pymacros/cells/vias.py b/sky130/cells/klayout/pymacros/cells/vias.py
new file mode 100644
index 000000000..7a8af67fe
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/vias.py
@@ -0,0 +1,199 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# Vias Generator for skywater130
+########################################################################################################################
+
+import pya
+
+from .via_generator import vias_gen_draw
+
+licon_size = (0.17, 0.17)
+
+licon_spacing = (0.17, 0.17)
+
+mcon_size = (0.17, 0.17)
+mcon_enc = (0.06, 0.03)
+mcon_spacing = (0.19, 0.19)
+
+via1_size = (0.15, 0.15)
+via1_enc = (0.085, 0.055)
+via1_spacing = (0.17, 0.17)
+
+via2_size = (0.2, 0.2)
+via2_enc = (0.085, 0.065)
+via2_spacing = (0.2, 0.2)
+
+via3_size = (0.2, 0.2)
+via3_enc = (0.09, 0.065)
+via3_spacing = (0.2, 0.2)
+
+via4_size = (0.8, 0.8)
+via4_enc = (0.31, 0.31)
+via4_spacing = (0.8, 0.8)
+
+
+class vias_gen(pya.PCellDeclarationHelper):
+ """
+ Vias Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Initialize super class.
+ super().__init__()
+
+ # ===================== PARAMETERS DECLARATIONS =====================
+
+ self.param("l", self.TypeDouble, "length", default=1, unit="um")
+ self.param("w", self.TypeDouble, "width", default=1, unit="um")
+
+ self.Type_handle = self.param("start_layer", self.TypeList, "Start Layer")
+ self.Type_handle.add_choice("poly", "poly")
+ self.Type_handle.add_choice("p_tap", "p_tap")
+ self.Type_handle.add_choice("n_tap", "n_tap")
+ self.Type_handle.add_choice("p_diff", "p_diff")
+ self.Type_handle.add_choice("n_diff", "n_diff")
+ self.Type_handle.add_choice("li", "li")
+ self.Type_handle.add_choice("metal1", "metal1")
+ self.Type_handle.add_choice("metal2", "metal2")
+ self.Type_handle.add_choice("metal3", "metal3")
+ self.Type_handle.add_choice("metal4", "metal4")
+
+ self.Type_handle = self.param("end_layer", self.TypeList, "End Layer")
+ self.Type_handle.add_choice("li", "li")
+ self.Type_handle.add_choice("metal1", "metal1")
+ self.Type_handle.add_choice("metal2", "metal2")
+ self.Type_handle.add_choice("metal3", "metal3")
+ self.Type_handle.add_choice("metal4", "metal4")
+ self.Type_handle.add_choice("metal5", "metal5")
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return "via (L=" + ("%.3f" % self.l) + ",W=" + ("%.3f" % self.w) + ")"
+
+ def coerce_parameters_impl(self):
+ # We employ coerce_parameters_impl to decide whether the handle or the
+ # numeric parameter has changed (by comparing against the effective
+ # radius ru) and set ru to the effective radius. We also update the
+ # numerical value or the shape, depending on which on has not changed.
+
+ base_layers = ["poly", "n_diff", "p_diff", "n_tap", "p_tap"]
+ metal_layers = ["li", "metal1", "metal2", "metal3", "metal4", "metal5"]
+
+ if self.start_layer in base_layers:
+ level_1 = -1
+ else:
+ for i in range(len(metal_layers)):
+ if self.start_layer == metal_layers[i]:
+ level_1 = i
+
+ if self.end_layer in base_layers:
+ level_2 = -1
+ else:
+ for i in range(len(metal_layers)):
+ if self.end_layer == metal_layers[i]:
+ level_2 = i
+
+ # if level_1 < level_2 :
+ # temp_layer = self.start_layer
+ # self.start_layer = self.end_layer
+ # self.end_layer = temp_layer
+
+ if level_1 <= -1 and level_2 > -1:
+ if self.start_layer == "poly":
+ licon_enc = (0.08, 0.05)
+ elif "diff" in self.start_layer:
+ licon_enc = (0.12, 0.06) # (0.06,0.04)
+ elif "tap" in self.start_layer:
+ licon_enc = (0.12, 0.06)
+ else:
+ licon_enc = (0.12, 0.12)
+
+ if self.l < (licon_size[0] + 2 * licon_enc[0]):
+ self.l = licon_size[0] + 2 * licon_enc[0]
+
+ if self.w < (licon_size[1] + 2 * licon_enc[1]):
+ self.w = licon_size[1] + 2 * licon_enc[1]
+
+ if level_1 <= 0 and level_2 > 0:
+ if self.l < (mcon_size[0] + 2 * mcon_enc[0]):
+ self.l = mcon_size[0] + 2 * mcon_enc[0]
+
+ if self.w < (mcon_size[1] + 2 * mcon_enc[1]):
+ self.w = mcon_size[1] + 2 * mcon_enc[1]
+
+ if level_1 <= 1 and level_2 > 1:
+ if self.l < (via1_size[0] + 2 * via1_enc[0]):
+ self.l = via1_size[0] + 2 * via1_enc[0]
+
+ if self.w < (via1_size[1] + 2 * via1_enc[1]):
+ self.w = via1_size[1] + 2 * via1_enc[1]
+
+ if level_1 <= 2 and level_2 > 2:
+ if self.l < (via2_size[0] + 2 * via2_enc[0]):
+ self.l = via2_size[0] + 2 * via2_enc[0]
+
+ if self.w < (via2_size[1] + 2 * via2_enc[1]):
+ self.w = via2_size[1] + 2 * via2_enc[1]
+
+ if level_1 <= 3 and level_2 > 3:
+ if self.l < (via3_size[0] + 2 * via3_enc[0]):
+ self.l = via3_size[0] + 2 * via3_enc[0]
+
+ if self.w < (via3_size[1] + 2 * via3_enc[1]):
+ self.w = via3_size[1] + 2 * via3_enc[1]
+
+ if level_1 <= 4 and level_2 > 4:
+ if self.l < (via4_size[0] + 2 * via4_enc[0]):
+ self.l = via4_size[0] + 2 * via4_enc[0]
+
+ if self.w < (via4_size[1] + 2 * via4_enc[1]):
+ self.w = via4_size[1] + 2 * via4_enc[1]
+
+ def can_create_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we can use any shape which
+ # has a finite bounding box
+ return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
+
+ def parameters_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we set r and l from the shape's
+ # bounding box width and layer
+ self.r = self.shape.bbox().width() * self.layout.dbu / 2
+ self.l = self.layout.get_info(self.layer)
+
+ def transformation_from_shape_impl(self):
+ # Implement the "Create PCell from shape" protocol: we use the center of the shape's
+ # bounding box to determine the transformation
+ return pya.Trans(self.shape.bbox().center())
+
+ def produce_impl(self):
+ instance = vias_gen_draw(
+ layout=self.layout,
+ l_vias=self.l,
+ w=self.w,
+ start_layer=self.start_layer,
+ end_layer=self.end_layer,
+ )
+ write_cells = pya.CellInstArray(
+ instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.insert(write_cells)
+ self.cell.flatten(1)
diff --git a/sky130/cells/klayout/pymacros/cells/vpp.py b/sky130/cells/klayout/pymacros/cells/vpp.py
new file mode 100644
index 000000000..7724e25bf
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/cells/vpp.py
@@ -0,0 +1,67 @@
+# Copyright 2022 Skywater 130nm pdk development
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+########################################################################################################################
+# VPP CAP Generator for skywater130
+########################################################################################################################
+
+
+import pya
+
+from .draw_vpp import draw_vpp
+from .globals import VPP_CAP_DEV
+
+
+class cap_vpp(pya.PCellDeclarationHelper):
+ """
+ VPP Cap Generator for Skywater130
+ """
+
+ def __init__(self):
+ # Important: initialize the super class
+ super().__init__()
+ self.Type_handle = self.param("Type", self.TypeList, "Type")
+
+ for i in range(len(VPP_CAP_DEV)):
+ self.Type_handle.add_choice(VPP_CAP_DEV[i], VPP_CAP_DEV[i])
+
+ self.param(
+ "Model",
+ self.TypeString,
+ "Model",
+ default="sky130_fd_pr__cap_vpp",
+ readonly=True,
+ )
+
+ def display_text_impl(self):
+ # Provide a descriptive text for the cell
+ return str(self.Type)
+
+ def produce_impl(self):
+ # This is the main part of the implementation: create the layout
+
+ self.percision = 1 / self.layout.dbu
+ vpp_instance = draw_vpp(layout=self.layout, device_name=self.Type)
+ write_cells = pya.CellInstArray(
+ vpp_instance.cell_index(),
+ pya.Trans(pya.Point(0, 0)),
+ pya.Vector(0, 0),
+ pya.Vector(0, 0),
+ 1,
+ 1,
+ )
+ self.cell.flatten(1)
+ self.cell.insert(write_cells)
+ self.layout.cleanup()
diff --git a/sky130/cells/klayout/pymacros/sky130.lym b/sky130/cells/klayout/pymacros/sky130.lym
new file mode 100644
index 000000000..713cc161c
--- /dev/null
+++ b/sky130/cells/klayout/pymacros/sky130.lym
@@ -0,0 +1,50 @@
+
+
+
+
+
+ pymacros
+
+
+
+ true
+ false
+
+ false
+
+
+ python
+
+
+
+import sys
+import os
+
+technology_macros_path = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, technology_macros_path)
+
+from cells import sky130
+
+# Instantiate and register the library
+sky130()
+
+print("## Sky130 PDK Pcells loaded.")
+print(sys.path)
+
+
+