Source code for sky130.pcells.pnp

from math import ceil

import gdsfactory as gf
from gdsfactory.typings import Float2, LayerSpec


[docs] @gf.cell def pnp( E_width: float = 0.68, E_length: float = 0.68, B_width: float = 0.4, C_width: float = 0.4, np_spacing: float = 0.27, diffusion_layer: LayerSpec = (65, 20), tap_layer: LayerSpec = (65, 44), diff_enclosure: Float2 = (0.18, 0.18), contact_size: Float2 = (0.17, 0.17), contact_spacing: Float2 = (0.17, 0.17), contact_layer: LayerSpec = (66, 44), contact_enclosure: Float2 = (0.06, 0.06), nwell_layer: LayerSpec = (64, 20), sdm_enclosure: Float2 = (0.125, 0.125), nsdm_layer: LayerSpec = (93, 44), psdm_layer: LayerSpec = (94, 20), pnp_layer: LayerSpec = (82, 44), li_layer: LayerSpec = (67, 20), li_enclosure: float = 0.08, mcon_layer: LayerSpec = (67, 44), mcon_enclosure: Float2 = (0.09, 0.09), m1_layer: LayerSpec = (68, 20), ) -> gf.Component: """Return pnp. Args: E_width: Emitter width. E_length: Emitter length. B_width: Base width. C_width: Collector width. np_spacing: Spacing between N+ and P+ implants. diffusion_layer: Layer for the diffusion. tap_layer: Layer for the tap. diff_enclosure: Enclosure for the diffusion. contact_size: Contact size. contact_spacing: Contact spacing. contact_layer: Layer for the contact. contact_enclosure: Enclosure for the contact. nwell_layer: Layer for the nwell. sdm_enclosure: Enclosure for the source/drain implants. nsdm_layer: Layer for the n+ source/drain implants. psdm_layer: Layer for the p+ source/drain implants. pnp_layer: Layer for the pnp. li_layer: Layer for the local interconnect. li_enclosure: Enclosure for the local interconnect. mcon_layer: Layer for the mcon. mcon_enclosure: Enclosure for the mcon. m1_layer: Layer for the metal1. .. plot:: :include-source: import sky130 c = sky130.pcells.pnp(E_length=3.4, E_width=3.4, np_spacing=1, B_width=1, C_width=1) c.plot() """ c = gf.Component() # generating Emitter rect_E = gf.components.rectangle(size=(E_width, E_length), layer=diffusion_layer) E = c.add_ref(rect_E) # generate its p+ implant rect_pme = gf.components.rectangle( size=(E_width + 2 * sdm_enclosure[0], E_length + 2 * sdm_enclosure[1]), layer=psdm_layer, ) psdm_e = c.add_ref(rect_pme) psdm_e.dmove((-sdm_enclosure[0], -sdm_enclosure[1])) # generate its contacts and local interconnects and mcon and metal1 rect_c = gf.components.rectangle(size=contact_size, layer=contact_layer) nr_e = ceil(E_length / (contact_size[1] + contact_spacing[1])) nc_e = ceil(E_width / (contact_size[0] + contact_spacing[0])) if ( E_width - nc_e * contact_size[0] - (nc_e - 1) * contact_spacing[0] ) / 2 < contact_enclosure[0]: nc_e -= 1 if ( E_length - nr_e * contact_size[1] - (nr_e - 1) * contact_spacing[1] ) / 2 < contact_enclosure[1]: nr_e -= 1 rect_mc = gf.components.rectangle(size=contact_size, layer=mcon_layer) rect_c_mc = [rect_c, rect_mc] for i in rect_c_mc: con_sp = ( contact_size[0] + contact_spacing[0], contact_size[1] + contact_spacing[1], ) cont_e_arr = c.add_ref(i, rows=nr_e, columns=nc_e, spacing=con_sp) cont_e_arr.dmovex( (E_width - nc_e * contact_size[0] - (nc_e - 1) * contact_spacing[0]) / 2 ) cont_e_arr.dmovey( (E_length - nr_e * contact_size[1] - (nr_e - 1) * contact_spacing[1]) / 2 ) rect_layer = [li_layer, m1_layer] for i in range(2): rect_eli_m1 = gf.components.rectangle( size=( nc_e * contact_size[0] + (nc_e - 1) * contact_spacing[0] + 2 * (1 - i) * li_enclosure + 2 * i * mcon_enclosure[0], nr_e * contact_size[1] + (nr_e - 1) * contact_spacing[1] + 2 * (1 - i) * li_enclosure + 2 * i * mcon_enclosure[1], ), layer=rect_layer[i], ) li_m1_e = c.add_ref(rect_eli_m1) li_m1_e.dmovex( ( E_width - nc_e * contact_size[0] - (nc_e - 1) * contact_spacing[0] - 2 * (1 - i) * li_enclosure - 2 * i * mcon_enclosure[0] ) / 2 ) li_m1_e.dmovey( ( E_length - nr_e * contact_size[1] - (nr_e - 1) * contact_spacing[1] - 2 * (1 - i) * li_enclosure - 2 * i * mcon_enclosure[1] ) / 2 ) # generating base rect_B_in = gf.components.rectangle( size=(E_width + 2 * np_spacing, E_length + 2 * np_spacing), layer=tap_layer ) rect_B_out = gf.components.rectangle( size=( E_width + 2 * np_spacing + 2 * B_width, E_length + 2 * np_spacing + 2 * B_width, ), layer=tap_layer, ) c_B = gf.Component() c_B.add_ref(rect_E) B_in = c_B.add_ref(rect_B_in) B_out = c_B.add_ref(rect_B_out) B_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) B_in.dmovex(E_width + np_spacing) B_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) B_out.dmovex(E_width + np_spacing + B_width) c.add_ref(gf.boolean(A=B_out, B=B_in, operation="not", layer=tap_layer)) # generate its n+ implants rect_nmB_in = gf.components.rectangle( size=( E_width + 2 * np_spacing - 2 * sdm_enclosure[0], E_length + 2 * np_spacing - 2 * sdm_enclosure[1], ), layer=nsdm_layer, ) rect_nmB_out = gf.components.rectangle( size=( E_width + 2 * np_spacing + 2 * B_width + 2 * sdm_enclosure[0], E_length + 2 * np_spacing + 2 * B_width + 2 * sdm_enclosure[1], ), layer=nsdm_layer, ) nmB_in = c_B.add_ref(rect_nmB_in) nmB_out = c_B.add_ref(rect_nmB_out) nmB_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) nmB_in.dmovex(E_width + np_spacing - sdm_enclosure[0]) nmB_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) nmB_out.dmovex(E_width + np_spacing + B_width + sdm_enclosure[1]) c.add_ref(gf.boolean(A=nmB_out, B=nmB_in, operation="not", layer=nsdm_layer)) # generate its contacts and local interconnects and mcon and metal1 nr_v = ceil((B_in.dymax - B_in.dymin) / (contact_size[1] + contact_spacing[1])) nc_v = ceil((B_width) / (contact_size[0] + contact_spacing[0])) if ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) < contact_enclosure[0]: nc_v -= 1 if ( ( B_in.dymax - B_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) < contact_enclosure[1]: nr_v -= 1 nc_h = ceil((B_in.dxmax - B_in.dxmin) / (contact_size[0] + contact_spacing[0])) nr_h = ceil((B_width) / (contact_size[1] + contact_spacing[1])) if ( (B_width - nr_h * contact_size[0] - (nr_h - 1) * contact_spacing[0]) / 2 ) < contact_enclosure[0]: nr_h -= 1 if ( ( B_in.dxmax - B_in.dxmin - nc_h * contact_size[1] - (nc_h - 1) * contact_spacing[1] ) / 2 ) < contact_enclosure[1]: nc_h -= 1 for i in range(2): rect_in = gf.components.rectangle( size=( E_width + 2 * np_spacing + (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) - 2 * i * mcon_enclosure[0] - 2 * (1 - i) * li_enclosure, E_length + 2 * np_spacing + ( (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) - 2 * i * mcon_enclosure[1] - 2 * (1 - i) * li_enclosure ), ), layer=rect_layer[i], ) rect_out = gf.components.rectangle( size=( E_width + 2 * np_spacing + 2 * B_width - (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) + 2 * i * mcon_enclosure[0] + 2 * (1 - i) * li_enclosure, E_length + 2 * np_spacing + 2 * B_width - (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) + 2 * i * mcon_enclosure[1] + 2 * (1 - i) * li_enclosure, ), layer=rect_layer[i], ) li_m1_b_in = c_B.add_ref(rect_in) li_m1_b_out = c_B.add_ref(rect_out) li_m1_b_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) li_m1_b_in.dmovex( ( E_width + np_spacing + (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) - i * mcon_enclosure[0] - (1 - i) * li_enclosure ) li_m1_b_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) li_m1_b_out.dmovex( ( E_width + np_spacing + B_width - ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) + i * mcon_enclosure[0] ) + (1 - i) * li_enclosure ) c.add_ref( gf.boolean( A=li_m1_b_out, B=li_m1_b_in, operation="not", layer=rect_layer[i] ) ) for i in rect_c_mc: cont_B_arr1 = c.add_ref(i, rows=nr_v, columns=nc_v, spacing=con_sp) # left side cont_B_arr1.dmove((-np_spacing - B_width, -np_spacing)) cont_B_arr1.dmovex( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) cont_B_arr1.dmovey( ( B_in.dymax - B_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) cont_B_arr2 = c.add_ref( i, rows=nr_v, columns=nc_v, spacing=con_sp ) # right side cont_B_arr2.dmove((E_width + np_spacing, -np_spacing)) cont_B_arr2.dmovex( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) cont_B_arr2.dmovey( ( B_in.dymax - B_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) cont_B_arr3 = c.add_ref( i, rows=nr_h, columns=nc_h, spacing=con_sp ) # upper side cont_B_arr3.dmove((-np_spacing, E_length + np_spacing)) cont_B_arr3.dmovex( ( B_in.dxmax - B_in.dxmin - nc_h * contact_size[0] - (nc_h - 1) * contact_spacing[0] ) / 2 ) cont_B_arr3.dmovey( (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2 ) cont_B_arr4 = c.add_ref( i, rows=nr_h, columns=nc_h, spacing=con_sp ) # bottom side cont_B_arr4.dmove((-np_spacing, -np_spacing - B_width)) cont_B_arr4.dmovex( ( B_in.dxmax - B_in.dxmin - nc_h * contact_size[0] - (nc_h - 1) * contact_spacing[0] ) / 2 ) cont_B_arr4.dmovey( (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2 ) cont_B_arrc1 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) # corners cont_B_arrc1.dmove((-np_spacing - B_width, -np_spacing - B_width)) cont_B_arrc1.dmove( ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_B_arrc2 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) cont_B_arrc2.dmove((-np_spacing - B_width, E_length + np_spacing)) cont_B_arrc2.dmove( ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_B_arrc3 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) cont_B_arrc3.dmove((E_width + np_spacing, -np_spacing - B_width)) cont_B_arrc3.dmove( ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_B_arrc4 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) cont_B_arrc4.dmove((E_width + np_spacing, E_length + np_spacing)) cont_B_arrc4.dmove( ( (B_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (B_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) # generating collector rect_C_in = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width, E_length + 4.5 * np_spacing + 2 * B_width, ), layer=tap_layer, ) rect_C_out = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width + 2 * C_width, E_length + 4.5 * np_spacing + 2 * B_width + 2 * C_width, ), layer=tap_layer, ) c_C = gf.Component() c_C.add_ref(rect_E) C_in = c_C.add_ref(rect_C_in) C_out = c_C.add_ref(rect_C_out) C_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) C_in.dmovex(E_width + 2.25 * np_spacing + B_width) C_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) C_out.dmovex(E_width + 2.25 * np_spacing + B_width + C_width) c.add_ref(gf.boolean(A=C_out, B=C_in, operation="not", layer=tap_layer)) # generate its p+ implants rect_pmC_in = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width - 2 * sdm_enclosure[0], E_length + 4.5 * np_spacing + 2 * B_width - 2 * sdm_enclosure[1], ), layer=psdm_layer, ) rect_pmC_out = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width + 2 * C_width + 2 * sdm_enclosure[0], E_length + 4.5 * np_spacing + 2 * B_width + 2 * C_width + 2 * sdm_enclosure[1], ), layer=psdm_layer, ) pmC_in = c_C.add_ref(rect_pmC_in) pmC_out = c_C.add_ref(rect_pmC_out) pmC_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) pmC_in.dmovex(E_width + 2.25 * np_spacing + B_width - sdm_enclosure[0]) pmC_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) pmC_out.dmovex(E_width + 2.25 * np_spacing + B_width + C_width + sdm_enclosure[0]) c.add_ref(gf.boolean(A=pmC_out, B=pmC_in, operation="A-B", layer=psdm_layer)) # generate its contact and local interconnects nr_v = ceil((C_in.dymax - C_in.dymin) / (contact_size[1] + contact_spacing[1])) nc_v = ceil((C_width) / (contact_size[0] + contact_spacing[0])) if ( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) < contact_enclosure[0]: nc_v -= 1 if ( ( C_in.dymax - C_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) < contact_enclosure[1]: nr_v -= 1 nc_h = ceil((C_in.dxmax - C_in.dxmin) / (contact_size[0] + contact_spacing[0])) nr_h = ceil((C_width) / (contact_size[1] + contact_spacing[1])) if ( (C_width - nr_h * contact_size[0] - (nr_h - 1) * contact_spacing[1]) / 2 ) < contact_enclosure[1]: nr_h -= 1 if ( ( C_in.dxmax - C_in.dxmin - nc_h * contact_size[1] - (nc_h - 1) * contact_spacing[0] ) / 2 ) < contact_enclosure[0]: nc_h -= 1 for i in range(2): rect_in = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width + (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) - 2 * i * mcon_enclosure[0] - 2 * (1 - i) * li_enclosure, E_length + 4.5 * np_spacing + 2 * B_width + (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) - 2 * i * mcon_enclosure[1] - 2 * (1 - i) * li_enclosure, ), layer=rect_layer[i], ) rect_out = gf.components.rectangle( size=( E_width + 4.5 * np_spacing + 2 * B_width + 2 * C_width - (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) + 2 * i * mcon_enclosure[0] + 2 * (1 - i) * li_enclosure, E_length + 4.5 * np_spacing + 2 * B_width + 2 * C_width - (C_width - nr_h * contact_size[0] - (nr_h - 1) * contact_spacing[0]) + 2 * i * mcon_enclosure[1] + 2 * (1 - i) * li_enclosure, ), layer=rect_layer[i], ) li_m1_c_in = c_C.add_ref(rect_in) li_m1_c_out = c_C.add_ref(rect_out) li_m1_c_in.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) li_m1_c_in.dmovex( E_width + 2.25 * np_spacing + B_width + (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 - i * mcon_enclosure[0] - (1 - i) * li_enclosure ) li_m1_c_out.connect( "e1", E.ports["e1"], allow_layer_mismatch=True, allow_width_mismatch=True ) li_m1_c_out.dmovex( E_width + 2.25 * np_spacing + B_width + C_width - (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 + i * mcon_enclosure[0] + (1 - i) * li_enclosure ) c.add_ref( gf.boolean( A=li_m1_c_out, B=li_m1_c_in, operation="A-B", layer=rect_layer[i] ) ) for i in rect_c_mc: cont_C_arr1 = c.add_ref(i, rows=nr_v, columns=nc_v, spacing=con_sp) # left side cont_C_arr1.dmove( (-2.25 * np_spacing - B_width - C_width, -2.25 * np_spacing - B_width) ) cont_C_arr1.dmovex( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) cont_C_arr1.dmovey( ( C_in.dymax - C_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) cont_C_arr2 = c.add_ref( i, rows=nr_v, columns=nc_v, spacing=con_sp ) # right side cont_C_arr2.dmove( (E_width + 2.25 * np_spacing + B_width, -2.25 * np_spacing - B_width) ) cont_C_arr2.dmovex( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2 ) cont_C_arr2.dmovey( ( C_in.dymax - C_in.dymin - nr_v * contact_size[1] - (nr_v - 1) * contact_spacing[1] ) / 2 ) cont_C_arr3 = c.add_ref( i, rows=nr_h, columns=nc_h, spacing=con_sp ) # upper side cont_C_arr3.dmove( (-2.25 * np_spacing - B_width, E_length + 2.25 * np_spacing + B_width) ) cont_C_arr3.dmovex( ( C_in.dxmax - C_in.dxmin - nc_h * contact_size[0] - (nc_h - 1) * contact_spacing[0] ) / 2 ) cont_C_arr3.dmovey( (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2 ) cont_C_arr4 = c.add_ref( i, rows=nr_h, columns=nc_h, spacing=con_sp ) # bottom side cont_C_arr4.dmove( (-2.25 * np_spacing - B_width, -2.25 * np_spacing - B_width - C_width) ) cont_C_arr4.dmovex( ( C_in.dxmax - C_in.dxmin - nc_h * contact_size[0] - (nc_h - 1) * contact_spacing[0] ) / 2 ) cont_C_arr4.dmovey( (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2 ) cont_C_arrc1 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) # corners cont_C_arrc1.dmove( ( -2.25 * np_spacing - B_width - C_width, -2.25 * np_spacing - B_width - C_width, ) ) cont_C_arrc1.dmove( ( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_C_arrc2 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) # corners cont_C_arrc2.dmove( ( -2.25 * np_spacing - B_width - C_width, E_length + 2.25 * np_spacing + B_width, ) ) cont_C_arrc2.dmove( ( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_C_arrc3 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) # corners cont_C_arrc3.dmove( ( E_width + 2.25 * np_spacing + B_width, E_length + 2.25 * np_spacing + B_width, ) ) cont_C_arrc3.dmove( ( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (C_width - nr_h * contact_size[1] - (nr_h - 1) * contact_spacing[1]) / 2, ) ) cont_C_arrc4 = c.add_ref(i, rows=nr_h, columns=nc_v, spacing=con_sp) # corners cont_C_arrc4.dmove( ( E_width + 2.25 * np_spacing + B_width, -2.25 * np_spacing - B_width - C_width, ) ) cont_C_arrc4.dmove( ( (C_width - nc_v * contact_size[0] - (nc_v - 1) * contact_spacing[0]) / 2, (C_width - nc_v * contact_size[1] - (nc_v - 1) * contact_spacing[1]) / 2, ) ) # generating nwell around E & B rect_nwell = gf.components.rectangle( size=( B_out.dxmax - B_out.dxmin + 2 * diff_enclosure[0], B_out.dymax - B_out.dymin + 2 * diff_enclosure[1], ), layer=nwell_layer, ) nwell = c.add_ref(rect_nwell) nwell.connect( "e1", B_out.ports["e3"], allow_layer_mismatch=True, allow_width_mismatch=True ) nwell.dmovex(B_out.dxmax - B_out.dxmin + diff_enclosure[0]) # generating pnp identifier npn = c.add_ref( gf.components.rectangle( size=(C_out.dxmax - C_out.dxmin, C_out.dymax - C_out.dymin), layer=pnp_layer ) ) npn.connect( "e1", C_out.ports["e3"], allow_layer_mismatch=True, allow_width_mismatch=True ) npn.dmovex(C_out.dxmax - C_out.dxmin) return c
if __name__ == "__main__": c = pnp(E_length=3.4, E_width=3.4, np_spacing=1, B_width=1, C_width=1) # c = pnp(np_spacing=1, B_width= 0.65, C_width=0.65) c.show()