From 577f3b2d7fc7d95f4706ef9cdd4b0f7dc90d843b Mon Sep 17 00:00:00 2001 From: FaragElsayed2 Date: Fri, 10 Feb 2023 16:50:30 +0200 Subject: [PATCH] Adding ruby linting checks, Fixing some linting issues in drc files --- .github/workflows/linting.yml | 14 +- .github/workflows/regression.yml | 3 - .rubocop.yml | 45 + Makefile | 9 +- klayout/drc/rule_decks/dualgate.drc | 121 +-- klayout/drc/rule_decks/main.drc | 1450 +++++++++++-------------- klayout/drc/rule_decks/tail.drc | 6 +- klayout/drc/testing/run_regression.py | 2 +- pdk_regression.yml | 1 + 9 files changed, 791 insertions(+), 860 deletions(-) create mode 100644 .rubocop.yml diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 275c512b..f5578329 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -21,12 +21,20 @@ on: jobs: lint_python: runs-on: ubuntu-latest - strategy: - max-parallel: 12 steps: - uses: actions/checkout@v3 with: submodules: 'recursive' - name: Lint with flake8 run: | - make lint + make lint_python + + lint_ruby: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Lint with rubocop + run: | + make lint_ruby diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 6b7678f0..e222aae4 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -45,7 +45,6 @@ jobs: needs: build_drc-matrix runs-on: ubuntu-latest strategy: - max-parallel: 4 fail-fast: false matrix: part: [drc] @@ -64,7 +63,6 @@ jobs: drc_switch: runs-on: ubuntu-latest strategy: - max-parallel: 4 fail-fast: false matrix: include: @@ -83,7 +81,6 @@ jobs: lvs_regression: runs-on: ubuntu-latest strategy: - max-parallel: 4 fail-fast: false matrix: include: diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..ca447691 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,45 @@ +# The behavior of RuboCop can be controlled via the .rubocop.yml +# configuration file. It makes it possible to enable/disable +# certain cops (checks) and to alter their behavior if they accept +# any parameters. The file can be placed either in your home +# directory or in some project directory. +# +# RuboCop will start looking for the configuration file in the directory +# where the inspected file is and continue its way up to the root directory. +# +# See https://docs.rubocop.org/rubocop/configuration + +Style/FrozenStringLiteralComment: + Enabled: false + +GlobalVars: + Description: Do not introduce global variables. + Enabled: false + +UselessAssignment: + Description: Useless assignment to variable. + Enabled: false + +Metrics/AbcSize: + Description: Assignment Branch Condition size for conn_space is too high. + Enabled: false + +Metrics/MethodLength: + Description: Method has too many lines. + Enabled: false + +RSpec/VariableName: + Description: Use snake_case for variable names. + EnforcedStyle: "snake_case" + Enabled: false + +Metrics/BlockNesting: + Description: Avoid more than 3 levels of block nesting. + Enabled: false + +AllCops: + Exclude: + - 'env/**/*' + Include: + - '**/*.rb' + - '**/*.drc' diff --git a/Makefile b/Makefile index 21f134b2..87c50bbd 100644 --- a/Makefile +++ b/Makefile @@ -25,12 +25,19 @@ ENVIRONMENT_FILE := pdk_regression.yml # Path to regression KLAYOUT_TESTS := klayout/drc/testing/ + include third_party/make-env/conda.mk # Lint python code -lint: | $(CONDA_ENV_PYTHON) +lint_python: | $(CONDA_ENV_PYTHON) @$(IN_CONDA_ENV) flake8 . +# Lint ruby code +lint_ruby:| $(CONDA_ENV_PYTHON) + @$(IN_CONDA_ENV) gem install rubocop + @ln -s $$CONDA_PREFIX/bin/ruby $$CONDA_PREFIX/share/rubygems/bin/ruby + @$(IN_CONDA_ENV) rubocop . + ################################################################################ ## DRC Regression section ################################################################################ diff --git a/klayout/drc/rule_decks/dualgate.drc b/klayout/drc/rule_decks/dualgate.drc index 871a7a6e..0490b8b9 100644 --- a/klayout/drc/rule_decks/dualgate.drc +++ b/klayout/drc/rule_decks/dualgate.drc @@ -15,74 +15,73 @@ ################################################################################################ if FEOL - #================================================ - #--------------------DUALGATE-------------------- - #================================================ + #================================================ + #--------------------DUALGATE-------------------- + #================================================ - # Rule DV.1: Min. Dualgate enclose DNWELL. is 0.5µm - logger.info("Executing rule DV.1") - dv1_l1 = dualgate.enclosing(dnwell, 0.5.um, euclidian).polygons(0.001) - dv1_l2 = dnwell.not_outside(dualgate).not(dualgate) - dv1_l = dv1_l1.or(dv1_l2) - dv1_l.output("DV.1", "DV.1 : Min. Dualgate enclose DNWELL. : 0.5µm") - dv1_l1.forget - dv1_l2.forget - dv1_l.forget + # Rule DV.1: Min. Dualgate enclose DNWELL. is 0.5µm + logger.info('Executing rule DV.1') + dv1_l1 = dualgate.enclosing(dnwell, 0.5.um, euclidian).polygons(0.001) + dv1_l2 = dnwell.not_outside(dualgate).not(dualgate) + dv1_l = dv1_l1.or(dv1_l2) + dv1_l.output('DV.1', 'DV.1 : Min. Dualgate enclose DNWELL. : 0.5µm') + dv1_l1.forget + dv1_l2.forget + dv1_l.forget - # Rule DV.2: Min. Dualgate Space. Merge if Space is less than this design rule. is 0.44µm - logger.info("Executing rule DV.2") - dv2_l1 = dualgate.space(0.44.um, euclidian).polygons(0.001) - dv2_l1.output("DV.2", "DV.2 : Min. Dualgate Space. Merge if Space is less than this design rule. : 0.44µm") - dv2_l1.forget + # Rule DV.2: Min. Dualgate Space. Merge if Space is less than this design rule. is 0.44µm + logger.info('Executing rule DV.2') + dv2_l1 = dualgate.space(0.44.um, euclidian).polygons(0.001) + dv2_l1.output('DV.2', 'DV.2 : Min. Dualgate Space. Merge if Space is less than this design rule. : 0.44µm') + dv2_l1.forget - # Rule DV.3: Min. Dualgate to COMP space [unrelated]. is 0.24µm - logger.info("Executing rule DV.3") - dv3_l1 = dualgate.separation(comp.outside(dualgate), 0.24.um, euclidian).polygons(0.001) - dv3_l1.output("DV.3", "DV.3 : Min. Dualgate to COMP space [unrelated]. : 0.24µm") - dv3_l1.forget + # Rule DV.3: Min. Dualgate to COMP space [unrelated]. is 0.24µm + logger.info('Executing rule DV.3') + dv3_l1 = dualgate.separation(comp.outside(dualgate), 0.24.um, euclidian).polygons(0.001) + dv3_l1.output('DV.3', 'DV.3 : Min. Dualgate to COMP space [unrelated]. : 0.24µm') + dv3_l1.forget - # rule DV.4 is not a DRC check - # Refer to: https://gf180mcu-pdk.readthedocs.io/en/latest/physical_verification/design_manual/drm_07_07.html + # rule DV.4 is not a DRC check + # Refer to: https://gf180mcu-pdk.readthedocs.io/en/latest/physical_verification/design_manual/drm_07_07.html - # Rule DV.5: Min. Dualgate width. is 0.7µm - logger.info("Executing rule DV.5") - dv5_l1 = dualgate.width(0.7.um, euclidian).polygons(0.001) - dv5_l1.output("DV.5", "DV.5 : Min. Dualgate width. : 0.7µm") - dv5_l1.forget + # Rule DV.5: Min. Dualgate width. is 0.7µm + logger.info('Executing rule DV.5') + dv5_l1 = dualgate.width(0.7.um, euclidian).polygons(0.001) + dv5_l1.output('DV.5', 'DV.5 : Min. Dualgate width. : 0.7µm') + dv5_l1.forget - comp_dv = comp.not(pcomp.outside(nwell)) - # Rule DV.6: Min. Dualgate enclose COMP (except substrate tap). is 0.24µm - logger.info("Executing rule DV.6") - dv6_l1 = dualgate.enclosing(comp_dv, 0.24.um, euclidian).polygons(0.001) - dv6_l2 = comp_dv.not_outside(dualgate).not(dualgate) - dv6_l = dv6_l1.or(dv6_l2) - dv6_l.output("DV.6", "DV.6 : Min. Dualgate enclose COMP (except substrate tap). : 0.24µm") - dv6_l1.forget - dv6_l2.forget - dv6_l.forget + comp_dv = comp.not(pcomp.outside(nwell)) + # Rule DV.6: Min. Dualgate enclose COMP (except substrate tap). is 0.24µm + logger.info('Executing rule DV.6') + dv6_l1 = dualgate.enclosing(comp_dv, 0.24.um, euclidian).polygons(0.001) + dv6_l2 = comp_dv.not_outside(dualgate).not(dualgate) + dv6_l = dv6_l1.or(dv6_l2) + dv6_l.output('DV.6', 'DV.6 : Min. Dualgate enclose COMP (except substrate tap). : 0.24µm') + dv6_l1.forget + dv6_l2.forget + dv6_l.forget - # Rule DV.7: COMP (except substrate tap) can not be partially overlapped by Dualgate. - logger.info("Executing rule DV.7") - dv7_l1 = dualgate.not_outside(comp_dv).not(dualgate.covering(comp_dv)) - dv7_l1.output("DV.7", "DV.7 : COMP (except substrate tap) can not be partially overlapped by Dualgate.") - dv7_l1.forget + # Rule DV.7: COMP (except substrate tap) can not be partially overlapped by Dualgate. + logger.info('Executing rule DV.7') + dv7_l1 = dualgate.not_outside(comp_dv).not(dualgate.covering(comp_dv)) + dv7_l1.output('DV.7', 'DV.7 : COMP (except substrate tap) can not be partially overlapped by Dualgate.') + dv7_l1.forget - comp_dv.forget + comp_dv.forget - # Rule DV.8: Min Dualgate enclose Poly2. is 0.4µm - logger.info("Executing rule DV.8") - dv8_l1 = dualgate.enclosing(poly2, 0.4.um, euclidian).polygons(0.001) - dv8_l2 = poly2.not_outside(dualgate).not(dualgate) - dv8_l = dv8_l1.or(dv8_l2) - dv8_l.output("DV.8", "DV.8 : Min Dualgate enclose Poly2. : 0.4µm") - dv8_l1.forget - dv8_l2.forget - dv8_l.forget - - # Rule DV.9: 3.3V and 5V/6V PMOS cannot be sitting inside same NWELL. - logger.info("Executing rule DV.9") - dv9_l1 = nwell.covering(pgate.and(dualgate)).covering(pgate.not_inside(v5_xtor).not_inside(dualgate)) - dv9_l1.output("DV.9", "DV.9 : 3.3V and 5V/6V PMOS cannot be sitting inside same NWELL.") - dv9_l1.forget -end #FEOL + # Rule DV.8: Min Dualgate enclose Poly2. is 0.4µm + logger.info('Executing rule DV.8') + dv8_l1 = dualgate.enclosing(poly2, 0.4.um, euclidian).polygons(0.001) + dv8_l2 = poly2.not_outside(dualgate).not(dualgate) + dv8_l = dv8_l1.or(dv8_l2) + dv8_l.output('DV.8', 'DV.8 : Min Dualgate enclose Poly2. : 0.4µm') + dv8_l1.forget + dv8_l2.forget + dv8_l.forget + # Rule DV.9: 3.3V and 5V/6V PMOS cannot be sitting inside same NWELL. + logger.info('Executing rule DV.9') + dv9_l1 = nwell.covering(pgate.and(dualgate)).covering(pgate.not_inside(v5_xtor).not_inside(dualgate)) + dv9_l1.output('DV.9', 'DV.9 : 3.3V and 5V/6V PMOS cannot be sitting inside same NWELL.') + dv9_l1.forget +end diff --git a/klayout/drc/rule_decks/main.drc b/klayout/drc/rule_decks/main.drc index e575e6c1..cd27dd52 100644 --- a/klayout/drc/rule_decks/main.drc +++ b/klayout/drc/rule_decks/main.drc @@ -14,880 +14,766 @@ # limitations under the License. ################################################################################################ -#=========================================================================================================================== -#------------------------------------------- GF 0.18um MCU DRC RULE DECK -------------------------------------------------- -#=========================================================================================================================== +#======================================================================================================================= +#--------------------------------------------- GF 0.18um MCU DRC RULE DECK --------------------------------------------- +#======================================================================================================================= require 'time' -require "logger" +require 'logger' require 'etc' exec_start_time = Time.now -logger = Logger.new(STDOUT) +logger = Logger.new($stdout) -logger.formatter = proc do |severity, datetime, progname, msg| - "#{datetime}: Memory Usage (" + `pmap #{Process.pid} | tail -1`[10,40].strip + ") : #{msg} +logger.formatter = proc do |_severity, datetime, _progname, msg| + "#{datetime}: Memory Usage (" + `pmap #{Process.pid} | tail -1`[10, 40].strip + ") : #{msg} " end #================================================ #----------------- FILE SETUP ------------------- #================================================ -logger.info("Starting running GF180MCU Klayout DRC runset on %s" % [$input]) -logger.info("Ruby Version for klayout: %s" % [RUBY_VERSION]) +logger.info("Starting running GF180MCU Klayout DRC runset on #{$input}") +logger.info("Ruby Version for klayout: #{RUBY_VERSION}") if $input - if $topcell - source($input, $topcell) - else - source($input) - end -end - -if $table_name - table_name = $table_name -else - table_name = "main" + if $topcell + source($input, $topcell) + else + source($input) + end end - -logger.info("Loading database to memory is complete.") +logger.info('Loading database to memory is complete.') if $report - logger.info("GF180MCU Klayout DRC runset output at: %s" % [$report]) - report("DRC Run Report at", $report) + logger.info("GF180MCU Klayout DRC runset output at: #{$report}") + report('DRC Run Report at', $report) else - layout_dir = Pathname.new(RBA::CellView::active.filename).parent.realpath - report_path = layout_dir.join("gf180_drc.lyrdb").to_s - logger.info("GF180MCU Klayout DRC runset output at default location: %s" % report_path) - report("DRC Run Report at", report_path) + layout_dir = Pathname.new(RBA::CellView.active.filename).parent.realpath + report_path = layout_dir.join('gf180_drc.lyrdb').to_s + logger.info('GF180MCU Klayout DRC runset output at default location: %s', report_path) + report('DRC Run Report at', report_path) end #================================================ #------------------ SWITCHES -------------------- #================================================ -logger.info("Evaluate switches.") +logger.info('Evaluate switches.') + +def bool_check?(obj) + obj.to_s.downcase == 'true' +end # connectivity rules -if $conn_drc == "true" - CONNECTIVITY_RULES = $conn_drc - logger.info("connectivity rules are enabled.") -else - CONNECTIVITY_RULES = false - logger.info("connectivity rules are disabled.") -end # connectivity rules +CONNECTIVITY_RULES = bool_check?($conn_drc) + +logger.info("CONNECTIVITY_RULES enabled: #{CONNECTIVITY_RULES}") # WEDGE -if $wedge == "false" - WEDGE = $wedge -else - WEDGE = "true" -end # WEDGE +WEDGE = bool_check?($wedge) -logger.info("Wedge enabled %s" % [WEDGE]) +logger.info("Wedge enabled: #{WEDGE}") # BALL -if $ball == "false" - BALL = $ball -else - BALL = "true" -end # BALL +BALL = bool_check?($ball) -logger.info("Ball enabled %s" % [BALL]) +logger.info("Ball enabled: #{BALL}") # GOLD -if $gold == "false" - GOLD = $gold -else - GOLD = "true" -end # GOLD +GOLD = bool_check?($gold) -logger.info("Gold enabled %s" % [GOLD]) +logger.info("Gold enabled: #{GOLD}") -if $mim_option - MIM_OPTION = $mim_option -else - MIM_OPTION = "B" -end +# MIM +MIM_OPTION = $mim_option || 'B' -logger.info("MIM Option selected %s" % [MIM_OPTION]) +logger.info("MIM Option selected: #{MIM_OPTION}") # OFFGRID -if $offgrid == "false" - OFFGRID = false -else - OFFGRID = true -end # OFFGRID +OFFGRID = $offgrid != 'false' -logger.info("Offgrid enabled %s" % [OFFGRID]) +logger.info("Offgrid enabled: #{OFFGRID}") +# threads if $thr - threads($thr) + threads($thr) else - thr ||= Etc.nprocessors - threads(thr) + thr ||= Etc.nprocessors + threads(thr) end -logger.info("Number of threads to use %s" % [$thr]) + +logger.info("Number of threads to use #{$thr}") #=== PRINT DETAILS === + +verbose(bool_check?($verbose)) + logger.info("Verbose mode: #{$verbose}") -if $verbose == "true" - verbose(true) -else - verbose(false) -end # === TILING MODE === -if $run_mode == "tiling" +case $run_mode +when 'tiling' tiles(500.um) tile_borders(10.um) - logger.info("Tiling mode is enabled.") + logger.info('Tiling mode is enabled.') -elsif $run_mode == "deep" +when 'deep' #=== HIER MODE === deep - logger.info("deep mode is enabled.") + logger.info('deep mode is enabled.') else #=== FLAT MODE === flat - logger.info("flat mode is enabled.") -end # run_mode + logger.info('flat mode is enabled.') +end # METAL_TOP -if $metal_top - METAL_TOP = $metal_top -else - METAL_TOP = "9K" -end # METAL_TOP +METAL_TOP = $metal_top || '9K' -logger.info("METAL_TOP Selected is %s" % [METAL_TOP]) +logger.info("METAL_TOP Selected is #{METAL_TOP}") # METAL_LEVEL -if $metal_level - METAL_LEVEL = $metal_level -else - METAL_LEVEL = "5LM" -end # METAL_LEVEL +METAL_LEVEL = $metal_level || '5LM' -logger.info("METAL_STACK Selected is %s" % [METAL_LEVEL]) +logger.info("METAL_STACK Selected is #{METAL_LEVEL}") # FEOL -if $feol == "false" - FEOL = $feol - logger.info("FEOL is disabled.") -else - FEOL = "true" - logger.info("FEOL is enabled.") -end # FEOL +FEOL = bool_check?($feol) + +logger.info("FEOL enabled: #{FEOL}") # BEOL -if $beol == "false" - BEOL = $beol - logger.info("BEOL is disabled.") -else - BEOL = "true" - logger.info("BEOL is enabled.") -end # BEOL +BEOL = bool_check?($beol) + +logger.info("BEOL enabled: #{BEOL}") #================================================ #------------- LAYERS DEFINITIONS --------------- #================================================ polygons_count = 0 -logger.info("Read in polygons from layers.") +logger.info('Read in polygons from layers.') -def get_polygons(l, d) - ps = polygons(l, d) - return $run_mode == "deep" ? ps : ps.merged +def get_polygons(layer, data_type) + ps = polygons(layer, data_type) + $run_mode == 'deep' ? ps : ps.merged end -comp = get_polygons(22 , 0 ) -count = comp.count() -logger.info("comp has %d polygons" % [count]) -polygons_count += count - -dnwell = get_polygons(12 , 0 ) -count = dnwell.count() -logger.info("dnwell has %d polygons" % [count]) -polygons_count += count - -nwell = get_polygons(21 , 0 ) -count = nwell.count() -logger.info("nwell has %d polygons" % [count]) -polygons_count += count - -lvpwell = get_polygons(204, 0 ) -count = lvpwell.count() -logger.info("lvpwell has %d polygons" % [count]) -polygons_count += count - -dualgate = get_polygons(55 , 0 ) -count = dualgate.count() -logger.info("dualgate has %d polygons" % [count]) -polygons_count += count - -poly2 = get_polygons(30 , 0 ) -count = poly2.count() -logger.info("poly2 has %d polygons" % [count]) -polygons_count += count - -nplus = get_polygons(32 , 0 ) -count = nplus.count() -logger.info("nplus has %d polygons" % [count]) -polygons_count += count - -pplus = get_polygons(31 , 0 ) -count = pplus.count() -logger.info("pplus has %d polygons" % [count]) -polygons_count += count - -sab = get_polygons(49 , 0 ) -count = sab.count() -logger.info("sab has %d polygons" % [count]) -polygons_count += count - -esd = get_polygons(24 , 0 ) -count = esd.count() -logger.info("esd has %d polygons" % [count]) -polygons_count += count - -resistor = get_polygons(62 , 0 ) -count = resistor.count() -logger.info("resistor has %d polygons" % [count]) -polygons_count += count - -fhres = get_polygons(227, 0 ) -count = fhres.count() -logger.info("fhres has %d polygons" % [count]) -polygons_count += count - -fusetop = get_polygons(75 , 0 ) -count = fusetop.count() -logger.info("fusetop has %d polygons" % [count]) -polygons_count += count - -fusewindow_d = get_polygons(96 , 1 ) -count = fusewindow_d.count() -logger.info("fusewindow_d has %d polygons" % [count]) -polygons_count += count - -polyfuse = get_polygons(220, 0 ) -count = polyfuse.count() -logger.info("polyfuse has %d polygons" % [count]) -polygons_count += count - -mvsd = get_polygons(210, 0 ) -count = mvsd.count() -logger.info("mvsd has %d polygons" % [count]) -polygons_count += count - -mvpsd = get_polygons(11 , 39) -count = mvpsd.count() -logger.info("mvpsd has %d polygons" % [count]) -polygons_count += count - -nat = get_polygons(5 , 0 ) -count = nat.count() -logger.info("nat has %d polygons" % [count]) -polygons_count += count - -comp_dummy = get_polygons(22 , 4 ) -count = comp_dummy.count() -logger.info("comp_dummy has %d polygons" % [count]) -polygons_count += count - -poly2_dummy = get_polygons(30 , 4 ) -count = poly2_dummy.count() -logger.info("poly2_dummy has %d polygons" % [count]) -polygons_count += count - -schottky_diode = get_polygons(241, 0 ) -count = schottky_diode.count() -logger.info("schottky_diode has %d polygons" % [count]) -polygons_count += count - -zener = get_polygons(178, 0 ) -count = zener.count() -logger.info("zener has %d polygons" % [count]) -polygons_count += count - -res_mk = get_polygons(110, 5 ) -count = res_mk.count() -logger.info("res_mk has %d polygons" % [count]) -polygons_count += count - -opc_drc = get_polygons(124, 5 ) -count = opc_drc.count() -logger.info("opc_drc has %d polygons" % [count]) -polygons_count += count - -ndmy = get_polygons(111, 5 ) -count = ndmy.count() -logger.info("ndmy has %d polygons" % [count]) -polygons_count += count - -pmndmy = get_polygons(152, 5 ) -count = pmndmy.count() -logger.info("pmndmy has %d polygons" % [count]) -polygons_count += count - -v5_xtor = get_polygons(112, 1 ) -count = v5_xtor.count() -logger.info("v5_xtor has %d polygons" % [count]) -polygons_count += count - -cap_mk = get_polygons(117, 5 ) -count = cap_mk.count() -logger.info("cap_mk has %d polygons" % [count]) -polygons_count += count - -mos_cap_mk = get_polygons(166, 5 ) -count = mos_cap_mk.count() -logger.info("mos_cap_mk has %d polygons" % [count]) -polygons_count += count - -ind_mk = get_polygons(151, 5 ) -count = ind_mk.count() -logger.info("ind_mk has %d polygons" % [count]) -polygons_count += count - -diode_mk = get_polygons(115, 5 ) -count = diode_mk.count() -logger.info("diode_mk has %d polygons" % [count]) -polygons_count += count - -drc_bjt = get_polygons(127, 5 ) -count = drc_bjt.count() -logger.info("drc_bjt has %d polygons" % [count]) -polygons_count += count - -lvs_bjt = get_polygons(118, 5 ) -count = lvs_bjt.count() -logger.info("lvs_bjt has %d polygons" % [count]) -polygons_count += count - -mim_l_mk = get_polygons(117, 10) -count = mim_l_mk.count() -logger.info("mim_l_mk has %d polygons" % [count]) -polygons_count += count - -latchup_mk = get_polygons(137, 5 ) -count = latchup_mk.count() -logger.info("latchup_mk has %d polygons" % [count]) -polygons_count += count - -guard_ring_mk = get_polygons(167, 5 ) -count = guard_ring_mk.count() -logger.info("guard_ring_mk has %d polygons" % [count]) -polygons_count += count - -otp_mk = get_polygons(173, 5 ) -count = otp_mk.count() -logger.info("otp_mk has %d polygons" % [count]) -polygons_count += count - -mtpmark = get_polygons(122, 5 ) -count = mtpmark.count() -logger.info("mtpmark has %d polygons" % [count]) -polygons_count += count - -neo_ee_mk = get_polygons(88 , 17) -count = neo_ee_mk.count() -logger.info("neo_ee_mk has %d polygons" % [count]) -polygons_count += count - -sramcore = get_polygons(108, 5 ) -count = sramcore.count() -logger.info("sramcore has %d polygons" % [count]) -polygons_count += count - -lvs_rf = get_polygons(100, 5 ) -count = lvs_rf.count() -logger.info("lvs_rf has %d polygons" % [count]) -polygons_count += count - -lvs_drain = get_polygons(100, 7 ) -count = lvs_drain.count() -logger.info("lvs_drain has %d polygons" % [count]) -polygons_count += count - -ind_mk = get_polygons(151, 5 ) -count = ind_mk.count() -logger.info("ind_mk has %d polygons" % [count]) -polygons_count += count - -hvpolyrs = get_polygons(123, 5 ) -count = hvpolyrs.count() -logger.info("hvpolyrs has %d polygons" % [count]) -polygons_count += count - -lvs_io = get_polygons(119, 5 ) -count = lvs_io.count() -logger.info("lvs_io has %d polygons" % [count]) -polygons_count += count - -probe_mk = get_polygons(13 , 17) -count = probe_mk.count() -logger.info("probe_mk has %d polygons" % [count]) -polygons_count += count - -esd_mk = get_polygons(24 , 5 ) -count = esd_mk.count() -logger.info("esd_mk has %d polygons" % [count]) -polygons_count += count - -lvs_source = get_polygons(100, 8 ) -count = lvs_source.count() -logger.info("lvs_source has %d polygons" % [count]) -polygons_count += count - -well_diode_mk = get_polygons(153, 51) -count = well_diode_mk.count() -logger.info("well_diode_mk has %d polygons" % [count]) -polygons_count += count - -ldmos_xtor = get_polygons(226, 0 ) -count = ldmos_xtor.count() -logger.info("ldmos_xtor has %d polygons" % [count]) -polygons_count += count - -plfuse = get_polygons(125, 5 ) -count = plfuse.count() -logger.info("plfuse has %d polygons" % [count]) -polygons_count += count - -efuse_mk = get_polygons(80 , 5 ) -count = efuse_mk.count() -logger.info("efuse_mk has %d polygons" % [count]) -polygons_count += count - -mcell_feol_mk = get_polygons(11 , 17) -count = mcell_feol_mk.count() -logger.info("mcell_feol_mk has %d polygons" % [count]) -polygons_count += count - -ymtp_mk = get_polygons(86 , 17) -count = ymtp_mk.count() -logger.info("ymtp_mk has %d polygons" % [count]) -polygons_count += count - -dev_wf_mk = get_polygons(128, 17) -count = dev_wf_mk.count() -logger.info("dev_wf_mk has %d polygons" % [count]) -polygons_count += count - -comp_label = get_polygons(22 , 10) -count = comp_label.count() -logger.info("comp_label has %d polygons" % [count]) -polygons_count += count - -poly2_label = get_polygons(30 , 10) -count = poly2_label.count() -logger.info("poly2_label has %d polygons" % [count]) -polygons_count += count - -mdiode = get_polygons(116, 5 ) -count = mdiode.count() -logger.info("mdiode has %d polygons" % [count]) -polygons_count += count - -contact = get_polygons(33 , 0 ) -count = contact.count() -logger.info("contact has %d polygons" % [count]) -polygons_count += count - -metal1_drawn = get_polygons(34 , 0 ) -count = metal1_drawn.count() -logger.info("metal1_drawn has %d polygons" % [count]) -polygons_count += count - -metal1_dummy = get_polygons(34 , 4 ) -count = metal1_dummy.count() -logger.info("metal1_dummy has %d polygons" % [count]) -polygons_count += count +comp = get_polygons(22, 0) +count = comp.count +logger.info("comp has #{count} polygons") +polygons_count += count + +dnwell = get_polygons(12, 0) +count = dnwell.count +logger.info("dnwell has #{count} polygons") +polygons_count += count + +nwell = get_polygons(21, 0) +count = nwell.count +logger.info("nwell has #{count} polygons") +polygons_count += count + +lvpwell = get_polygons(204, 0) +count = lvpwell.count +logger.info("lvpwell has #{count} polygons") +polygons_count += count + +dualgate = get_polygons(55, 0) +count = dualgate.count +logger.info("dualgate has #{count} polygons") +polygons_count += count + +poly2 = get_polygons(30, 0) +count = poly2.count +logger.info("poly2 has #{count} polygons") +polygons_count += count + +nplus = get_polygons(32, 0) +count = nplus.count +logger.info("nplus has #{count} polygons") +polygons_count += count + +pplus = get_polygons(31, 0) +count = pplus.count +logger.info("pplus has #{count} polygons") +polygons_count += count + +sab = get_polygons(49, 0) +count = sab.count +logger.info("sab has #{count} polygons") +polygons_count += count + +esd = get_polygons(24, 0) +count = esd.count +logger.info("esd has #{count} polygons") +polygons_count += count + +resistor = get_polygons(62, 0) +count = resistor.count +logger.info("resistor has #{count} polygons") +polygons_count += count + +fhres = get_polygons(227, 0) +count = fhres.count +logger.info("fhres has #{count} polygons") +polygons_count += count + +fusetop = get_polygons(75, 0) +count = fusetop.count +logger.info("fusetop has #{count} polygons") +polygons_count += count + +fusewindow_d = get_polygons(96, 1) +count = fusewindow_d.count +logger.info("fusewindow_d has #{count} polygons") +polygons_count += count + +polyfuse = get_polygons(220, 0) +count = polyfuse.count +logger.info("polyfuse has #{count} polygons") +polygons_count += count + +mvsd = get_polygons(210, 0) +count = mvsd.count +logger.info("mvsd has #{count} polygons") +polygons_count += count + +mvpsd = get_polygons(11, 39) +count = mvpsd.count +logger.info("mvpsd has #{count} polygons") +polygons_count += count + +nat = get_polygons(5, 0) +count = nat.count +logger.info("nat has #{count} polygons") +polygons_count += count + +comp_dummy = get_polygons(22, 4) +count = comp_dummy.count +logger.info("comp_dummy has #{count} polygons") +polygons_count += count + +poly2_dummy = get_polygons(30, 4) +count = poly2_dummy.count +logger.info("poly2_dummy has #{count} polygons") +polygons_count += count + +schottky_diode = get_polygons(241, 0) +count = schottky_diode.count +logger.info("schottky_diode has #{count} polygons") +polygons_count += count + +zener = get_polygons(178, 0) +count = zener.count +logger.info("zener has #{count} polygons") +polygons_count += count + +res_mk = get_polygons(110, 5) +count = res_mk.count +logger.info("res_mk has #{count} polygons") +polygons_count += count + +opc_drc = get_polygons(124, 5) +count = opc_drc.count +logger.info("opc_drc has #{count} polygons") +polygons_count += count + +ndmy = get_polygons(111, 5) +count = ndmy.count +logger.info("ndmy has #{count} polygons") +polygons_count += count + +pmndmy = get_polygons(152, 5) +count = pmndmy.count +logger.info("pmndmy has #{count} polygons") +polygons_count += count + +v5_xtor = get_polygons(112, 1) +count = v5_xtor.count +logger.info("v5_xtor has #{count} polygons") +polygons_count += count + +cap_mk = get_polygons(117, 5) +count = cap_mk.count +logger.info("cap_mk has #{count} polygons") +polygons_count += count + +mos_cap_mk = get_polygons(166, 5) +count = mos_cap_mk.count +logger.info("mos_cap_mk has #{count} polygons") +polygons_count += count + +ind_mk = get_polygons(151, 5) +count = ind_mk.count +logger.info("ind_mk has #{count} polygons") +polygons_count += count + +diode_mk = get_polygons(115, 5) +count = diode_mk.count +logger.info("diode_mk has #{count} polygons") +polygons_count += count + +drc_bjt = get_polygons(127, 5) +count = drc_bjt.count +logger.info("drc_bjt has #{count} polygons") +polygons_count += count + +lvs_bjt = get_polygons(118, 5) +count = lvs_bjt.count +logger.info("lvs_bjt has #{count} polygons") +polygons_count += count + +mim_l_mk = get_polygons(117, 10) +count = mim_l_mk.count +logger.info("mim_l_mk has #{count} polygons") +polygons_count += count + +latchup_mk = get_polygons(137, 5) +count = latchup_mk.count +logger.info("latchup_mk has #{count} polygons") +polygons_count += count + +guard_ring_mk = get_polygons(167, 5) +count = guard_ring_mk.count +logger.info("guard_ring_mk has #{count} polygons") +polygons_count += count + +otp_mk = get_polygons(173, 5) +count = otp_mk.count +logger.info("otp_mk has #{count} polygons") +polygons_count += count + +mtpmark = get_polygons(122, 5) +count = mtpmark.count +logger.info("mtpmark has #{count} polygons") +polygons_count += count + +neo_ee_mk = get_polygons(88, 17) +count = neo_ee_mk.count +logger.info("neo_ee_mk has #{count} polygons") +polygons_count += count + +sramcore = get_polygons(108, 5) +count = sramcore.count +logger.info("sramcore has #{count} polygons") +polygons_count += count + +lvs_rf = get_polygons(100, 5) +count = lvs_rf.count +logger.info("lvs_rf has #{count} polygons") +polygons_count += count + +lvs_drain = get_polygons(100, 7) +count = lvs_drain.count +logger.info("lvs_drain has #{count} polygons") +polygons_count += count + +ind_mk = get_polygons(151, 5) +count = ind_mk.count +logger.info("ind_mk has #{count} polygons") +polygons_count += count + +hvpolyrs = get_polygons(123, 5) +count = hvpolyrs.count +logger.info("hvpolyrs has #{count} polygons") +polygons_count += count + +lvs_io = get_polygons(119, 5) +count = lvs_io.count +logger.info("lvs_io has #{count} polygons") +polygons_count += count + +probe_mk = get_polygons(13, 17) +count = probe_mk.count +logger.info("probe_mk has #{count} polygons") +polygons_count += count + +esd_mk = get_polygons(24, 5) +count = esd_mk.count +logger.info("esd_mk has #{count} polygons") +polygons_count += count + +lvs_source = get_polygons(100, 8) +count = lvs_source.count +logger.info("lvs_source has #{count} polygons") +polygons_count += count + +well_diode_mk = get_polygons(153, 51) +count = well_diode_mk.count +logger.info("well_diode_mk has #{count} polygons") +polygons_count += count + +ldmos_xtor = get_polygons(226, 0) +count = ldmos_xtor.count +logger.info("ldmos_xtor has #{count} polygons") +polygons_count += count + +plfuse = get_polygons(125, 5) +count = plfuse.count +logger.info("plfuse has #{count} polygons") +polygons_count += count + +efuse_mk = get_polygons(80, 5) +count = efuse_mk.count +logger.info("efuse_mk has #{count} polygons") +polygons_count += count + +mcell_feol_mk = get_polygons(11, 17) +count = mcell_feol_mk.count +logger.info("mcell_feol_mk has #{count} polygons") +polygons_count += count + +ymtp_mk = get_polygons(86, 17) +count = ymtp_mk.count +logger.info("ymtp_mk has #{count} polygons") +polygons_count += count + +dev_wf_mk = get_polygons(128, 17) +count = dev_wf_mk.count +logger.info("dev_wf_mk has #{count} polygons") +polygons_count += count + +comp_label = get_polygons(22, 10) +count = comp_label.count +logger.info("comp_label has #{count} polygons") +polygons_count += count + +poly2_label = get_polygons(30, 10) +count = poly2_label.count +logger.info("poly2_label has #{count} polygons") +polygons_count += count + +mdiode = get_polygons(116, 5) +count = mdiode.count +logger.info("mdiode has #{count} polygons") +polygons_count += count + +contact = get_polygons(33, 0) +count = contact.count +logger.info("contact has #{count} polygons") +polygons_count += count + +metal1_drawn = get_polygons(34, 0) +count = metal1_drawn.count +logger.info("metal1_drawn has #{count} polygons") +polygons_count += count + +metal1_dummy = get_polygons(34, 4) +count = metal1_dummy.count +logger.info("metal1_dummy has #{count} polygons") +polygons_count += count metal1 = metal1_drawn + metal1_dummy -metal1_label = get_polygons(34 , 10) -count = metal1_label.count() -logger.info("metal1_label has %d polygons" % [count]) -polygons_count += count - -metal1_slot = get_polygons(34 , 3 ) -count = metal1_slot.count() -logger.info("metal1_slot has %d polygons" % [count]) -polygons_count += count - -metal1_blk = get_polygons(34 , 5 ) -count = metal1_blk.count() -logger.info("metal1_blk has %d polygons" % [count]) -polygons_count += count - -via1 = get_polygons(35 , 0 ) -count = via1.count() -logger.info("via1 has %d polygons" % [count]) -polygons_count += count - - -if METAL_LEVEL == "2LM" - metal2_drawn = get_polygons(36 , 0 ) - count = metal2_drawn.count() - logger.info("metal2_drawn has %d polygons" % [count]) - polygons_count += count - - metal2_dummy = get_polygons(36 , 4 ) - count = metal2_dummy.count() - logger.info("metal2_dummy has %d polygons" % [count]) - polygons_count += count - - metal2 = metal2_drawn + metal2_dummy - - metal2_label = get_polygons(36 , 10) - count = metal2_label.count() - logger.info("metal2_label has %d polygons" % [count]) - polygons_count += count - - metal2_slot = get_polygons(36 , 3 ) - count = metal2_slot.count() - logger.info("metal2_slot has %d polygons" % [count]) - polygons_count += count - - metal2_blk = get_polygons(36 , 5 ) - count = metal2_blk.count() - logger.info("metal2_blk has %d polygons" % [count]) - polygons_count += count - +metal1_label = get_polygons(34, 10) +count = metal1_label.count +logger.info("metal1_label has #{count} polygons") +polygons_count += count + +metal1_slot = get_polygons(34, 3) +count = metal1_slot.count +logger.info("metal1_slot has #{count} polygons") +polygons_count += count + +metal1_blk = get_polygons(34, 5) +count = metal1_blk.count +logger.info("metal1_blk has #{count} polygons") +polygons_count += count + +via1 = get_polygons(35, 0) +count = via1.count +logger.info("via1 has #{count} polygons") +polygons_count += count + +metal2_drawn = get_polygons(36, 0) +count = metal2_drawn.count +logger.info("metal2_drawn has #{count} polygons") +polygons_count += count + +metal2_dummy = get_polygons(36, 4) +count = metal2_dummy.count +logger.info("metal2_dummy has #{count} polygons") +polygons_count += count + +metal2 = metal2_drawn + metal2_dummy + +metal2_label = get_polygons(36, 10) +count = metal2_label.count +logger.info("metal2_label has #{count} polygons") +polygons_count += count + +metal2_slot = get_polygons(36, 3) +count = metal2_slot.count +logger.info("metal2_slot has #{count} polygons") +polygons_count += count + +metal2_blk = get_polygons(36, 5) +count = metal2_blk.count +logger.info("metal2_blk has #{count} polygons") +polygons_count += count + +if METAL_LEVEL == '2LM' + top_via = via1 topmin1_via = contact top_metal = metal2 topmin1_metal = metal1 - + else - metal2_drawn = get_polygons(36 , 0 ) - count = metal2_drawn.count() - logger.info("metal2_drawn has %d polygons" % [count]) - polygons_count += count - - metal2_dummy = get_polygons(36 , 4 ) - count = metal2_dummy.count() - logger.info("metal2_dummy has %d polygons" % [count]) - polygons_count += count - - metal2 = metal2_drawn + metal2_dummy - - metal2_label = get_polygons(36 , 10) - count = metal2_label.count() - logger.info("metal2_label has %d polygons" % [count]) - polygons_count += count - - metal2_slot = get_polygons(36 , 3 ) - count = metal2_slot.count() - logger.info("metal2_slot has %d polygons" % [count]) - polygons_count += count - - metal2_blk = get_polygons(36 , 5 ) - count = metal2_blk.count() - logger.info("metal2_blk has %d polygons" % [count]) - polygons_count += count - - via2 = get_polygons(38 , 0 ) - count = via2.count() - logger.info("via2 has %d polygons" % [count]) - polygons_count += count - - if METAL_LEVEL == "3LM" - metal3_drawn = get_polygons(42 , 0 ) - count = metal3_drawn.count() - logger.info("metal3_drawn has %d polygons" % [count]) - polygons_count += count - - metal3_dummy = get_polygons(42 , 4 ) - count = metal3_dummy.count() - logger.info("metal3_dummy has %d polygons" % [count]) - polygons_count += count - - metal3 = metal3_drawn + metal3_dummy - - metal3_label = get_polygons(42 , 10) - count = metal3_label.count() - logger.info("metal3_label has %d polygons" % [count]) - polygons_count += count - - metal3_slot = get_polygons(42 , 3 ) - count = metal3_slot.count() - logger.info("metal3_slot has %d polygons" % [count]) - polygons_count += count - - metal3_blk = get_polygons(42 , 5 ) - count = metal3_blk.count() - logger.info("metal3_blk has %d polygons" % [count]) - polygons_count += count - + + via2 = get_polygons(38, 0) + count = via2.count + logger.info("via2 has #{count} polygons") + polygons_count += count + + metal3_drawn = get_polygons(42, 0) + count = metal3_drawn.count + logger.info("metal3_drawn has #{count} polygons") + polygons_count += count + + metal3_dummy = get_polygons(42, 4) + count = metal3_dummy.count + logger.info("metal3_dummy has #{count} polygons") + polygons_count += count + + metal3 = metal3_drawn + metal3_dummy + + metal3_label = get_polygons(42, 10) + count = metal3_label.count + logger.info("metal3_label has #{count} polygons") + polygons_count += count + + metal3_slot = get_polygons(42, 3) + count = metal3_slot.count + logger.info("metal3_slot has #{count} polygons") + polygons_count += count + + metal3_blk = get_polygons(42, 5) + count = metal3_blk.count + logger.info("metal3_blk has #{count} polygons") + polygons_count += count + + if METAL_LEVEL == '3LM' + top_via = via2 topmin1_via = via1 top_metal = metal3 topmin1_metal = metal2 else - metal3_drawn = get_polygons(42 , 0 ) - count = metal3_drawn.count() - logger.info("metal3_drawn has %d polygons" % [count]) - polygons_count += count - - metal3_dummy = get_polygons(42 , 4 ) - count = metal3_dummy.count() - logger.info("metal3_dummy has %d polygons" % [count]) - polygons_count += count - - metal3 = metal3_drawn + metal3_dummy - - metal3_label = get_polygons(42 , 10) - count = metal3_label.count() - logger.info("metal3_label has %d polygons" % [count]) - polygons_count += count - - metal3_slot = get_polygons(42 , 3 ) - count = metal3_slot.count() - logger.info("metal3_slot has %d polygons" % [count]) - polygons_count += count - - metal3_blk = get_polygons(42 , 5 ) - count = metal3_blk.count() - logger.info("metal3_blk has %d polygons" % [count]) - polygons_count += count - - via3 = get_polygons(40 , 0 ) - - if METAL_LEVEL == "4LM" - metal4_drawn = get_polygons(46 , 0 ) - count = metal4_drawn.count() - logger.info("metal4_drawn has %d polygons" % [count]) - polygons_count += count - - metal4_dummy = get_polygons(46 , 4 ) - count = metal4_dummy.count() - logger.info("metal4_dummy has %d polygons" % [count]) - polygons_count += count - - metal4 = metal4_drawn + metal4_dummy - - metal4_label = get_polygons(46 , 10) - count = metal4_label.count() - logger.info("metal4_label has %d polygons" % [count]) - polygons_count += count - - metal4_slot = get_polygons(46 , 3 ) - count = metal4_slot.count() - logger.info("metal4_slot has %d polygons" % [count]) - polygons_count += count - - metal4_blk = get_polygons(46 , 5 ) - count = metal4_blk.count() - logger.info("metal4_blk has %d polygons" % [count]) - polygons_count += count - + + via3 = get_polygons(40, 0) + count = via3.count + logger.info("via3 has #{count} polygons") + polygons_count += count + + metal4_drawn = get_polygons(46, 0) + count = metal4_drawn.count + logger.info("metal4_drawn has #{count} polygons") + polygons_count += count + + metal4_dummy = get_polygons(46, 4) + count = metal4_dummy.count + logger.info("metal4_dummy has #{count} polygons") + polygons_count += count + + metal4 = metal4_drawn + metal4_dummy + + metal4_label = get_polygons(46, 10) + count = metal4_label.count + logger.info("metal4_label has #{count} polygons") + polygons_count += count + + metal4_slot = get_polygons(46, 3) + count = metal4_slot.count + logger.info("metal4_slot has #{count} polygons") + polygons_count += count + + metal4_blk = get_polygons(46, 5) + count = metal4_blk.count + logger.info("metal4_blk has #{count} polygons") + polygons_count += count + + if METAL_LEVEL == '4LM' + top_via = via3 topmin1_via = via2 top_metal = metal4 topmin1_metal = metal3 else - metal4_drawn = get_polygons(46 , 0 ) - count = metal4_drawn.count() - logger.info("metal4_drawn has %d polygons" % [count]) - polygons_count += count - - metal4_dummy = get_polygons(46 , 4 ) - count = metal4_dummy.count() - logger.info("metal4_dummy has %d polygons" % [count]) - polygons_count += count - - metal4 = metal4_drawn + metal4_dummy - - metal4_label = get_polygons(46 , 10) - count = metal4_label.count() - logger.info("metal4_label has %d polygons" % [count]) - polygons_count += count - - metal4_slot = get_polygons(46 , 3 ) - count = metal4_slot.count() - logger.info("metal4_slot has %d polygons" % [count]) - polygons_count += count - - metal4_blk = get_polygons(46 , 5 ) - count = metal4_blk.count() - logger.info("metal4_blk has %d polygons" % [count]) - polygons_count += count - - via4 = get_polygons(41 , 0 ) - count = via4.count() - logger.info("via4 has %d polygons" % [count]) - polygons_count += count - - if METAL_LEVEL == "5LM" - metal5_drawn = get_polygons(81 , 0 ) - count = metal5_drawn.count() - logger.info("metal5_drawn has %d polygons" % [count]) - polygons_count += count - - metal5_dummy = get_polygons(81 , 4 ) - count = metal5_dummy.count() - logger.info("metal5_dummy has %d polygons" % [count]) - polygons_count += count - - metal5 = metal5_drawn + metal5_dummy - - metal5_label = get_polygons(81 , 10) - count = metal5_label.count() - logger.info("metal5_label has %d polygons" % [count]) - polygons_count += count - - metal5_slot = get_polygons(81 , 3 ) - count = metal5_slot.count() - logger.info("metal5_slot has %d polygons" % [count]) - polygons_count += count - - metal5_blk = get_polygons(81 , 5 ) - count = metal5_blk.count() - logger.info("metal5_blk has %d polygons" % [count]) - polygons_count += count + + via4 = get_polygons(41, 0) + count = via4.count + logger.info("via4 has #{count} polygons") + polygons_count += count + + case METAL_LEVEL + when '5LM' + metal5_drawn = get_polygons(81, 0) + count = metal5_drawn.count + logger.info("metal5_drawn has #{count} polygons") + polygons_count += count + + metal5_dummy = get_polygons(81, 4) + count = metal5_dummy.count + logger.info("metal5_dummy has #{count} polygons") + polygons_count += count + + metal5 = metal5_drawn + metal5_dummy + + metal5_label = get_polygons(81, 10) + count = metal5_label.count + logger.info("metal5_label has #{count} polygons") + polygons_count += count + + metal5_slot = get_polygons(81, 3) + count = metal5_slot.count + logger.info("metal5_slot has #{count} polygons") + polygons_count += count + + metal5_blk = get_polygons(81, 5) + count = metal5_blk.count + logger.info("metal5_blk has #{count} polygons") + polygons_count += count top_via = via4 topmin1_via = via3 top_metal = metal5 topmin1_metal = metal4 - elsif METAL_LEVEL == "6LM" - metal5_drawn = get_polygons(81 , 0 ) - count = metal5_drawn.count() - logger.info("metal5_drawn has %d polygons" % [count]) - polygons_count += count + when '6LM' + metal5_drawn = get_polygons(81, 0) + count = metal5_drawn.count + logger.info("metal5_drawn has #{count} polygons") + polygons_count += count - metal5_dummy = get_polygons(81 , 4 ) - count = metal5_dummy.count() - logger.info("metal5_dummy has %d polygons" % [count]) - polygons_count += count + metal5_dummy = get_polygons(81, 4) + count = metal5_dummy.count + logger.info("metal5_dummy has #{count} polygons") + polygons_count += count metal5 = metal5_drawn + metal5_dummy - metal5_label = get_polygons(81 , 10) - count = metal5_label.count() - logger.info("metal5_label has %d polygons" % [count]) - polygons_count += count + metal5_label = get_polygons(81, 10) + count = metal5_label.count + logger.info("metal5_label has #{count} polygons") + polygons_count += count - metal5_slot = get_polygons(81 , 3 ) - count = metal5_slot.count() - logger.info("metal5_slot has %d polygons" % [count]) - polygons_count += count + metal5_slot = get_polygons(81, 3) + count = metal5_slot.count + logger.info("metal5_slot has #{count} polygons") + polygons_count += count - metal5_blk = get_polygons(81 , 5 ) - count = metal5_blk.count() - logger.info("metal5_blk has %d polygons" % [count]) - polygons_count += count + metal5_blk = get_polygons(81, 5) + count = metal5_blk.count + logger.info("metal5_blk has #{count} polygons") + polygons_count += count - via5 = get_polygons(82 , 0 ) - count = via5.count() - logger.info("via5 has %d polygons" % [count]) - polygons_count += count + via5 = get_polygons(82, 0) + count = via5.count + logger.info("via5 has #{count} polygons") + polygons_count += count + metaltop_drawn = get_polygons(53, 0) + count = metaltop_drawn.count + logger.info("metaltop_drawn has #{count} polygons") + polygons_count += count - metaltop_drawn = get_polygons(53 , 0 ) - count = metaltop_drawn.count() - logger.info("metaltop_drawn has %d polygons" % [count]) - polygons_count += count - - metaltop_dummy = get_polygons(53 , 4 ) - count = metaltop_dummy.count() - logger.info("metaltop_dummy has %d polygons" % [count]) - polygons_count += count + metaltop_dummy = get_polygons(53, 4) + count = metaltop_dummy.count + logger.info("metaltop_dummy has #{count} polygons") + polygons_count += count metaltop = metaltop_drawn + metaltop_dummy - metaltop_label = get_polygons(53 , 10) - count = metaltop_label.count() - logger.info("metaltop_label has %d polygons" % [count]) - polygons_count += count + metaltop_label = get_polygons(53, 10) + count = metaltop_label.count + logger.info("metaltop_label has #{count} polygons") + polygons_count += count - metaltop_slot = get_polygons(53 , 3 ) - count = metaltop_slot.count() - logger.info("metaltop_slot has %d polygons" % [count]) - polygons_count += count + metaltop_slot = get_polygons(53, 3) + count = metaltop_slot.count + logger.info("metaltop_slot has #{count} polygons") + polygons_count += count - metalt_blk = get_polygons(53 , 5 ) - count = metalt_blk.count() - logger.info("metalt_blk has %d polygons" % [count]) - polygons_count += count + metalt_blk = get_polygons(53, 5) + count = metalt_blk.count + logger.info("metalt_blk has #{count} polygons") + polygons_count += count top_via = via5 topmin1_via = via4 top_metal = metaltop topmin1_metal = metal5 else - logger.error("Unknown metal stack %s" % [METAL_LEVEL]) + logger.error("Unknown metal stack #{METAL_LEVEL}") raise end end end end -pad = get_polygons(37 , 0 ) -count = pad.count() -logger.info("pad has %d polygons" % [count]) -polygons_count += count - -ubmpperi = get_polygons(183, 0 ) -count = ubmpperi.count() -logger.info("ubmpperi has %d polygons" % [count]) -polygons_count += count - -ubmparray = get_polygons(184, 0 ) -count = ubmparray.count() -logger.info("ubmparray has %d polygons" % [count]) -polygons_count += count - -ubmeplate = get_polygons(185, 0 ) -count = ubmeplate.count() -logger.info("ubmeplate has %d polygons" % [count]) -polygons_count += count - -metal1_res = get_polygons(110, 11) -count = metal1_res.count() -logger.info("metal1_res has %d polygons" % [count]) -polygons_count += count - -metal2_res = get_polygons(110, 12) -count = metal2_res.count() -logger.info("metal2_res has %d polygons" % [count]) -polygons_count += count - -metal3_res = get_polygons(110, 13) -count = metal3_res.count() -logger.info("metal3_res has %d polygons" % [count]) -polygons_count += count - -metal4_res = get_polygons(110, 14) -count = metal4_res.count() -logger.info("metal4_res has %d polygons" % [count]) -polygons_count += count - -metal5_res = get_polygons(110, 15) -count = metal5_res.count() -logger.info("metal5_res has %d polygons" % [count]) -polygons_count += count - -metal6_res = get_polygons(110, 16) -count = metal6_res.count() -logger.info("metal6_res has %d polygons" % [count]) -polygons_count += count - -pr_bndry = get_polygons(0 , 0 ) -count = pr_bndry.count() -logger.info("pr_bndry has %d polygons" % [count]) -polygons_count += count - -border = get_polygons(63 , 0 ) -count = border.count() -logger.info("border has %d polygons" % [count]) -polygons_count += count +pad = get_polygons(37, 0) +count = pad.count +logger.info("pad has #{count} polygons") +polygons_count += count + +ubmpperi = get_polygons(183, 0) +count = ubmpperi.count +logger.info("ubmpperi has #{count} polygons") +polygons_count += count + +ubmparray = get_polygons(184, 0) +count = ubmparray.count +logger.info("ubmparray has #{count} polygons") +polygons_count += count + +ubmeplate = get_polygons(185, 0) +count = ubmeplate.count +logger.info("ubmeplate has #{count} polygons") +polygons_count += count + +metal1_res = get_polygons(110, 11) +count = metal1_res.count +logger.info("metal1_res has #{count} polygons") +polygons_count += count + +metal2_res = get_polygons(110, 12) +count = metal2_res.count +logger.info("metal2_res has #{count} polygons") +polygons_count += count + +metal3_res = get_polygons(110, 13) +count = metal3_res.count +logger.info("metal3_res has #{count} polygons") +polygons_count += count + +metal4_res = get_polygons(110, 14) +count = metal4_res.count +logger.info("metal4_res has #{count} polygons") +polygons_count += count + +metal5_res = get_polygons(110, 15) +count = metal5_res.count +logger.info("metal5_res has #{count} polygons") +polygons_count += count + +metal6_res = get_polygons(110, 16) +count = metal6_res.count +logger.info("metal6_res has #{count} polygons") +polygons_count += count + +pr_bndry = get_polygons(0, 0) +count = pr_bndry.count +logger.info("pr_bndry has #{count} polygons") +polygons_count += count + +border = get_polygons(63, 0) +count = border.count +logger.info("border has #{count} polygons") +polygons_count += count logger.info("Total no. of polygons in the design is #{polygons_count}") -logger.info("Starting deriving base layers.") +logger.info('Starting deriving base layers.') #===================================================== #------------- BASE LAYERS DERIVATIONS --------------- @@ -957,35 +843,35 @@ nwell_n_dn = nwell.not_interacting(dnwell) if CONNECTIVITY_RULES - logger.info("Construct connectivity for the design.") + logger.info('Construct connectivity for the design.') - connect(dnwell, ncomp) + connect(dnwell, ncomp) connect(ncomp, contact) connect(pcomp, contact) - connect(lvpwell_out, pcomp) + connect(lvpwell_out, pcomp) connect(lvpwell_dn, pcomp) - connect(nwell, ncomp) - connect(natcomp, contact) - connect(mvsd, ncomp) - connect(mvpsd, pcomp) - connect(contact, metal1) + connect(nwell, ncomp) + connect(natcomp, contact) + connect(mvsd, ncomp) + connect(mvpsd, pcomp) + connect(contact, metal1) connect(metal1, via1) connect(via1, metal2) - if METAL_LEVEL != "2LM" + if METAL_LEVEL != '2LM' connect(metal2, via2) connect(via2, metal3) - if METAL_LEVEL != "3LM" + if METAL_LEVEL != '3LM' connect(metal3, via3) connect(via3, metal4) - - if METAL_LEVEL != "4LM" + + if METAL_LEVEL != '4LM' connect(metal4, via4) connect(via4, metal5) - if METAL_LEVEL != "5LM" + if METAL_LEVEL != '5LM' connect(metal5, via5) connect(via5, metaltop) end @@ -993,21 +879,20 @@ if CONNECTIVITY_RULES end end -end #CONNECTIVITY_RULES +end #================================================ #------------ PRE-DEFINED FUNCTIONS ------------- #================================================ -def conn_space(layer,conn_val,not_conn_val, mode) - if conn_val > not_conn_val - raise "ERROR : Wrong connectivity implementation" - end +def conn_space(layer, conn_val, not_conn_val, mode) + raise 'ERROR : Wrong connectivity implementation' if conn_val > not_conn_val + connected_output = layer.space(conn_val.um, mode).polygons(0.001) unconnected_errors_unfiltered = layer.space(not_conn_val.um, mode) singularity_errors = layer.space(0.001.um) # Filter out the errors arising from the same net - unconnected_errors = DRC::DRCLayer::new(self, RBA::EdgePairs::new) + unconnected_errors = DRC::DRCLayer.new(self, RBA::EdgePairs.new) unconnected_errors_unfiltered.data.each do |ep| net1 = l2n_data.probe_net(layer.data, ep.first.p1) net2 = l2n_data.probe_net(layer.data, ep.second.p1) @@ -1019,17 +904,16 @@ def conn_space(layer,conn_val,not_conn_val, mode) end end unconnected_output = unconnected_errors.polygons.or(singularity_errors.polygons(0.001)) - return connected_output, unconnected_output + [connected_output, unconnected_output] end -def conn_separation(layer1, layer2, conn_val,not_conn_val, mode) - if conn_val > not_conn_val - raise "ERROR : Wrong connectivity implementation" - end +def conn_separation(layer1, layer2, conn_val, not_conn_val, mode) + raise 'ERROR : Wrong connectivity implementation' if conn_val > not_conn_val + connected_output = layer1.separation(layer2, conn_val.um, mode).polygons(0.001) unconnected_errors_unfiltered = layer1.separation(layer2, not_conn_val.um, mode) # Filter out the errors arising from the same net - unconnected_errors = DRC::DRCLayer::new(self, RBA::EdgePairs::new) + unconnected_errors = DRC::DRCLayer.new(self, RBA::EdgePairs.new) unconnected_errors_unfiltered.data.each do |ep| net1 = l2n_data.probe_net(layer1.data, ep.first.p1) net2 = l2n_data.probe_net(layer2.data, ep.second.p1) @@ -1041,30 +925,24 @@ def conn_separation(layer1, layer2, conn_val,not_conn_val, mode) end end unconnected_output = unconnected_errors.polygons(0.001) - return connected_output, unconnected_output + [connected_output, unconnected_output] end # === IMPLICIT EXTRACTION === if CONNECTIVITY_RULES - logger.info("Connectivity rules enabled, Netlist object will be generated.") + logger.info('Connectivity rules enabled, Netlist object will be generated.') netlist -end #CONNECTIVITY_RULES +end # === LAYOUT EXTENT === CHIP = extent.sized(0.0) -logger.info("Total area of the design is #{CHIP.area()} um^2.") +logger.info("Total area of the design is #{CHIP.area} um^2.") #================================================ #----------------- MAIN RUNSET ------------------ #================================================ -logger.info("Starting GF180MCU DRC rules.") -if FEOL - logger.info("Running all FEOL rules") -end #FEOL - -if BEOL - logger.info("Running all BEOL rules") -end #BEOL - +logger.info('Starting GF180MCU DRC rules.') +logger.info('Running all FEOL rules') if FEOL +logger.info('Running all BEOL rules') if BEOL diff --git a/klayout/drc/rule_decks/tail.drc b/klayout/drc/rule_decks/tail.drc index b4ef0bca..a9a22a63 100644 --- a/klayout/drc/rule_decks/tail.drc +++ b/klayout/drc/rule_decks/tail.drc @@ -14,10 +14,6 @@ # limitations under the License. ################################################################################################ - - exec_end_time = Time.now run_time = exec_end_time - exec_start_time -logger.info("%s DRC Total Run time %f seconds" % [table_name, run_time]) - - +logger.info("#{$table_name} DRC Total Run time #{run_time} seconds") diff --git a/klayout/drc/testing/run_regression.py b/klayout/drc/testing/run_regression.py index a3ba601c..f8109fca 100644 --- a/klayout/drc/testing/run_regression.py +++ b/klayout/drc/testing/run_regression.py @@ -444,7 +444,7 @@ def parse_existing_rules(rule_deck_path, output_path, target_table=None): with open(runset, "r") as f: for line in f: if ".output" in line: - line_list = line.split('"') + line_list = line.split("'") rule_info = dict() rule_info["table_name"] = os.path.basename(runset).replace( ".drc", "" diff --git a/pdk_regression.yml b/pdk_regression.yml index 7e29276a..d5216abb 100644 --- a/pdk_regression.yml +++ b/pdk_regression.yml @@ -5,6 +5,7 @@ channels: dependencies: - klayout - python + - ruby - pip - pip: - -r requirements.txt