Skip to content

Commit

Permalink
Merge pull request google#33 from efabless/main
Browse files Browse the repository at this point in the history
Performance Enhancement for DRC rule deck.
  • Loading branch information
atorkmabrains committed Dec 5, 2022
2 parents 6566620 + 7186d48 commit 982d250
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 39 deletions.
2 changes: 1 addition & 1 deletion rules/klayout/drc/rule_decks/comp.drc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if FEOL

df_2a.forget

df_2b = comp.drc(width <= 100.um).polygons(0.001).not_inside(mos_cap_mk)
df_2b = comp.width(100.um + 1.dbu).polygons(0.001).not_inside(mos_cap_mk)
# Rule DF.2b_3.3V: Max. COMP width for all cases except those used for capacitors, marked by ‘MOS_CAP_MK’ layer.
logger.info("Executing rule DF.2b_3.3V")
df2b_l1 = comp.not_inside(mos_cap_mk).not_interacting(df_2b).not_interacting(v5_xtor).not_interacting(dualgate)
Expand Down
45 changes: 20 additions & 25 deletions rules/klayout/drc/rule_decks/contact.drc
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,16 @@ if BEOL
co2b_l1.forget

merged_co1.forget

contact_mask.forget

selected_co1.forget

main_contact = contact.outside(sramcore)

# Rule CO.3: Poly2 overlap of contact. is 0.07µm
logger.info("Executing rule CO.3")
co3_l1 = poly2.enclosing(contact.outside(sramcore), 0.07.um, euclidian).polygons(0.001)
co3_l2 = contact.outside(sramcore).not_outside(poly2).not(poly2)
co3_l1 = poly2.enclosing(main_contact, 0.07.um, euclidian).polygons(0.001)
co3_l2 = cmain_contact.not_outside(poly2).not(poly2)

co3_l = co3_l1.or(co3_l2)
co3_l.output("CO.3", "CO.3 : Poly2 overlap of contact. : 0.07µm")
co3_l1.forget
Expand All @@ -59,50 +60,44 @@ if BEOL

# Rule CO.4: COMP overlap of contact. is 0.07µm
logger.info("Executing rule CO.4")
co4_l1 = comp.not(mvsd).not(mvpsd).enclosing(contact.outside(sramcore), 0.07.um, euclidian).polygons(0.001)
co4_l2 = contact.outside(sramcore).not_outside(comp.not(mvsd).not(mvpsd)).not(comp.not(mvsd).not(mvpsd))
comp_not_mvsd = comp.not(mvsd).not(mvpsd)
co4_l1 = comp_not_mvsd.enclosing(main_contact, 0.07.um, euclidian).polygons(0.001)
co4_l2 = main_contact.not_outside(comp_not_mvsd).not(comp_not_mvsd)
co4_l = co4_l1.or(co4_l2)
co4_l.output("CO.4", "CO.4 : COMP overlap of contact. : 0.07µm")
co4_l1.forget
co4_l2.forget
co4_l.forget
comp_not_mvsd.forget

co_5a_ncomp_butted = ncomp.not(pplus).interacting(pcomp.not(nplus)).not_overlapping(pcomp.not(nplus))
# Rule CO.5a: Nplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). is 0.1µm
logger.info("Executing rule CO.5a")
co5a_l1 = co_5a_ncomp_butted.enclosing(contact, 0.1.um, euclidian).polygons(0.001)
co5a_l2 = contact.not_outside(co_5a_ncomp_butted).not(co_5a_ncomp_butted)
co5a_l = co5a_l1.or(co5a_l2)
co5a_l.output("CO.5a", "CO.5a : Nplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). : 0.1µm")
co_5a_ncomp_butted = ncomp.interacting(pcomp)
co5a_l1 = co_5a_ncomp_butted.enclosing(contact, 0.1.um, euclidian)
co5a_l1.output("CO.5a", "CO.5a : Nplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). : 0.1µm")
co5a_l1.forget
co5a_l2.forget
co5a_l.forget

