diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 2da483769..ae2972a1b 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -45,7 +45,7 @@ namespace db // Note: the iterator provides the hierarchical selection (enabling/disabling cells etc.) LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter) - : m_iter (iter), m_layout_index (0), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false) + : m_iter (iter), m_layout_index (0), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false), m_top_level_mode (false) { // check the iterator if (iter.has_complex_region () || iter.region () != db::Box::world ()) { @@ -65,7 +65,7 @@ LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter) } LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index) - : mp_dss (dss), m_layout_index (layout_index), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false) + : mp_dss (dss), m_layout_index (layout_index), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false), m_top_level_mode (false) { if (dss->is_valid_layout_index (m_layout_index)) { m_iter = db::RecursiveShapeIterator (dss->layout (m_layout_index), dss->initial_cell (m_layout_index), std::set ()); @@ -73,7 +73,7 @@ LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_i } LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu) - : m_iter (), m_netlist_extracted (false), m_is_flat (true), m_device_scaling (1.0), m_include_floating_subcircuits (false) + : m_iter (), m_netlist_extracted (false), m_is_flat (true), m_device_scaling (1.0), m_include_floating_subcircuits (false), m_top_level_mode (false) { mp_internal_dss.reset (new db::DeepShapeStore (topcell_name, dbu)); mp_dss.reset (mp_internal_dss.get ()); @@ -84,7 +84,7 @@ LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu) LayoutToNetlist::LayoutToNetlist () : m_iter (), mp_internal_dss (new db::DeepShapeStore ()), mp_dss (mp_internal_dss.get ()), m_layout_index (0), - m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false) + m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false), m_top_level_mode (false) { init (); } @@ -488,12 +488,12 @@ void LayoutToNetlist::check_must_connect (const db::Circuit &c, const db::Net &a } } else { if (a.expanded_name () == b.expanded_name ()) { - db::LogEntryData warn (db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name ())); + db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name ())); warn.set_cell_name (c.name ()); warn.set_category_name ("must-connect"); log_entry (warn); } else { - db::LogEntryData warn (db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name (), b.expanded_name ())); + db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name (), b.expanded_name ())); warn.set_cell_name (c.name ()); warn.set_category_name ("must-connect"); log_entry (warn); diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index be1bb68c0..bfa07f98e 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -192,6 +192,27 @@ public: m_filename = filename; } + /** + * @brief Gets the top level mode flag + */ + bool top_level_mode () const + { + return m_top_level_mode; + } + + /** + * @brief Sets top level mode + * + * In top level mode, must-connect warnings are turned into + * errors for example. + * + * By default, top-level mode is off. + */ + void set_top_level_mode (bool f) + { + m_top_level_mode = f; + } + /** * @brief Gets the log entries */ @@ -999,6 +1020,7 @@ private: db::DeepLayer m_dummy_layer; std::string m_generator; bool m_include_floating_subcircuits; + bool m_top_level_mode; std::list m_joined_net_names; std::list > m_joined_net_names_per_cell; std::list > m_joined_nets; diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index 59915bdfe..3d29e8e68 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -464,6 +464,20 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "\n" "This attribute has been introduced in version 0.27.\n" ) + + gsi::method ("top_level_mode=", &db::LayoutToNetlist::set_top_level_mode, gsi::arg ("flag"), + "@brief Sets a flag indicating whether top level mode is enabled.\n" + "\n" + "In top level mode, must-connect warnings are turned into errors for example.\n" + "To enable top level mode, set this attribute to true. By default, top-level mode is turned off.\n" + "\n" + "This attribute has been introduced in version 0.28.13." + ) + + gsi::method ("top_level_mode", &db::LayoutToNetlist::top_level_mode, + "@brief Gets a flag indicating whether top level mode is enabled.\n" + "See \\top_level_mode= for details.\n" + "\n" + "This attribute has been introduced in version 0.28.13.\n" + ) + gsi::method ("clear_join_net_names", &db::LayoutToNetlist::clear_join_net_names, "@brief Clears all implicit net joining expressions.\n" "See \\extract_netlist for more details about this feature.\n" diff --git a/src/doc/doc/manual/lvs_connect.xml b/src/doc/doc/manual/lvs_connect.xml index 44bdb0108..501695d35 100644 --- a/src/doc/doc/manual/lvs_connect.xml +++ b/src/doc/doc/manual/lvs_connect.xml @@ -137,7 +137,14 @@ connect(metal2, metal2_labels)

