blob: 517bdc88dce22d777af4a9ee996e955d8f925670 [file] [log] [blame]
########################################################################################################################
# Copyright 2022 Mabrains Company LLC
#
# Licensed under the LGPL v2.1 License (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.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
#
# 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.
##
########################################################################################################################
##
## Mabrains rectangualr_shielding Generator for Skywaters 130nm
########################################################################################################################
from .layers_definiations import *
import pya
import math
import pandas as pd
"""
Mabrains Via Generator for Skywaters 130nm
"""
class triangular_shielding_Generator(pya.PCellDeclarationHelper):
"""
Mabrains Via Generator for Skywaters 130nm
"""
def __init__(self):
## Initialize super class.
super(triangular_shielding_Generator, self).__init__()
# declare the parameters
self.param("W", self.TypeDouble, "Width of the conductors", default=2)
self.param("S", self.TypeDouble, "Spacing between conductors", default=4)
self.param("Louter", self.TypeDouble, "outer dimension", default=40)
# self.param("via", self.TypeLayer, "via_layer", default = pya.LayerInfo(via_lay_num,via_lay_dt), hidden = True)
# Below shows how to create hidden parameter is used to determine whether the radius has changed
# or the "s" handle has been moved
## self.param("ru", self.TypeDouble, "Radius", default = 0.0, hidden = True)
## self.param("rd", self.TypeDouble, "Double radius", readonly = True)
def display_text_impl(self):
# Provide a descriptive text for the cell
return "( triangular_shielding spacing" + str(self.S) + " width = " + str(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.
pass
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.w = self.shape.bbox().width() * self.layout.dbu
# self.l = self.shape.bbox().length() * self.layout.dbu
self.ls = 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().p1())
def produce_impl(self):
PERCISION = 1000
met1 = self.layout.layer(met1_lay_num, met1_lay_dt)
met2 = self.layout.layer(met2_lay_num, met2_lay_dt)
met3 = self.layout.layer(met3_lay_num, met3_lay_dt)
met4 = self.layout.layer(met4_lay_num, met4_lay_dt)
met5 = self.layout.layer(met5_lay_num, met5_lay_dt)
via = self.layout.layer(via_lay_num, via_lay_dt)
via2 = self.layout.layer(via2_lay_num, via2_lay_dt)
via3 = self.layout.layer(via3_lay_num, via3_lay_dt)
via4 = self.layout.layer(via4_lay_num, via4_lay_dt)
diff = self.layout.layer(diff_lay_num, diff_lay_dt)
psdm = self.layout.layer(psdm_lay_num, psdm_lay_dt)
licon1 = self.layout.layer(licon_lay_num, licon_lay_dt)
li1 = self.layout.layer(li_lay_num, li_lay_dt)
mcon = self.layout.layer(mcon_lay_num, mcon_lay_dt)
nwell = self.layout.layer(nwell_lay_num, nwell_lay_dt)
nsdm = self.layout.layer(nsdm_lay_num, nsdm_lay_dt)
W = self.W * PERCISION # width of the conductors
S = self.S * PERCISION # minimum spacing between the conductors is 1.27*PERCISION due to the N_well
S_min = 1.27 * PERCISION
Lver = self.Louter * PERCISION # Lver==Lhor because it's assumed that the overall shape is square
Lhor = self.Louter * PERCISION
N_Conductors = int((Lhor + S) / (S + W)) # number of conductors
xcor = 0
ycor = 0
xcor2 = 0
ycor2 = 0
y_check = 0
x_check = 0
Shielding_with_diffusion = 1
all_hole_points = []
print(N_Conductors)
Diffusion_Width = 0.15 * PERCISION
Diffusion_Spacing = 0.27 * PERCISION
Diffusion_Encloses_Licon = 0.06 * PERCISION
Nwell_width = 0.84 * PERCISION
Nwell_Spacing = 1.27 * PERCISION
nsdm_Width = 0.38 * PERCISION
nsdm_Spacing = 0.38 * PERCISION
nsdm_Encloses_Diffusion = 0.125 * PERCISION
nsdm_Area_min = 0.265 * PERCISION * PERCISION
Met1_Width = 0.14 * PERCISION
Met1_Spacing = 0.14 * PERCISION
Met1_Encloses_Mcon = 0.03 * PERCISION
Met1_Encloses_Mcon_Two_Sides = 0.06 * PERCISION
Met1_Area_min = 0.083 * PERCISION * PERCISION
Psdm_Width = 0.38 * PERCISION
Psdm_Spacing = 0.38 * PERCISION
Psdm_Encloses_Diffusion = 0.125 * PERCISION
Psdm_Area_min = 0.255 * PERCISION * PERCISION
Licon_Width_Length = 0.17 * PERCISION
Licon_Spacing = 0.17 * PERCISION
Li_Width = 0.17 * PERCISION
Li_Spacing = 0.17 * PERCISION
Li_Area_min = 0.0561 * PERCISION * PERCISION
Li_Encloses_Licon_Two_Sides = 0.08 * PERCISION
Mcon_Width_Length = 0.17 * PERCISION
Mcon_Spacing = 0.19 * PERCISION
# find the number of licon needed for the horizontal distance
N_Licon_hor = int((W - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (Licon_Width_Length + Licon_Spacing))
Remaining_Licon_hor = W - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_hor * Licon_Width_Length - (
N_Licon_hor - 1) * Licon_Spacing
N_Licon_ver = int(
(Lver - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (Licon_Width_Length + Licon_Spacing))
Remaining_Licon_ver = Lver - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_ver * Licon_Width_Length - (
N_Licon_ver - 1) * Licon_Spacing
xcor_Licon = 0
ycor_Licon = 0
# print(N_Licon_hor,N_Licon_ver)
# find the number of mcon needed for the horizontal distance
N_Mcon_hor = int((W - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_hor = W - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_hor * Mcon_Width_Length - (
N_Mcon_hor - 1) * Mcon_Spacing
N_Mcon_ver = int((Lver - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_ver = Lver - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_ver * Mcon_Width_Length - (
N_Mcon_ver - 1) * Mcon_Spacing
xcor_Mcon = 0
ycor_Mcon = 0
# print(N_Mcon_hor,N_Mcon_ver)
Slope = Lver / Lhor
if N_Conductors % 2 == 0: # draw odd numbers of conductors
N_Conductors = N_Conductors - 1
N_of_half_Conductors = int(N_Conductors / 2)
for i in range(N_of_half_Conductors): # draw the vertical conductors
xcor = - Lhor / 2 + i * (W + S)
ycor = -Lver / 2
self.cell.shapes(met1).insert(
pya.Box(xcor, ycor, xcor + W, ycor + (i + 1) * (W + S) * Slope)) # left down vertical conductors
self.cell.shapes(met1).insert(
pya.Box(-xcor, ycor, -xcor - W, ycor + (i + 1) * (W + S) * Slope)) # right down vertical conductors
self.cell.shapes(met1).insert(pya.Box(xcor, ycor + Lver, xcor + W, ycor + Lver - (i + 1) * (
W + S) * Slope)) # left up vertical conductors
self.cell.shapes(met1).insert(pya.Box(-xcor, ycor + Lver, -xcor - W, ycor + Lver - (i + 1) * (
W + S) * Slope)) # right up vertical conductors
if Shielding_with_diffusion == 1:
self.cell.shapes(nwell).insert(
pya.Box(xcor, ycor, xcor + W, ycor + (i + 1) * (W + S) * Slope)) # left down vertical conductors
self.cell.shapes(nwell).insert(
pya.Box(-xcor, ycor, -xcor - W, ycor + (i + 1) * (W + S) * Slope)) # right down vertical conductors
self.cell.shapes(nwell).insert(pya.Box(xcor, ycor + Lver, xcor + W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # left up vertical conductors
self.cell.shapes(nwell).insert(pya.Box(-xcor, ycor + Lver, -xcor - W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # right up vertical conductors
self.cell.shapes(li1).insert(
pya.Box(xcor, ycor, xcor + W, ycor + (i + 1) * (W + S) * Slope)) # left down vertical conductors
self.cell.shapes(li1).insert(
pya.Box(-xcor, ycor, -xcor - W, ycor + (i + 1) * (W + S) * Slope)) # right down vertical conductors
self.cell.shapes(li1).insert(pya.Box(xcor, ycor + Lver, xcor + W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # left up vertical conductors
self.cell.shapes(li1).insert(pya.Box(-xcor, ycor + Lver, -xcor - W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # right up vertical conductors
self.cell.shapes(nsdm).insert(
pya.Box(xcor, ycor, xcor + W, ycor + (i + 1) * (W + S) * Slope)) # left down vertical conductors
self.cell.shapes(nsdm).insert(
pya.Box(-xcor, ycor, -xcor - W, ycor + (i + 1) * (W + S) * Slope)) # right down vertical conductors
self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor + Lver, xcor + W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # left up vertical conductors
self.cell.shapes(nsdm).insert(pya.Box(-xcor, ycor + Lver, -xcor - W,
ycor + Lver - (i + 1) * (
W + S) * Slope)) # right up vertical conductors
N_Licon_hor = int(
(W - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (Licon_Width_Length + Licon_Spacing))
Remaining_Licon_hor = W - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_hor * Licon_Width_Length - (
N_Licon_hor - 1) * Licon_Spacing
N_Licon_ver = int(((i + 1) * (W + S) * Slope - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_ver = (i + 1) * (
W + S) * Slope - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_ver * Licon_Width_Length - (
N_Licon_ver - 1) * Licon_Spacing
for u in range(N_Licon_ver):
ycor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_ver / 2 + u * (
Licon_Width_Length + Licon_Spacing)
for k in range(N_Licon_hor):
xcor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_hor / 2 + k * (
Licon_Width_Length + Licon_Spacing)
self.cell.shapes(licon1).insert(pya.Box(xcor + xcor_Licon, ycor + ycor_Licon,
xcor + xcor_Licon + Licon_Width_Length,
ycor + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(pya.Box(-xcor - xcor_Licon, ycor + ycor_Licon,
-xcor - xcor_Licon - Licon_Width_Length,
ycor + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(pya.Box(xcor + xcor_Licon, ycor + Lver - ycor_Licon,
xcor + xcor_Licon + Licon_Width_Length,
ycor + Lver - ycor_Licon - Licon_Width_Length))
self.cell.shapes(licon1).insert(pya.Box(-xcor - xcor_Licon, ycor + Lver - ycor_Licon,
-xcor - xcor_Licon - Licon_Width_Length,
ycor + Lver - ycor_Licon - Licon_Width_Length))
N_Mcon_hor = int(
(W - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_hor = W - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_hor * Mcon_Width_Length - (
N_Mcon_hor - 1) * Mcon_Spacing
N_Mcon_ver = int(((i + 1) * (W + S) * Slope - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_ver = (i + 1) * (
W + S) * Slope - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_ver * Mcon_Width_Length - (
N_Mcon_ver - 1) * Mcon_Spacing
for u in range(N_Mcon_ver):
ycor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_ver / 2 + u * (
Mcon_Width_Length + Mcon_Spacing)
for k in range(N_Mcon_hor):
xcor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_hor / 2 + k * (
Mcon_Width_Length + Mcon_Spacing)
self.cell.shapes(mcon).insert(pya.Box(xcor + xcor_Mcon, ycor + ycor_Mcon,
xcor + xcor_Mcon + Mcon_Width_Length,
ycor + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(pya.Box(-xcor - xcor_Mcon, ycor + ycor_Mcon,
-xcor - xcor_Mcon - Mcon_Width_Length,
ycor + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(pya.Box(xcor + xcor_Mcon, ycor + Lver - ycor_Mcon,
xcor + xcor_Mcon + Mcon_Width_Length,
ycor + Lver - ycor_Mcon - Mcon_Width_Length))
self.cell.shapes(mcon).insert(pya.Box(-xcor - xcor_Mcon, ycor + Lver - ycor_Mcon,
-xcor - xcor_Mcon - Mcon_Width_Length,
ycor + Lver - ycor_Mcon - Mcon_Width_Length))
if i == N_of_half_Conductors - 1:
y_check = ycor + (i + 1) * (W + S) * Slope
# drawing the rest of spaces for the vertical conductor
xcor = xcor + (W + S)
self.cell.shapes(met1).insert(pya.Box(xcor, ycor, -xcor, -S / 2))
self.cell.shapes(met1).insert(pya.Box(xcor, ycor + Lver, -xcor, S / 2))
if Shielding_with_diffusion == 1:
self.cell.shapes(nwell).insert(pya.Box(xcor, ycor, -xcor, -S / 2))
self.cell.shapes(nwell).insert(pya.Box(xcor, ycor + Lver, -xcor, S / 2))
self.cell.shapes(li1).insert(pya.Box(xcor, ycor, -xcor, -S / 2))
self.cell.shapes(li1).insert(pya.Box(xcor, ycor + Lver, -xcor, S / 2))
self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor, -xcor, -S / 2))
self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor + Lver, -xcor, S / 2))
N_Licon_hor = int(
(-2 * xcor - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (Licon_Width_Length + Licon_Spacing))
Remaining_Licon_hor = -2 * xcor - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_hor * Licon_Width_Length - (
N_Licon_hor - 1) * Licon_Spacing
N_Licon_ver = int(((-ycor - S / 2) - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_ver = (
-ycor - S / 2) - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_ver * Licon_Width_Length - (
N_Licon_ver - 1) * Licon_Spacing
for u in range(N_Licon_ver):
ycor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_ver / 2 + u * (
Licon_Width_Length + Licon_Spacing)
for k in range(N_Licon_hor):
xcor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_hor / 2 + k * (
Licon_Width_Length + Licon_Spacing)
self.cell.shapes(licon1).insert(pya.Box(xcor + xcor_Licon, ycor + ycor_Licon,
xcor + xcor_Licon + Licon_Width_Length,
ycor + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(pya.Box(xcor + xcor_Licon, ycor + Lver - ycor_Licon,
xcor + xcor_Licon + Licon_Width_Length,
ycor + Lver - ycor_Licon - Licon_Width_Length))
N_Mcon_hor = int(
(-2 * xcor - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_hor = -2 * xcor - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_hor * Mcon_Width_Length - (
N_Mcon_hor - 1) * Mcon_Spacing
N_Mcon_ver = int(((-ycor - S / 2) - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_ver = (-ycor - S / 2) - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_ver * Mcon_Width_Length - (
N_Mcon_ver - 1) * Mcon_Spacing
for u in range(N_Mcon_ver):
ycor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_ver / 2 + u * (
Mcon_Width_Length + Mcon_Spacing)
for k in range(N_Mcon_hor):
xcor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_hor / 2 + k * (
Mcon_Width_Length + Mcon_Spacing)
self.cell.shapes(mcon).insert(pya.Box(xcor + xcor_Mcon, ycor + ycor_Mcon,
xcor + xcor_Mcon + Mcon_Width_Length,
ycor + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(pya.Box(xcor + xcor_Mcon, ycor + Lver - ycor_Mcon,
xcor + xcor_Mcon + Mcon_Width_Length,
ycor + Lver - ycor_Mcon - Mcon_Width_Length))
for j in range(N_of_half_Conductors - 1): # For loop for horizontal conductors
xcor2 = -Lhor / 2
ycor2 = -Lver / 2
self.cell.shapes(met1).insert(
pya.Box(xcor2, ycor2 + (j + 1) * (W + S) * Slope + S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(met1).insert(
pya.Box(xcor2, ycor2 + Lver - (j + 1) * (W + S) * Slope - S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(met1).insert(pya.Box(xcor2 + Lhor, ycor2 + (j + 1) * (W + S) * Slope + S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + (j + 1) * (
W + S) * Slope + S + W)) # right down horizontal conductors
self.cell.shapes(met1).insert(pya.Box(xcor2 + Lhor, ycor2 + Lver - (j + 1) * (W + S) * Slope - S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + Lver - (j + 1) * (
W + S) * Slope - S - W)) # right up horizontal conductors
if Shielding_with_diffusion == 1:
self.cell.shapes(nwell).insert(
pya.Box(xcor2, ycor2 + (j + 1) * (W + S) * Slope + S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(nwell).insert(
pya.Box(xcor2, ycor2 + Lver - (j + 1) * (W + S) * Slope - S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(nwell).insert(
pya.Box(xcor2 + Lhor, ycor2 + (j + 1) * (W + S) * Slope + S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(nwell).insert(pya.Box(xcor2 + Lhor, ycor2 + Lver - (j + 1) * (W + S) * Slope - S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + Lver - (j + 1) * (
W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(li1).insert(
pya.Box(xcor2, ycor2 + (j + 1) * (W + S) * Slope + S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(li1).insert(
pya.Box(xcor2, ycor2 + Lver - (j + 1) * (W + S) * Slope - S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(li1).insert(
pya.Box(xcor2 + Lhor, ycor2 + (j + 1) * (W + S) * Slope + S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(li1).insert(pya.Box(xcor2 + Lhor, ycor2 + Lver - (j + 1) * (W + S) * Slope - S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + Lver - (j + 1) * (
W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(nsdm).insert(
pya.Box(xcor2, ycor2 + (j + 1) * (W + S) * Slope + S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(nsdm).insert(
pya.Box(xcor2, ycor2 + Lver - (j + 1) * (W + S) * Slope - S, xcor2 + (j + 1) * (W + S) * Slope - S
, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - W)) # left up horizontal conductors
self.cell.shapes(nsdm).insert(
pya.Box(xcor2 + Lhor, ycor2 + (j + 1) * (W + S) * Slope + S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + (j + 1) * (W + S) * Slope + S + W)) # left down horizontal conductors
self.cell.shapes(nsdm).insert(pya.Box(xcor2 + Lhor, ycor2 + Lver - (j + 1) * (W + S) * Slope - S,
xcor2 + Lhor - (j + 1) * (W + S) * Slope + S
, ycor2 + Lver - (j + 1) * (
W + S) * Slope - S - W)) # left up horizontal conductors
N_Licon_hor = int(((j + 1) * (W + S) * Slope - S - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_hor = (j + 1) * (
W + S) * Slope - S - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_hor * Licon_Width_Length - (
N_Licon_hor - 1) * Licon_Spacing
N_Licon_ver = int((W - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_ver = W - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_ver * Licon_Width_Length - (
N_Licon_ver - 1) * Licon_Spacing
for u in range(N_Licon_ver):
ycor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_ver / 2 + u * (
Licon_Width_Length + Licon_Spacing)
for k in range(N_Licon_hor):
xcor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_hor / 2 + k * (
Licon_Width_Length + Licon_Spacing)
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + xcor_Licon, ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Licon,
xcor2 + xcor_Licon + Licon_Width_Length,
ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + xcor_Licon, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Licon,
xcor2 + xcor_Licon + Licon_Width_Length,
ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Licon - Licon_Width_Length))
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + Lhor - xcor_Licon, ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Licon,
xcor2 + Lhor - xcor_Licon - Licon_Width_Length,
ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + Lhor - xcor_Licon,
ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Licon,
xcor2 + Lhor - xcor_Licon - Licon_Width_Length,
ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Licon - Licon_Width_Length))
N_Mcon_hor = int(((j + 1) * (W + S) * Slope - S - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_hor = (j + 1) * (
W + S) * Slope - S - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_hor * Mcon_Width_Length - (
N_Mcon_hor - 1) * Mcon_Spacing
N_Mcon_ver = int((W - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_ver = W - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_ver * Mcon_Width_Length - (
N_Mcon_ver - 1) * Mcon_Spacing
for u in range(N_Mcon_ver):
ycor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_ver / 2 + u * (
Mcon_Width_Length + Mcon_Spacing)
for k in range(N_Mcon_hor):
xcor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_hor / 2 + k * (
Mcon_Width_Length + Mcon_Spacing)
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + xcor_Mcon, ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Mcon,
xcor2 + xcor_Mcon + Mcon_Width_Length,
ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + xcor_Mcon, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Mcon,
xcor2 + xcor_Mcon + Mcon_Width_Length,
ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Mcon - Mcon_Width_Length))
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + Lhor - xcor_Mcon, ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Mcon,
xcor2 + Lhor - xcor_Mcon - Mcon_Width_Length,
ycor2 + (j + 1) * (W + S) * Slope + S + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + Lhor - xcor_Mcon, ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Mcon,
xcor2 + Lhor - xcor_Mcon - Mcon_Width_Length,
ycor2 + Lver - (j + 1) * (W + S) * Slope - S - ycor_Mcon - Mcon_Width_Length))
# y_check is used for drawing the rest of spaces for the horizontal conductors
if j == N_of_half_Conductors - 2:
x_check = xcor2 + (j + 1) * (W + S) * Slope + W
if (-y_check * 2) >= (2 * S + 0.14):
self.cell.shapes(met1).insert(pya.Box(xcor2, y_check + S, x_check, -y_check - S))
self.cell.shapes(met1).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, -y_check - S))
if Shielding_with_diffusion == 1:
self.cell.shapes(nwell).insert(pya.Box(xcor2, y_check + S, x_check, -y_check - S))
self.cell.shapes(nwell).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, -y_check - S))
self.cell.shapes(li1).insert(pya.Box(xcor2, y_check + S, x_check, -y_check - S))
self.cell.shapes(li1).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, -y_check - S))
self.cell.shapes(nsdm).insert(pya.Box(xcor2, y_check + S, x_check, -y_check - S))
self.cell.shapes(nsdm).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, -y_check - S))
N_Licon_hor = int(((x_check - xcor2) - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_hor = (
x_check - xcor2) - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_hor * Licon_Width_Length - (
N_Licon_hor - 1) * Licon_Spacing
N_Licon_ver = int((-y_check * 2 - 2 * S - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / (
Licon_Width_Length + Licon_Spacing))
Remaining_Licon_ver = -y_check * 2 - 2 * S - 2 * Li_Encloses_Licon_Two_Sides - N_Licon_ver * Licon_Width_Length - (
N_Licon_ver - 1) * Licon_Spacing
for u in range(N_Licon_ver):
ycor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_ver / 2 + u * (
Licon_Width_Length + Licon_Spacing)
for k in range(N_Licon_hor):
xcor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_hor / 2 + k * (
Licon_Width_Length + Licon_Spacing)
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + xcor_Licon, y_check + S + ycor_Licon,
xcor2 + xcor_Licon + Licon_Width_Length,
y_check + S + ycor_Licon + Licon_Width_Length))
self.cell.shapes(licon1).insert(
pya.Box(xcor2 + Lhor - xcor_Licon, y_check + S + ycor_Licon,
xcor2 + Lhor - xcor_Licon - Licon_Width_Length,
y_check + S + ycor_Licon + Licon_Width_Length))
N_Mcon_hor = int(((x_check - xcor2) - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_hor = (
x_check - xcor2) - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_hor * Mcon_Width_Length - (
N_Mcon_hor - 1) * Mcon_Spacing
N_Mcon_ver = int((-y_check * 2 - 2 * S - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / (
Mcon_Width_Length + Mcon_Spacing))
Remaining_Mcon_ver = -y_check * 2 - 2 * S - 2 * Met1_Encloses_Mcon_Two_Sides - N_Mcon_ver * Mcon_Width_Length - (
N_Mcon_ver - 1) * Mcon_Spacing
for u in range(N_Mcon_ver):
ycor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_ver / 2 + u * (
Mcon_Width_Length + Mcon_Spacing)
for k in range(N_Mcon_hor):
xcor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_hor / 2 + k * (
Mcon_Width_Length + Mcon_Spacing)
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + xcor_Mcon, y_check + S + ycor_Mcon,
xcor2 + xcor_Mcon + Mcon_Width_Length,
y_check + S + ycor_Mcon + Mcon_Width_Length))
self.cell.shapes(mcon).insert(
pya.Box(xcor2 + Lhor - xcor_Mcon, y_check + S + ycor_Mcon,
xcor2 + Lhor - xcor_Mcon - Mcon_Width_Length,
y_check + S + ycor_Mcon + Mcon_Width_Length))