diff --git a/klayout/drc/rule_decks/lres.drc b/klayout/drc/rule_decks/lres.drc new file mode 100644 index 00000000..79be7ce7 --- /dev/null +++ b/klayout/drc/rule_decks/lres.drc @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +################################################################################################ +# Copyright 2022 GlobalFoundries PDK Authors +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# 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. +################################################################################################ + +if FEOL + #================================================ + #----------------N+ POLY RESISTOR---------------- + #================================================ + + logger.info('Starting LRES derivations') + + poly_nplus = poly2.and(nplus) + lres_poly = poly_nplus.interacting(sab).interacting(res_mk) + + # Rule LRES.1: Minimum width of Poly2 resistor is 0.8µm. + logger.info('Executing rule LRES.1') + lres1_l1 = lres_poly.width(0.8.um, euclidian) + lres1_l1.output('LRES.1', 'LRES.1 : Minimum width of Poly2 resistor: 0.8µm') + lres1_l1.forget + + # Rule LRES.2: Minimum space between Poly2 resistors is 0.4µm. + logger.info('Executing rule LRES.2') + lres2_l1 = lres_poly.isolated(0.4.um, euclidian) + lres2_l1.output('LRES.2', 'LRES.2 : Minimum space between Poly2 resistors: 0.4µm') + lres2_l1.forget + + # Rule LRES.3: Minimum space from Poly2 resistor to COMP is 0.6um. + logger.info('Executing rule LRES.3') + lres3_l1 = lres_poly.separation(comp, 0.6.um, euclidian).polygons(0.001.um).or(comp.not_outside(lres_poly)) + lres3_l1.output('LRES.3', 'LRES.3 : Minimum space from Poly2 resistor to COMP: 0.6.um') + lres3_l1.forget + + # Rule LRES.4: Minimum space from Poly2 resistor to unrelated Poly2 is 0.6µm. + logger.info('Executing rule LRES.4') + lres4_l1 = lres_poly.separation(poly2.not_interacting(sab), 0.6.um, euclidian) + lres4_l1.output('LRES.4', 'LRES.4 : Minimum space from Poly2 resistor to unrelated Poly2: 0.6µm') + lres4_l1.forget + + # Rule LRES.5: Minimum Nplus implant overlap of Poly2 resistor is 0.3µm. + logger.info('Executing rule LRES.5') + lres5_l1 = lres_poly.enclosed(nplus, 0.3.um, euclidian).polygons(0.001.um) + lres5_l2 = lres_poly.not_outside(nplus).not(nplus) + lres5_l = lres5_l1.or(lres5_l2) + lres5_l.output('LRES.5', 'LRES.5 : Minimum Nplus implant overlap of Poly2 resistor: 0.3µm') + lres5_l1.forget + lres5_l2.forget + lres5_l.forget + + # Rule LRES.6: Minimum salicide block overlap of Poly2 resistor in width direction is 0.28µm. + logger.info('Executing rule LRES.6') + lres6_l1 = lres_poly.enclosed(sab, 0.28.um) + lres6_l1.output('LRES.6', 'LRES.6 : Minimum salicide block overlap of Poly2 resistor in width direction: 0.28µm') + lres6_l1.forget + + # Rule LRES.7: Minimum space from salicide block to contact on Poly2 resistor is 0.22.um. + logger.info('Executing rule LRES.7') + cont_lres7 = contact.and(lres_poly) + lres7_l1 = cont_lres7.separation(sab, 0.22.um).polygons(0.001.um) + lres7_l2 = cont_lres7.interacting(sab) + lres7_l = lres7_l1.or(lres7_l2) + lres7_l.output('LRES.7', 'LRES.7 : Minimum space from salicide block to contact on Poly2 resistor: 0.22.um') + lres7_l.forget + lres7_l1.forget + lres7_l2.forget + cont_lres7.forget + + # Rule LRES.8 is not a DRC check + ## Please refer to https://gf180mcu-pdk.readthedocs.io/en/latest/physical_verification/design_manual/drm_10_02.html#n-poly-resistor-low-sheet-rho + + # Rule LRES.9a: Nplus Poly2 resistor shall be covered by RES_MK marking. + ## RES_MK length shall be coincide with resistor length (Defined by SAB length) + ## and width covering the width of Poly2. + logger.info('Executing rule LRES.9a') + mk_lres9 = res_mk.edges.not(poly_nplus.and(sab).edges).inside_part(poly2) + lres9a_l1 = res_mk.interacting(lres_poly).interacting(mk_lres9) + lres9a_l1.output('LRES.9a', + 'LRES.9a : Nplus Poly2 resistor shall be covered by RES_MK marking. + RES_MK length shall be coincide with resistor length (Defined by SAB length) + and width covering the width of Poly2. ') + lres9a_l1.forget + mk_lres9.forget + poly_nplus.forget + + # Rule LRES.9b: If the size of single RES_MK mark layer is greater than 15000um2 + ## and both side (X and Y) are greater than 80um. + ## then the minimum spacing to adjacent RES_MK layer is 20µm. + logger.info('Executing rule LRES.9b') + lres9b = res_mk.with_area(15_000.001.um, nil).edges.with_length(80.001.um, nil) + lres9b_l1 = lres9b.separation(res_mk.edges, 20.um) + lres9b_l1.output('LRES.9b', + 'LRES.9b : If the size of single RES_MK mark layer is greater than 15000um2 + and both side (X and Y) are greater than 80um. + then the minimum spacing to adjacent RES_MK layer: 20µm') + lres9b_l1.forget + lres9b.forget + lres_poly.forget + +end diff --git a/klayout/drc/testing/testcases/unit/lres.gds b/klayout/drc/testing/testcases/unit/lres.gds new file mode 100644 index 00000000..c5885840 Binary files /dev/null and b/klayout/drc/testing/testcases/unit/lres.gds differ diff --git a/klayout/drc/testing/testcases/unit/lres.svg b/klayout/drc/testing/testcases/unit/lres.svg new file mode 100644 index 00000000..dcc0ddad --- /dev/null +++ b/klayout/drc/testing/testcases/unit/lres.svg @@ -0,0 +1,690 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +LRES.9a +LRES.9a +LRES.9b +LRES.9b +LRES.9a +LRES.9a +LRES.9b +LRES.9b +LRES.9b +LRES.1 +LRES.1 +LRES.9a +LRES.9a +LRES.9a +LRES.9a +LRES.9a +LRES.9a +LRES.9a +LRES.1 +LRES.1 +LRES.1 +LRES.1 +LRES.1 +LRES.9a +LRES.7 +LRES.7 +LRES.1 +LRES.7 +LRES.7 +LRES.7 +LRES.7 +LRES.7 +LRES.7 +LRES.7 +LRES.1 +LRES.1 +LRES.1 +LRES.1 +LRES.1 +LRES.7 +LRES.7 +LRES.6 +LRES.6 +LRES.6 +LRES.6 +LRES.6 +LRES.6 +FALSE +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.5 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.2 +LRES.3 +LRES.3 +LRES.5 +LRES.5 +LRES.4 +LRES.4 +LRES.4 +LRES.4 +LRES.4 +LRES.4 +LRES.4 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.4 +LRES.4 +LRES.4 +LRES.4 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.3 +LRES.3 + + \ No newline at end of file