- This feature is also called "must connect" nets in other systems. + You can declare the layout as being a top level one. This turns the + warning about missing physical connections into an error: +

+ +
top_level(true)
+ +

+ The "connect_implicit" feature is also called "must connect" nets in other systems.

@@ -222,11 +229,11 @@ connect(metal2, metal2_labels) To align layout and schematic, bulk and VSS pins can be connected explicitly. Same for n-well and VDD. This scheme is similar to the "connect_implicit" scheme explained - above, but acts on differently named nets. + above, but can connect differently named nets.

- To establish an explicit connection, make sure that n-well and + To establish an explicit connection in the above example, make sure that n-well and bulk have proper names. For the n-well this can be done by creating labels on the n-well islands giving them a proper name - e.g. "NWELL". The bulk isn't a real layout layer with polygons on it. Using "connect_global" @@ -257,8 +264,7 @@ connect_explicit("INV", [ "BULK", "VSS" ])

Like implicit connections, explicit connections are checked for being made on the next level of hierarchy, either physically or by another explicit or - implicit connection. - This feature is also called "must connect" nets in other systems. + implicit connection.

diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 70cd8bfa8..79de6a0c7 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -2277,6 +2277,12 @@ CODE # @synopsis device_scaling(factor) # See \Netter#device_scaling for a description of that function. + # %DRC% + # @name top_level + # @brief Specifies that the circuit is a chip top level circuit + # @synopsis top_level(flag) + # See \Netter#top_level for a description of that function. + # %DRC% # @name ignore_extraction_errors # @brief Specifies whether to ignore extraction errors @@ -2305,6 +2311,7 @@ CODE connect_implicit connect_explicit device_scaling + top_level ignore_extraction_errors extract_devices l2n_data diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 7dbdf6c20..99823336b 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -70,6 +70,7 @@ module DRC @lnum = 0 @device_scaling = 1.0 @ignore_extraction_errors = false + @top_level = false end # %DRC% @@ -236,6 +237,24 @@ module DRC end end + # %DRC% + # @name top_level + # @brief Specifies top level mode + # @synopsis top_level(value) + # With this value set to false (the default), it is assumed that the + # circuit is not used as a top level chip circuit. In that case, for + # example must-connect nets which are not connected are reported as + # as warnings. If top level mode is set to true, such disconnected + # nets are reported as errors as this indicates a missing physical + # connection. + + def top_level(value) + @engine._context("top_level") do + @top_level = value + @l2n && @l2n.top_level_mode = value + end + end + # %DRC% # @name ignore_extraction_errors # @brief Specifies whether to ignore extraction errors @@ -672,6 +691,7 @@ module DRC @layers = {} _make_data @l2n.device_scaling = @device_scaling + @l2n.top_level_mode = @top_level end end diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 5a8c838e3..7f000a3b6 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -279,9 +279,11 @@ TEST(29_DeviceCombineAndTolerances) TEST(30_MustConnect1) { run_test (_this, "must_connect1", "must_connect1.gds"); + run_test (_this, "must_connect1_tl", "must_connect1.gds"); } TEST(31_MustConnect2) { run_test (_this, "must_connect2", "must_connect2.gds"); } + diff --git a/testdata/lvs/must_connect1_tl.cir b/testdata/lvs/must_connect1_tl.cir new file mode 100644 index 000000000..9b6488f75 --- /dev/null +++ b/testdata/lvs/must_connect1_tl.cir @@ -0,0 +1,23 @@ +* Extracted by KLayout + +.SUBCKT TOP VSSTOP A Q +X$1 \$8 \$2 \$1 \$1 Q VSSTOP INV2 +X$2 A \$3 VSSTOP \$3 \$2 \$8 INVCHAIN +.ENDS TOP + +.SUBCKT INVCHAIN IN IN2 VSS|VSS2|VSS2B OUT OUT2 VDD +X$1 VDD IN2 \$1 \$1 OUT2 VSS|VSS2|VSS2B INV2 +X$2 VDD IN \$2 \$2 OUT VSS|VSS2|VSS2B INV2 +.ENDS INVCHAIN + +.SUBCKT INV2 VDD A1 A2 Q1 Q2 VSS +X$1 VSS VDD A2 Q2 INV +X$2 VSS VDD A1 Q1 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 +M$1 \$2 \$3 \$4 \$4 PMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U ++ PD=3.45U +M$2 \$1 \$3 \$4 \$4 NMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U ++ PD=3.45U +.ENDS INV diff --git a/testdata/lvs/must_connect1_tl.lvs b/testdata/lvs/must_connect1_tl.lvs new file mode 100644 index 000000000..4e9cc35ed --- /dev/null +++ b/testdata/lvs/must_connect1_tl.lvs @@ -0,0 +1,143 @@ + +$lvs_test_source && source($lvs_test_source) + +if $lvs_test_target_lvsdb + report_lvs($lvs_test_target_lvsdb) +else + report_lvs +end + + +writer = write_spice(true, false) +$lvs_test_target_cir && target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout") + +# Turns the warning about VSSTOP into an error +top_level(true) +ignore_extraction_errors(true) + +# needs this delegate because we use MOS3 which is not available in Spice +class SpiceReaderDelegate < RBA::NetlistSpiceReaderDelegate + + # says we want to catch these subcircuits as devices + def wants_subcircuit(name) + name == "HVNMOS" || name == "HVPMOS" + end + + # translate the element + def element(circuit, el, name, model, value, nets, params) + + if el != "M" + # all other elements are left to the standard implementation + return super + end + + if nets.size != 4 + error("Device #{model} needs four nodes") + end + + # provide a device class + cls = circuit.netlist.device_class_by_name(model) + if ! cls + cls = RBA::DeviceClassMOS3Transistor::new + cls.name = model + circuit.netlist.add(cls) + end + + # create a device + device = circuit.create_device(cls, name) + + # and configure the device + [ "S", "G", "D" ].each_with_index do |t,index| + device.connect_terminal(t, nets[index]) + end + device.set_parameter("W", params["W"] * 1e6) + device.set_parameter("L", params["L"] * 1e6) + + device + + end + +end + +reader = RBA::NetlistSpiceReader::new(SpiceReaderDelegate::new) +schematic(File.basename(source.path, ".*") + ".sch", reader) + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +poly = input(3, 0) +poly_lbl = input(3, 1) +diff_cont = input(4, 0) +poly_cont = input(5, 0) +metal1 = input(6, 0) +metal1_lbl = input(6, 1) +via1 = input(7, 0) +metal2 = input(8, 0) +metal2_lbl = input(8, 1) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +psd = nil +nsd = nil + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell +pgate = pactive & poly +psd = pactive - pgate + +active_outside_nwell = active - nwell +nactive = active_outside_nwell +ngate = nactive & poly +nsd = nactive - ngate + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos3("PMOS"), { "SD" => psd, "G" => pgate, + "tS" => psd, "tD" => psd, "tG" => poly }) + +# NMOS transistor device extraction +extract_devices(mos3("NMOS"), { "SD" => nsd, "G" => ngate, + "tS" => nsd, "tD" => nsd, "tG" => poly }) + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, diff_cont) +connect(nsd, diff_cont) +connect(poly, poly_cont) +connect(diff_cont, metal1) +connect(poly_cont, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# attach labels +connect(poly, poly_lbl) +connect(metal1, metal1_lbl) +connect(metal2, metal2_lbl) + +# Global +connect_global(bulk, "SUBSTRATE") + +# Implicit connection of the INV2 +# VSS nets +connect_implicit("INV2", "VSS") +connect_implicit("TOP", "VSS*") +# Fix 1 +connect_explicit("INVCHAIN", ["VSS2", "VSS2B", "VSS"]) +connect_implicit("INVCHAIN", "VDD") + +# Compare section + +netlist.simplify +align + +compare + diff --git a/testdata/lvs/must_connect1_tl.lvsdb b/testdata/lvs/must_connect1_tl.lvsdb new file mode 100644 index 000000000..0bd8468c4 --- /dev/null +++ b/testdata/lvs/must_connect1_tl.lvsdb @@ -0,0 +1,484 @@ +#%lvsdb-klayout +J( + W(TOP) + U(0.001) + L(l3 '3/0') + L(l11 '3/1') + L(l6 '4/0') + L(l7 '5/0') + L(l8 '6/0') + L(l12 '6/1') + L(l9 '7/0') + L(l10 '8/0') + L(l13 '8/1') + L(l14) + L(l2) + L(l5) + C(l3 l3 l11 l7) + C(l11 l3 l11) + C(l6 l6 l8 l2 l5) + C(l7 l3 l7 l8) + C(l8 l6 l7 l8 l12 l9) + C(l12 l8 l12) + C(l9 l8 l9 l10) + C(l10 l9 l10 l13) + C(l13 l10 l13) + C(l14 l14) + C(l2 l6 l2) + C(l5 l6 l5) + G(l14 SUBSTRATE) + H(E B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect')) + K(PMOS MOS3) + K(NMOS MOS3) + D(D$PMOS PMOS + T(S + R(l2 (-900 -475) (775 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l2 (125 -475) (775 950)) + ) + ) + D(D$NMOS NMOS + T(S + R(l5 (-900 -475) (775 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l5 (125 -475) (775 950)) + ) + ) + X(INV + R((-1500 -800) (3000 4600)) + N(1 + R(l6 (290 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l5 (-1375 -925) (775 950)) + ) + N(2 + R(l6 (290 2490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l2 (-1375 -925) (775 950)) + ) + N(3 + R(l3 (-125 -250) (250 2500)) + R(l3 (-250 -3050) (250 1600)) + R(l3 (-250 1200) (250 1600)) + ) + N(4 + R(l6 (-510 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -3530) (360 2840)) + R(l8 (-360 -2800) (360 760)) + R(l8 (-360 2040) (360 760)) + R(l2 (-680 -855) (775 950)) + R(l5 (-775 -3750) (775 950)) + ) + P(1) + P(2) + P(3) + P(4) + D(1 D$PMOS + Y(0 2800) + E(L 0.25) + E(W 0.95) + E(AS 0.73625) + E(AD 0.73625) + E(PS 3.45) + E(PD 3.45) + T(S 4) + T(G 3) + T(D 2) + ) + D(2 D$NMOS + Y(0 0) + E(L 0.25) + E(W 0.95) + E(AS 0.73625) + E(AD 0.73625) + E(PS 3.45) + E(PD 3.45) + T(S 4) + T(G 3) + T(D 1) + ) + ) + X(INV2 + R((0 0) (3000 9200)) + N(1 I(VDD) + R(l10 (0 3150) (3000 2900)) + R(l13 (-1890 -1450) (0 0)) + ) + N(2 I(A1) + R(l11 (1480 7110) (0 0)) + ) + N(3 I(A2) + R(l11 (1520 1950) (0 0)) + ) + N(4 I(Q1) + R(l12 (1920 7070) (0 0)) + ) + N(5 I(Q2) + R(l12 (1940 1950) (0 0)) + ) + N(6 I(VSS) + R(l13 (2680 8390) (0 0)) + R(l13 (-30 -7640) (0 0)) + ) + P(1 I(VDD)) + P(2 I(A1)) + P(3 I(A2)) + P(4 I(Q1)) + P(5 I(Q2)) + P(6 I(VSS)) + X(1 INV M O(180) Y(1500 800) + P(0 6) + P(1 1) + P(2 3) + P(3 5) + ) + X(2 INV O(180) Y(1500 8400) + P(0 6) + P(1 1) + P(2 2) + P(3 4) + ) + ) + X(INVCHAIN + R((-915 -15) (10415 9215)) + N(1 + R(l3 (7340 1650) (2160 250)) + R(l3 (-250 0) (250 4990)) + R(l3 (-1605 0) (1605 250)) + R(l7 (-1545 -250) (240 250)) + R(l8 (-560 -375) (690 510)) + ) + N(2 + R(l3 (1625 1835) (2160 250)) + R(l3 (-250 0) (250 4990)) + R(l3 (-1605 0) (1605 250)) + R(l7 (-1545 -250) (240 250)) + R(l8 (-560 -375) (690 510)) + ) + N(3 I(IN) + R(l3 (-90 6850) (1590 650)) + R(l11 (-700 -350) (0 0)) + ) + N(4 I(IN2) + R(l3 (5665 6790) (1590 650)) + R(l11 (-700 -350) (0 0)) + ) + N(5 I('VSS,VSS2,VSS2B') + R(l10 (-915 675) (915 250)) + R(l10 (-915 0) (250 7325)) + R(l10 (-250 0) (915 250)) + R(l13 (-510 -125) (0 0)) + R(l13 (8990 -255) (0 0)) + R(l13 (25 -7115) (0 0)) + ) + N(6 I(OUT) + R(l12 (1890 2105) (0 0)) + ) + N(7 I(OUT2) + R(l12 (7730 2155) (0 0)) + ) + N(8 I(VDD) + R(l13 (8035 4540) (0 0)) + R(l13 (-5735 60) (0 0)) + ) + P(3 I(IN)) + P(4 I(IN2)) + P(5 I('VSS,VSS2,VSS2B')) + P(6 I(OUT)) + P(7 I(OUT2)) + P(8 I(VDD)) + X(1 INV2 Y(5780 -15) + P(0 8) + P(1 4) + P(2 1) + P(3 1) + P(4 7) + P(5 5) + ) + X(2 INV2 Y(0 0) + P(0 8) + P(1 3) + P(2 2) + P(3 2) + P(4 6) + P(5 5) + ) + ) + X(TOP + R((-305 350) (15415 9225)) + N(1 + R(l3 (12950 2130) (2160 250)) + R(l3 (-250 0) (250 4990)) + R(l3 (-1605 0) (1605 250)) + R(l7 (-1545 -250) (240 250)) + R(l8 (-560 -375) (690 510)) + ) + N(2 + R(l3 (12100 7300) (640 530)) + R(l7 (-540 -415) (270 250)) + R(l8 (-1695 -250) (1695 250)) + R(l8 (-4075 -5650) (2630 250)) + R(l8 (-250 0) (250 5150)) + ) + N(3 + R(l7 (6465 7325) (220 240)) + R(l8 (-4100 -5365) (3125 250)) + R(l8 (-250 0) (250 4860)) + R(l8 (-250 0) (1225 250)) + ) + N(4 I(VSSTOP) + R(l10 (3610 8300) (2815 440)) + R(l10 (-710 -250) (0 0)) + R(l10 (3675 -165) (1975 565)) + R(l10 (-1975 -8190) (1975 575)) + R(l10 (-1005 -255) (0 0)) + ) + N(5 I(A) + R(l11 (975 7530) (0 0)) + ) + N(6 I(Q) + R(l12 (13260 2010) (0 0)) + ) + N(7 + R(l10 (3450 4840) (3055 250)) + R(l10 (2885 -250) (1975 250)) + ) + P(4 I(VSSTOP)) + P(5 I(A)) + P(6 I(Q)) + X(1 INV2 Y(11365 375) + P(0 7) + P(1 2) + P(2 1) + P(3 1) + P(4 6) + P(5 4) + ) + X(2 INVCHAIN Y(610 365) + P(0 5) + P(1 3) + P(2 4) + P(3 3) + P(4 2) + P(5 7) + ) + ) +) +H( + K(PMOS MOS3) + K(NMOS MOS3) + X(INV + N(1 I(VDD)) + N(2 I(VSS)) + N(3 I(A)) + N(4 I(Q)) + P(1 I(VDD)) + P(2 I(VSS)) + P(3 I(A)) + P(4 I(Q)) + D(1 PMOS + I($1) + E(L 0.25) + E(W 0.95) + E(AS 0) + E(AD 0) + E(PS 0) + E(PD 0) + T(S 1) + T(G 3) + T(D 4) + ) + D(2 NMOS + I($3) + E(L 0.25) + E(W 0.95) + E(AS 0) + E(AD 0) + E(PS 0) + E(PD 0) + T(S 2) + T(G 3) + T(D 4) + ) + ) + X(INV2 + N(1 I(VDD)) + N(2 I(VSS)) + N(3 I(A1)) + N(4 I(Q1)) + N(5 I(A2)) + N(6 I(Q2)) + P(1 I(VDD)) + P(2 I(VSS)) + P(3 I(A1)) + P(4 I(Q1)) + P(5 I(A2)) + P(6 I(Q2)) + X(1 INV I($1) + P(0 1) + P(1 2) + P(2 3) + P(3 4) + ) + X(2 INV I($2) + P(0 1) + P(1 2) + P(2 5) + P(3 6) + ) + ) + X(INVCHAIN + N(1 I(VDD)) + N(2 I(VSS)) + N(3 I(A1)) + N(4 I(Q1)) + N(5 I(A2)) + N(6 I(Q2)) + N(7 I('1')) + N(8 I('2')) + P(1 I(VDD)) + P(2 I(VSS)) + P(3 I(A1)) + P(4 I(Q1)) + P(5 I(A2)) + P(6 I(Q2)) + X(1 INV2 I($2) + P(0 1) + P(1 2) + P(2 3) + P(3 7) + P(4 7) + P(5 4) + ) + X(2 INV2 I($3) + P(0 1) + P(1 2) + P(2 5) + P(3 8) + P(4 8) + P(5 6) + ) + ) + X(TOP + N(1 I(VDD)) + N(2 I(VSS)) + N(3 I(A)) + N(4 I('1')) + N(5 I('3')) + N(6 I('2')) + N(7 I(Q)) + X(1 INVCHAIN I($1) + P(0 1) + P(1 2) + P(2 3) + P(3 4) + P(4 4) + P(5 5) + ) + X(2 INV2 I($2) + P(0 1) + P(1 2) + P(2 5) + P(3 6) + P(4 6) + P(5 7) + ) + ) +) +Z( + X(INV INV 1 + Z( + N(3 3 1) + N(4 4 1) + N(2 1 1) + N(1 2 1) + P(2 2 1) + P(3 3 1) + P(1 0 1) + P(0 1 1) + D(2 2 1) + D(1 1 1) + ) + ) + X(INV2 INV2 1 + Z( + N(2 3 1) + N(3 5 1) + N(4 4 1) + N(5 6 1) + N(1 1 1) + N(6 2 1) + P(1 2 1) + P(2 4 1) + P(3 3 1) + P(4 5 1) + P(0 0 1) + P(5 1 1) + X(2 1 1) + X(1 2 1) + ) + ) + X(INVCHAIN INVCHAIN 1 + L( + M(W B('Matching nets OUT vs. Q1 from an ambiguous group of nets')) + M(W B('Matching nets OUT2 vs. Q2 from an ambiguous group of nets')) + M(I B('Matching nets $2 vs. 1 following an ambiguous match')) + M(I B('Matching nets IN vs. A1 following an ambiguous match')) + M(I B('Matching nets $1 vs. 2 following an ambiguous match')) + M(I B('Matching nets IN2 vs. A2 following an ambiguous match')) + ) + Z( + N(2 7 1) + N(1 8 1) + N(3 3 1) + N(4 5 1) + N(6 4 W) + N(7 6 W) + N(8 1 1) + N(5 2 1) + P(0 2 1) + P(1 4 1) + P(3 3 1) + P(4 5 1) + P(5 0 1) + P(2 1 1) + X(2 1 1) + X(1 2 1) + ) + ) + X(TOP TOP 1 + Z( + N(3 4 1) + N(1 6 1) + N(2 5 1) + N(7 1 1) + N(5 3 1) + N(6 7 1) + N(4 2 1) + P(1 () 1) + P(2 () 1) + P(0 () 1) + X(1 2 1) + X(2 1 1) + ) + ) +)