new release to mr deck + non-mr deck
diff --git a/sky130/klayout/sky130A_mr.drc b/sky130/klayout/sky130A_mr.drc index 4f5b4e9..ca2965e 100755 --- a/sky130/klayout/sky130A_mr.drc +++ b/sky130/klayout/sky130A_mr.drc
@@ -5,7 +5,7 @@ # Distributed under GNU GPLv3: https://www.gnu.org/licenses/ # # History : -# 2020-10-04 : v1.0 : initial release +# 2022-1-13 : 2022.1.13_01.03 release # ########################################################################################## @@ -222,6 +222,8 @@ log("START: 64/20 (nwell)") nwell.width(0.84, euclidian).output("nwell.1", "nwell.1 : min. nwell width : 0.84um") nwell.space(1.27, euclidian).output("nwell.2a", "nwell.2a : min. nwell spacing (merged if less) : 1.27um") +nwell_interact = nwell.merge +dnwell.enclosing(nwell_interact.holes, 1.03, euclidian).output("nwell.6", "nwell.6 : min enclosure of nwellHole by dnwell : 1.03um") log("END: 64/20 (nwell)") # hvtp @@ -299,18 +301,17 @@ # nsdm log("START: 93/44 (nsdm)") -nsdm.width(0.38, euclidian).output("nsd.1", "nsd.1 : min. nsdm width : 0.38um") -nsdm.space(0.38, euclidian).output("nsd.2", "nsd.2 : min. nsdm spacing, should be manually merged if less than : 0.38um") +nsdm.outside(areaid_ce).width(0.38, euclidian).output("nsd.1", "nsd.1 : min. nsdm width : 0.38um") +nsdm.not(areaid_ce).space(0.38, euclidian).output("nsd.2", "nsd.2 : min. nsdm spacing, should be manually merged if less than : 0.38um") log("END: 93/44 (nsdm)") # psdm log("START: 94/20 (psdm)") -psdm.width(0.38, euclidian).output("psd.1", "psd.1 : min. psdm width : 0.38um") -psdm.space(0.38, euclidian).output("psd.2", "psd.2 : min. psdm spacing, should be manually merged if less than : 0.38um") +psdm.outside(areaid_ce).width(0.38, euclidian).output("psd.1", "psd.1 : min. psdm width : 0.38um") +psdm.not(areaid_ce).space(0.38, euclidian).output("psd.2", "psd.2 : min. psdm spacing, should be manually merged if less than : 0.38um") log("END: 94/20 (psdm)") # licon -# licon log("START: 66/44 (licon)") if SEAL ringLICON = licon.drc(with_holes > 0)
diff --git a/sky130/klayout/sky130A_non-mr.drc b/sky130/klayout/sky130A_non-mr.drc new file mode 100644 index 0000000..0a0bc78 --- /dev/null +++ b/sky130/klayout/sky130A_non-mr.drc
@@ -0,0 +1,222 @@ +# DRC for SKY130 according to : +# https://skywater-pdk.readthedocs.io/en/latest/rules/periphery.html +# https://skywater-pdk.readthedocs.io/en/latest/rules/layers.html +# +# Distributed under GNU GPLv3: https://www.gnu.org/licenses/ +# +# History : +# 2022-01-13 : 2022.1.13_01.01 initial release +# +########################################################################################## + +# optionnal for a batch launch : klayout -b -rd input=my_layout.gds -rd report=sky130_drc.txt -r drc_sky130.drc +if $input + source($input, $top_cell) +end + +if $report + report("SKY130 DRC runset", $report) +else + report("SKY130 DRC runset", File.join(File.dirname(RBA::CellView::active.filename), "sky130_drc.txt")) +end + +AL = true # do not change +CU = false # do not change +# choose betwen only one of AL or CU back-end flow here : +backend_flow = AL + +# enable / disable rule groups +if $feol == "1" || $feol == "true" + FEOL = true # front-end-of-line checks +else + FEOL = false +end + +if $beol == "1" || $beol == "true" + BEOL = true # back-end-of-line checks +else + BEOL = false +end + +if $offgrid == "1" || $offgrid == "true" + OFFGRID = true # manufacturing grid/angle checks +else + OFFGRID = false +end + +if $seal == "1" || $seal == "true" + SEAL = true # SEAL RING checks +else + SEAL = false +end + +if $floating_met == "1" || $floating_met == "true" + FLOATING_MET = true # back-end-of-line checks +else + FLOATING_MET = false +end + +# klayout setup +######################## +# use a tile size of 1mm - not used in deep mode- +# tiles(1000.um) +# use a tile border of 10 micron: +# tile_borders(1.um) +#no_borders + +# hierachical +deep + +if $thr + threads($thr) +else + threads(4) +end + +# if more inof is needed, set true +# verbose(true) +verbose(true) + +# layers definitions +######################## + +# all except purpose (datatype) 5 -- label and 44 -- via +li_wildcard = "67/20" +mcon_wildcard = "67/44" + +m1_wildcard = "68/20" +via_wildcard = "68/44" + +m2_wildcard = "69/20" +via2_wildcard = "69/44" + +m3_wildcard = "70/20" +via3_wildcard = "70/44" + +m4_wildcard = "71/20" +via4_wildcard = "71/44" + +m5_wildcard = "72/20" + +diff = input(65, 20) +tap = polygons(65, 44) +nwell = polygons(64, 20) +dnwell = polygons(64, 18) +pwbm = polygons(19, 44) +pwde = polygons(124, 20) +natfet = polygons(124, 21) +hvtr = polygons(18, 20) +hvtp = polygons(78, 44) +ldntm = polygons(11, 44) +hvi = polygons(75, 20) +tunm = polygons(80, 20) +lvtn = polygons(125, 44) +poly = polygons(66, 20) +hvntm = polygons(125, 20) +nsdm = polygons(93, 44) +psdm = polygons(94, 20) +rpm = polygons(86, 20) +urpm = polygons(79, 20) +npc = polygons(95, 20) +licon = polygons(66, 44) + +li = polygons(li_wildcard) +mcon = polygons(mcon_wildcard) + +m1 = polygons(m1_wildcard) +via = polygons(via_wildcard) + +m2 = polygons(m2_wildcard) +via2 = polygons(via2_wildcard) + +m3 = polygons(m3_wildcard) +via3 = polygons(via3_wildcard) + +m4 = polygons(m4_wildcard) +via4 = polygons(via4_wildcard) + +m5 = polygons(m5_wildcard) + +pad = polygons(76, 20) +nsm = polygons(61, 20) +capm = polygons(89, 44) +cap2m = polygons(97, 44) +vhvi = polygons(74, 21) +uhvi = polygons(74, 22) +npn = polygons(82, 20) +inductor = polygons(82, 24) +vpp = polygons(82, 64) +pnp = polygons(82, 44) +lvs_prune = polygons(84, 44) +ncm = polygons(92, 44) +padcenter = polygons(81, 20) +mf = polygons(76, 44) +areaid_sl = polygons(81, 1) +areaid_ce = polygons(81, 2) +areaid_fe = polygons(81, 3) +areaid_sc = polygons(81, 4) +areaid_sf = polygons(81, 6) +areaid_sw = polygons(81, 7) +areaid_sr = polygons(81, 8) +areaid_mt = polygons(81, 10) +areaid_dt = polygons(81, 11) +areaid_ft = polygons(81, 12) +areaid_ww = polygons(81, 13) +areaid_ld = polygons(81, 14) +areaid_ns = polygons(81, 15) +areaid_ij = polygons(81, 17) +areaid_zr = polygons(81, 18) +areaid_ed = polygons(81, 19) +areaid_de = polygons(81, 23) +areaid_rd = polygons(81, 24) +areaid_dn = polygons(81, 50) +areaid_cr = polygons(81, 51) +areaid_cd = polygons(81, 52) +areaid_st = polygons(81, 53) +areaid_op = polygons(81, 54) +areaid_en = polygons(81, 57) +areaid_en20 = polygons(81, 58) +areaid_le = polygons(81, 60) +areaid_hl = polygons(81, 63) +areaid_sd = polygons(81, 70) +areaid_po = polygons(81, 81) +areaid_it = polygons(81, 84) +areaid_et = polygons(81, 101) +areaid_lvt = polygons(81, 108) +areaid_re = polygons(81, 125) +areaid_ag = polygons(81, 79) +poly_rs = polygons(66, 13) +diff_rs = polygons(65, 13) +pwell_rs = polygons(64, 13) +li_rs = polygons(67, 13) +cfom = polygons(22, 20) + + +# Define a new custom function that selects polygons by their number of holes: +# It will return a new layer containing those polygons with min to max holes. +# max can be nil to omit the upper limit. +class DRC::DRCLayer + def with_holes(min, max) + new_data = RBA::Region::new + self.data.each do |p| + if p.holes >= (min || 0) && (!max || p.holes <= max) + new_data.insert(p) + end + end + DRC::DRCLayer::new(@engine, new_data) + end +end + +# DRC section +######################## +log("DRC section") + +if FEOL +log("FEOL section") + +# nsdm +log("START: 93/44 (nsdm)") +nsdm.and(psdm).output("nsd.1", "nsd.1 : nsdm should not overlap psdm") +log("END: 93/44 (nsdm)") + +end #FEOL