| ############################################################################################### |
| # 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 |
| |
| #================================================ |
| #---------------------POLY2---------------------- |
| #================================================ |
| |
| # Rule PL.1: Interconnect Width . is 0.18µm |
| logger.info('Executing rule PL.1') |
| pl1_l1 = poly2.width(0.18.um, euclidian).polygons(0.001) |
| pl1_l1.output('PL.1', 'PL.1 : Interconnect Width. : 0.18µm') |
| pl1_l1.forget |
| |
| # ULP process --> Used for SRAM |
| # Rule PL.2a: Gate Width (channel length except ULP process). is 0.18µm |
| logger.info('Executing rule PL.2a') |
| pl2_l1 = poly2.outside(sramcore).edges.and(tgate.edges).width(0.18.um, euclidian).polygons(0.001) |
| pl2_l1.output('PL.2a', 'PL.2a : Gate Width (channel length except ULP process). : 0.18µm') |
| pl2_l1.forget |
| |
| # Rule PL.2b: Gate Width (channel length for ULP process). is 0.2µm |
| logger.info('Executing rule PL.2b') |
| pl2_l1 = poly2.interacting(sramcore).edges.and(tgate.edges).width(0.2.um, euclidian).polygons(0.001) |
| pl2_l1.output('PL.2b', 'PL.2b : Gate Width (channel length for ULP process). : 0.2µm') |
| pl2_l1.forget |
| |
| # Rule PL.3a: Space on COMP/Field. is 0.25µm |
| logger.info('Executing rule PL.3a') |
| pl3a_l1 = (tgate).or(poly2.not(comp)).space(0.25.um, euclidian).polygons(0.001) |
| pl3a_l1.output('PL.3a', 'PL.3a : Space on COMP/Field. : 0.25µm') |
| pl3a_l1.forget |
| |
| # rule PL.3b is not a DRC check |
| |
| # Rule PL.4: Extension beyond COMP to form Poly2 end cap. is 0.22µm |
| logger.info('Executing rule PL.4') |
| pl4_l1 = poly2.outside(sramcore).enclosing(comp, 0.22.um, euclidian).polygons(0.001) |
| pl4_l1.output('PL.4', 'PL.4 : Extension beyond COMP to form Poly2 end cap. : 0.22µm') |
| pl4_l1.forget |
| |
| # Rule PL.5a: Space from field Poly2 to unrelated COMP. is 0.1µm |
| logger.info('Executing rule PL.5a') |
| pl5a_l1 = poly2.separation(comp, 0.1.um, euclidian).polygons(0.001) |
| pl5a_l1.output('PL.5a', 'PL.5a : Space from field Poly2 to unrelated COMP Spacer from field Poly2 to Guard-ring. : 0.1µm') |
| pl5a_l1.forget |
| |
| # Rule PL.5b: Space from field Poly2 to related COMP. is 0.1µm |
| logger.info('Executing rule PL.5b') |
| pl5b_l1 = poly2.outside(sramcore).separation(comp, 0.1.um, euclidian).polygons(0.001) |
| pl5b_l1.output('PL.5b', 'PL.5b : Space from field Poly2 to related COMP. : 0.1µm') |
| pl5b_l1.forget |
| |
| poly_90deg = poly2.corners(90.0).sized(0.1).or(poly2.corners(-90.0).sized(0.1)) |
| # Rule PL.6: 90 degree bends on the COMP are not allowed. |
| logger.info('Executing rule PL.6') |
| pl6_l1 = poly2.corners(90.0).sized(0.1).or(poly2.corners(-90.0).sized(0.1)).inside(comp) |
| pl6_l1.output('PL.6', 'PL.6 : 90 degree bends on the COMP are not allowed.') |
| pl6_l1.forget |
| |
| poly_90deg.forget |
| |
| poly_45deg = poly2.edges.with_angle(-45).or(poly2.edges.with_angle(45)) |
| # Rule PL.7: 45 degree bent gate width is 0.2µm |
| logger.info('Executing rule PL.7') |
| pl7_l1 = poly_45deg.width(0.2.um, euclidian).polygons(0.001) |
| pl7_l1.output('PL.7', 'PL.7 : 45 degree bent gate width : 0.2µm') |
| pl7_l1.forget |
| |
| poly_45deg.forget |
| |
| # Rule PL.1a.DV2N: Gate width (channel length) for NMOS. is 0.35µm |
| logger.info('Executing rule PL.1a.DV2N') |
| pl1a_dv2n_l1 = poly2.interacting(ngate).interacting(ncomp).edges.and(ngate.edges).width(0.35.um, euclidian).polygons(0.001) |
| pl1a_dv2n_l1.output('PL.1a.DV2N', 'PL.1a.DV2N : Gate width (channel length) for NMOS. : 0.35m') |
| pl1a_dv2n_l1.forget |
| |
| # Rule PL.1a.DV2P: Gate width (channel length) for PMOS. is 0.3µm |
| logger.info('Executing rule PL.1a.DV2P') |
| pl1a_dv2p_l1 = poly2.interacting(pgate).interacting(pcomp).edges.and(pgate.edges).width(0.3.um, euclidian).polygons(0.001) |
| pl1a_dv2p_l1.output('PL.1a.DV2P', 'PL.1a.DV2P : Gate width (channel length) for PMOS. : 0.3m') |
| pl1a_dv2p_l1.forget |
| |
| end #FEOL |