diff --git a/cells/klayout/pymacros/cells/draw_fet.py b/cells/klayout/pymacros/cells/draw_fet.py index 0ee52c50..1d85cfc1 100644 --- a/cells/klayout/pymacros/cells/draw_fet.py +++ b/cells/klayout/pymacros/cells/draw_fet.py @@ -155,16 +155,23 @@ def alter_interdig( m2_y = via_size[1] + 2 * via_enc[1] m2 = gf.components.rectangle( - size=(sd_diff.xmax - sd_diff.xmin, m2_y), layer=layer["metal2"], + size=(sd_diff.xmax - sd_diff.xmin, m2_y), + layer=layer["metal2"], ) m2_arrb = c_inst.add_array( - component=m2, columns=1, rows=nl_b, spacing=(0, -m2_y - m2_spacing), + component=m2, + columns=1, + rows=nl_b, + spacing=(0, -m2_y - m2_spacing), ) m2_arrb.movey(pc1.ymin - m2_spacing - m2_y) m2_arru = c_inst.add_array( - component=m2, columns=1, rows=nl_u, spacing=(0, m2_y + m2_spacing), + component=m2, + columns=1, + rows=nl_u, + spacing=(0, m2_y + m2_spacing), ) m2_arru.movey(pc2.ymax + m2_spacing) @@ -295,7 +302,10 @@ def alter_interdig( m2_join_b = c_inst.add_ref( gf.components.rectangle( - size=(m2_y + sd_l + (i + 1) * (m3_spacing + m3_x), m2_y,), + size=( + m2_y + sd_l + (i + 1) * (m3_spacing + m3_x), + m2_y, + ), layer=layer["metal2"], ) ).move( @@ -307,7 +317,10 @@ def alter_interdig( m2_join_u = c_inst.add_ref( gf.components.rectangle( - size=(m2_y + sd_l + (i + 1) * (m3_spacing + m3_x), m2_y,), + size=( + m2_y + sd_l + (i + 1) * (m3_spacing + m3_x), + m2_y, + ), layer=layer["metal2"], ) ).move( @@ -318,7 +331,10 @@ def alter_interdig( ) m3 = c_inst.add_ref( gf.components.rectangle( - size=(m3_x, m2_join_u.ymax - m2_join_b.ymin,), + size=( + m3_x, + m2_join_u.ymax - m2_join_b.ymin, + ), layer=layer["metal1"], ) ) @@ -335,7 +351,10 @@ def alter_interdig( component=via2_dr, columns=1, rows=2, - spacing=(0, m2_join_u.ymin - m2_join_b.ymin,), + spacing=( + 0, + m2_join_u.ymin - m2_join_b.ymin, + ), ) # via2_draw return c_inst @@ -490,7 +509,10 @@ def interdigit( elif gate_con_pos == "bottom": m2_arr = c_inst.add_array( - component=m2, columns=1, rows=nl, spacing=(0, -m2_y - m2_spacing), + component=m2, + columns=1, + rows=nl, + spacing=(0, -m2_y - m2_spacing), ) m2_arr.movey(pc2.ymin - m2_spacing - m2_y) @@ -576,7 +598,10 @@ def hv_gen(c, c_inst, volt, dg_encx: float = 0.1, dg_ency: float = 0.1): if volt == "5V" or volt == "6V": dg = c.add_ref( gf.components.rectangle( - size=(c_inst.size[0] + (2 * dg_encx), c_inst.size[1] + (2 * dg_ency),), + size=( + c_inst.size[0] + (2 * dg_encx), + c_inst.size[1] + (2 * dg_ency), + ), layer=layer["dualgate"], ) ) @@ -656,7 +681,10 @@ def bulk_gr_gen( rect_bulk_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw)) B = c.add_ref( gf.geometry.boolean( - A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=layer["comp"], + A=rect_bulk_out, + B=rect_bulk_in, + operation="A-B", + layer=layer["comp"], ) ) @@ -679,7 +707,12 @@ def bulk_gr_gen( layer=layer["pplus"], ) ) - psdm_out.move((rect_bulk_out.xmin - comp_pp_enc, rect_bulk_out.ymin - comp_pp_enc,)) + psdm_out.move( + ( + rect_bulk_out.xmin - comp_pp_enc, + rect_bulk_out.ymin - comp_pp_enc, + ) + ) c.add_ref( gf.geometry.boolean(A=psdm_out, B=psdm_in, operation="A-B", layer=implant_layer) ) # implant_draw(pplus or nplus) @@ -752,7 +785,10 @@ def bulk_gr_gen( comp_m1_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw)) c.add_ref( gf.geometry.boolean( - A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=layer["metal1"], + A=rect_bulk_out, + B=rect_bulk_in, + operation="A-B", + layer=layer["metal1"], ) ) # metal1_gaurdring @@ -787,6 +823,7 @@ def bulk_gr_gen( else: c.add_ref( pfet_deep_nwell( + c_inst=B, deepnwell=deepnwell, pcmpgr=pcmpgr, enc_size=(B.size[0], B.size[1]), @@ -841,7 +878,10 @@ def pcmpgr_gen(dn_rect, grw: float = 0.36) -> gf.Component: rect_pcmpgr_out.move((rect_pcmpgr_in.xmin - grw, rect_pcmpgr_in.ymin - grw)) c.add_ref( gf.geometry.boolean( - A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["comp"], + A=rect_pcmpgr_out, + B=rect_pcmpgr_in, + operation="A-B", + layer=layer["comp"], ) ) # guardring bulk @@ -855,7 +895,10 @@ def pcmpgr_gen(dn_rect, grw: float = 0.36) -> gf.Component: ) ) psdm_in.move( - (rect_pcmpgr_in.xmin + comp_pp_enc, rect_pcmpgr_in.ymin + comp_pp_enc,) + ( + rect_pcmpgr_in.xmin + comp_pp_enc, + rect_pcmpgr_in.ymin + comp_pp_enc, + ) ) psdm_out = c_temp_gr.add_ref( gf.components.rectangle( @@ -867,7 +910,10 @@ def pcmpgr_gen(dn_rect, grw: float = 0.36) -> gf.Component: ) ) psdm_out.move( - (rect_pcmpgr_out.xmin - comp_pp_enc, rect_pcmpgr_out.ymin - comp_pp_enc,) + ( + rect_pcmpgr_out.xmin - comp_pp_enc, + rect_pcmpgr_out.ymin - comp_pp_enc, + ) ) c.add_ref( gf.geometry.boolean( @@ -879,7 +925,10 @@ def pcmpgr_gen(dn_rect, grw: float = 0.36) -> gf.Component: c.add_ref( via_generator( - x_range=(rect_pcmpgr_in.xmin + con_size, rect_pcmpgr_in.xmax - con_size,), + x_range=( + rect_pcmpgr_in.xmin + con_size, + rect_pcmpgr_in.xmax - con_size, + ), y_range=(rect_pcmpgr_out.ymin, rect_pcmpgr_in.ymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], @@ -930,14 +979,20 @@ def pcmpgr_gen(dn_rect, grw: float = 0.36) -> gf.Component: comp_m1_out = c_temp_gr.add_ref( gf.components.rectangle( - size=((comp_m1_in.size[0]) + 2 * grw, (comp_m1_in.size[1]) + 2 * grw,), + size=( + (comp_m1_in.size[0]) + 2 * grw, + (comp_m1_in.size[1]) + 2 * grw, + ), layer=layer["metal1"], ) ) comp_m1_out.move((rect_pcmpgr_in.xmin - grw, rect_pcmpgr_in.ymin - grw)) c.add_ref( gf.geometry.boolean( - A=rect_pcmpgr_out, B=rect_pcmpgr_in, operation="A-B", layer=layer["metal1"], + A=rect_pcmpgr_out, + B=rect_pcmpgr_in, + operation="A-B", + layer=layer["metal1"], ) ) # metal1 guardring @@ -1333,7 +1388,10 @@ def draw_nfet( component=sd_con, columns=2, rows=1, - spacing=(sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), 0,), + spacing=( + sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), + 0, + ), ) sd_con_area = sd_con.size[0] * sd_con.size[1] @@ -1717,6 +1775,7 @@ def draw_nfet( @gf.cell def pfet_deep_nwell( + c_inst, volt="3.3V", deepnwell: bool = 0, pcmpgr: bool = 0, @@ -1740,81 +1799,56 @@ def pfet_deep_nwell( c = gf.Component() - dnwell_enc_pcmp: float = 1.1 dg_enc_dn: float = 0.5 + dn_enc_nw: float = 0.51 + + # nwell generation + nw = c.add_ref( + gf.components.rectangle( + size=( + c_inst.size[0] + (2 * nw_enc_pcmp), + c_inst.size[0] + (2 * nw_enc_pcmp), + ), + layer=layer["nwell"], + ) + ) + nw.xmin = c_inst.xmin - nw_enc_pcmp + nw.ymin = c_inst.ymin - nw_enc_pcmp if deepnwell == 1: dn_rect = c.add_ref( gf.components.rectangle( size=( - enc_size[0] + (2 * dnwell_enc_pcmp), - enc_size[1] + (2 * dnwell_enc_pcmp), + nw.size[0] + (2 * dn_enc_nw), + nw.size[1] + (2 * dn_enc_nw), ), layer=layer["dnwell"], ) ) - dn_rect.xmin = enc_xmin - dnwell_enc_pcmp - dn_rect.ymin = enc_ymin - dnwell_enc_pcmp + dn_rect.xmin = nw.xmin - dn_enc_nw + dn_rect.ymin = nw.ymin - dn_enc_nw if pcmpgr == 1: c.add_ref(pcmpgr_gen(dn_rect=dn_rect, grw=grw)) - if volt == "5V" or volt == "6V": - dg = c.add_ref( - gf.components.rectangle( - size=( - dn_rect.size[0] + (2 * dg_enc_dn), - dn_rect.size[1] + (2 * dg_enc_dn), - ), - layer=layer["dualgate"], - ) - ) - dg.xmin = dn_rect.xmin - dg_enc_dn - dg.ymin = dn_rect.ymin - dg_enc_dn - - if volt == "5V": - v5x = c.add_ref( - gf.components.rectangle( - size=(dg.size[0], dg.size[1]), layer=layer["v5_xtor"] - ) - ) - v5x.xmin = dg.xmin - v5x.ymin = dg.ymin + hv_gen( + c=c, + c_inst=dn_rect, + volt=volt, + dg_encx=dg_enc_dn, + dg_ency=dg_enc_dn, + ) else: - # nwell generation - nw = c.add_ref( - gf.components.rectangle( - size=( - enc_size[0] + (2 * nw_enc_pcmp), - enc_size[1] + (2 * nw_enc_pcmp), - ), - layer=layer["nwell"], - ) + hv_gen( + c=c, + c_inst=nw, + volt=volt, + dg_encx=dg_enc_dn, + dg_ency=dg_enc_dn, ) - nw.xmin = enc_xmin - nw_enc_pcmp - nw.ymin = enc_ymin - nw_enc_pcmp - - if volt == "5V" or volt == "6V": - dg = c.add_ref( - gf.components.rectangle( - size=(nw.size[0] + (2 * dg_enc_dn), nw.size[1] + (2 * dg_enc_dn),), - layer=layer["dualgate"], - ) - ) - dg.xmin = nw.xmin - dg_enc_dn - dg.ymin = nw.ymin - dg_enc_dn - - if volt == "5V": - v5x = c.add_ref( - gf.components.rectangle( - size=(dg.size[0], dg.size[1]), layer=layer["v5_xtor"] - ) - ) - v5x.xmin = dg.xmin - v5x.ymin = dg.ymin return c @@ -1947,7 +1981,10 @@ def draw_pfet( component=sd_con, columns=2, rows=1, - spacing=(sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), 0,), + spacing=( + sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), + 0, + ), ) sd_con_area = sd_con.size[0] * sd_con.size[1] @@ -2218,6 +2255,7 @@ def draw_pfet( c.add_ref( pfet_deep_nwell( + c_inst=c_inst, deepnwell=deepnwell, pcmpgr=pcmpgr, enc_size=(sd_diff.size[0], sd_diff.size[1]), @@ -2294,6 +2332,7 @@ def draw_pfet( nw_enc_pcmp: float = 0.45 + comp_np_enc + psdm.ymax - nsdm.ymax c.add_ref( pfet_deep_nwell( + c_inst=c_inst, deepnwell=deepnwell, pcmpgr=pcmpgr, enc_size=(sd_diff.size[0] + rect_bulk.size[0], sd_diff.size[1]), @@ -2457,7 +2496,10 @@ def draw_nfet_06v0_nvt( component=sd_con, columns=2, rows=1, - spacing=(sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), 0,), + spacing=( + sd_l + nf * l_gate + (nf - 1) * inter_sd_l + 2 * (pl_cmp_spacing), + 0, + ), ) sd_con_area = sd_con.size[0] * sd_con.size[1] @@ -2803,7 +2845,10 @@ def draw_nfet_06v0_nvt( rect_bulk_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw)) c.add_ref( gf.geometry.boolean( - A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=layer["comp"], + A=rect_bulk_out, + B=rect_bulk_in, + operation="A-B", + layer=layer["comp"], ) ) @@ -2827,7 +2872,10 @@ def draw_nfet_06v0_nvt( ) ) psdm_out.move( - (rect_bulk_out.xmin - comp_pp_enc, rect_bulk_out.ymin - comp_pp_enc,) + ( + rect_bulk_out.xmin - comp_pp_enc, + rect_bulk_out.ymin - comp_pp_enc, + ) ) psdm = c.add_ref( gf.geometry.boolean( @@ -2839,7 +2887,10 @@ def draw_nfet_06v0_nvt( c.add_ref( via_generator( - x_range=(rect_bulk_in.xmin + con_size, rect_bulk_in.xmax - con_size,), + x_range=( + rect_bulk_in.xmin + con_size, + rect_bulk_in.xmax - con_size, + ), y_range=(rect_bulk_out.ymin, rect_bulk_in.ymin), via_enclosure=(con_comp_enc, con_comp_enc), via_layer=layer["contact"], @@ -2903,7 +2954,10 @@ def draw_nfet_06v0_nvt( comp_m1_out.move((rect_bulk_in.xmin - grw, rect_bulk_in.ymin - grw)) b_gr = c.add_ref( gf.geometry.boolean( - A=rect_bulk_out, B=rect_bulk_in, operation="A-B", layer=layer["metal1"], + A=rect_bulk_out, + B=rect_bulk_in, + operation="A-B", + layer=layer["metal1"], ) ) # guardring metal1