| ################################################################################################ |
| # 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 BEOL |
| |
| if METAL_LEVEL == '6LM' |
| #================================================ |
| #----------------------VIA5---------------------- |
| #================================================ |
| |
| # Rule V5.1a: Min/max Via5 size . is 0.26µm |
| logger.info('Executing rule V5.1a') |
| v5_1a_l1 = via5.edges.without_length(0.26.um).extended(0, 0, 0.001, 0.001) |
| v5_1a_l1.output('V5.1a', 'V5.1a : Min/max Via5 size . : 0.26µm') |
| v5_1a_l1.forget |
| |
| # Rule V5.2a: min. via5 spacing is 0.26µm |
| logger.info('Executing rule V5.2a') |
| v5_2a_l1 = via5.space(0.26.um, euclidian).polygons(0.001) |
| v5_2a_l1.output('V5.2a', 'V5.2a : min. via5 spacing : 0.26µm') |
| v5_2a_l1.forget |
| |
| if METAL_TOP == '9K' |
| # Rule V5.1b: Min/max Via5 size (Only 8KÅ and above MetalTop is available with bigger (0.36 um) top via size). is 0.36µm |
| logger.info('Executing rule V5.1b') |
| v5_1b_l1 = via5.edges.without_length(0.36.um).extended(0, 0, 0.001, 0.001) |
| v5_1b_l1.output('V5.1b', 'V5.1b : Min/max Via4 size (Only 8KÅ and above MetalTop is available with bigger (0.36 um) top via size). : 0.36µm') |
| v5_1b_l1.forget |
| |
| # Rule V5.2b: min. via5 spacing (Only 8KÅ and above MetalTop is available with bigger (0.36 um) top via size). is 0.35µm |
| logger.info('Executing rule V5.2b') |
| v5_2b_l1 = via5.space(0.35.um, euclidian).polygons(0.001) |
| v5_2b_l1.output('V5.2b', 'V5.2b : min. via5 spacing (Only 8KÅ and above MetalTop is available with bigger (0.36 um) top via size) : 0.35µm') |
| v5_2b_l1.forget |
| end |
| |
| # Rule V5.3a: metal5 overlap of via5. is 0.01um |
| logger.info('Executing rule V5.3a') |
| v5_3a_l1 = metal5.enclosing(via5, 0.01.um, euclidian).polygons(0.001).or(via5.not(metal5)) |
| v5_3a_l1.output('V5.3a', 'V5.3a : metal5 overlap of via5.: 0.01um') |
| v5_3a_l1.forget |
| |
| v5_3b_cond = metal5.drc( width <= 0.34.um).with_length(0.28.um,nil,both) |
| v5_3b_eol = metal5.edges.with_length(nil, 0.34.um).interacting(v5_3b_cond.first_edges).interacting(v5_3b_cond.second_edges).not(v5_3b_cond.first_edges).not(v5_3b_cond.second_edges) |
| # Rule V5.3b: metal5 (< 0.34um) end-of-line overlap. is 0.06µm |
| logger.info('Executing rule V5.3b') |
| v5_3b_l1 = v5_3b_eol.enclosing(via5.edges,0.06.um, projection).polygons(0.001) |
| v5_3b_l1.output('V5.3b', 'V5.3b : metal5 (< 0.34um) end-of-line overlap. : 0.06µm') |
| v5_3b_l1.forget |
| v5_3b_cond.forget |
| v5_3b_eol.forget |
| |
| v5_3c_1 = via5.edges.interacting(via5.drc(enclosed(metal5, projection) < 0.04.um).edges.centers(0, 0.5)) |
| v5_3c_2 = via5.edges.interacting(via5.drc(0.04.um <= enclosed(metal5, projection) < 0.06.um).centers(0, 0.5)) |
| v5_3c_3 = v5_3c_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule V5.3c: If metal5 overlap via5 by < 0.04um on one side, adjacent metal5 edges overlap. is 0.06µm |
| logger.info('Executing rule V5.3c') |
| v5_3c_l1 = v5_3c_2.not_in(v5_3c_1).interacting(v5_3c_1).or(v5_3c_1.interacting(v5_3c_3)).enclosed(metal5.edges, 0.06.um).polygons(0.001) |
| v5_3c_l1.output('V5.3c', 'V5.3c : If metal5 overlap via5 by < 0.04um on one side, adjacent metal5 edges overlap. : 0.06µm') |
| v5_3c_l1.forget |
| v5_3c_1.forget |
| v5_3c_2.forget |
| v5_3c_3.forget |
| |
| # rule V5.3e is not a DRC check |
| |
| # Rule V5.4a: metaltop overlap of via5. is 0.01um |
| logger.info('Executing rule V5.4a') |
| v5_4a_l1 = metaltop.enclosing(via5, 0.01.um, euclidian).polygons(0.001) |
| v5_4a_l2 = via5.interacting(metaltop).not(metaltop) |
| v5_4a_l = v5_4a_l1.join(v5_4a_l2) |
| v5_4a_l.output('V5.4a', 'V5.4a : metaltop overlap of via5.: 0.01um') |
| v5_4a_l1.forget |
| v5_4a_l2.forget |
| v5_4a_l.forget |
| |
| v5_4b_cond = top_metal.drc( width <= 0.34.um).with_length(0.28.um,nil,both) |
| v5_4b_eol = top_metal.edges.with_length(nil, 0.34.um).interacting(v5_4b_cond.first_edges).interacting(v5_4b_cond.second_edges).not(v5_4b_cond.first_edges).not(v5_4b_cond.second_edges) |
| # Rule V5.4b: metaltop (< 0.34um) end-of-line overlap. is 0.06µm |
| logger.info('Executing rule V5.4b') |
| v5_4b_l1 = v5_4b_eol.enclosing(via5.edges,0.06.um, projection).polygons(0.001) |
| v5_4b_l1.output('V5.4b', 'V5.4b : metaltop (< 0.34um) end-of-line overlap. : 0.06µm') |
| v5_4b_l1.forget |
| v5_4b_cond.forget |
| v5_4b_eol.forget |
| |
| v5_4c_1 = via5.edges.interacting(via5.drc(enclosed(top_metal, projection) < 0.04.um).edges.centers(0, 0.5)) |
| v5_4c_2 = via5.edges.interacting(via5.drc(0.04.um <= enclosed(top_metal, projection) < 0.06.um).centers(0, 0.5)) |
| v5_4c_3 = v5_4c_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule V5.4c: If metaltop overlap via5 by < 0.04um on one side, adjacent metaltop edges overlap. is 0.06µm |
| logger.info('Executing rule V5.4c') |
| v5_4c_l1 = v5_4c_2.not_in(v5_4c_1).interacting(v5_4c_1).or(v5_4c_1.interacting(v5_4c_3)).enclosed(top_metal.edges, 0.06.um).polygons(0.001) |
| v5_4c_l1.output('V5.4c', 'V5.4c : If metaltop overlap via5 by < 0.04um on one side, adjacent metaltop edges overlap. : 0.06µm') |
| v5_4c_l1.forget |
| v5_4c_1.forget |
| v5_4c_2.forget |
| v5_4c_3.forget |
| |
| # rule V5.4d is not a DRC check |
| |
| # rule V5.5 is not a DRC check |
| |
| end # METAL_LEVEL |
| end #BEOL |