Source code for gf180mcu.cells.diode

import gdsfactory as gf
from gdsfactory.typings import Float2

from gf180mcu.cells.via_generator import via_generator, via_stack
from gf180mcu.layers import layer


[docs] @gf.cell def diode_nd2ps( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, volt: str = "3.3V", deepnwell: bool = False, pcmpgr: bool = False, label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Draw N+/LVPWELL diode (Outside DNWELL) by specifying parameters. Args:: la: Float of diff length (anode). wa: Float of diff width (anode). cw: Float of cathode width. volt: String of operating voltage of the diode [3.3V, 5V/6V]. deepnwell: Boolean of using Deep NWELL device. pcmpgr : Boolean of using P+ Guard Ring for Deep NWELL devices only. label: Boolean of adding labels. """ c = gf.Component("diode_nd2ps_dev") comp_spacing: float = 0.48 np_enc_comp: float = 0.16 pp_enc_comp: float = 0.16 con_size = 0.22 con_sp = 0.28 con_comp_enc = 0.07 dg_enc_cmp = 0.24 dn_enc_lvpwell = 2.5 lvpwell_enc_ncmp = 0.6 lvpwell_enc_pcmp = 0.16 pcmpgr_enc_dn = 2.5 # n generation ncmp = c.add_ref(gf.components.rectangle(size=(wa, la), layer=layer["comp"])) nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp diode_mk = c.add_ref( gf.components.rectangle( size=(ncmp.dxsize, ncmp.dysize), layer=layer["diode_mk"] ) ) diode_mk.dxmin = ncmp.dxmin diode_mk.dymin = ncmp.dymin ncmp_con = c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp_con # p generation pcmp = c.add_ref(gf.components.rectangle(size=(cw, la), layer=layer["comp"])) pcmp.dxmax = ncmp.dxmin - comp_spacing pplus = c.add_ref( gf.components.rectangle( size=( pcmp.dxsize + (2 * pp_enc_comp), pcmp.dysize + (2 * pp_enc_comp), ), layer=layer["pplus"], ) ) pplus.dxmin = pcmp.dxmin - pp_enc_comp pplus.dymin = pcmp.dymin - pp_enc_comp pcmp_con = c.add_ref( via_stack( x_range=(pcmp.dxmin, pcmp.dxmax), y_range=(pcmp.dymin, pcmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # pcomp_con # labels generation if label == 1: # n_label generation c.add_label( n_label, position=( ncmp_con.dxmin + (ncmp_con.dxsize / 2), ncmp_con.dymin + (ncmp_con.dysize / 2), ), layer=layer["metal1_label"], ) # p_label generation c.add_label( p_label, position=( pcmp_con.dxmin + (pcmp_con.dxsize / 2), pcmp_con.dymin + (pcmp_con.dysize / 2), ), layer=layer["metal1_label"], ) if volt == "5/6V": dg = c.add_ref( gf.components.rectangle( size=( ncmp.dxmax - pcmp.dxmin + (2 * dg_enc_cmp), ncmp.dysize + (2 * dg_enc_cmp), ), layer=layer["dualgate"], ) ) dg.dxmin = pcmp.dxmin - dg_enc_cmp dg.dymin = pcmp.dymin - dg_enc_cmp if deepnwell == 1: lvpwell = c.add_ref( gf.components.rectangle( size=( ncmp.dxmax - pcmp.dxmin + (lvpwell_enc_ncmp + lvpwell_enc_pcmp), ncmp.dysize + (2 * lvpwell_enc_ncmp), ), layer=layer["lvpwell"], ) ) lvpwell.dxmin = pcmp.dxmin - lvpwell_enc_pcmp lvpwell.dymin = ncmp.dymin - lvpwell_enc_ncmp dn_rect = c.add_ref( gf.components.rectangle( size=( lvpwell.dxsize + (2 * dn_enc_lvpwell), lvpwell.dysize + (2 * dn_enc_lvpwell), ), layer=layer["dnwell"], ) ) dn_rect.dxmin = lvpwell.dxmin - dn_enc_lvpwell dn_rect.dymin = lvpwell.dymin - dn_enc_lvpwell if pcmpgr == 1: c_temp_gr = gf.Component("temp_store guard ring") rect_pcmpgr_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (dn_rect.dxmax - dn_rect.dxmin) + 2 * pcmpgr_enc_dn, (dn_rect.dymax - dn_rect.dymin) + 2 * pcmpgr_enc_dn, ), layer=layer["comp"], ) ) rect_pcmpgr_in.dmove( (dn_rect.dxmin - pcmpgr_enc_dn, dn_rect.dymin - pcmpgr_enc_dn) ) rect_pcmpgr_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["comp"], ) ) rect_pcmpgr_out.dmove( (rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw) ) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], ) ) # guardring Bulk draw psdm_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) - 2 * pp_enc_comp, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_in.dmove( ( rect_pcmpgr_in.dxmin + pp_enc_comp, rect_pcmpgr_in.dymin + pp_enc_comp, ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_out.dxmax - rect_pcmpgr_out.dxmin) + 2 * pp_enc_comp, (rect_pcmpgr_out.dymax - rect_pcmpgr_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_out.dmove( ( rect_pcmpgr_out.dxmin - pp_enc_comp, rect_pcmpgr_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=layer["pplus"]) ) # psdm draw # generatingg contacts c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_out.dymin, rect_pcmpgr_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_in.dymax, rect_pcmpgr_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact c.add_ref( via_generator( x_range=(rect_pcmpgr_out.dxmin, rect_pcmpgr_in.dxmin), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact c.add_ref( via_generator( x_range=(rect_pcmpgr_in.dxmax, rect_pcmpgr_out.dxmax), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact comp_m1_in = c_temp_gr.add_ref( gf.components.rectangle( size=(rect_pcmpgr_in.dxsize, rect_pcmpgr_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (comp_m1_in.dxsize) + 2 * cw, (comp_m1_in.dysize) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 return c
[docs] @gf.cell def diode_pd2nw( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, volt: str = "3.3V", deepnwell: bool = False, pcmpgr: bool = False, label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Usage:- used to draw 3.3V P+/Nwell diode (Outside DNWELL) by specifying parameters Arguments:- la : Float of diffusion length (anode) wa : Float of diffusion width (anode) volt : String of operating voltage of the diode [3.3V, 5V/6V] deepnwell : Boolean of using Deep NWELL device pcmpgr : Boolean of using P+ Guard Ring for Deep NWELL devices only. """ c = gf.Component("diode_pd2nw_dev") comp_spacing: float = 0.48 np_enc_comp: float = 0.16 pp_enc_comp: float = 0.16 con_size = 0.22 con_sp = 0.28 con_comp_enc = 0.07 dg_enc_cmp = 0.24 dn_enc_nwell = 0.5 nwell_ncmp_enc = 0.12 nwell_pcmp_enc = 0.43 pcmpgr_enc_dn = 2.5 # p generation pcmp = c.add_ref(gf.components.rectangle(size=(wa, la), layer=layer["comp"])) pplus = c.add_ref( gf.components.rectangle( size=( pcmp.dxsize + (2 * pp_enc_comp), pcmp.dysize + (2 * pp_enc_comp), ), layer=layer["pplus"], ) ) pplus.dxmin = pcmp.dxmin - pp_enc_comp pplus.dymin = pcmp.dymin - pp_enc_comp diode_mk = c.add_ref( gf.components.rectangle( size=(pcmp.dxsize, pcmp.dysize), layer=layer["diode_mk"] ) ) diode_mk.dxmin = pcmp.dxmin diode_mk.dymin = pcmp.dymin pcmp_con = c.add_ref( via_stack( x_range=(pcmp.dxmin, pcmp.dxmax), y_range=(pcmp.dymin, pcmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # pcomp_contact # n generation ncmp = c.add_ref(gf.components.rectangle(size=(cw, la), layer=layer["comp"])) ncmp.dxmax = pcmp.dxmin - comp_spacing nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp ncmp_con = c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp contact # labels generation if label == 1: # n_label generation c.add_label( n_label, position=( ncmp_con.dxmin + (ncmp_con.dxsize / 2), ncmp_con.dymin + (ncmp_con.dysize / 2), ), layer=layer["metal1_label"], ) # p_label generation c.add_label( p_label, position=( pcmp_con.dxmin + (pcmp_con.dxsize / 2), pcmp_con.dymin + (pcmp_con.dysize / 2), ), layer=layer["metal1_label"], ) if volt == "5/6V": dg = c.add_ref( gf.components.rectangle( size=( pcmp.dxmax - ncmp.dxmin + (2 * dg_enc_cmp), ncmp.dysize + (2 * dg_enc_cmp), ), layer=layer["dualgate"], ) ) dg.dxmin = ncmp.dxmin - dg_enc_cmp dg.dymin = ncmp.dymin - dg_enc_cmp # nwell generation nwell = c.add_ref( gf.components.rectangle( size=( pcmp.dxmax - ncmp.dxmin + (nwell_ncmp_enc + nwell_pcmp_enc), pcmp.dysize + (2 * nwell_pcmp_enc), ), layer=layer["nwell"], ) ) nwell.dxmin = ncmp.dxmin - nwell_ncmp_enc nwell.dymin = pcmp.dymin - nwell_pcmp_enc if deepnwell == 1: dn_rect = c.add_ref( gf.components.rectangle( size=( nwell.dxsize + (2 * dn_enc_nwell), nwell.dysize + (2 * dn_enc_nwell), ), layer=layer["dnwell"], ) ) dn_rect.dxmin = nwell.dxmin - dn_enc_nwell dn_rect.dymin = nwell.dymin - dn_enc_nwell if pcmpgr == 1: c_temp_gr = gf.Component("temp_store guard ring") rect_pcmpgr_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (dn_rect.dxmax - dn_rect.dxmin) + 2 * pcmpgr_enc_dn, (dn_rect.dymax - dn_rect.dymin) + 2 * pcmpgr_enc_dn, ), layer=layer["comp"], ) ) rect_pcmpgr_in.dmove( (dn_rect.dxmin - pcmpgr_enc_dn, dn_rect.dymin - pcmpgr_enc_dn) ) rect_pcmpgr_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["comp"], ) ) rect_pcmpgr_out.dmove( (rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw) ) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], ) ) # Bulk guardring psdm_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) - 2 * pp_enc_comp, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_in.dmove( ( rect_pcmpgr_in.dxmin + pp_enc_comp, rect_pcmpgr_in.dymin + pp_enc_comp, ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_out.dxmax - rect_pcmpgr_out.dxmin) + 2 * pp_enc_comp, (rect_pcmpgr_out.dymax - rect_pcmpgr_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_out.dmove( ( rect_pcmpgr_out.dxmin - pp_enc_comp, rect_pcmpgr_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=layer["pplus"]) ) # psdm guardring # generatingg contacts c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_out.dymin, rect_pcmpgr_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_in.dymax, rect_pcmpgr_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact c.add_ref( via_generator( x_range=(rect_pcmpgr_out.dxmin, rect_pcmpgr_in.dxmin), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact c.add_ref( via_generator( x_range=(rect_pcmpgr_in.dxmax, rect_pcmpgr_out.dxmax), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact comp_m1_in = c_temp_gr.add_ref( gf.components.rectangle( size=(rect_pcmpgr_in.dxsize, rect_pcmpgr_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (comp_m1_in.dxsize) + 2 * cw, (comp_m1_in.dysize) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 return c
[docs] @gf.cell def diode_nw2ps( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, volt: str = "3.3V", label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Used to draw 3.3V Nwell/Psub diode by specifying parameters. Args: la: anode length. wa: anode width. cw: cathode width. volt: operating voltage of the diode [3.3V, 5V/6V] """ c = gf.Component() comp_spacing: float = 0.48 np_enc_comp: float = 0.16 pp_enc_comp: float = 0.16 dg_enc_cmp = 0.24 nwell_ncmp_enc = 0.16 # n generation ncmp = c.add_ref(gf.components.rectangle(size=(wa, la), layer=layer["comp"])) nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp diode_mk = c.add_ref( gf.components.rectangle( size=(ncmp.dxsize, ncmp.dysize), layer=layer["diode_mk"] ) ) diode_mk.dxmin = ncmp.dxmin diode_mk.dymin = ncmp.dymin nwell = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * nwell_ncmp_enc), ncmp.dysize + (2 * nwell_ncmp_enc), ), layer=layer["nwell"], ) ) nwell.dxmin = ncmp.dxmin - nwell_ncmp_enc nwell.dymin = ncmp.dymin - nwell_ncmp_enc n_con = c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp contact # p generation pcmp = c.add_ref(gf.components.rectangle(size=(cw, la), layer=layer["comp"])) pcmp.dxmax = ncmp.dxmin - comp_spacing pplus = c.add_ref( gf.components.rectangle( size=( pcmp.dxsize + (2 * pp_enc_comp), pcmp.dysize + (2 * pp_enc_comp), ), layer=layer["pplus"], ) ) pplus.dxmin = pcmp.dxmin - pp_enc_comp pplus.dymin = pcmp.dymin - pp_enc_comp p_con = c.add_ref( via_stack( x_range=(pcmp.dxmin, pcmp.dxmax), y_range=(pcmp.dymin, pcmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # pcmop contact # labels generation if label == 1: # n_label generation c.add_label( n_label, position=( n_con.dxmin + (n_con.dxsize / 2), n_con.dymin + (n_con.dysize / 2), ), layer=layer["metal1_label"], ) # p_label generation c.add_label( p_label, position=( p_con.dxmin + (p_con.dxsize / 2), p_con.dymin + (p_con.dysize / 2), ), layer=layer["metal1_label"], ) if volt == "5/6V": dg = c.add_ref( gf.components.rectangle( size=( ncmp.dxmax - pcmp.dxmin + (2 * dg_enc_cmp), ncmp.dysize + (2 * dg_enc_cmp), ), layer=layer["dualgate"], ) ) dg.dxmin = pcmp.dxmin - dg_enc_cmp dg.dymin = pcmp.dymin - dg_enc_cmp return c
[docs] @gf.cell def diode_pw2dw( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, volt: str = "3.3V", pcmpgr: bool = False, label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Used to draw LVPWELL/DNWELL diode by specifying parameters. Args: la: anode length. wa: anode width. cw: cathode width. volt: operating voltage of the diode [3.3V, 5V/6V] pcmpgr: if True, pcmpgr will be added. label: if True, labels will be added. p_label: p contact label. n_label: n contact label. """ c = gf.Component() comp_spacing: float = 0.48 np_enc_comp: float = 0.16 pp_enc_comp: float = 0.16 dg_enc_dn = 0.5 lvpwell_enc_pcmp = 0.16 dn_enc_lvpwell = 2.5 con_size = 0.22 con_sp = 0.28 con_comp_enc = 0.07 pcmpgr_enc_dn = 2.5 # p generation pcmp = c.add_ref(gf.components.rectangle(size=(wa, la), layer=layer["comp"])) pplus = c.add_ref( gf.components.rectangle( size=( pcmp.dxsize + (2 * pp_enc_comp), pcmp.dysize + (2 * pp_enc_comp), ), layer=layer["pplus"], ) ) pplus.dxmin = pcmp.dxmin - pp_enc_comp pplus.dymin = pcmp.dymin - pp_enc_comp diode_mk = c.add_ref( gf.components.rectangle( size=(pcmp.dxsize, pcmp.dysize), layer=layer["diode_mk"] ) ) diode_mk.dxmin = pcmp.dxmin diode_mk.dymin = pcmp.dymin lvpwell = c.add_ref( gf.components.rectangle( size=( pcmp.dxsize + (2 * lvpwell_enc_pcmp), pcmp.dysize + (2 * lvpwell_enc_pcmp), ), layer=layer["lvpwell"], ) ) lvpwell.dxmin = pcmp.dxmin - lvpwell_enc_pcmp lvpwell.dymin = pcmp.dymin - lvpwell_enc_pcmp p_con = c.add_ref( via_stack( x_range=(pcmp.dxmin, pcmp.dxmax), y_range=(pcmp.dymin, pcmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # pcomp_contact # n generation ncmp = c.add_ref(gf.components.rectangle(size=(cw, la), layer=layer["comp"])) ncmp.dxmax = pcmp.dxmin - comp_spacing nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp n_con = c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp contact # labels generation if label == 1: # n_label generation c.add_label( n_label, position=( n_con.dxmin + (n_con.dxsize / 2), n_con.dymin + (n_con.dysize / 2), ), layer=layer["metal1_label"], ) # p_label generation c.add_label( p_label, position=( p_con.dxmin + (p_con.dxsize / 2), p_con.dymin + (p_con.dysize / 2), ), layer=layer["metal1_label"], ) dn_rect = c.add_ref( gf.components.rectangle( size=( lvpwell.dxsize + (2 * dn_enc_lvpwell), lvpwell.dysize + (2 * dn_enc_lvpwell), ), layer=layer["dnwell"], ) ) dn_rect.dxmin = lvpwell.dxmin - dn_enc_lvpwell dn_rect.dymin = lvpwell.dymin - dn_enc_lvpwell if pcmpgr == 1: c_temp_gr = gf.Component("temp_store guard ring") rect_pcmpgr_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (dn_rect.dxmax - dn_rect.dxmin) + 2 * pcmpgr_enc_dn, (dn_rect.dymax - dn_rect.dymin) + 2 * pcmpgr_enc_dn, ), layer=layer["comp"], ) ) rect_pcmpgr_in.dmove( (dn_rect.dxmin - pcmpgr_enc_dn, dn_rect.dymin - pcmpgr_enc_dn) ) rect_pcmpgr_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["comp"], ) ) rect_pcmpgr_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], ) ) # guardring Bulk psdm_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) - 2 * pp_enc_comp, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_in.dmove( ( rect_pcmpgr_in.dxmin + pp_enc_comp, rect_pcmpgr_in.dymin + pp_enc_comp, ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_out.dxmax - rect_pcmpgr_out.dxmin) + 2 * pp_enc_comp, (rect_pcmpgr_out.dymax - rect_pcmpgr_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_out.dmove( ( rect_pcmpgr_out.dxmin - pp_enc_comp, rect_pcmpgr_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=layer["pplus"]) ) # guardring psdm # generatingg contacts c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_out.dymin, rect_pcmpgr_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_in.dymax, rect_pcmpgr_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact c.add_ref( via_generator( x_range=(rect_pcmpgr_out.dxmin, rect_pcmpgr_in.dxmin), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact c.add_ref( via_generator( x_range=(rect_pcmpgr_in.dxmax, rect_pcmpgr_out.dxmax), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact comp_m1_in = c_temp_gr.add_ref( gf.components.rectangle( size=(rect_pcmpgr_in.dxsize, rect_pcmpgr_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (comp_m1_in.dxsize) + 2 * cw, (comp_m1_in.dysize) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 if volt == "5/6V": dg = c.add_ref( gf.components.rectangle( size=( dn_rect.dxsize + (2 * dg_enc_dn), dn_rect.dysize + (2 * dg_enc_dn), ), layer=layer["dualgate"], ) ) dg.dxmin = dn_rect.dxmin - dg_enc_dn dg.dymin = dn_rect.dymin - dg_enc_dn return c
[docs] @gf.cell def diode_dw2ps( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, volt: str = "3.3V", pcmpgr: bool = False, label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Used to draw LVPWELL/DNWELL diode by specifying parameters. Args: la: anode length. wa: anode width. cw: cathode width. volt: operating voltage of the diode [3.3V, 5V/6V]. pcmpgr: True if pwell guardring is required. label: True if labels are required. p_label: label for pwell. n_label: label for nwell. """ c = gf.Component() if volt == "5/6V": dn_enc_ncmp = 0.66 else: dn_enc_ncmp = 0.62 comp_spacing = 0.32 np_enc_comp: float = 0.16 pp_enc_comp: float = 0.16 con_size = 0.22 con_sp = 0.28 con_comp_enc = 0.07 dg_enc_dn = 0.5 pcmpgr_enc_dn = 2.5 if (wa < ((2 * cw) + comp_spacing)) or (la < ((2 * cw) + comp_spacing)): ncmp = c.add_ref(gf.components.rectangle(size=(wa, la), layer=layer["comp"])) n_con = c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp_contact nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp else: c_temp = gf.Component("temp_store guard ring") ncmp_in = c_temp.add_ref( gf.components.rectangle( size=(wa - (2 * cw), la - (2 * cw)), layer=layer["comp"], ) ) ncmp_out = c_temp.add_ref( gf.components.rectangle( size=(wa, la), layer=layer["comp"], ) ) ncmp_out.dmove((ncmp_in.dxmin - cw, ncmp_in.dymin - cw)) ncmp = c.add_ref( gf.boolean( A=ncmp_out, B=ncmp_in, operation="A-B", layer=layer["comp"], ) ) pplus_in = c_temp.add_ref( gf.components.rectangle( size=( (ncmp_in.dxmax - ncmp_in.dxmin) - 2 * pp_enc_comp, (ncmp_in.dymax - ncmp_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) pplus_in.dmove( ( ncmp_in.dxmin + pp_enc_comp, ncmp_in.dymin + pp_enc_comp, ) ) pplus_out = c_temp.add_ref( gf.components.rectangle( size=( (ncmp_out.dxmax - ncmp_out.dxmin) + 2 * pp_enc_comp, (ncmp_out.dymax - ncmp_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) pplus_out.dmove( ( ncmp_out.dxmin - pp_enc_comp, ncmp_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=pplus_out, B=pplus_in, operation="A-B", layer=layer["nplus"]) ) # nplus # generatingg contacts c.add_ref( via_generator( x_range=( ncmp_in.dxmin + con_size, ncmp_in.dxmax - con_size, ), y_range=(ncmp_out.dymin, ncmp_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( ncmp_in.dxmin + con_size, ncmp_in.dxmax - con_size, ), y_range=(ncmp_in.dymax, ncmp_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact n_con = c.add_ref( via_generator( x_range=(ncmp_out.dxmin, ncmp_in.dxmin), y_range=( ncmp_in.dymin + con_size, ncmp_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact c.add_ref( via_generator( x_range=(ncmp_in.dxmax, ncmp_out.dxmax), y_range=( ncmp_in.dymin + con_size, ncmp_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact comp_m1_in = c_temp.add_ref( gf.components.rectangle( size=(ncmp_in.dxsize, ncmp_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp.add_ref( gf.components.rectangle( size=( (comp_m1_in.dxsize) + 2 * cw, (comp_m1_in.dxsize) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((ncmp_in.dxmin - cw, ncmp_in.dymin - cw)) c.add_ref( gf.boolean( A=ncmp_out, B=ncmp_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 # labels generation if label == 1: # n_label generation c.add_label( n_label, position=( n_con.dxmin + (n_con.dxsize / 2), n_con.dymin + (n_con.dysize / 2), ), layer=layer["metal1_label"], ) # generate dnwell dn_rect = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * dn_enc_ncmp), ncmp.dysize + (2 * dn_enc_ncmp), ), layer=layer["dnwell"], ) ) dn_rect.dxmin = ncmp.dxmin - dn_enc_ncmp dn_rect.dymin = ncmp.dymin - dn_enc_ncmp diode_mk = c.add_ref( gf.components.rectangle( size=(dn_rect.dxsize, dn_rect.dysize), layer=layer["diode_mk"] ) ) diode_mk.dxmin = dn_rect.dxmin diode_mk.dymin = dn_rect.dymin if pcmpgr == 1: c_temp_gr = gf.Component("temp_store guard ring") rect_pcmpgr_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (dn_rect.dxmax - dn_rect.dxmin) + 2 * pcmpgr_enc_dn, (dn_rect.dymax - dn_rect.dymin) + 2 * pcmpgr_enc_dn, ), layer=layer["comp"], ) ) rect_pcmpgr_in.dmove( (dn_rect.dxmin - pcmpgr_enc_dn, dn_rect.dymin - pcmpgr_enc_dn) ) rect_pcmpgr_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["comp"], ) ) rect_pcmpgr_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], ) ) # guardring Bulk psdm_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) - 2 * pp_enc_comp, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_in.dmove( ( rect_pcmpgr_in.dxmin + pp_enc_comp, rect_pcmpgr_in.dymin + pp_enc_comp, ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_out.dxmax - rect_pcmpgr_out.dxmin) + 2 * pp_enc_comp, (rect_pcmpgr_out.dymax - rect_pcmpgr_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_out.dmove( ( rect_pcmpgr_out.dxmin - pp_enc_comp, rect_pcmpgr_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=layer["pplus"]) ) # psdm # generatingg contacts c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_out.dymin, rect_pcmpgr_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_in.dymax, rect_pcmpgr_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact p_con = c.add_ref( via_generator( x_range=(rect_pcmpgr_out.dxmin, rect_pcmpgr_in.dxmin), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact c.add_ref( via_generator( x_range=(rect_pcmpgr_in.dxmax, rect_pcmpgr_out.dxmax), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact # labels generation if label == 1: # n_label generation c.add_label( p_label, position=( p_con.dxmin + (p_con.dxsize / 2), p_con.dymin + (p_con.dysize / 2), ), layer=layer["metal1_label"], ) comp_m1_in = c_temp_gr.add_ref( gf.components.rectangle( size=(rect_pcmpgr_in.dxsize, rect_pcmpgr_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 # generate dualgate if volt == "5/6V": dg = c.add_ref( gf.components.rectangle( size=( dn_rect.dxsize + (2 * dg_enc_dn), dn_rect.dysize + (2 * dg_enc_dn), ), layer=layer["dualgate"], ) ) dg.dxmin = dn_rect.dxmin - dg_enc_dn dg.dymin = dn_rect.dymin - dg_enc_dn return c
[docs] @gf.cell def sc_diode( la: float = 0.1, wa: float = 0.1, cw: float = 0.1, m: int = 1, pcmpgr: bool = False, label: bool = False, p_label: str = "", n_label: str = "", ) -> gf.Component: """Used to draw N+/LVPWELL diode (Outside DNWELL) by specifying parameters. Args: la : Float of diff length (anode) wa : Float of diff width (anode) m : Integer of number of fingers pcmpgr : Boolean of using P+ Guard Ring for Deep NWELL devices only """ c = gf.Component("sc_diode_dev") sc_enc_comp = 0.16 sc_comp_spacing = 0.28 dn_enc_sc_an = 1.4 np_enc_comp = 0.03 m1_w = 0.23 pcmpgr_enc_dn = 2.5 pp_enc_comp: float = 0.16 con_size = 0.22 con_sp = 0.28 con_comp_enc = 0.07 # cathode draw @gf.cell def sc_cathode_strap(size: Float2 = (0.1, 0.1)) -> gf.Component: """Returns sc_diode cathode array element. Args : size : size of cathode array element """ c = gf.Component() ncmp = c.add_ref(gf.components.rectangle(size=size, layer=layer["comp"])) nplus = c.add_ref( gf.components.rectangle( size=( ncmp.dxsize + (2 * np_enc_comp), ncmp.dysize + (2 * np_enc_comp), ), layer=layer["nplus"], ) ) nplus.dxmin = ncmp.dxmin - np_enc_comp nplus.dymin = ncmp.dymin - np_enc_comp c.add_ref( via_stack( x_range=(ncmp.dxmin, ncmp.dxmax), y_range=(ncmp.dymin, ncmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # ncomp contact return c @gf.cell def sc_anode_strap(size: Float2 = (0.1, 0.1)) -> gf.Component: """Returns sc_diode anode array element. Args : size : size of anode array element """ c = gf.Component() cmp = c.add_ref(gf.components.rectangle(size=size, layer=layer["comp"])) c.add_ref( via_stack( x_range=(cmp.dxmin, cmp.dxmax), y_range=(cmp.dymin, cmp.dymax), base_layer=layer["comp"], metal_level=1, ) ) # comp contact return c sc_an = sc_anode_strap(size=(wa, la)) sc_cath = sc_cathode_strap(size=(cw, la)) sc_cathode = c.add_ref( component=sc_cath, rows=1, columns=(m + 1), column_pitch=cw + wa + (2 * sc_comp_spacing), ) cath_m1_xmin = sc_cathode.dxmin cath_m1_ymin = sc_cathode.dymin cath_m1_xmax = sc_cathode.dxmax cath_m1_v = c.add_ref( component=gf.components.rectangle( size=( cath_m1_xmax - cath_m1_xmin, cath_m1_ymin - sc_cathode.dymin + m1_w, ), layer=layer["metal1"], ), rows=1, columns=(m + 1), column_pitch=(cw + wa + (2 * sc_comp_spacing)), ) cath_m1_v.dxmin = cath_m1_xmin cath_m1_v.dymax = cath_m1_ymin cath_m1_h = c.add_ref( gf.components.rectangle(size=(cath_m1_v.dxsize, m1_w), layer=layer["metal1"]) ) cath_m1_h.dxmin = cath_m1_v.dxmin cath_m1_h.dymax = cath_m1_v.dymin # cathode label generation if label == 1: c.add_label( n_label, position=( cath_m1_h.dxmin + (cath_m1_h.dxsize / 2), cath_m1_h.dymin + (cath_m1_h.dysize / 2), ), layer=layer["metal1_label"], ) sc_anode = c.add_ref( component=sc_an, rows=1, columns=m, column_pitch=(wa + cw + (2 * sc_comp_spacing)), ) sc_anode.dxmin = sc_cathode.dxmin + (cw + sc_comp_spacing) an_m1_xmin = sc_anode.dxmin an_m1_ymin = sc_anode.dymin an_m1_xmax = sc_anode.dxmax an_m1_ymax = sc_anode.dymax if m > 1: an_m1_v = c.add_ref( component=gf.components.rectangle( size=( an_m1_xmax - an_m1_xmin, cath_m1_ymin - sc_an.dymin + m1_w, ), layer=layer["metal1"], ), rows=1, columns=m, spacing=((cw + wa + (2 * sc_comp_spacing)), 0), ) an_m1_v.dxmin = an_m1_xmin an_m1_v.dymin = an_m1_ymax an_m1_h = c.add_ref( gf.components.rectangle(size=(an_m1_v.dxsize, m1_w), layer=layer["metal1"]) ) an_m1_h.dxmin = an_m1_v.dxmin an_m1_h.dymin = an_m1_v.dymax # anode label generation if label == 1: c.add_label( p_label, position=( an_m1_h.dxmin + (an_m1_h.dxsize / 2), an_m1_h.dymin + (an_m1_h.dysize / 2), ), layer=layer["metal1_label"], ) else: # anode label generation if label == 1: c.add_label( p_label, position=( an_m1_xmin + ((an_m1_xmax - an_m1_xmin) / 2), an_m1_ymin + ((an_m1_ymax - an_m1_ymin) / 2), ), layer=layer["metal1_label"], ) # diode_mk diode_mk = c.add_ref( gf.components.rectangle( size=( sc_cathode.dxsize + (2 * sc_enc_comp), sc_cathode.dysize + (2 * sc_enc_comp), ), layer=layer["schottky_diode"], ) ) diode_mk.dxmin = sc_cathode.dxmin - sc_enc_comp diode_mk.dymin = sc_cathode.dymin - sc_enc_comp # dnwell dn_rect = c.add_ref( gf.components.rectangle( size=( sc_anode.dxsize + (2 * dn_enc_sc_an), sc_anode.dysize + (2 * dn_enc_sc_an), ), layer=layer["dnwell"], ) ) dn_rect.dxmin = sc_anode.dxmin - dn_enc_sc_an dn_rect.dymin = sc_anode.dymin - dn_enc_sc_an if pcmpgr == 1: c_temp_gr = gf.Component("temp_store guard ring") rect_pcmpgr_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (dn_rect.dxmax - dn_rect.dxmin) + 2 * pcmpgr_enc_dn, (dn_rect.dymax - dn_rect.dymin) + 2 * pcmpgr_enc_dn, ), layer=layer["comp"], ) ) rect_pcmpgr_in.dmove( (dn_rect.dxmin - pcmpgr_enc_dn, dn_rect.dymin - pcmpgr_enc_dn) ) rect_pcmpgr_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) + 2 * cw, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) + 2 * cw, ), layer=layer["comp"], ) ) rect_pcmpgr_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], ) ) # guardring Bulk psdm_in = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_in.dxmax - rect_pcmpgr_in.dxmin) - 2 * pp_enc_comp, (rect_pcmpgr_in.dymax - rect_pcmpgr_in.dymin) - 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_in.dmove( ( rect_pcmpgr_in.dxmin + pp_enc_comp, rect_pcmpgr_in.dymin + pp_enc_comp, ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (rect_pcmpgr_out.dxmax - rect_pcmpgr_out.dxmin) + 2 * pp_enc_comp, (rect_pcmpgr_out.dymax - rect_pcmpgr_out.dymin) + 2 * pp_enc_comp, ), layer=layer["pplus"], ) ) psdm_out.dmove( ( rect_pcmpgr_out.dxmin - pp_enc_comp, rect_pcmpgr_out.dymin - pp_enc_comp, ) ) c.add_ref( gf.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=layer["pplus"]) ) # psdm # generatingg contacts c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_out.dymin, rect_pcmpgr_in.dymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # bottom contact c.add_ref( via_generator( x_range=( rect_pcmpgr_in.dxmin + con_size, rect_pcmpgr_in.dxmax - con_size, ), y_range=(rect_pcmpgr_in.dymax, rect_pcmpgr_out.dymax), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # upper contact c.add_ref( via_generator( x_range=(rect_pcmpgr_out.dxmin, rect_pcmpgr_in.dxmin), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # right contact c.add_ref( via_generator( x_range=(rect_pcmpgr_in.dxmax, rect_pcmpgr_out.dxmax), y_range=( rect_pcmpgr_in.dymin + con_size, rect_pcmpgr_in.dymax - con_size, ), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], via_size=(con_size, con_size), via_spacing=(con_sp, con_sp), ) ) # left contact comp_m1_in = c_temp_gr.add_ref( gf.components.rectangle( size=(rect_pcmpgr_in.dxsize, rect_pcmpgr_in.dysize), layer=layer["metal1"], ) ) comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( size=( (comp_m1_in.dxsize) + 2 * cw, (comp_m1_in.dysize) + 2 * cw, ), layer=layer["metal1"], ) ) comp_m1_out.dmove((rect_pcmpgr_in.dxmin - cw, rect_pcmpgr_in.dymin - cw)) c.add_ref( gf.boolean( A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], ) ) # guardring metal1 # creating layout and cell in klayout return c
if __name__ == "__main__": c = sc_diode() # c = diode_pd2nw() c.show()