Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing headers #82

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions sky130/cells/klayout/pymacros/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Skywater130_PCells

Contains klayout pcells generator.
72 changes: 72 additions & 0 deletions sky130/cells/klayout/pymacros/cells/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# ============================================================================
# ---------------- 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")
97 changes: 97 additions & 0 deletions sky130/cells/klayout/pymacros/cells/bjt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
########################################################################################################################
# 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()
197 changes: 197 additions & 0 deletions sky130/cells/klayout/pymacros/cells/cap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
########################################################################################################################
# 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)
Loading
Loading