co_5a_ncomp_butted.forget

co_5b_pcomp_butted = pcomp.not(nplus).interacting(ncomp.not(pplus)).not_overlapping(ncomp.not(pplus))
# Rule CO.5b: Pplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). is 0.1µm
logger.info("Executing rule CO.5b")
co5b_l1 = co_5b_pcomp_butted.enclosing(contact, 0.1.um, euclidian).polygons(0.001)
co5b_l2 = contact.not_outside(co_5b_pcomp_butted).not(co_5b_pcomp_butted)
co5b_l = co5b_l1.or(co5b_l2)
co5b_l.output("CO.5b", "CO.5b : Pplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). : 0.1µm")
co_5b_pcomp_butted = pcomp.interacting(ncomp)
co5b_l1 = co_5b_pcomp_butted.enclosing(contact, 0.1.um, euclidian)
co5b_l1.output("CO.5b", "CO.5b : Pplus overlap of contact on COMP (Only for contacts to butted Nplus and Pplus COMP areas). : 0.1µm")
co5b_l1.forget
co5b_l2.forget
co5b_l.forget

co_5b_pcomp_butted.forget

# Rule CO.6: Metal1 overlap of contact.
logger.info("Executing rule CO.6")
co6_l1 = metal1.enclosing(contact, 0.005.um, euclidian).polygons(0.001).or(contact.not_inside(metal1).not(metal1))

co6_l1 = contact.enclosed(metal1, 0.005.um, euclidian).polygons(0.001) + contact.not(metal1)
co6_l1.output("CO.6", "CO.6 : Metal1 overlap of contact.")
co6_l1.forget

cop6a_cond = metal1.drc( width <= 0.34.um).with_length(0.24.um,nil,both)
cop6a_eol = metal1.edges.with_length(nil, 0.34.um).interacting(cop6a_cond.first_edges).interacting(cop6a_cond.second_edges).not(cop6a_cond.first_edges).not(cop6a_cond.second_edges)
# Rule CO.6a: (i) Metal1 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule CO.6a")
cop6a_cond = metal1.width(0.34.um + 1.dbu).with_length(0.24.um, nil, both)
cop6a_eol = metal1.edges.with_length(nil, 0.34.um).interacting(cop6a_cond.first_edges).interacting(cop6a_cond.second_edges).not(cop6a_cond.first_edges).not(cop6a_cond.second_edges)

co6a_l1 = cop6a_eol.enclosing(contact.edges,0.06.um, projection).polygons(0.001)
co6a_l1.output("CO.6a", "CO.6a : (i) Metal1 (< 0.34um) end-of-line overlap. : 0.06µm")
co6a_l1.forget
Expand Down
6 changes: 3 additions & 3 deletions rules/klayout/drc/rule_decks/efuse.drc
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,19 @@ ef17_l1.forget

# Rule EF.18: PLFUSE must sit on field oxide (NOT COMP), no cross with any COMP, Nplus, Pplus, ESD, SAB, Resistor, Metal1, Metal2.
logger.info("Executing rule EF.18")
ef18_l1 = plfuse.not_outside(comp.or(nplus).or(esd).or(sab).or(resistor).or(metal1).or(metal2))
ef18_l1 = plfuse.not(plfuse.outside(comp).outside(nplus).outside(esd).outside(sab).outside(resistor).outside(metal1).outside(metal2))
ef18_l1.output("EF.18", "EF.18 : PLFUSE must sit on field oxide (NOT COMP), no cross with any COMP, Nplus, Pplus, ESD, SAB, Resistor, Metal1, Metal2.")
ef18_l1.forget

