From 8121f70e65921618aec5bdf1257f8af252b56db5 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 18 Apr 2019 00:01:21 +0200 Subject: [PATCH] Netlist compare: Net mismatches reported if nets don't match but we still will proceed --- src/db/db/dbNetlistCompare.cc | 225 ++++++++++++++++----- src/db/db/dbNetlistCompare.h | 3 + src/db/db/gsiDeclDbNetlistCompare.cc | 4 + src/db/unit_tests/dbNetlistCompareTests.cc | 72 +++---- testdata/ruby/dbNetlistCompare.rb | 16 +- 5 files changed, 230 insertions(+), 90 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 20b5ac5ad..344f9e1b5 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -38,6 +38,13 @@ namespace db // -------------------------------------------------------------------------------------------------------------------- // DeviceCompare definition and implementation +/** + * @brief The device compare function with "less" (operator()) and "equal" predicates + * + * Device comparison is based on the equivalence of device classes (by category) and + * in a second step, by equivalence of the devices. The device class will implement + * the device equivalence function. + */ struct DeviceCompare { bool operator() (const std::pair &d1, const std::pair &d2) const @@ -60,6 +67,12 @@ struct DeviceCompare // -------------------------------------------------------------------------------------------------------------------- // SubCircuitCompare definition and implementation +/** + * @brief The compare function for subcircuits + * + * As Subcircuits are not parametrized, the comparison of subcircuits is only based on + * the circuit equivalence (via category). + */ struct SubCircuitCompare { bool operator() (const std::pair &sc1, const std::pair &sc2) const @@ -76,6 +89,14 @@ struct SubCircuitCompare // -------------------------------------------------------------------------------------------------------------------- // CircuitPinMapper definition and implementation +/** + * @brief The Circuit pin mapper handles swappable pin definitions per circuit + * + * Swappable pins are implemented by mapping a pin ID to an equivalent or + * effective ID which is shared by all swappable pins. + * + * This class manages swappable pins on a per-circuit basis. + */ class CircuitPinMapper { public: @@ -130,6 +151,15 @@ private: // -------------------------------------------------------------------------------------------------------------------- // CircuitMapper definition and implementation +/** + * @brief A circuit mapper + * + * The circuit mapper handles the circuit equivalence between the circuits of + * netlist A and B and also the pin mapping between the circuits from these netlists. + * + * The "other" attribute will hold the circuit for the other netlist. + * The other methods handle pin mapping from "other" into "this" pin space. + */ class CircuitMapper { public: @@ -187,6 +217,13 @@ private: // -------------------------------------------------------------------------------------------------------------------- // DeviceFilter definition and implementation +/** + * @brief A device filter class + * + * This class implements a device filter which is used to skip devices when + * generating the net graph. This is useful for stripping small caps or big + * resistors. + */ class DeviceFilter { public: @@ -221,6 +258,12 @@ private: // -------------------------------------------------------------------------------------------------------------------- // DeviceCategorizer definition and implementation +/** + * @brief A device categorizer + * + * The objective of this class is to supply a category ID for a given device class. + * The category ID also identities equivalent device classes from netlist A and B. + */ class DeviceCategorizer { public: @@ -280,6 +323,12 @@ public: // -------------------------------------------------------------------------------------------------------------------- // CircuitCategorizer definition and implementation +/** + * @brief A circuit categorizer + * + * The objective of this class is to supply a category ID for a given device circuit. + * The category ID also identities equivalent circuit from netlist A and B. + */ class CircuitCategorizer { public: @@ -332,19 +381,39 @@ public: }; // -------------------------------------------------------------------------------------------------------------------- -// NetDeviceGraphNode definition and implementation +// NetGraphNode definition and implementation static size_t translate_terminal_id (size_t tid, const db::Device *device) { return device->device_class () ? device->device_class ()->normalize_terminal_id (tid) : tid; } +/** + * @brief A node within the net graph + * + * This class represents a node and the edges leading from this node to + * other nodes. + * + * A graph edge is a collection of transitions, connecting terminals of + * devices or pins of subcircuits plus the index of node at the other end + * of the edge. + * + * Transitions are sorted within the edge. + */ class NetGraphNode { public: - struct EdgeDesc { + /** + * @brief Represents one transition within an edge_iterator + * + * Each transition connects two pins of subcircuits or terminals + * of devices. + * An edge is basically a collection of transitions. + */ + struct Transition + { - EdgeDesc (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id) + Transition (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id) { device_pair ().first = device; device_pair ().second = device_category; @@ -352,7 +421,7 @@ public: m_id2 = terminal2_id; } - EdgeDesc (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id) + Transition (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id) { subcircuit_pair ().first = subcircuit; subcircuit_pair ().second = subcircuit_category; @@ -360,7 +429,7 @@ public: m_id2 = pin2_id; } - bool operator< (const EdgeDesc &other) const + bool operator< (const Transition &other) const { if (is_for_subcircuit () != other.is_for_subcircuit ()) { return is_for_subcircuit () < other.is_for_subcircuit (); @@ -400,7 +469,7 @@ public: return m_id2 < other.m_id2; } - bool operator== (const EdgeDesc &other) const + bool operator== (const Transition &other) const { if (is_for_subcircuit () != other.is_for_subcircuit ()) { return false; @@ -469,13 +538,13 @@ public: struct EdgeToEdgeOnlyCompare { - bool operator() (const std::pair, std::pair > &a, const std::vector &b) const + bool operator() (const std::pair, std::pair > &a, const std::vector &b) const { return a.first < b; } }; - typedef std::vector, std::pair > >::const_iterator edge_iterator; + typedef std::vector, std::pair > >::const_iterator edge_iterator; NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map) : mp_net (net), m_other_net_index (std::numeric_limits::max ()) @@ -560,14 +629,14 @@ public: // NOTE: if a pin mapping is given, EdgeDesc::pin1_id and EdgeDesc::pin2_id are given // as pin ID's of the other circuit. - EdgeDesc ed (sc, circuit_categorizer.cat_for_subcircuit (sc), pin_id, pin_map->normalize_pin_id (cr, pin2_id)); + Transition ed (sc, circuit_categorizer.cat_for_subcircuit (sc), pin_id, pin_map->normalize_pin_id (cr, pin2_id)); const db::Net *net2 = sc->net_for_pin (this_pin2_id); std::map::const_iterator in = n2entry.find (net2); if (in == n2entry.end ()) { in = n2entry.insert (std::make_pair (net2, m_edges.size ())).first; - m_edges.push_back (std::make_pair (std::vector (), std::make_pair (size_t (0), net2))); + m_edges.push_back (std::make_pair (std::vector (), std::make_pair (size_t (0), net2))); } m_edges [in->second].first.push_back (ed); @@ -592,14 +661,14 @@ public: if (it->id () != i->terminal_id ()) { size_t terminal2_id = translate_terminal_id (it->id (), d); - EdgeDesc ed2 (d, device_cat, terminal1_id, terminal2_id); + Transition ed2 (d, device_cat, terminal1_id, terminal2_id); const db::Net *net2 = d->net_for_terminal (it->id ()); std::map::const_iterator in = n2entry.find (net2); if (in == n2entry.end ()) { in = n2entry.insert (std::make_pair (net2, m_edges.size ())).first; - m_edges.push_back (std::make_pair (std::vector (), std::make_pair (size_t (0), net2))); + m_edges.push_back (std::make_pair (std::vector (), std::make_pair (size_t (0), net2))); } m_edges [in->second].first.push_back (ed2); @@ -643,14 +712,14 @@ public: void apply_net_index (const std::map &ni) { - for (std::vector, std::pair > >::iterator i = m_edges.begin (); i != m_edges.end (); ++i) { + for (std::vector, std::pair > >::iterator i = m_edges.begin (); i != m_edges.end (); ++i) { std::map::const_iterator j = ni.find (i->second.second); tl_assert (j != ni.end ()); i->second.first = j->second; } // "deep sorting" of the edge descriptor - for (std::vector, std::pair > >::iterator i = m_edges.begin (); i != m_edges.end (); ++i) { + for (std::vector, std::pair > >::iterator i = m_edges.begin (); i != m_edges.end (); ++i) { std::sort (i->first.begin (), i->first.end ()); } @@ -708,7 +777,7 @@ public: return m_edges.end (); } - edge_iterator find_edge (const std::vector &edge) const + edge_iterator find_edge (const std::vector &edge) const { edge_iterator res = std::lower_bound (begin (), end (), edge, NetGraphNode::EdgeToEdgeOnlyCompare ()); if (res == end () || res->first != edge) { @@ -721,7 +790,7 @@ public: private: const db::Net *mp_net; size_t m_other_net_index; - std::vector, std::pair > > m_edges; + std::vector, std::pair > > m_edges; /** * @brief Compares edges as "less" @@ -777,7 +846,7 @@ private: }; // -------------------------------------------------------------------------------------------------------------------- -// NetDeviceGraph definition and implementation +// NetGraph definition and implementation } @@ -802,18 +871,27 @@ struct CompareNodePtr class TentativeNodeMapping; -class NetDeviceGraph +/** + * @brief The net graph for the compare algorithm + */ +class NetGraph { public: typedef std::vector::const_iterator node_iterator; - NetDeviceGraph () + NetGraph () { // .. nothing yet .. } + /** + * @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); + /** + * @brief Gets the node index for the given net + */ size_t node_index_for_net (const db::Net *net) const { std::map::const_iterator j = m_net_index.find (net); @@ -821,31 +899,65 @@ public: return j->second; } + /** + * @brief Gets the node for a given node index + */ + const db::NetGraphNode &node (size_t net_index) const + { + return m_nodes [net_index]; + } + + /** + * @brief Gets the node for a given node index (non-const version) + */ + db::NetGraphNode &node (size_t net_index) + { + return m_nodes [net_index]; + } + + /** + * @brief Gets the net for a given node index + */ const db::Net *net_by_node_index (size_t net_index) const { return m_nodes [net_index].net (); } + /** + * @brief Establishes an equivalence between two nodes of netlist A (this) and B (other) + */ void identify (size_t net_index, size_t other_net_index) { m_nodes [net_index].set_other_net (other_net_index); } + /** + * @brief Removes the equivalence from the node with the given index + */ void unidentify (size_t net_index) { m_nodes [net_index].unset_other_net (); } + /** + * @brief Iterator over the nodes in this graph (begin) + */ node_iterator begin () const { return m_nodes.begin (); } + /** + * @brief Iterator over the nodes in this graph (end) + */ node_iterator end () const { return m_nodes.end (); } + /** + * @brief The circuit this graph is associated with + */ const db::Circuit *circuit () const { return mp_circuit; @@ -870,14 +982,22 @@ public: * backtracking depth (number of graph jumps) and decision tree * branching complexity N (="n_branch", means: N*N decisions to be made). * - * The limits "depth_max" and "n_branch_max" are attributes of the graph. + * If "tentative" is non-null, assignments will be recorded in the TentativeMapping + * audit object and can be undone afterwards when backtracking recursion happens. * - * If tentative is true, assignments will not be retained and just the - * status is reported. + * If "with_ambiguous" is true, ambiguous matches are considered. This will happen + * in a second pass to give exact and unique matches priority over ambiguous matches. */ - size_t derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous); + size_t derive_node_identities (size_t net_index, NetGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous); - size_t derive_node_identities_from_node_set (const std::vector &nodes, const std::vector &other_nodes, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous); + /** + * @brief The backtracking driver + * + * This method will analyze the given nodes and call "derive_node_identities" for all nodes + * with a proposed identity. With "with_ambiguous", amiguities are resolved by trying + * different combinations in tentative mode and deciding for one combination if possible. + */ + size_t derive_node_identities_from_node_set (const std::vector &nodes, const std::vector &other_nodes, NetGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous); private: std::vector m_nodes; @@ -887,6 +1007,9 @@ private: // -------------------------------------------------------------------------------------------------------------------- +/** + * @brief Represents an interval of NetGraphNode objects in a node set + */ struct NodeRange { NodeRange (size_t _num, std::vector::const_iterator _n1, std::vector::const_iterator _nn1, std::vector::const_iterator _n2, std::vector::const_iterator _nn2) @@ -906,10 +1029,13 @@ struct NodeRange // -------------------------------------------------------------------------------------------------------------------- +/** + * @brief An audit object which allows reverting tentative node assignments + */ class TentativeNodeMapping { public: - TentativeNodeMapping (NetDeviceGraph *g1, NetDeviceGraph *g2) + TentativeNodeMapping (NetGraph *g1, NetGraph *g2) : mp_g1 (g1), mp_g2 (g2) { } @@ -921,7 +1047,7 @@ public: } } - static void map_pair (TentativeNodeMapping *nm, NetDeviceGraph *g1, size_t n1, NetDeviceGraph *g2, size_t n2) + static void map_pair (TentativeNodeMapping *nm, NetGraph *g1, size_t n1, NetGraph *g2, size_t n2) { g1->identify (n1, n2); g2->identify (n2, n1); @@ -932,7 +1058,7 @@ public: private: std::vector > m_to_undo; - NetDeviceGraph *mp_g1, *mp_g2; + NetGraph *mp_g1, *mp_g2; void keep (size_t n1, size_t n2) { @@ -941,9 +1067,10 @@ private: }; // -------------------------------------------------------------------------------------------------------------------- +// NetGraph implementation void -NetDeviceGraph::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) { tl::SelfTimer timer (tl::verbosity () >= 31, tl::to_string (tr ("Building net graph for circuit: ")) + c->name ()); @@ -979,10 +1106,10 @@ NetDeviceGraph::build (const db::Circuit *c, DeviceCategorizer &device_categoriz } size_t -NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous) +NetGraph::derive_node_identities (size_t net_index, NetGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous) { - NetGraphNode *n = & m_nodes[net_index]; - NetGraphNode *nother = & other.m_nodes[n->other_net_index ()]; + NetGraphNode *n = & node (net_index); + NetGraphNode *nother = & other.node (n->other_net_index ()); #if defined(PRINT_DEBUG_NETCOMPARE) std::string indent; @@ -1018,7 +1145,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, other_nodes.reserve (ee - e); for (NetGraphNode::edge_iterator i = e; i != ee; ++i) { - const NetGraphNode *n = &m_nodes[i->second.first]; + const NetGraphNode *n = &node (i->second.first); nodes.push_back (n); } @@ -1037,7 +1164,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t count_other = 0; for (NetGraphNode::edge_iterator i = e_other; i != ee_other && count_other < 2; ++i) { - const NetGraphNode *n = &other.m_nodes[i->second.first]; + const NetGraphNode *n = &other.node (i->second.first); other_nodes.push_back (n); } @@ -1099,7 +1226,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, } size_t -NetDeviceGraph::derive_node_identities_from_node_set (const std::vector &nodes, const std::vector &other_nodes, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous) +NetGraph::derive_node_identities_from_node_set (const std::vector &nodes, const std::vector &other_nodes, NetGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous) { #if defined(PRINT_DEBUG_NETCOMPARE) std::string indent; @@ -1133,8 +1260,11 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vectornet ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name (); #endif - if (! tentative) { - if (logger) { + if (logger && ! tentative) { + if (! (node (ni) == other.node (other_ni))) { + // this is a mismatch but we continue, because that is the only candidate + logger->net_mismatch (nodes.front ()->net (), other_nodes.front ()->net ()); + } else { logger->match_nets (nodes.front ()->net (), other_nodes.front ()->net ()); } } @@ -1279,8 +1409,11 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vectorn1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); #endif - if (! tentative) { - if (logger) { + if (logger && ! tentative) { + if (! (node (ni) == other.node (other_ni))) { + // this is a mismatch, but we continue with this + logger->net_mismatch ((*nr->n1)->net (), (*nr->n2)->net ()); + } else { logger->match_nets ((*nr->n1)->net (), (*nr->n2)->net ()); } } @@ -1694,7 +1827,7 @@ NetlistComparer::all_subcircuits_verified (const db::Circuit *c, const std::set< } static std::vector > -compute_device_key (const db::Device &device, const db::NetDeviceGraph &g) +compute_device_key (const db::Device &device, const db::NetGraph &g) { std::vector > k; @@ -1712,7 +1845,7 @@ compute_device_key (const db::Device &device, const db::NetDeviceGraph &g) } static std::vector > -compute_subcircuit_key (const db::SubCircuit &subcircuit, const db::NetDeviceGraph &g, const std::map *circuit_map, const CircuitPinMapper *pin_map) +compute_subcircuit_key (const db::SubCircuit &subcircuit, const db::NetGraph &g, const std::map *circuit_map, const CircuitPinMapper *pin_map) { std::vector > k; @@ -1755,7 +1888,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, { db::DeviceFilter device_filter (m_cap_threshold, m_res_threshold); - db::NetDeviceGraph g1, g2; + db::NetGraph g1, g2; // NOTE: for normalization we map all subcircuits of c1 to c2. // Also, pin swapping will only happen there. @@ -1800,7 +1933,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, size_t new_identities = 0; - for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { + for (db::NetGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { if (i1->has_other () && i1->net ()) { size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, m_max_depth, 1, m_max_n_branch, mp_logger, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/); if (ni > 0 && ni != std::numeric_limits::max ()) { @@ -1821,14 +1954,14 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, std::vector nodes, other_nodes; nodes.reserve (g1.end () - g1.begin ()); - for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { + for (db::NetGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { if (! i1->has_other () && i1->net ()) { nodes.push_back (i1.operator-> ()); } } other_nodes.reserve (g2.end () - g2.begin ()); - for (db::NetDeviceGraph::node_iterator i2 = g2.begin (); i2 != g2.end (); ++i2) { + for (db::NetGraph::node_iterator i2 = g2.begin (); i2 != g2.end (); ++i2) { if (! i2->has_other () && i2->net ()) { other_nodes.push_back (i2.operator-> ()); } @@ -1864,13 +1997,13 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, // Report missing net assignment - for (db::NetDeviceGraph::node_iterator i = g1.begin (); i != g1.end (); ++i) { + for (db::NetGraph::node_iterator i = g1.begin (); i != g1.end (); ++i) { if (! i->has_other () && mp_logger) { mp_logger->net_mismatch (i->net (), 0); } } - for (db::NetDeviceGraph::node_iterator i = g2.begin (); i != g2.end (); ++i) { + for (db::NetGraph::node_iterator i = g2.begin (); i != g2.end (); ++i) { if (! i->has_other () && mp_logger) { mp_logger->net_mismatch (0, i->net ()); } diff --git a/src/db/db/dbNetlistCompare.h b/src/db/db/dbNetlistCompare.h index c2946a997..1de9af01c 100644 --- a/src/db/db/dbNetlistCompare.h +++ b/src/db/db/dbNetlistCompare.h @@ -99,6 +99,9 @@ public: /** * @brief Net a or b doesn't match * "a" is null if there is no match for b and vice versa. + * In some cases, a mismatch is reported with two nets given. This means, + * nets are known not to match. Still the compare algorithm will proceed as + * if these nets were equivalent to derive further matches. */ virtual void net_mismatch (const db::Net * /*a*/, const db::Net * /*b*/) { } diff --git a/src/db/db/gsiDeclDbNetlistCompare.cc b/src/db/db/gsiDeclDbNetlistCompare.cc index e5a652ecb..773b7cccc 100644 --- a/src/db/db/gsiDeclDbNetlistCompare.cc +++ b/src/db/db/gsiDeclDbNetlistCompare.cc @@ -374,6 +374,10 @@ Class decl_GenericNetlistCompareLogger ("db", "Gene "@brief This function is called when a net can't be paired.\n" "This method will be called, if a net cannot be identified as identical with another net. The corresponding argument " "will identify the net and source netlist. The other argument will be nil.\n" + "\n" + "In some cases, a mismatch is reported with two nets given. This means,\n" + "nets are known not to match. Still the compare algorithm will proceed as\n" + "if these nets were equivalent to derive further matches.\n" ) + gsi::callback ("match_devices", &GenericNetlistCompareLogger::match_devices, &GenericNetlistCompareLogger::cb_match_devices, gsi::arg ("a"), gsi::arg ("b"), "@brief This function is called when two devices are identified.\n" diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 289bec5c5..bd6476908 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -438,9 +438,9 @@ TEST(1_SimpleInverterSkippedDevices) EXPECT_EQ (logger.text (), "begin_circuit INV INV\n" "match_nets VDD VDD\n" - "match_nets OUT OUT\n" + "net_mismatch OUT OUT\n" "match_nets VSS VSS\n" - "match_nets IN IN\n" + "net_mismatch IN IN\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -670,8 +670,8 @@ TEST(5_BufferTwoPathsDifferentParameters) "begin_circuit BUF BUF\n" "match_nets OUT OUT\n" "match_nets INT $10\n" - "match_nets IN IN\n" - "match_nets INT2 $11\n" + "net_mismatch IN IN\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -722,8 +722,8 @@ TEST(5_BufferTwoPathsDifferentParameters) "begin_circuit BUF BUF\n" "match_nets OUT OUT\n" "match_nets INT $10\n" - "match_nets IN IN\n" - "match_nets INT2 $11\n" + "net_mismatch IN IN\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -748,8 +748,8 @@ TEST(5_BufferTwoPathsDifferentParameters) "begin_circuit BUF BUF\n" "match_nets OUT OUT\n" "match_nets INT $10\n" - "match_nets IN IN\n" - "match_nets INT2 $11\n" + "net_mismatch IN IN\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -828,8 +828,8 @@ TEST(5_BufferTwoPathsDifferentParameters) "begin_circuit BUF BUF\n" "match_nets OUT OUT\n" "match_nets INT $10\n" - "match_nets IN IN\n" - "match_nets INT2 $11\n" + "net_mismatch IN IN\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -892,8 +892,8 @@ TEST(5_BufferTwoPathsDifferentDeviceClasses) "begin_circuit BUF BUF\n" "match_nets INT $10\n" "match_nets IN IN\n" - "match_nets OUT OUT\n" - "match_nets INT2 $11\n" + "net_mismatch OUT OUT\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -955,10 +955,10 @@ TEST(6_BufferTwoPathsAdditionalResistor) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" - "match_nets INT $10\n" + "net_mismatch INT $10\n" "match_nets IN IN\n" "match_nets OUT OUT\n" - "match_nets INT2 $11\n" + "net_mismatch INT2 $11\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -1017,11 +1017,11 @@ TEST(6_BufferTwoPathsAdditionalDevices) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" "match_nets INT $11\n" - "match_nets VDD VDD\n" + "net_mismatch VDD VDD\n" "match_nets IN IN\n" - "match_nets VSS VSS\n" - "match_nets OUT OUT\n" - "match_nets INT2 $10\n" + "net_mismatch VSS VSS\n" + "net_mismatch OUT OUT\n" + "net_mismatch INT2 $10\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -1110,8 +1110,8 @@ TEST(7_ResistorsParameterMismatch) EXPECT_EQ (logger.text (), "begin_circuit TRIANGLE TRIANGLE\n" "match_nets P2 P2\n" - "match_nets P1 P1\n" - "match_nets P3 P3\n" + "net_mismatch P1 P1\n" + "net_mismatch P3 P3\n" "match_pins $0 $0\n" "match_pins $1 $1\n" "match_pins $2 $2\n" @@ -1152,8 +1152,8 @@ TEST(7_ResistorsPlusOneDevice) EXPECT_EQ (logger.text (), "begin_circuit TRIANGLE TRIANGLE\n" "match_nets P3 P3\n" - "match_nets P2 P2\n" - "match_nets P1 P1\n" + "net_mismatch P2 P2\n" + "net_mismatch P1 P1\n" "match_pins $0 $0\n" "match_pins $1 $1\n" "match_pins $2 $2\n" @@ -1235,8 +1235,8 @@ TEST(8_DiodesDontMatchOnSwappedPins) EXPECT_EQ (logger.text (), "begin_circuit TRIANGLE TRIANGLE\n" "match_nets P1 P3\n" - "match_nets P2 P1\n" - "match_nets P3 P2\n" + "net_mismatch P2 P1\n" + "net_mismatch P3 P2\n" "match_pins $0 $2\n" "match_pins $1 $0\n" "match_pins $2 $1\n" @@ -1413,9 +1413,9 @@ TEST(11_MismatchingSubcircuits) EXPECT_EQ (logger.text (), "begin_circuit INV INV\n" "match_nets VSS VSS\n" - "match_nets OUT OUT\n" - "match_nets IN IN\n" - "match_nets VDD VDD\n" + "net_mismatch OUT OUT\n" + "net_mismatch IN IN\n" + "net_mismatch VDD VDD\n" "match_pins $0 $1\n" "match_pins $1 $3\n" "match_pins $2 $0\n" @@ -1489,10 +1489,10 @@ TEST(12_MismatchingSubcircuitsDuplicates) "end_circuit INV INV MATCH\n" "begin_circuit TOP TOP\n" "match_nets IN IN\n" - "match_nets VDD VDD\n" - "match_nets VSS VSS\n" - "match_nets INT INT\n" - "match_nets OUT OUT\n" + "net_mismatch VDD VDD\n" + "net_mismatch VSS VSS\n" + "net_mismatch INT INT\n" + "net_mismatch OUT OUT\n" "match_pins $0 $1\n" "match_pins $1 $0\n" "match_pins $2 $2\n" @@ -1703,11 +1703,11 @@ TEST(14_Subcircuit2NandMismatchNoSwap) "end_circuit NAND NAND MATCH\n" "begin_circuit TOP TOP\n" "match_nets OUT OUT\n" - "match_nets IN1 INT\n" - "match_nets INT IN1\n" - "match_nets VDD VDD\n" - "match_nets VSS VSS\n" - "match_nets IN2 IN2\n" + "net_mismatch IN1 INT\n" + "net_mismatch INT IN1\n" + "net_mismatch VDD VDD\n" + "net_mismatch VSS VSS\n" + "net_mismatch IN2 IN2\n" "pin_mismatch $0 (null)\n" "match_pins $1 $1\n" "match_pins $2 $2\n" diff --git a/testdata/ruby/dbNetlistCompare.rb b/testdata/ruby/dbNetlistCompare.rb index f51bfd979..59a6910c9 100644 --- a/testdata/ruby/dbNetlistCompare.rb +++ b/testdata/ruby/dbNetlistCompare.rb @@ -461,8 +461,8 @@ END begin_circuit BUF BUF match_nets OUT OUT match_nets INT $10 -match_nets IN IN -match_nets INT2 $11 +net_mismatch IN IN +net_mismatch INT2 $11 match_pins $0 $1 match_pins $1 $3 match_pins $2 $0 @@ -616,8 +616,8 @@ END begin_circuit BUF BUF match_nets INT $10 match_nets IN IN -match_nets OUT OUT -match_nets INT2 $11 +net_mismatch OUT OUT +net_mismatch INT2 $11 match_pins $0 $1 match_pins $1 $3 match_pins $2 $0 @@ -684,10 +684,10 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF -match_nets INT $10 +net_mismatch INT $10 match_nets IN IN match_nets OUT OUT -match_nets INT2 $11 +net_mismatch INT2 $11 match_pins $0 $1 match_pins $1 $3 match_pins $2 $0 @@ -945,9 +945,9 @@ END assert_equal(logger.text(), <<"END") begin_circuit INV INV match_nets VDD VDD -match_nets OUT OUT +net_mismatch OUT OUT match_nets VSS VSS -match_nets IN IN +net_mismatch IN IN match_pins $0 $1 match_pins $1 $3 match_pins $2 $0