| ######################################################################################################################## |
| # 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 Inductor Generator for Skywaters 130nm |
| ######################################################################################################################## |
| from .layers_definiations import * |
| import pya |
| import math |
| import pandas as pd |
| |
| |
| """ |
| Mabrains Via Generator for Skywaters 130nm |
| """ |
| |
| |
| |
| class new_single_octagon_Generator(pya.PCellDeclarationHelper): |
| """ |
| Mabrains Via Generator for Skywaters 130nm |
| """ |
| |
| |
| def __init__(self): |
| ## Initialize super class. |
| super(new_single_octagon_Generator, self).__init__() |
| |
| # declare the parameters |
| self.param("N", self.TypeInt, "number of turns", default=3) |
| 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("distance_input", self.TypeDouble, "Input distance", default=30) |
| |
| shielding_option = self.param("shielding", self.TypeString, "Shielding Type", default=200) |
| shielding_option.add_choice("No shielding", 0) |
| shielding_option.add_choice("rectangular_shielding", 1) |
| shielding_option.add_choice("triangular_shielding", 2) |
| |
| self.param("W_shielding", self.TypeDouble, "Width of the conductors for shielding", default=2) |
| self.param("S_shielding", self.TypeDouble, "Spacing between conductors for shielding", default=4) |
| self.param("Lvert_shielding", self.TypeDouble, "vertical dimension for shielding", default=40) |
| self.param("Lhor_shielding", self.TypeDouble, "horizontal dimension for shielding", default=40) |
| self.param("diffusion_shielding", self.TypeBoolean, "Diffusion shielding", default=1) |
| |
| |
| |
| |
| #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 "( new_single_octagon" + str(self.N) + " 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 rectangular_shielding(self,W,S,Lver,Lhor,diffusion,input_distance): |
| PERCISION = 1000 |
| input_distance = input_distance*PERCISION |
| met1 = self.layout.layer(met1_lay_num, met1_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 = W * PERCISION # width of the conductors |
| S = S * PERCISION # minimum spacing between the conductors is 1.27*PERCISION |
| S_min = 1.27 * PERCISION |
| Lver = Lver * PERCISION # the vertical length |
| Lhor = Lhor * PERCISION # the horizontal length |
| N_Conductors = int((Lhor + S) / (S + W)) # number of conductors |
| xcor = -Lhor/2 |
| ycor = input_distance |
| Shielding_with_diffusion = diffusion |
| print("shifty" + str(input_distance)) |
| |
| # defining different parameters for different layers |
| 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 |
| # find the number of licon needed for the vertical distance |
| 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 |
| # find the number of mcon needed for the vertical distance |
| 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) |
| |
| for i in range(N_Conductors): |
| |
| if S < S_min: |
| print("Spacing between the Inductors must be greater than 1.27 um ") |
| break |
| xcor = i * (W + S) -Lhor/2 |
| ycor = input_distance |
| self.cell.shapes(met1).insert(pya.Box(xcor, ycor, xcor + W, ycor + Lver)) # draw the metal conductors |
| if Shielding_with_diffusion == 1: # inserting diffusion layer if it's true |
| # self.cell.shapes(diff).insert(pya.Box(xcor, ycor, xcor + W, ycor + Lver)) |
| self.cell.shapes(li1).insert(pya.Box(xcor, ycor, xcor + W, ycor + Lver)) |
| # self.cell.shapes(nsdm).insert(pya.Box(xcor-nsdm_Encloses_Diffusion,ycor-nsdm_Encloses_Diffusion |
| # ,xcor+W+nsdm_Encloses_Diffusion,ycor+Lver+nsdm_Encloses_Diffusion)) |
| self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor, xcor + W, ycor + Lver)) |
| self.cell.shapes(nwell).insert(pya.Box(xcor, ycor, xcor + W, ycor + Lver)) |
| |
| # drawing licon and mcon as rows and columns |
| for j in range(N_Licon_ver): # drawing the licon in yaxis |
| ycor_Licon = Li_Encloses_Licon_Two_Sides + Remaining_Licon_ver / 2 + j * ( |
| Licon_Width_Length + Licon_Spacing) |
| for k in range(N_Licon_hor): # drawing the licon in xaxis |
| 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)) |
| |
| for j in range(N_Mcon_ver): # drawing the mcon in yaxis |
| ycor_Mcon = Met1_Encloses_Mcon_Two_Sides + Remaining_Mcon_ver / 2 + j * ( |
| Mcon_Width_Length + Mcon_Spacing) |
| for k in range(N_Mcon_hor): # drawing the mcon in xaxis |
| 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)) |
| if S >= S_min: |
| self.cell.shapes(met1).insert(pya.Box(-Lhor/2, Lver / 2 - W / 2+input_distance, Lhor/2, Lver / 2 + W / 2+input_distance)) |
| |
| |
| def triangular_shielding(self,W,S,Lhor,diffusion,input_distance): |
| 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 = W * PERCISION # width of the conductors |
| S = S* PERCISION # minimum spacing between the conductors is 1.27*PERCISION due to the N_well |
| S_min = 1.27 * PERCISION |
| Lver = Lhor * PERCISION # Lver==Lhor because it's assumed that the overall shape is square |
| Lhor = Lhor* PERCISION |
| input_distance = input_distance*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 = diffusion |
| 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 = input_distance |
| 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, ycor+Lver/2-S / 2)) |
| self.cell.shapes(met1).insert(pya.Box(xcor, ycor + Lver, -xcor,ycor+Lver/2+ S / 2)) |
| if Shielding_with_diffusion == 1: |
| self.cell.shapes(nwell).insert(pya.Box(xcor, ycor, -xcor, ycor+Lver/2-S / 2)) |
| self.cell.shapes(nwell).insert(pya.Box(xcor, ycor + Lver, -xcor, ycor+Lver/2+S / 2)) |
| self.cell.shapes(li1).insert(pya.Box(xcor, ycor, -xcor, ycor+Lver/2-S / 2)) |
| self.cell.shapes(li1).insert(pya.Box(xcor, ycor + Lver, -xcor, ycor+Lver/2+S / 2)) |
| self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor, -xcor, ycor+Lver/2-S / 2)) |
| self.cell.shapes(nsdm).insert(pya.Box(xcor, ycor + Lver, -xcor, ycor+Lver/2+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(((Lver/2 - S / 2) - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / ( |
| Licon_Width_Length + Licon_Spacing)) |
| print(N_Licon_ver) |
| Remaining_Licon_ver = ( |
| Lver/2 - 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(((Lver/2 - S / 2) - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / ( |
| Mcon_Width_Length + Mcon_Spacing)) |
| Remaining_Mcon_ver = (Lver/2 - 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 = input_distance |
| 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 |
| y_check2=y_check-Lver/2-input_distance |
| print(y_check2,"y_check2") |
| if (-y_check2 * 2) >= (2 * S + 0.14): |
| self.cell.shapes(met1).insert(pya.Box(xcor2, y_check + S, x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(met1).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, y_check-y_check2*2 - S)) |
| if Shielding_with_diffusion == 1: |
| self.cell.shapes(nwell).insert(pya.Box(xcor2, y_check + S, x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(nwell).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(li1).insert(pya.Box(xcor2, y_check + S, x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(li1).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(nsdm).insert(pya.Box(xcor2, y_check + S, x_check, y_check-y_check2*2 - S)) |
| self.cell.shapes(nsdm).insert(pya.Box(xcor2 + Lhor, y_check + S, -x_check, y_check-y_check2*2 - 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_check2 * 2 - 2 * S - 2 * Li_Encloses_Licon_Two_Sides + Licon_Spacing) / ( |
| Licon_Width_Length + Licon_Spacing)) |
| Remaining_Licon_ver = -y_check2 * 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_check2 * 2 - 2 * S - 2 * Met1_Encloses_Mcon_Two_Sides + Mcon_Spacing) / ( |
| Mcon_Width_Length + Mcon_Spacing)) |
| Remaining_Mcon_ver = -y_check2 * 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)) |
| |
| def produce_impl(self): |
| PERCISION = 1000 |
| |
| # create the shape |
| if self.shielding == 1: |
| self.rectangular_shielding(self.W_shielding,self.S_shielding,self.Lvert_shielding,self.Lhor_shielding,self.diffusion_shielding,self.distance_input) |
| |
| if self.shielding == 2: |
| self.triangular_shielding(self.W_shielding,self.S_shielding,self.Lhor_shielding,self.diffusion_shielding,self.distance_input) |
| |
| 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) |
| |
| N = self.N # number of turns |
| W = self.W* PERCISION # width of the conductors |
| S = self.S * PERCISION # spacing between the conductors |
| Louter = self.Louter * PERCISION # outer dimension |
| Dist_input = self.distance_input * PERCISION |
| angle = math.pi / 4 # outer angle of the side is 60 degrees (written here in radian) |
| X_angle = math.cos(angle) |
| Y_angle = math.sin(angle) |
| Z_angle = math.tan(math.pi * 3 / 8) |
| Side_length = Louter / (1 + 2 * X_angle) |
| NumOfPoints = int((8 * N) + 1) |
| NumOfSides = 8 # number of sides of the polygon |
| |
| all_points = [] |
| xcor = 0 |
| ycor = Dist_input + W / 2 |
| xpos = 1 # to change the horizontal sides |
| hor_side = 0 |
| ypos = 1 # to change the vertical sides |
| ver_side = 0 |
| check1 = 0 |
| check2 = 0 |
| LouterCor = Louter |
| Side_lengthCor = Side_length |
| diagonal = 1 |
| y_check1 = 0 |
| y_check2 = 0 |
| |
| # trying to solve the problem |
| for i in range(N): |
| |
| for j in range(NumOfSides): |
| if j == 0: |
| xcor = xcor |
| ycor = ycor |
| elif j == (4 * hor_side + 1): |
| if i == N - 1: |
| y_check1 = ycor |
| print(y_check1) |
| if xpos == 1: |
| xcor = xcor + Side_lengthCor / 2 |
| xpos = 0 |
| hor_side = 1 |
| else: |
| xcor = xcor - Side_lengthCor |
| xpos = 1 |
| hor_side = 0 |
| elif j == (4 * ver_side + 3): |
| if ypos == 1: |
| ycor = ycor + Side_lengthCor |
| ypos = 0 |
| ver_side = 1 |
| else: |
| ycor = ycor - (Side_lengthCor - (W + S)) |
| ypos = 1 |
| ver_side = 0 |
| else: |
| if diagonal == 1: |
| xcor = xcor + Side_lengthCor * X_angle |
| ycor = ycor + Side_lengthCor * Y_angle |
| if check1 == 1: |
| xcor = xcor - 2 * Side_lengthCor * X_angle |
| check1 = check1 + 1 |
| if check1 == 2: |
| diagonal = 0 |
| check1 = 0 |
| else: |
| xcor = xcor - Side_lengthCor * X_angle |
| ycor = ycor - Side_lengthCor * Y_angle |
| diagonal = 1 |
| PointCoordinates = pya.Point(xcor, ycor) |
| all_points.append(PointCoordinates) |
| xcor = -Side_lengthCor / 2 |
| ycor = (i + 1) * (W + S) + W / 2 + Dist_input |
| # Side_lengthCor1=Side_lengthCor1-2*(W+S)/Z_angle |
| # Side_lengthCor2 = Side_lengthCor2 - (W + S) / Z_angle |
| |
| PointCoordinates = pya.Point(xcor, ycor) |
| all_points.append(PointCoordinates) |
| Side_lengthCor = Side_lengthCor - 2 * (W + S) / Z_angle |
| if i == N - 1: |
| xcor = -S |
| y_check2 = ycor |
| print(y_check2) |
| PointCoordinates = pya.Point(xcor, ycor) |
| all_points.append(PointCoordinates) |
| if N == 1: |
| self.cell.shapes(met5).insert(pya.Box(-S, ycor - W / 2, -(S + W), Dist_input)) |
| else: |
| self.cell.shapes(met4).insert(pya.Box(-S, ycor + W / 2, -(S + W), Dist_input / 2)) |
| self.cell.shapes(via4).insert(pya.Box(-S, ycor + W / 2, -(S + W), ycor - W / 2)) |
| self.cell.shapes(via4).insert(pya.Box(-S, Dist_input, -(S + W), Dist_input / 2)) |
| |
| |
| |
| else: |
| xcor = 0 |
| # self.cell.shapes(via4).insert(pya.Box(xcor-Side_lengthCor/4,ycor-W/2,xcor+Side_lengthCor/2,ycor+W/2)) |
| |
| self.cell.shapes(met5).insert(pya.Path(all_points, W)) |
| self.cell.shapes(met5).insert(pya.Box(0, 0, W, Dist_input)) |
| self.cell.shapes(met5).insert(pya.Box(-S, Dist_input, -(S + W), 0)) |
| |
| # self.cell.shapes(met5).insert(pya.Path(all_points,W)) |
| # self.cell.shapes(via4).insert(pya.Box(xcor-W/2,ycor,xcor+W,ycor+W)) |
| # self.cell.shapes(met4).insert(pya.Box(xcor-W/2,ycor,xcor+Louter-(N-1)*W-(N-1)*S,ycor+W)) |
| |
| # all_points=[] |
| # all_points.append(pya.Point(0,0)) |
| # all_points.append(pya.Point(4000,0)) |
| # all_points.append(pya.Point(4000+4000*math.cos(math.pi/3),4000*math.sin(math.pi/3))) |
| # all_points.append(pya.Point(4000+4000*math.cos(math.pi/3)-4000*math.cos(math.pi/3),4000*math.sin(math.pi/3)*2)) |
| # all_points.append(pya.Point(0,2*4000*math.sin(math.pi/3))) |
| # all_points.append(pya.Point(-math.cos(math.pi/3)*4000,4000*math.sin(math.pi/3))) |
| # all_points.append(pya.Point(0,0)) |
| # polygen = pya.Polygon([pya.Point(0,0),pya.Point(0,500),pya.Point(500,500),pya.Point(500,0)]) |
| # polygen.insert_hole([pya.Point(250,250),pya.Point(-125,250),pya.Point(-125,125),pya.Point(250,125)]) |
| # self.cell.shapes(met5).insert(polygen) |
| |
| # variables for inductor value calculation |
| # https://coil32.net/pcb-coil.html |
| uo = 4 * math.pi * 1e-7 |
| K1 = 2.25 |
| Dout = Louter |
| print(Dout) |
| Din = y_check1 - y_check2 |
| print(Din) |
| Davg = (Dout + Din) / 2 |
| K2 = 3.55 |
| phi = (Dout - Din) / (Dout + Din) |
| |
| # the inductor equation in nH |
| |
| Inductor_Value = ((K1 * uo * N * N * Davg) / (1 + K2 * phi)) |
| |
| print("the inductor value is =", Inductor_Value, " nH ") |
| |
| |
| |