# Rule EF.19: Min. PLFUSE space to Metal1, Metal2.
logger.info("Executing rule EF.19")
ef19_l1 = plfuse.not_outside(metal1.or(metal2))
ef19_l1 = plfuse.not(plfuse.outside(metal1).outside(metal2))
ef19_l1.output("EF.19", "EF.19 : Min. PLFUSE space to Metal1, Metal2.")
ef19_l1.forget

# Rule EF.20: Min. PLFUSE space to COMP, Nplus, Pplus, Resistor, ESD, SAB. is 2.73µm
logger.info("Executing rule EF.20")
ef20_l1 = plfuse.separation(comp.or(nplus).or(esd).or(sab).or(resistor), 2.73.um, euclidian).polygons(0.001)
ef20_l1 = plfuse.separation(comp + nplus + esd + sab + resistor, 2.73.um, euclidian)
ef20_l1.output("EF.20", "EF.20 : Min. PLFUSE space to COMP, Nplus, Pplus, Resistor, ESD, SAB. : 2.73µm")
ef20_l1.forget

Expand Down
3 changes: 2 additions & 1 deletion rules/klayout/drc/rule_decks/metaltop.drc
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ if BEOL

# Rule MT30.6: Thick MetalTop end-of-line (width <2.5um) enclose underlying via (for example: via5 for 6LM case) [Outside Not Allowed].
logger.info("Executing rule MT30.6")
mt30p6_cond = top_metal.drc( width < 2.5.um)

mt30p6_cond = top_metal.width(2.5.um)
mt30p6_eol = top_metal.edges.with_length(nil, 2.5.um).interacting(mt30p6_cond.first_edges).interacting(mt30p6_cond.second_edges).not(mt30p6_cond.first_edges).not(mt30p6_cond.second_edges)
mt306_l1 = mt30p6_eol.enclosing(top_via.edges,0.25.um, projection)
mt306_l1.output("MT30.6", "MT30.6 : Thick MetalTop end-of-line (width <2.5um) enclose underlying via (for example: via5 for 6LM case) [Outside Not Allowed].")
Expand Down
5 changes: 3 additions & 2 deletions rules/klayout/drc/rule_decks/via1.drc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ if BEOL

# rule V1.3b is not a DRC check

v1p3c_cond = metal1.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v1p3c_cond = metal1.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)
v1p3c_eol = metal1.edges.with_length(nil, 0.34.um).interacting(v1p3c_cond.first_edges).interacting(v1p3c_cond.second_edges).not(v1p3c_cond.first_edges).not(v1p3c_cond.second_edges)
# Rule V1.3c: metal-1 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V1.3c")
Expand Down Expand Up @@ -88,8 +88,9 @@ if BEOL
v14a_l1 = metal2.enclosing(via1, 0.01.um, euclidian).polygons(0.001).or(via1.not_inside(metal2).not(metal2))
v14a_l1.output("V1.4a", "V1.4a : metal-2 overlap of via1.")
v14a_l1.forget

v1p4b_cond = metal2.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)

v1p4b_cond = metal2.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v1p4b_eol = metal2.edges.with_length(nil, 0.34.um).interacting(v1p4b_cond.first_edges).interacting(v1p4b_cond.second_edges).not(v1p4b_cond.first_edges).not(v1p4b_cond.second_edges)
# Rule V1.4b: metal-2 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V1.4b")
Expand Down
6 changes: 4 additions & 2 deletions rules/klayout/drc/rule_decks/via2.drc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ if BEOL
v23b_l1 = metal2.enclosing(via2, 0.01.um, euclidian).polygons(0.001).or(via2.not_inside(metal2).not(metal2))
v23b_l1.output("V2.3b", "V2.3b : metal2 overlap of via2.")
v23b_l1.forget

v2p3c_cond = metal2.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)

