diff --git a/technology/freepdk45/tech/freepdk45.lydrc b/technology/freepdk45/tech/freepdk45.lydrc
index 965e0488..1d719e33 100644
--- a/technology/freepdk45/tech/freepdk45.lydrc
+++ b/technology/freepdk45/tech/freepdk45.lydrc
@@ -14,7 +14,8 @@
tools_menu.drc.end
dsl
drc-dsl-xml
- #
+
+#
# DRC for FreePDK45 according to :
# https://www.eda.ncsu.edu/wiki/FreePDK45:RuleDevel
# https://www.eda.ncsu.edu/wiki/FreePDK45:Contents
@@ -41,14 +42,15 @@ end
###############
OFFGRID = true
ANTENNA = true
+DRC = true
# KLAYOUT setup
########################
# Use a tile size of 1mm
-tiles(1000.um)
+# tiles(100.um)
# Use a tile border of 10 micron:
-tile_borders(1.um)
-#no_borders
+# tile_borders(1.um)
+# no_borders
# Hierachical
deep
@@ -64,30 +66,37 @@ pwell = polygons(2, 0)
nwell = polygons(3, 0)
nplus = polygons(4, 0)
pplus = polygons(5, 0)
-vtg = polygons(6, 0)
-vth = polygons(7, 0)
-thkox = polygons(8, 0)
+vtg = polygons(6, 0)
+vth = polygons(7, 0)
+thkox = polygons(8, 0)
poly = polygons(9, 0)
cont = polygons(10, 0)
-metal1 = polygons(11, 0)
-via1 = polygons(12, 0)
-metal2 = polygons(13, 0)
-via2 = polygons(14, 0)
-metal3 = polygons(15, 0)
-via3 = polygons(16, 0)
-metal4 = polygons(17, 0)
-via4 = polygons(18, 0)
-metal5 = polygons(19, 0)
-via5 = polygons(20, 0)
-metal6 = polygons(21, 0)
-via6 = polygons(22, 0)
-metal7 = polygons(23, 0)
-via7 = polygons(24, 0)
-metal8 = polygons(25, 0)
-via8 = polygons(26, 0)
-metal9 = polygons(27, 0)
-via9 = polygons(28, 0)
-metal10 = polygons(29, 0)
+metal1 = polygons(11, 0)
+via1 = polygons(12, 0)
+metal2 = polygons(13, 0)
+via2 = polygons(14, 0)
+metal3 = polygons(15, 0)
+via3 = polygons(16, 0)
+metal4 = polygons(17, 0)
+via4 = polygons(18, 0)
+metal5 = polygons(19, 0)
+via5 = polygons(20, 0)
+metal6 = polygons(21, 0)
+via6 = polygons(22, 0)
+metal7 = polygons(23, 0)
+via7 = polygons(24, 0)
+metal8 = polygons(25, 0)
+via8 = polygons(26, 0)
+metal9 = polygons(27, 0)
+via9 = polygons(28, 0)
+metal10 = polygons(29, 0)
+
+# Computed layers
+well = nwell.or(pwell)
+gate = poly & active
+implant = nplus.or(pplus)
+
+if DRC
# DRC section
########################
@@ -99,7 +108,6 @@ def classify_by_width(layer, *dimensions)
end
# Wells
-well = nwell + pwell
nwell.and(pwell).output("WELL.1", "WELL.1 : nwell/pwell must not overlap")
# the rule "WELL.2 : Minimum spacing of well at different potential : 225nm" was not coded : see : https://www.klayout.de/forum/discussion/comment/6021
nwell.space(135.nm, euclidian).output("WELL.3", "WELL.3 : Minimum spacing of nwell at same potential : 135nm")
@@ -109,11 +117,12 @@ vtg.not(well).output("VT.1","VT.1 : Vtg adjust layers must coincide with well")
vth.not(well).output("VT.1","VT.1 : Vth adjust layers must coincide with well")
# Poly
-gate = poly & active
poly.width(50.nm, euclidian).output("POLY.1", "POLY.1 : Minimum width of poly : 50nm")
-if poly.separation(active, 140.nm, projection).polygons?
- poly.separation(active, 140.nm, projection).polygons.without_area(0).output("POLY.2", "POLY.2 : Minimum spacing of poly AND active: 140nm")
+poly_sep_active = poly.separation(active, 140.nm, projection)
+if poly_sep_active.polygons?
+ poly_sep_active.polygons.without_area(0).output("POLY.2", "POLY.2 : Minimum spacing of poly AND active: 140nm")
end
+poly_sep_active.forget
poly.enclosing(gate, 55.nm, projection).polygons.without_area(0).output("POLY.3", "POLY.3 : Minimum poly extension beyond active : 55nm")
active.enclosing(gate, 70.nm, projection).polygons.without_area(0).output("POLY.4", "POLY.4 : Minimum enclosure of active around gate : 70nm")
poly.not(active).separation(active, 50.nm, projection).polygons.without_area(0).output("POLY.5", "POLY.5 : Minimum spacing of field poly to active: 50nm")
@@ -126,17 +135,17 @@ well.enclosing(active, 55.nm, euclidian).output("ACTIVE.3", "ACTIVE.3 : Minimum
active.not(well).output("ACTIVE.4", "ACTIVE.4 : active must be inside nwell or pwell")
# Implant
-implant = nplus + pplus
implant.separation(gate, 70.nm, projection).polygons.without_area(0).output("IMPLANT.1", "IMPLANT.1 : Minimum spacing of nimplant/ pimplant to channel : 70nm")
implant.separation(cont, 25.nm, projection).polygons.without_area(0).output("IMPLANT.2", "IMPLANT.1 : Minimum spacing of nimplant/ pimplant to contact : 25nm")
implant.width(45.nm, euclidian).output("IMPLANT.3", "IMPLANT.3 : Minimum width of nimplant/ pimplant : 45nm")
implant.space(45.nm, euclidian).output("IMPLANT.4", "IMPLANT.4 : Minimum spacing of nimplant/ pimplant : 45nm")
nplus.and(pplus).output("IMPLANT.5", "IMPLANT.5 : Nimplant and pimplant must not overlap")
+implant.forget
# Contact
cont.edges.without_length(65.nm).output("CONTACT.1", "CONTACT.1 : Minimum/Maximum width of contact : 65nm")
cont.space(75.nm, euclidian).output("CONTACT.2", "CONTACT.2 : Minimum spacing of contact : 75nm")
-cont.not(active + poly + metal1).output("CONTACT.3", "CONTACT.3 : contact must be inside active or poly or metal1")
+cont.not(active).not(poly).not(metal1).output("CONTACT.3", "CONTACT.3 : contact must be inside active or poly or metal1")
active.enclosing(cont, 5.nm, euclidian).output("CONTACT.4", "CONTACT.4 : Minimum enclosure of active around contact : 5nm")
poly.enclosing(cont, 5.nm, euclidian).output("CONTACT.5", "CONTACT.5 : Minimum enclosure of poly around contact : 5nm")
cont.separation(poly, 35.nm, euclidian).output("CONTACT.6", "CONTACT.6 : Minimum spacing of contact and poly : 35nm")
@@ -146,16 +155,21 @@ metal1.width(65.nm, euclidian).output("METAL1.1", "METAL1.1 : Minimum width of m
metal1.space(65.nm, euclidian).output("METAL1.2", "METAL1.2 : Minimum spacing of metal1 : 65nm")
cont_edges_with_less_enclosure = metal1.enclosing(cont, 35.nm, projection).second_edges
error_corners = cont_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+cont_edges_with_less_enclosure.forget
cont.interacting(error_corners.polygons(1.dbu)).output("METAL1.3", "METAL1.3 : Minimum enclosure around contact on two opposite sides : 35nm")
+error_corners.forget
via1_edges_with_less_enclosure = metal1.enclosing(via1, 35.nm, projection).second_edges
error_corners = via1_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+via1_edges_with_less_enclosure.forget
via1.interacting(error_corners.polygons(1.dbu)).output("METAL1.4", "METAL1.4 : Minimum enclosure around via1 on two opposite sides : 35nm")
+error_corners.forget
metal1_gt90, metal1_gt270, metal1_gt500, metal1_gt900, metal1_gt1500 = classify_by_width(metal1, 90.nm, 270.nm, 500.nm, 900.nm, 1500.nm)
metal1_gt90.edges.with_length(300.nm,nil).space(90.nm,euclidian).output("METAL1.5", "METAL1.5 : Minimum spacing of metal1 wider than 90 nm and longer than 300 nm : 90nm")
metal1_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL1.6", "METAL1.6 : Minimum spacing of metal1 wider than 270 nm and longer than 900 nm : 270nm")
metal1_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL1.7", "METAL1.7 : Minimum spacing of metal1 wider than 500 nm and longer than 1.8 um : 500nm")
metal1_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL1.8", "METAL1.8 : Minimum spacing of metal1 wider than 900 nm and longer than 2.7 um : 900nm")
metal1_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL1.9", "METAL1.9 : Minimum spacing of metal1 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal1_gt90, metal1_gt270, metal1_gt500, metal1_gt900, metal1_gt1500 ].each { |l| l.forget }
# Via1
via1.edges.without_length(65.nm).output("VIA1.1", "VIA1.1 : Minimum/Maximum width of via1 : 65nm")
@@ -168,23 +182,25 @@ metal2.width(70.nm, euclidian).output("METAL2.1", "METAL2.1 : Minimum width of
metal2.space(70.nm, euclidian).output("METAL2.2", "METAL2.2 : Minimum spacing of intermediate metal2 : 70nm")
via1_edges_with_less_enclosure = metal2.enclosing(via1, 35.nm, projection).second_edges
error_corners = via1_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+via1_edges_with_less_enclosure.forget
via1.interacting(error_corners.polygons(1.dbu)).output("METAL2.3", "METAL2.3 : Minimum enclosure around via1 on two opposite sides : 35nm")
+error_corners.forget
via2_edges_with_less_enclosure = metal2.enclosing(via2, 35.nm, projection).second_edges
error_corners = via2_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+via2_edges_with_less_enclosure.forget
via2.interacting(error_corners.polygons(1.dbu)).output("METAL2.4", "METAL2.4 : Minimum enclosure around via2 on two opposite sides : 35nm")
+error_corners.forget
metal2_gt90, metal2_gt270, metal2_gt500, metal2_gt900, metal2_gt1500 = classify_by_width(metal2, 90.nm, 270.nm, 500.nm, 900.nm, 1500.nm)
metal2_gt90.edges.with_length(300.nm,nil).space(90.nm,euclidian).output("METAL2.5", "METAL2.5 : Minimum spacing of intermediate metal2 wider than 90 nm and longer than 300 nm : 90nm")
metal2_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL2.6", "METAL2.6 : Minimum spacing of intermediate metal2 wider than 270 nm and longer than 900 nm : 270nm")
metal2_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL2.7", "METAL2.7 : Minimum spacing of intermediate metal2 wider than 500 nm and longer than 1.8 um : 500nm")
metal2_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL2.8", "METAL2.8 : Minimum spacing of intermediate metal2 wider than 900 nm and longer than 2.7 um : 900nm")
metal2_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL2.9", "METAL2.9 : Minimum spacing of intermediate metal2 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal2_gt90, metal2_gt270, metal2_gt500, metal2_gt900, metal2_gt1500 ].each { |l| l.forget }
# via2
-# The FreePDK45 design rules say this is 70nm, but their Calibre deck uses 65nm, so we are using that for compatibility.
-#via2.edges.without_length(70.nm).output("VIA2.1", "VIA2.1 : Minimum/Maximum width of via2 : 70nm")
-via2.edges.without_length(65.nm).output("VIA2.1", "VIA2.1 : Minimum/Maximum width of via2 : 65nm")
-#via2.space(85.nm, euclidian).output("VIA2.2", "VIA2.2 : Minimum spacing of via2 : 85nm")
-via2.space(75.nm, euclidian).output("VIA2.2", "VIA2.2 : Minimum spacing of via2 : 75nm")
+via2.edges.without_length(70.nm).output("VIA2.1", "VIA2.1 : Minimum/Maximum width of via2 : 70nm")
+via2.space(85.nm, euclidian).output("VIA2.2", "VIA2.2 : Minimum spacing of via2 : 85nm")
via2.not(metal2).output("VIA2.3", "VIA2.3 : via2 must be inside metal2")
via2.not(metal3).output("VIA2.4", "VIA2.4 : via2 must be inside metal3")
@@ -193,16 +209,21 @@ metal3.width(70.nm, euclidian).output("METAL3.1", "METAL3.1 : Minimum width of
metal3.space(70.nm, euclidian).output("METAL3.2", "METAL3.2 : Minimum spacing of intermediate metal3 : 70nm")
via2_edges_with_less_enclosure = metal3.enclosing(via2, 35.nm, projection).second_edges
error_corners = via2_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+via2_edges_with_less_enclosure.forget
via2.interacting(error_corners.polygons(1.dbu)).output("METAL3.3", "METAL3.3 : Minimum enclosure around via2 on two opposite sides : 35nm")
+error_corners.forget
via3_edges_with_less_enclosure = metal3.enclosing(via3, 35.nm, projection).second_edges
error_corners = via3_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
+via3_edges_with_less_enclosure.forget
via3.interacting(error_corners.polygons(1.dbu)).output("METAL3.4", "METAL3.4 : Minimum enclosure around via3 on two opposite sides : 35nm")
+error_corners.forget
metal3_gt90, metal3_gt270, metal3_gt500, metal3_gt900, metal3_gt1500 = classify_by_width(metal3, 90.nm, 270.nm, 500.nm, 900.nm, 1500.nm)
metal3_gt90.edges.with_length(300.nm,nil).space(90.nm,euclidian).output("METAL3.5", "METAL3.5 : Minimum spacing of intermediate metal3 wider than 90 nm and longer than 300 nm : 90nm")
metal3_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL3.6", "METAL3.6 : Minimum spacing of intermediate metal3 wider than 270 nm and longer than 900 nm : 270nm")
metal3_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL3.7", "METAL3.7 : Minimum spacing of intermediate metal3 wider than 500 nm and longer than 1.8 um : 500nm")
metal3_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL3.8", "METAL3.8 : Minimum spacing of intermediate metal3 wider than 900 nm and longer than 2.7 um : 900nm")
metal3_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL3.9", "METAL3.9 : Minimum spacing of intermediate metal3 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal3_gt90, metal3_gt270, metal3_gt500, metal3_gt900, metal3_gt1500 ].each { |l| l.forget }
# via3
via3.edges.without_length(70.nm).output("VIA3.1", "VIA3.1 : Minimum/Maximum width of via3 : 70nm")
@@ -217,6 +238,7 @@ metal4_gt270, metal4_gt500, metal4_gt900 = classify_by_width(metal4, 270.nm, 500
metal4_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL4.6", "METAL4.6 : Minimum spacing of semi-global metal4 wider than 270 nm and longer than 900 nm : 270nm")
metal4_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL4.7", "METAL4.7 : Minimum spacing of semi-global metal4 wider than 500 nm and longer than 1.8 um : 500nm")
metal4_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL4.8", "METAL4.8 : Minimum spacing of semi-global meta4l wider than 900 nm and longer than 2.7 um : 900nm")
+[ metal4_gt270, metal4_gt500, metal4_gt900 ].each { |l| l.forget }
# via4
via4.edges.without_length(140.nm).output("VIA4.1", "VIA4.1 : Minimum/Maximum width of via4 : 140nm")
@@ -231,6 +253,7 @@ metal5_gt270, metal5_gt500, metal5_gt900 = classify_by_width(metal5, 270.nm, 500
metal5_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL5.6", "METAL5.6 : Minimum spacing of semi-global metal5 wider than 270 nm and longer than 900 nm : 270nm")
metal5_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL5.7", "METAL5.7 : Minimum spacing of semi-global metal5 wider than 500 nm and longer than 1.8 um : 500nm")
metal5_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL5.8", "METAL5.8 : Minimum spacing of semi-global meta5l wider than 900 nm and longer than 2.7 um : 900nm")
+[ metal5_gt270, metal5_gt500, metal5_gt900 ].each { |l| l.forget }
# via5
via5.edges.without_length(140.nm).output("VIA5.1", "VIA5.1 : Minimum/Maximum width of via5 : 140nm")
@@ -245,6 +268,7 @@ metal6_gt270, metal6_gt500, metal6_gt900 = classify_by_width(metal6, 270.nm, 500
metal6_gt270.edges.with_length(900.nm,nil).space(270.nm,euclidian).output("METAL6.6", "METAL6.6 : Minimum spacing of semi-global metal6 wider than 270 nm and longer than 900 nm : 270nm")
metal6_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL6.7", "METAL6.7 : Minimum spacing of semi-global metal6 wider than 500 nm and longer than 1.8 um : 500nm")
metal6_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL6.8", "METAL6.8 : Minimum spacing of semi-global metal6 wider than 900 nm and longer than 2.7 um : 900nm")
+[ metal6_gt270, metal6_gt500, metal6_gt900 ].each { |l| l.forget }
# via6
via6.edges.without_length(140.nm).output("VIA6.1", "VIA6.1 : Minimum/Maximum width of via6 : 140nm")
@@ -259,6 +283,7 @@ metal7_gt500, metal7_gt900, metal7_gt1500 = classify_by_width(metal7, 500.nm, 90
metal7_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL7.7", "METAL7.7 : Minimum spacing of thin global metal7 wider than 500 nm and longer than 1.8 um : 500nm")
metal7_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL7.8", "METAL7.8 : Minimum spacing of thin global metal7 wider than 900 nm and longer than 2.7 um : 900nm")
metal7_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL7.9", "METAL7.9 : Minimum spacing of thin global meta7l wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal7_gt500, metal7_gt900, metal7_gt1500 ].each { |l| l.forget }
# via7
via7.edges.without_length(400.nm).output("VIA6.1", "VIA6.1 : Minimum/Maximum width of via7 : 400nm")
@@ -273,6 +298,7 @@ metal8_gt500, metal8_gt900, metal8_gt1500 = classify_by_width(metal8, 500.nm, 90
metal8_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL8.7", "METAL8.7 : Minimum spacing of thin global metal8 wider than 500 nm and longer than 1.8 um : 500nm")
metal8_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL8.8", "METAL8.8 : Minimum spacing of thin global metal8 wider than 900 nm and longer than 2.7 um : 900nm")
metal8_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL8.9", "METAL8.9 : Minimum spacing of thin global metal8 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal8_gt500, metal8_gt900, metal8_gt1500 ].each { |l| l.forget }
# via8
via8.edges.without_length(400.nm).output("VIA8.1", "VIA8.1 : Minimum/Maximum width of via8 : 400nm")
@@ -287,6 +313,7 @@ metal9_gt500, metal9_gt900, metal9_gt1500 = classify_by_width(metal9, 500.nm, 90
metal9_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL9.7", "METAL9.7 : Minimum spacing of global metal9 wider than 500 nm and longer than 1.8 um : 500nm")
metal9_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL9.8", "METAL9.8 : Minimum spacing of global metal9 wider than 900 nm and longer than 2.7 um : 900nm")
metal9_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL9.9", "METAL9.9 : Minimum spacing of global metal9 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal9_gt500, metal9_gt900, metal9_gt1500 ].each { |l| l.forget }
# via9
via9.edges.without_length(800.nm).output("VIA9.1", "VIA9.1 : Minimum/Maximum width of via9 : 800nm")
@@ -301,7 +328,9 @@ metal10_gt500, metal10_gt900, metal10_gt1500 = classify_by_width(metal10, 500.nm
metal10_gt500.edges.with_length(1.8.um,nil).space(500.nm,euclidian).output("METAL10.7", "METAL10.7 : Minimum spacing of global metal10 wider than 500 nm and longer than 1.8 um : 500nm")
metal10_gt900.edges.with_length(2.7.um,nil).space(900.nm,euclidian).output("METAL10.8", "METAL10.8 : Minimum spacing of global metal10 wider than 900 nm and longer than 2.7 um : 900nm")
metal10_gt1500.edges.with_length(4.um,nil).space(1500.nm,euclidian).output("METAL10.9", "METAL10.9 : Minimum spacing of global metal10 wider than 1500 nm and longer than 4.0 um : 1500nm")
+[ metal10_gt500, metal10_gt900, metal10_gt1500 ].each { |l| l.forget }
+end
# ONGRID also defined in :
@@ -325,46 +354,70 @@ end
if ANTENNA
info("ANTENNA section")
-# build connections of poly+gate to metals
+diode = nplus & active - nwell # diode recognition layer
+
+# build connction of poly+gate to metal1
connect(gate, poly)
connect(poly, cont)
+connect(diode, cont)
connect(cont, metal1)
+
+antenna_check(gate, metal1, 300.0, diode).output("METAL1_ANTENNA", "METAL1_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal2
connect(metal1, via1)
connect(via1, metal2)
+
+antenna_check(gate, metal2, 300.0, diode).output("METAL2_ANTENNA", "METAL2_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal3
connect(metal2, via2)
connect(via2, metal3)
+
+antenna_check(gate, metal3, 300.0, diode).output("METAL3_ANTENNA", "METAL3_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal4
connect(metal3, via3)
connect(via3, metal4)
+
+antenna_check(gate, metal4, 300.0, diode).output("METAL4_ANTENNA", "METAL4_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal5
connect(metal4, via4)
connect(via4, metal5)
+
+antenna_check(gate, metal5, 300.0, diode).output("METAL5_ANTENNA", "METAL5_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal6
connect(metal5, via5)
connect(via5, metal6)
+
+antenna_check(gate, metal6, 300.0, diode).output("METAL6_ANTENNA", "METAL6_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal7
connect(metal6, via6)
connect(via6, metal7)
+
+antenna_check(gate, metal7, 300.0, diode).output("METAL7_ANTENNA", "METAL7_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal8
connect(metal7, via7)
connect(via7, metal8)
+
+antenna_check(gate, metal8, 300.0, diode).output("METAL8_ANTENNA", "METAL8_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal9
connect(metal8, via8)
connect(via8, metal9)
+
+antenna_check(gate, metal9, 300.0, diode).output("METAL9_ANTENNA", "METAL9_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
+
+# build connction of poly+gate to metal10
connect(metal9, via9)
connect(via9, metal10)
-diode = nplus & active - nwell # diode recognition layer
-connect(diode, cont)
-
-# runs an antenna checks for each metal with a ratio of 300
-antenna_check(gate, metal1, 300.0, diode).output("METAL1_ANTENNA", "METAL1_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal2, 300.0, diode).output("METAL2_ANTENNA", "METAL2_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal3, 300.0, diode).output("METAL3_ANTENNA", "METAL3_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal4, 300.0, diode).output("METAL4_ANTENNA", "METAL4_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal5, 300.0, diode).output("METAL5_ANTENNA", "METAL5_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal6, 300.0, diode).output("METAL6_ANTENNA", "METAL6_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal7, 300.0, diode).output("METAL7_ANTENNA", "METAL7_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal8, 300.0, diode).output("METAL8_ANTENNA", "METAL8_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-antenna_check(gate, metal9, 300.0, diode).output("METAL9_ANTENNA", "METAL9_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
antenna_check(gate, metal10, 300.0, diode).output("METAL10_ANTENNA", "METAL10_ANTENNA : Ratio of Maximum Allowed (Field poly area or Metal Layer Area) to transistor gate area : 300:1")
-# this will remove all connections made
-clear_connections
end
# time spent for the DRC
@@ -372,5 +425,6 @@ time = Time.now
hours = ((time - tstart)/3600).to_i
minutes = ((time - tstart)/60 - hours * 60).to_i
seconds = ((time - tstart) - (minutes * 60 + hours * 3600)).to_i
-$stdout.write "DRC finished at : #{time.hour}:#{time.min}:#{time.sec} - DRC duration = #{hours} hrs. #{minutes} min. #{seconds} sec.\n"
+$stdout.write "DRC finished at : #{time.hour}:#{time.min}:#{time.sec} - DRC duration = #{hours} hrs. #{minutes} min. #{seconds} sec.\n"
+
diff --git a/technology/freepdk45/tech/freepdk45.lylvs b/technology/freepdk45/tech/freepdk45.lylvs
index c8dfccef..5d8e50b3 100644
--- a/technology/freepdk45/tech/freepdk45.lylvs
+++ b/technology/freepdk45/tech/freepdk45.lylvs
@@ -26,7 +26,7 @@ if $input
end
if $report
- report($report)
+ report_lvs($report)
else
report_lvs("lvs_report.lvsdb")
end
@@ -34,8 +34,7 @@ end
if $schematic
#reference netlist
schematic($schematic)
-else
-# schematic("sram_8_256_freepdk45.sp")
+else
schematic(RBA::CellView::active.filename.sub(/\.(oas|gds|oas.gz|gds.gz)$/, ".sp"))
end
@@ -45,12 +44,12 @@ spice_with_net_names = true
# true: put in comments with details
# false: no comments
-spice_with_comments = false
+spice_with_comments = true
if $target_netlist
target_netlist($target_netlist)
else
- # target_netlist("netlist.cir", write_spice(spice_with_net_names, spice_with_comments), "The netlist comment goes here.")
+ # target_netlist("netlist.cir", write_spice(spice_with_net_names, spice_with_comments), "The netlist comment goes here.")
target_netlist(File.join(File.dirname(RBA::CellView::active.filename), source.cell_name+"_extracted.cir"), write_spice(spice_with_net_names, spice_with_comments), "Extracted by KLayout on : #{Time.now.strftime("%d/%m/%Y %H:%M")}")
end
@@ -136,7 +135,7 @@ lv_ngate = ngate - vtg - thkox
gv_ngate = ngate & vtg - vth - thkox
hv_ngate = ngate - vtg - vth & thkox
-cheat("cell_6t", "dummy_cell_6t", "cell_1rw", "dummy_cell_1rw", "cell_2rw", "dummy_cell_2rw", "dff","wordline_driver_0", "replica_cell_1rw", "replica_bitcell_array") {
+cheat("cell_6t", "dummy_cell_6t", "cell_1rw", "dummy_cell_1rw", "cell_2rw", "dummy_cell_2rw", "dff","wordline_driver_0") {
# PMOS transistor device extraction
extract_devices(mos4("PMOS_VTL"), { "SD" => psd, "G" => lv_pgate, "tS" => psd, "tD" => psd, "tG" => poly, "W" => nwell })
@@ -210,286 +209,16 @@ connect_global(pwell, "PWELL")
connect_global(nwell, "NWELL")
connect_global(bulk, "BULK")
-for pat in %w(pnand*_0 and2_dec_0 port_address* replica_bitcell_array)
- connect_explicit(pat, [ "NWELL", "vdd" ])
- connect_explicit(pat, [ "BULK", "PWELL", "gnd" ])
-end
-
-for pat in %w(XOR* XNOR* TLAT* TINV* TBUF* SDFF* OR* OAI* NOR* NAND* MUX* LOGIC* INV* HA* FILLCELL*
- FA* DLL* DLH* DFF* DFFS* DFFR* DFFRS* CLKGATE* CLKBUF* BUF* AOI* ANTENNA* AND*)
- connect_explicit(pat, [ "NWELL", "VDD" ])
- connect_explicit(pat, [ "BULK", "VSS" ])
-end
+#for pat in %w(pnand*_0 and2_dec_0 port_address* replica_bitcell_array)
+# connect_explicit(pat, [ "NWELL", "vdd" ])
+# connect_explicit(pat, [ "BULK", "PWELL", "gnd" ])
+#end
-# NangateOpenCellLibrary Digital gates VDD VSS implicit connection due to lack of taps insides the cells
-connect_implicit("AND2_X1" , "VDD")
-connect_implicit("AND2_X1" , "VSS")
-connect_implicit("AND2_X2" , "VDD")
-connect_implicit("AND2_X2" , "VSS")
-connect_implicit("AND2_X4" , "VDD")
-connect_implicit("AND2_X4" , "VSS")
-connect_implicit("AND3_X1" , "VDD")
-connect_implicit("AND3_X1" , "VSS")
-connect_implicit("AND3_X2" , "VDD")
-connect_implicit("AND3_X2" , "VSS")
-connect_implicit("AND3_X4" , "VDD")
-connect_implicit("AND3_X4" , "VSS")
-connect_implicit("AND4_X1" , "VDD")
-connect_implicit("AND4_X1" , "VSS")
-connect_implicit("AND4_X2" , "VDD")
-connect_implicit("AND4_X2" , "VSS")
-connect_implicit("AND4_X4" , "VDD")
-connect_implicit("AND4_X4" , "VSS")
-connect_implicit("ANTENNA_X1" , "VDD")
-connect_implicit("ANTENNA_X1" , "VSS")
-connect_implicit("AOI211_X1" , "VDD")
-connect_implicit("AOI211_X1" , "VSS")
-connect_implicit("AOI211_X2" , "VDD")
-connect_implicit("AOI211_X2" , "VSS")
-connect_implicit("AOI211_X4" , "VDD")
-connect_implicit("AOI211_X4" , "VSS")
-connect_implicit("AOI21_X1" , "VDD")
-connect_implicit("AOI21_X1" , "VSS")
-connect_implicit("AOI21_X2" , "VDD")
-connect_implicit("AOI21_X2" , "VSS")
-connect_implicit("AOI21_X4" , "VDD")
-connect_implicit("AOI21_X4" , "VSS")
-connect_implicit("AOI221_X1" , "VDD")
-connect_implicit("AOI221_X1" , "VSS")
-connect_implicit("AOI221_X2" , "VDD")
-connect_implicit("AOI221_X2" , "VSS")
-connect_implicit("AOI221_X4" , "VDD")
-connect_implicit("AOI221_X4" , "VSS")
-connect_implicit("AOI222_X1" , "VDD")
-connect_implicit("AOI222_X1" , "VSS")
-connect_implicit("AOI222_X2" , "VDD")
-connect_implicit("AOI222_X2" , "VSS")
-connect_implicit("AOI222_X4" , "VDD")
-connect_implicit("AOI222_X4" , "VSS")
-connect_implicit("AOI22_X1" , "VDD")
-connect_implicit("AOI22_X1" , "VSS")
-connect_implicit("AOI22_X2" , "VDD")
-connect_implicit("AOI22_X2" , "VSS")
-connect_implicit("AOI22_X4" , "VDD")
-connect_implicit("AOI22_X4" , "VSS")
-connect_implicit("BUF_X1" , "VDD")
-connect_implicit("BUF_X1" , "VSS")
-connect_implicit("BUF_X16" , "VDD")
-connect_implicit("BUF_X16" , "VSS")
-connect_implicit("BUF_X2" , "VDD")
-connect_implicit("BUF_X2" , "VSS")
-connect_implicit("BUF_X32" , "VDD")
-connect_implicit("BUF_X32" , "VSS")
-connect_implicit("BUF_X4" , "VDD")
-connect_implicit("BUF_X4" , "VSS")
-connect_implicit("BUF_X8" , "VDD")
-connect_implicit("BUF_X8" , "VSS")
-connect_implicit("CLKBUF_X1" , "VDD")
-connect_implicit("CLKBUF_X1" , "VSS")
-connect_implicit("CLKBUF_X2" , "VDD")
-connect_implicit("CLKBUF_X2" , "VSS")
-connect_implicit("CLKBUF_X3" , "VDD")
-connect_implicit("CLKBUF_X3" , "VSS")
-connect_implicit("CLKGATETST_X1" , "VDD")
-connect_implicit("CLKGATETST_X1" , "VSS")
-connect_implicit("CLKGATETST_X2" , "VDD")
-connect_implicit("CLKGATETST_X2" , "VSS")
-connect_implicit("CLKGATETST_X4" , "VDD")
-connect_implicit("CLKGATETST_X4" , "VSS")
-connect_implicit("CLKGATETST_X8" , "VDD")
-connect_implicit("CLKGATETST_X8" , "VSS")
-connect_implicit("CLKGATE_X1" , "VDD")
-connect_implicit("CLKGATE_X1" , "VSS")
-connect_implicit("CLKGATE_X2" , "VDD")
-connect_implicit("CLKGATE_X2" , "VSS")
-connect_implicit("CLKGATE_X4" , "VDD")
-connect_implicit("CLKGATE_X4" , "VSS")
-connect_implicit("CLKGATE_X8" , "VDD")
-connect_implicit("CLKGATE_X8" , "VSS")
-connect_implicit("DFFRS_X1" , "VDD")
-connect_implicit("DFFRS_X1" , "VSS")
-connect_implicit("DFFRS_X2" , "VDD")
-connect_implicit("DFFRS_X2" , "VSS")
-connect_implicit("DFFR_X1" , "VDD")
-connect_implicit("DFFR_X1" , "VSS")
-connect_implicit("DFFR_X2" , "VDD")
-connect_implicit("DFFR_X2" , "VSS")
-connect_implicit("DFFS_X1" , "VDD")
-connect_implicit("DFFS_X1" , "VSS")
-connect_implicit("DFFS_X2" , "VDD")
-connect_implicit("DFFS_X2" , "VSS")
-connect_implicit("DFF_X1" , "VDD")
-connect_implicit("DFF_X1" , "VSS")
-connect_implicit("DFF_X2" , "VDD")
-connect_implicit("DFF_X2" , "VSS")
-connect_implicit("DLH_X1" , "VDD")
-connect_implicit("DLH_X1" , "VSS")
-connect_implicit("DLH_X2" , "VDD")
-connect_implicit("DLH_X2" , "VSS")
-connect_implicit("DLL_X1" , "VDD")
-connect_implicit("DLL_X1" , "VSS")
-connect_implicit("DLL_X2" , "VDD")
-connect_implicit("DLL_X2" , "VSS")
-connect_implicit("FA_X1" , "VDD")
-connect_implicit("FA_X1" , "VSS")
-connect_implicit("FILLCELL_X1" , "VDD")
-connect_implicit("FILLCELL_X1" , "VSS")
-connect_implicit("FILLCELL_X16" , "VDD")
-connect_implicit("FILLCELL_X16" , "VSS")
-connect_implicit("FILLCELL_X2" , "VDD")
-connect_implicit("FILLCELL_X2" , "VSS")
-connect_implicit("FILLCELL_X32" , "VDD")
-connect_implicit("FILLCELL_X32" , "VSS")
-connect_implicit("FILLCELL_X4" , "VDD")
-connect_implicit("FILLCELL_X4" , "VSS")
-connect_implicit("FILLCELL_X8" , "VDD")
-connect_implicit("FILLCELL_X8" , "VSS")
-connect_implicit("HA_X1" , "VDD")
-connect_implicit("HA_X1" , "VSS")
-connect_implicit("INV_X1" , "VDD")
-connect_implicit("INV_X1" , "VSS")
-connect_implicit("INV_X16" , "VDD")
-connect_implicit("INV_X16" , "VSS")
-connect_implicit("INV_X2" , "VDD")
-connect_implicit("INV_X2" , "VSS")
-connect_implicit("INV_X32" , "VDD")
-connect_implicit("INV_X32" , "VSS")
-connect_implicit("INV_X4" , "VDD")
-connect_implicit("INV_X4" , "VSS")
-connect_implicit("INV_X8" , "VDD")
-connect_implicit("INV_X8" , "VSS")
-connect_implicit("LOGIC0_X1" , "VDD")
-connect_implicit("LOGIC0_X1" , "VSS")
-connect_implicit("LOGIC1_X1" , "VDD")
-connect_implicit("LOGIC1_X1" , "VSS")
-connect_implicit("MUX2_X1" , "VDD")
-connect_implicit("MUX2_X1" , "VSS")
-connect_implicit("MUX2_X2" , "VDD")
-connect_implicit("MUX2_X2" , "VSS")
-connect_implicit("NAND2_X1" , "VDD")
-connect_implicit("NAND2_X1" , "VSS")
-connect_implicit("NAND2_X2" , "VDD")
-connect_implicit("NAND2_X2" , "VSS")
-connect_implicit("NAND2_X4" , "VDD")
-connect_implicit("NAND2_X4" , "VSS")
-connect_implicit("NAND3_X1" , "VDD")
-connect_implicit("NAND3_X1" , "VSS")
-connect_implicit("NAND3_X2" , "VDD")
-connect_implicit("NAND3_X2" , "VSS")
-connect_implicit("NAND3_X4" , "VDD")
-connect_implicit("NAND3_X4" , "VSS")
-connect_implicit("NAND4_X1" , "VDD")
-connect_implicit("NAND4_X1" , "VSS")
-connect_implicit("NAND4_X2" , "VDD")
-connect_implicit("NAND4_X2" , "VSS")
-connect_implicit("NAND4_X4" , "VDD")
-connect_implicit("NAND4_X4" , "VSS")
-connect_implicit("NOR2_X1" , "VDD")
-connect_implicit("NOR2_X1" , "VSS")
-connect_implicit("NOR2_X2" , "VDD")
-connect_implicit("NOR2_X2" , "VSS")
-connect_implicit("NOR2_X4" , "VDD")
-connect_implicit("NOR2_X4" , "VSS")
-connect_implicit("NOR3_X1" , "VDD")
-connect_implicit("NOR3_X1" , "VSS")
-connect_implicit("NOR3_X2" , "VDD")
-connect_implicit("NOR3_X2" , "VSS")
-connect_implicit("NOR3_X4" , "VDD")
-connect_implicit("NOR3_X4" , "VSS")
-connect_implicit("NOR4_X1" , "VDD")
-connect_implicit("NOR4_X1" , "VSS")
-connect_implicit("NOR4_X2" , "VDD")
-connect_implicit("NOR4_X2" , "VSS")
-connect_implicit("NOR4_X4" , "VDD")
-connect_implicit("NOR4_X4" , "VSS")
-connect_implicit("OAI211_X1" , "VDD")
-connect_implicit("OAI211_X1" , "VSS")
-connect_implicit("OAI211_X2" , "VDD")
-connect_implicit("OAI211_X2" , "VSS")
-connect_implicit("OAI211_X4" , "VDD")
-connect_implicit("OAI211_X4" , "VSS")
-connect_implicit("OAI21_X1" , "VDD")
-connect_implicit("OAI21_X1" , "VSS")
-connect_implicit("OAI21_X2" , "VDD")
-connect_implicit("OAI21_X2" , "VSS")
-connect_implicit("OAI21_X4" , "VDD")
-connect_implicit("OAI21_X4" , "VSS")
-connect_implicit("OAI221_X1" , "VDD")
-connect_implicit("OAI221_X1" , "VSS")
-connect_implicit("OAI221_X2" , "VDD")
-connect_implicit("OAI221_X2" , "VSS")
-connect_implicit("OAI221_X4" , "VDD")
-connect_implicit("OAI221_X4" , "VSS")
-connect_implicit("OAI222_X1" , "VDD")
-connect_implicit("OAI222_X1" , "VSS")
-connect_implicit("OAI222_X2" , "VDD")
-connect_implicit("OAI222_X2" , "VSS")
-connect_implicit("OAI222_X4" , "VDD")
-connect_implicit("OAI222_X4" , "VSS")
-connect_implicit("OAI22_X1" , "VDD")
-connect_implicit("OAI22_X1" , "VSS")
-connect_implicit("OAI22_X2" , "VDD")
-connect_implicit("OAI22_X2" , "VSS")
-connect_implicit("OAI22_X4" , "VDD")
-connect_implicit("OAI22_X4" , "VSS")
-connect_implicit("OAI33_X1" , "VDD")
-connect_implicit("OAI33_X1" , "VSS")
-connect_implicit("OR2_X1" , "VDD")
-connect_implicit("OR2_X1" , "VSS")
-connect_implicit("OR2_X2" , "VDD")
-connect_implicit("OR2_X2" , "VSS")
-connect_implicit("OR2_X4" , "VDD")
-connect_implicit("OR2_X4" , "VSS")
-connect_implicit("OR3_X1" , "VDD")
-connect_implicit("OR3_X1" , "VSS")
-connect_implicit("OR3_X2" , "VDD")
-connect_implicit("OR3_X2" , "VSS")
-connect_implicit("OR3_X4" , "VDD")
-connect_implicit("OR3_X4" , "VSS")
-connect_implicit("OR4_X1" , "VDD")
-connect_implicit("OR4_X1" , "VSS")
-connect_implicit("OR4_X2" , "VDD")
-connect_implicit("OR4_X2" , "VSS")
-connect_implicit("OR4_X4" , "VDD")
-connect_implicit("OR4_X4" , "VSS")
-connect_implicit("SDFFRS_X1" , "VDD")
-connect_implicit("SDFFRS_X1" , "VSS")
-connect_implicit("SDFFRS_X2" , "VDD")
-connect_implicit("SDFFRS_X2" , "VSS")
-connect_implicit("SDFFR_X1" , "VDD")
-connect_implicit("SDFFR_X1" , "VSS")
-connect_implicit("SDFFR_X2" , "VDD")
-connect_implicit("SDFFR_X2" , "VSS")
-connect_implicit("SDFFS_X1" , "VDD")
-connect_implicit("SDFFS_X1" , "VSS")
-connect_implicit("SDFFS_X2" , "VDD")
-connect_implicit("SDFFS_X2" , "VSS")
-connect_implicit("SDFF_X1" , "VDD")
-connect_implicit("SDFF_X1" , "VSS")
-connect_implicit("SDFF_X2" , "VDD")
-connect_implicit("SDFF_X2" , "VSS")
-connect_implicit("TBUF_X1" , "VDD")
-connect_implicit("TBUF_X1" , "VSS")
-connect_implicit("TBUF_X16" , "VDD")
-connect_implicit("TBUF_X16" , "VSS")
-connect_implicit("TBUF_X2" , "VDD")
-connect_implicit("TBUF_X2" , "VSS")
-connect_implicit("TBUF_X4" , "VDD")
-connect_implicit("TBUF_X4" , "VSS")
-connect_implicit("TBUF_X8" , "VDD")
-connect_implicit("TBUF_X8" , "VSS")
-connect_implicit("TINV_X1" , "VDD")
-connect_implicit("TINV_X1" , "VSS")
-connect_implicit("TLAT_X1" , "VDD")
-connect_implicit("TLAT_X1" , "VSS")
-connect_implicit("XNOR2_X1" , "VDD")
-connect_implicit("XNOR2_X1" , "VSS")
-connect_implicit("XNOR2_X2" , "VDD")
-connect_implicit("XNOR2_X2" , "VSS")
-connect_implicit("XOR2_X1" , "VDD")
-connect_implicit("XOR2_X1" , "VSS")
-connect_implicit("XOR2_X2" , "VDD")
-connect_implicit("XOR2_X2" , "VSS")
+#for pat in %w(XOR* XNOR* TLAT* TINV* TBUF* SDFF* OR* OAI* NOR* NAND* MUX* LOGIC* INV* HA* FILLCELL*
+# FA* DLL* DLH* DFF* DFFS* DFFR* DFFRS* CLKGATE* CLKBUF* BUF* AOI* ANTENNA* AND*)
+# connect_explicit(pat, [ "NWELL", "VDD" ])
+# connect_explicit(pat, [ "BULK", "VSS" ])
+#end
# Actually performs the extraction
netlist # ... not really required
@@ -518,121 +247,13 @@ tolerance("NMOS_GVT", "L", :absolute => 1.nm, :relative => 0.001)
tolerance("NMOS_HVT", "W", :absolute => 1.nm, :relative => 0.001)
tolerance("NMOS_HVT", "L", :absolute => 1.nm, :relative => 0.001)
-# NangateOpenCellLibrary Digital gates input equivalence :
-equivalent_pins("AND2_X1", "A1", "A2")
-equivalent_pins("AND2_X2", "A1", "A2")
-equivalent_pins("AND2_X4", "A1", "A2")
-equivalent_pins("AND3_X1", "A1", "A2", "A3")
-equivalent_pins("AND3_X2", "A1", "A2", "A3")
-equivalent_pins("AND3_X4", "A1", "A2", "A3")
-equivalent_pins("AND4_X1", "A1", "A2", "A3", "A4")
-equivalent_pins("AND4_X2", "A1", "A2", "A3", "A4")
-equivalent_pins("AND4_X4", "A1", "A2", "A3", "A4")
-equivalent_pins("NAND2_X1", "A1", "A2")
-equivalent_pins("NAND2_X2", "A1", "A2")
-equivalent_pins("NAND2_X4", "A1", "A2")
-equivalent_pins("NAND3_X1", "A1", "A2", "A3")
-equivalent_pins("NAND3_X2", "A1", "A2", "A3")
-equivalent_pins("NAND3_X4", "A1", "A2", "A3")
-equivalent_pins("NAND4_X1", "A1", "A2", "A3", "A4")
-equivalent_pins("NAND4_X2", "A1", "A2", "A3", "A4")
-equivalent_pins("NAND4_X4", "A1", "A2", "A3", "A4")
-equivalent_pins("OR2_X1", "A1", "A2")
-equivalent_pins("OR2_X2", "A1", "A2")
-equivalent_pins("OR2_X4", "A1", "A2")
-equivalent_pins("OR3_X1", "A1", "A2", "A3")
-equivalent_pins("OR3_X2", "A1", "A2", "A3")
-equivalent_pins("OR3_X4", "A1", "A2", "A3")
-equivalent_pins("OR4_X1", "A1", "A2", "A3", "A4")
-equivalent_pins("OR4_X2", "A1", "A2", "A3", "A4")
-equivalent_pins("OR4_X4", "A1", "A2", "A3", "A4")
-equivalent_pins("NOR2_X1", "A1", "A2")
-equivalent_pins("NOR2_X2", "A1", "A2")
-equivalent_pins("NOR2_X4", "A1", "A2")
-equivalent_pins("NOR3_X1", "A1", "A2", "A3")
-equivalent_pins("NOR3_X2", "A1", "A2", "A3")
-equivalent_pins("NOR3_X4", "A1", "A2", "A3")
-equivalent_pins("NOR4_X1", "A1", "A2", "A3", "A4")
-equivalent_pins("NOR4_X2", "A1", "A2", "A3", "A4")
-equivalent_pins("NOR4_X4", "A1", "A2", "A3", "A4")
-equivalent_pins("XOR2_X1", "A", "B")
-equivalent_pins("XOR2_X2", "A", "B")
-equivalent_pins("XNOR2_X1", "A", "B")
-equivalent_pins("XNOR2_X2", "A", "B")
-
-equivalent_pins("AOI211_X1","A","B")
-equivalent_pins("AOI211_X1","C1","C2")
-equivalent_pins("AOI211_X2","A","B")
-equivalent_pins("AOI211_X2","C1","C2")
-equivalent_pins("AOI211_X4","A","B")
-equivalent_pins("AOI211_X4","C1","C2")
-equivalent_pins("AOI21_X1","B1","B2")
-equivalent_pins("AOI21_X2","B1","B2")
-equivalent_pins("AOI21_X4","B1","B2")
-equivalent_pins("AOI221_X1","B1","B2")
-equivalent_pins("AOI221_X1","C1","C2")
-equivalent_pins("AOI221_X2","B1","B2")
-equivalent_pins("AOI221_X2","C1","C2")
-equivalent_pins("AOI221_X4","B1","B2")
-equivalent_pins("AOI221_X4","C1","C2")
-equivalent_pins("AOI222_X1","A1","A2")
-equivalent_pins("AOI222_X1","B1","B2")
-equivalent_pins("AOI222_X1","C1","C2")
-equivalent_pins("AOI222_X2","A1","A2")
-equivalent_pins("AOI222_X2","B1","B2")
-equivalent_pins("AOI222_X2","C1","C2")
-equivalent_pins("AOI222_X4","A1","A2")
-equivalent_pins("AOI222_X4","B1","B2")
-equivalent_pins("AOI222_X4","C1","C2")
-equivalent_pins("AOI22_X1","A1","A2")
-equivalent_pins("AOI22_X1","B1","B2")
-equivalent_pins("AOI22_X2","A1","A2")
-equivalent_pins("AOI22_X2","B1","B2")
-equivalent_pins("AOI22_X4","A1","A2")
-equivalent_pins("AOI22_X4","B1","B2")
-
-equivalent_pins("OAI211_X1","A","B")
-equivalent_pins("OAI211_X1","C1","C2")
-equivalent_pins("OAI211_X2","A","B")
-equivalent_pins("OAI211_X2","C1","C2")
-equivalent_pins("OAI211_X4","A","B")
-equivalent_pins("OAI211_X4","C1","C2")
-equivalent_pins("OAI21_X1","B1","B2")
-equivalent_pins("OAI21_X2","B1","B2")
-equivalent_pins("OAI21_X4","B1","B2")
-equivalent_pins("OAI221_X1","B1","B2")
-equivalent_pins("OAI221_X1","C1","C2")
-equivalent_pins("OAI221_X2","B1","B2")
-equivalent_pins("OAI221_X2","C1","C2")
-equivalent_pins("OAI221_X4","B1","B2")
-equivalent_pins("OAI221_X4","C1","C2")
-equivalent_pins("OAI222_X1","A1","A2")
-equivalent_pins("OAI222_X1","B1","B2")
-equivalent_pins("OAI222_X1","C1","C2")
-equivalent_pins("OAI222_X2","A1","A2")
-equivalent_pins("OAI222_X2","B1","B2")
-equivalent_pins("OAI222_X2","C1","C2")
-equivalent_pins("OAI222_X4","A1","A2")
-equivalent_pins("OAI222_X4","B1","B2")
-equivalent_pins("OAI222_X4","C1","C2")
-equivalent_pins("OAI22_X1","A1","A2")
-equivalent_pins("OAI22_X1","B1","B2")
-equivalent_pins("OAI22_X2","A1","A2")
-equivalent_pins("OAI22_X2","B1","B2")
-equivalent_pins("OAI22_X4","A1","A2")
-equivalent_pins("OAI22_X4","B1","B2")
-equivalent_pins("OAI33_X1","A1","A2","A3")
-equivalent_pins("OAI33_X1","B1","B2","B3")
-
-equivalent_pins("HA_X1","A","B")
-
#max_res(1000000)
#min_caps(1e-15)
max_branch_complexity(65536)
max_depth(16)
-if ! compare
+if ! compare
#raise "ERROR : Netlists don't match"
puts "ERROR : Netlists don't match"
else