diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 862d86cb0..d7ca56d48 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -917,12 +917,12 @@ public: /** * @brief Builds a node for a net */ - NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t &unique_pin_id); + NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t *unique_pin_id); /** * @brief Builds a virtual node for a subcircuit */ - NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t &unique_pin_id); + NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t *unique_pin_id); void expand_subcircuit_nodes (NetGraph *graph); @@ -970,8 +970,18 @@ public: void apply_net_index (const std::map &ni); - bool operator< (const NetGraphNode &node) const; - bool operator== (const NetGraphNode &node) const; + bool less (const NetGraphNode &node, bool with_name) const; + bool equal (const NetGraphNode &node, bool with_name) const; + + bool operator== (const NetGraphNode &node) const + { + return equal (node, false); + } + + bool operator< (const NetGraphNode &node) const + { + return less (node, false); + } void swap (NetGraphNode &other) { @@ -1009,13 +1019,13 @@ private: * @brief Compares edges as "less" * Edge comparison is based on the pins attached (name of the first pin). */ - static bool net_less (const db::Net *a, const db::Net *b); + static bool net_less (const db::Net *a, const db::Net *b, bool with_name); /** * @brief Compares edges as "equal" * See edge_less for the comparison details. */ - static bool edge_equal (const db::Net *a, const db::Net *b); + static bool net_equal (const db::Net *a, const db::Net *b, bool with_name); }; // -------------------------------------------------------------------------------------------------------------------- @@ -1038,7 +1048,7 @@ struct CompareNodePtr { bool operator() (const std::pair &a, const std::pair &b) const { - return *a.first < *b.first; + return a.first->less (*b.first, true); } }; @@ -1072,7 +1082,7 @@ public: /** * @brief Builds the net graph */ - void build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper); + void build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper, size_t *unique_pin_id); /** * @brief Gets the node index for the given net @@ -1223,7 +1233,7 @@ private: // -------------------------------------------------------------------------------------------------------------------- -NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t &unique_pin_id) +NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t *unique_pin_id) : mp_net (net), m_other_net_index (invalid_id) { if (! net) { @@ -1262,8 +1272,10 @@ NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_catego // isolated pins are ignored, others are considered for the matching if (net->pin_count () == 0 && net->terminal_count () == 0 && net->subcircuit_pin_count () == 1) { continue; + } else if (! unique_pin_id) { + continue; } else { - pin_id = unique_pin_id++; + pin_id = (*unique_pin_id)++; } } else { @@ -1340,7 +1352,7 @@ NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_catego } } -NetGraphNode::NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t &unique_pin_id) +NetGraphNode::NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map *circuit_map, const CircuitPinMapper *pin_map, size_t *unique_pin_id) : mp_net (0), m_other_net_index (invalid_id) { std::map n2entry; @@ -1373,8 +1385,10 @@ NetGraphNode::NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circui // isolated pins are ignored, others are considered for the matching if (net_at_pin->pin_count () == 0 && net_at_pin->terminal_count () == 0 && net_at_pin->subcircuit_pin_count () == 1) { continue; + } else if (! unique_pin_id) { + continue; } else { - pin_id = unique_pin_id++; + pin_id = (*unique_pin_id)++; } } else { @@ -1517,7 +1531,7 @@ NetGraphNode::apply_net_index (const std::map &ni) } bool -NetGraphNode::operator< (const NetGraphNode &node) const +NetGraphNode::less (const NetGraphNode &node, bool with_name) const { if (m_edges.size () != node.m_edges.size ()) { return m_edges.size () < node.m_edges.size (); @@ -1529,13 +1543,13 @@ NetGraphNode::operator< (const NetGraphNode &node) const } if (m_edges.empty ()) { // do a more detailed analysis on the nets involved - return net_less (net (), node.net ()); + return net_less (net (), node.net (), with_name); } return false; } bool -NetGraphNode::operator== (const NetGraphNode &node) const +NetGraphNode::equal (const NetGraphNode &node, bool with_name) const { if (m_edges.size () != node.m_edges.size ()) { return false; @@ -1547,13 +1561,13 @@ NetGraphNode::operator== (const NetGraphNode &node) const } if (m_edges.empty ()) { // do a more detailed analysis on the edges - return edge_equal (net (), node.net ()); + return net_equal (net (), node.net (), with_name); } return true; } bool -NetGraphNode::net_less (const db::Net *a, const db::Net *b) +NetGraphNode::net_less (const db::Net *a, const db::Net *b, bool with_name) { if ((a != 0) != (b != 0)) { return (a != 0) < (b != 0); @@ -1564,14 +1578,11 @@ NetGraphNode::net_less (const db::Net *a, const db::Net *b) if (a->pin_count () != b->pin_count ()) { return a->pin_count () < b->pin_count (); } - if (a->pin_count () == 0) { - return true; - } - return db::Netlist::name_compare (combined_case_sensitive (a->netlist (), b->netlist ()), a->begin_pins ()->pin ()->name (), b->begin_pins ()->pin ()->name ()) < 0; + return with_name ? name_compare (a, b) < 0 : false; } bool -NetGraphNode::edge_equal (const db::Net *a, const db::Net *b) +NetGraphNode::net_equal (const db::Net *a, const db::Net *b, bool with_name) { if ((a != 0) != (b != 0)) { return false; @@ -1582,10 +1593,7 @@ NetGraphNode::edge_equal (const db::Net *a, const db::Net *b) if (a->pin_count () != b->pin_count ()) { return false; } - if (a->pin_count () == 0) { - return true; - } - return db::Netlist::name_compare (combined_case_sensitive (a->netlist (), b->netlist ()), a->begin_pins ()->pin ()->name (), b->begin_pins ()->pin ()->name ()) == 0; + return with_name ? name_compare (a, b) == 0 : true; } // -------------------------------------------------------------------------------------------------------------------- @@ -1871,7 +1879,7 @@ private: // NetGraph implementation void -NetGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper) +NetGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper, size_t *unique_pin_id) { tl::SelfTimer timer (tl::verbosity () >= 31, tl::to_string (tr ("Building net graph for circuit: ")) + c->name ()); @@ -1880,8 +1888,6 @@ NetGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, Ci m_nodes.clear (); m_net_index.clear (); - size_t unique_pin_id = Transition::first_unique_pin_id (); - // create a dummy node for a null net m_nodes.push_back (NetGraphNode (0, device_categorizer, circuit_categorizer, device_filter, circuit_and_pin_mapping, circuit_pin_mapper, unique_pin_id)); @@ -3613,16 +3619,21 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::NetGraph g1, g2; + size_t unique_pin_id = Transition::first_unique_pin_id (); + // NOTE: for normalization we map all subcircuits of c1 to c2. // Also, pin swapping will only happen there. if (options ()->debug_netgraph) { tl::info << "Netlist graph:"; } - g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper); + g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper, (size_t *)0); + if (options ()->debug_netgraph) { tl::info << "Other netlist graph:"; } - g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper); + // NOTE: the second netlist graph is the reference (schematic). We treat it a little more carefully by using pins from subcircuits which + // lead to passive nets but connect to non-trivial nets on the outside. This is done by specifying a unique_pin_id counter for the last argument. + g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper, &unique_pin_id); // Match dummy nodes for null nets g1.identify (0, 0); @@ -4287,14 +4298,19 @@ NetlistComparer::do_subcircuit_assignment (const db::Circuit *c1, const db::NetG bool mapped = true, valid = true; std::vector > k = compute_subcircuit_key_for_this (*sc, g1, &c12_circuit_and_pin_mapping, &circuit_pin_mapper, mapped, valid); - if (! mapped || ! valid) { + if (! mapped) { if (mp_logger) { mp_logger->subcircuit_mismatch (sc.operator-> (), 0); } good = false; - } else { + } else if (valid) { // TODO: report devices which cannot be distinguished topologically? subcircuit_map.insert (std::make_pair (k, std::make_pair (sc.operator-> (), sc_cat))); + } else { + // emit a mismatch event but do not consider that an error - this may happen if the circuit has been dropped intentionally (e.g. via cells) + if (mp_logger) { + mp_logger->subcircuit_mismatch (sc.operator-> (), 0); + } } } @@ -4584,7 +4600,7 @@ NetlistComparer::join_symmetric_nets (db::Circuit *circuit) db::NetGraph graph; db::CircuitCategorizer circuit_categorizer; db::DeviceCategorizer device_categorizer; - graph.build (circuit, device_categorizer, circuit_categorizer, device_filter, &circuit_and_pin_mapping, &circuit_pin_mapper); + graph.build (circuit, device_categorizer, circuit_categorizer, device_filter, &circuit_and_pin_mapping, &circuit_pin_mapper, (size_t *) 0); // sort the nodes so we can easily identify the identical ones (in terms of topology) // nodes are identical if the attached devices and circuits are of the same kind and with the same parameters diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index 155a371fd..7acad9839 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -1140,17 +1140,17 @@ TEST(3_GlobalNetConnections) CHECKPOINT (); db::compare_netlist (_this, *l2n.netlist (), "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" - " subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n" - " subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n" - " subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n" - " subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n" - " subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n" + " subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n" + " subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n" + " subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n" + " subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n" + " subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n" "end;\n" - "circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n" - " subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n" - " subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n" + "circuit INV2PAIR ($2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n" + " subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6);\n" + " subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6);\n" "end;\n" - "circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n" + "circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n" " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 081351a47..9d10f8b88 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -1984,6 +1984,7 @@ TEST(13_MismatchingSubcircuitsAdditionalHierarchy) "match_pins $1 $0\n" "match_pins $2 $2\n" "match_pins $3 $3\n" + "subcircuit_mismatch $2 (null)\n" "match_subcircuits $3 $1\n" "match_subcircuits $1 $2\n" "end_circuit TOP TOP MATCH" @@ -3931,25 +3932,6 @@ TEST(21_BusLikeAmbiguousConnections) TEST(22_NodesRemoved) { const char *nls1 = - "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" - " subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n" - " subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n" - " subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n" - " subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n" - " subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n" - "end;\n" - "circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n" - " subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n" - " subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n" - "end;\n" - "circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n" - " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" - " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" - " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" - " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" - "end;\n"; - - const char *nls2 = "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" " subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n" " subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n" @@ -3968,6 +3950,25 @@ TEST(22_NodesRemoved) " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" "end;\n"; + const char *nls2 = + "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" + " subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n" + " subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n" + " subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n" + " subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n" + " subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n" + "end;\n" + "circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n" + " subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n" + " subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n" + "end;\n" + "circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n" + " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" + " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" + "end;\n"; + db::Netlist nl1, nl2; prep_nl (nl1, nls1); prep_nl (nl2, nls2); @@ -3980,6 +3981,79 @@ TEST(22_NodesRemoved) std::string txt = logger.text (); + EXPECT_EQ (txt, + "begin_circuit INV2 INV2\n" + "match_nets VDD VDD\n" + "match_nets OUT OUT\n" + "match_nets $3 $3\n" + "match_nets IN IN\n" + "match_nets VSS VSS\n" + "match_nets $1 (null)\n" + "match_nets BULK (null)\n" + "match_pins IN IN\n" + "match_pins $2 $1\n" + "match_pins OUT OUT\n" + "match_pins VSS VSS\n" + "match_pins VDD VDD\n" + "match_pins $0 (null)\n" + "match_pins BULK (null)\n" + "match_devices $1 $1\n" + "match_devices $2 $2\n" + "match_devices $3 $3\n" + "match_devices $4 $4\n" + "end_circuit INV2 INV2 MATCH\n" + "begin_circuit INV2PAIR INV2PAIR\n" + "match_nets $I2 $I2\n" + "match_nets $I6 $I5\n" + "match_nets $I5 $I4\n" + "match_nets $I4 $I6\n" + "match_nets $I3 $I3\n" + "match_nets $I7 $I7\n" + "match_nets $I8 $I8\n" + "match_nets BULK (null)\n" + "match_nets $I1 (null)\n" + "match_pins $1 $0\n" + "match_pins $2 $1\n" + "match_pins $3 $2\n" + "match_pins $4 $3\n" + "match_pins $5 $4\n" + "match_pins BULK (null)\n" + "match_pins $6 (null)\n" + "match_subcircuits $1 $1\n" + "match_subcircuits $2 $2\n" + "end_circuit INV2PAIR INV2PAIR MATCH\n" + "begin_circuit RINGO RINGO\n" + "match_nets OSC OSC\n" + "match_nets $I7 $I7\n" + "match_nets $I6 $I6\n" + "match_nets $I5 $I5\n" + "match_nets $I13 $I21\n" + "match_nets FB FB\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets $I22 $I22\n" + "match_nets $I23 $I23\n" + "match_nets $I24 $I24\n" + "match_nets $I25 $I25\n" + "match_pins FB FB\n" + "match_pins OSC OSC\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits $1 $1\n" + "match_subcircuits $2 $2\n" + "match_subcircuits $3 $3\n" + "match_subcircuits $4 $4\n" + "match_subcircuits $5 $5\n" + "end_circuit RINGO RINGO MATCH" + ); + EXPECT_EQ (good, true); + + logger.clear (); + good = comp.compare (&nl2, &nl1); + + txt = logger.text (); + + // additional nodes are not ignored when they come from the reference side (second) EXPECT_EQ (txt, "begin_circuit INV2 INV2\n" "match_nets VDD VDD\n" @@ -4028,24 +4102,28 @@ TEST(22_NodesRemoved) "match_nets $I5 $I5\n" "match_nets $I21 $I13\n" "match_nets FB FB\n" - "match_nets VSS VSS\n" - "match_nets VDD VDD\n" "match_nets $I22 $I22\n" "match_nets $I23 $I23\n" "match_nets $I24 $I24\n" "match_nets $I25 $I25\n" + "net_mismatch VDD (null)\n" + "net_mismatch VSS (null)\n" + "net_mismatch (null) VDD\n" + "net_mismatch (null) VSS\n" "match_pins FB FB\n" "match_pins OSC OSC\n" - "match_pins VDD VDD\n" - "match_pins VSS VSS\n" - "match_subcircuits $1 $1\n" - "match_subcircuits $2 $2\n" - "match_subcircuits $3 $3\n" - "match_subcircuits $4 $4\n" - "match_subcircuits $5 $5\n" - "end_circuit RINGO RINGO MATCH" + "match_pins VDD (null)\n" + "match_pins VSS (null)\n" + "match_pins (null) VDD\n" + "match_pins (null) VSS\n" + "subcircuit_mismatch $1 $1\n" + "subcircuit_mismatch $2 $2\n" + "subcircuit_mismatch $3 $3\n" + "subcircuit_mismatch $4 $4\n" + "subcircuit_mismatch $5 $5\n" + "end_circuit RINGO RINGO NOMATCH" ); - EXPECT_EQ (good, true); + EXPECT_EQ (good, false); } TEST(23_NodesRemovedWithError) @@ -4150,25 +4228,6 @@ TEST(23_NodesRemovedWithError) TEST(24_NodesRemovedButConnectedInOther) { const char *nls1 = - "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" - " subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n" - " subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n" - " subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n" - " subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n" - " subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n" - "end;\n" - "circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n" - " subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n" - " subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n" - "end;\n" - "circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n" - " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" - " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" - " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" - " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" - "end;\n"; - - const char *nls2 = "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" " subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n" " subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n" @@ -4189,6 +4248,25 @@ TEST(24_NodesRemovedButConnectedInOther) " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" "end;\n"; + const char *nls2 = + "circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n" + " subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n" + " subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n" + " subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n" + " subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n" + " subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n" + "end;\n" + "circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n" + " subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n" + " subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n" + "end;\n" + "circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n" + " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" + " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" + "end;\n"; + db::Netlist nl1, nl2; prep_nl (nl1, nls1); prep_nl (nl2, nls2); @@ -4208,15 +4286,15 @@ TEST(24_NodesRemovedButConnectedInOther) "match_nets $3 $3\n" "match_nets IN IN\n" "match_nets VSS VSS\n" - "match_nets (null) $1\n" - "match_nets (null) BULK\n" + "match_nets $1 (null)\n" + "match_nets BULK (null)\n" "match_pins IN IN\n" - "match_pins $1 $2\n" + "match_pins $2 $1\n" "match_pins OUT OUT\n" "match_pins VSS VSS\n" "match_pins VDD VDD\n" - "match_pins (null) $0\n" - "match_pins (null) BULK\n" + "match_pins $0 (null)\n" + "match_pins BULK (null)\n" "match_devices $1 $1\n" "match_devices $2 $2\n" "match_devices $3 $3\n" @@ -4224,21 +4302,21 @@ TEST(24_NodesRemovedButConnectedInOther) "end_circuit INV2 INV2 MATCH\n" "begin_circuit INV2PAIR INV2PAIR\n" "match_nets $I2 $I2\n" - "match_nets $I5 $I6\n" - "match_nets $I4 $I5\n" - "match_nets $I6 $I4\n" + "match_nets $I6 $I5\n" + "match_nets $I5 $I4\n" + "match_nets $I4 $I6\n" "match_nets $I3 $I3\n" "match_nets $I7 $I7\n" "match_nets $I8 $I8\n" - "match_nets (null) BULK\n" - "match_nets (null) $I1\n" - "match_pins $0 $1\n" - "match_pins $1 $2\n" - "match_pins $2 $3\n" - "match_pins $3 $4\n" - "match_pins $4 $5\n" - "match_pins (null) BULK\n" - "match_pins (null) $6\n" + "match_nets BULK (null)\n" + "match_nets $I1 (null)\n" + "match_pins $1 $0\n" + "match_pins $2 $1\n" + "match_pins $3 $2\n" + "match_pins $4 $3\n" + "match_pins $5 $4\n" + "match_pins BULK (null)\n" + "match_pins $6 (null)\n" "match_subcircuits $1 $1\n" "match_subcircuits $2 $2\n" "end_circuit INV2PAIR INV2PAIR MATCH\n" @@ -4247,7 +4325,7 @@ TEST(24_NodesRemovedButConnectedInOther) "match_nets $I7 $I7\n" "match_nets $I6 $I6\n" "match_nets $I5 $I5\n" - "match_nets $I21 $I13\n" + "match_nets $I13 $I21\n" "match_nets FB FB\n" "match_nets VSS VSS\n" "match_nets VDD VDD\n" @@ -4267,6 +4345,62 @@ TEST(24_NodesRemovedButConnectedInOther) "end_circuit RINGO RINGO MATCH" ); EXPECT_EQ (good, true); + + + logger.clear (); + good = comp.compare (&nl2, &nl1); + + txt = logger.text (); + + // NOTE: additional nets are ignored in the first netlist but not from the second + EXPECT_EQ (txt, + "begin_circuit INV2 INV2\n" + "match_nets VDD VDD\n" + "match_nets OUT OUT\n" + "match_nets $3 $3\n" + "match_nets IN IN\n" + "match_nets VSS VSS\n" + "match_nets (null) $1\n" + "match_nets (null) BULK\n" + "match_pins IN IN\n" + "match_pins $1 $2\n" + "match_pins OUT OUT\n" + "match_pins VSS VSS\n" + "match_pins VDD VDD\n" + "match_pins (null) $0\n" + "match_pins (null) BULK\n" + "match_devices $1 $1\n" + "match_devices $2 $2\n" + "match_devices $3 $3\n" + "match_devices $4 $4\n" + "end_circuit INV2 INV2 MATCH\n" + "begin_circuit INV2PAIR INV2PAIR\n" + "match_nets $I2 $I2\n" + "match_nets $I5 $I6\n" + "match_nets $I8 $I8\n" + "match_nets $I7 $I7\n" + "net_mismatch $I6 $I4\n" + "net_mismatch $I4 (null)\n" + "net_mismatch $I3 (null)\n" + "net_mismatch (null) BULK\n" + "net_mismatch (null) $I5\n" + "net_mismatch (null) $I3\n" + "net_mismatch (null) $I1\n" + "match_pins $0 $1\n" + "match_pins $1 $2\n" + "match_pins $4 $5\n" + "pin_mismatch $2 (null)\n" + "pin_mismatch $3 (null)\n" + "pin_mismatch (null) BULK\n" + "pin_mismatch (null) $3\n" + "pin_mismatch (null) $4\n" + "pin_mismatch (null) $6\n" + "subcircuit_mismatch $1 $1\n" + "subcircuit_mismatch $2 $2\n" + "end_circuit INV2PAIR INV2PAIR NOMATCH\n" + "circuit_skipped RINGO RINGO" + ); + EXPECT_EQ (good, false); } TEST(25_JoinSymmetricNets)