v2p3c_cond = metal2.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v2p3c_eol = metal2.edges.with_length(nil, 0.34.um).interacting(v2p3c_cond.first_edges).interacting(v2p3c_cond.second_edges).not(v2p3c_cond.first_edges).not(v2p3c_cond.second_edges)
# Rule V2.3c: metal2 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V2.3c")
Expand Down Expand Up @@ -91,7 +92,8 @@ if BEOL
v24a_l1.output("V2.4a", "V2.4a : metal3 overlap of via2.")
v24a_l1.forget

v2p4b_cond = metal3.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v2p4b_cond = metal3.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)

v2p4b_eol = metal3.edges.with_length(nil, 0.34.um).interacting(v2p4b_cond.first_edges).interacting(v2p4b_cond.second_edges).not(v2p4b_cond.first_edges).not(v2p4b_cond.second_edges)
# Rule V2.4b: metal3 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V2.4b")
Expand Down
6 changes: 4 additions & 2 deletions rules/klayout/drc/rule_decks/via3.drc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ if BEOL
v33b_l1.output("V3.3b", "V3.3b : metal3 overlap of via3.")
v33b_l1.forget

v3p3c_cond = metal3.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v3p3c_cond = metal3.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)

v3p3c_eol = metal3.edges.with_length(nil, 0.34.um).interacting(v3p3c_cond.first_edges).interacting(v3p3c_cond.second_edges).not(v3p3c_cond.first_edges).not(v3p3c_cond.second_edges)
# Rule V3.3c: metal3 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V3.3c")
Expand Down Expand Up @@ -90,7 +91,8 @@ if BEOL
v34a_l1.output("V3.4a", "V3.4a : metal4 overlap of via3.")
v34a_l1.forget

v3p4b_cond = metal4.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v3p4b_cond = metal4.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)

v3p4b_eol = metal4.edges.with_length(nil, 0.34.um).interacting(v3p4b_cond.first_edges).interacting(v3p4b_cond.second_edges).not(v3p4b_cond.first_edges).not(v3p4b_cond.second_edges)
# Rule V3.4b: metal4 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V3.4b")
Expand Down
4 changes: 2 additions & 2 deletions rules/klayout/drc/rule_decks/via4.drc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ if BEOL
v43b_l1.output("V4.3b", "V4.3b : metal4 overlap of via4.")
v43b_l1.forget

v4p3c_cond = metal4.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v4p3c_cond = v4p3c_cond = metal4.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)
v4p3c_eol = metal4.edges.with_length(nil, 0.34.um).interacting(v4p3c_cond.first_edges).interacting(v4p3c_cond.second_edges).not(v4p3c_cond.first_edges).not(v4p3c_cond.second_edges)
# Rule V4.3c: metal4 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V4.3c")
Expand Down Expand Up @@ -91,7 +91,7 @@ if BEOL
v44a_l1.output("V4.4a", "V4.4a : metal5 overlap of via4.")
v44a_l1.forget

v4p4b_cond = metal5.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v4p4b_cond = metal5.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)
v4p4b_eol = metal5.edges.with_length(nil, 0.34.um).interacting(v4p4b_cond.first_edges).interacting(v4p4b_cond.second_edges).not(v4p4b_cond.first_edges).not(v4p4b_cond.second_edges)
# Rule V4.4b: metal5 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V4.4b")
Expand Down
2 changes: 1 addition & 1 deletion rules/klayout/drc/rule_decks/via5.drc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ if BEOL
v53b_l1.output("V5.3b", "V5.3b : metal5 overlap of via5.")
v53b_l1.forget

v5p3c_cond = metal5.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v5p4b_cond = metaltop.width(0.34.um + 1.dbu).with_length(0.28.um,nil,both)
v5p3c_eol = metal5.edges.with_length(nil, 0.34.um).interacting(v5p3c_cond.first_edges).interacting(v5p3c_cond.second_edges).not(v5p3c_cond.first_edges).not(v5p3c_cond.second_edges)
# Rule V5.3c: metal5 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info("Executing rule V5.3c")
Expand Down

0 comments on commit 982d250

Please sign in to comment.