From 65ea72c56920e9ead87ec58c187022487e15b314 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 16 May 2019 23:26:49 +0200 Subject: [PATCH] WIP: netlist cross reference - refactoring of sorting, more robust --- src/db/db/dbNetlistCrossReference.cc | 195 +++++++++++++-------- src/db/db/dbNetlistCrossReference.h | 8 + src/db/unit_tests/dbNetlistCompareTests.cc | 24 +-- 3 files changed, 139 insertions(+), 88 deletions(-) diff --git a/src/db/db/dbNetlistCrossReference.cc b/src/db/db/dbNetlistCrossReference.cc index 6bc39e1f2..9657665c3 100644 --- a/src/db/db/dbNetlistCrossReference.cc +++ b/src/db/db/dbNetlistCrossReference.cc @@ -98,86 +98,129 @@ NetlistCrossReference::begin_netlist (const db::Netlist *a, const db::Netlist *b namespace { +static int string_value_compare (const std::string &a, const std::string &b) +{ + return a == b ? 0 : (a < b ? -1 : 1); +} + +template +struct by_name_value_compare +{ + int operator() (const Obj &a, const Obj &b) const + { + return string_value_compare (a.name (), b.name ()); + } +}; + +template +struct by_expanded_name_value_compare +{ + int operator() (const Obj &a, const Obj &b) const + { + return string_value_compare (a.expanded_name (), b.expanded_name ()); + } +}; + +template +struct net_object_compare; + +template <> +struct net_object_compare +{ + int operator() (const db::NetTerminalRef &a, const db::NetTerminalRef &b) const + { + int ct = by_expanded_name_value_compare () (*a.device (), *b.device ()); + if (ct == 0) { + return (a.terminal_id () != b.terminal_id () ? (a.terminal_id () < b.terminal_id () ? -1 : 1) : 0); + } else { + return ct; + } + } +}; + +template <> +struct net_object_compare +{ + int operator() (const db::NetSubcircuitPinRef &a, const db::NetSubcircuitPinRef &b) const + { + int ct = by_expanded_name_value_compare () (*a.subcircuit (), *b.subcircuit ()); + if (ct == 0) { + return by_expanded_name_value_compare () (*a.pin (), *b.pin ()); + } else { + return ct; + } + } +}; + +template <> +struct net_object_compare +{ + int operator() (const db::NetPinRef &a, const db::NetPinRef &b) const + { + return by_expanded_name_value_compare () (*a.pin (), *b.pin ()); + } +}; + +template +struct two_pointer_compare +{ + int operator() (const Obj *a, const Obj *b) const + { + if ((a == 0) != (b == 0)) { + return (a == 0) > (b == 0) ? -1 : 1; + } + if (a != 0) { + return ValueCompare () (*a, *b); + } else { + return 0; + } + } +}; + +template +struct two_pair_compare +{ + bool operator() (const std::pair &a, const std::pair &b) + { + int ct = two_pointer_compare () (a.first, b.first); + if (ct != 0) { + return ct < 0; + } + return two_pointer_compare () (a.second, b.second) < 0; + } +}; + +template +struct pair_data_compare +{ + bool operator () (const PairData &a, const PairData &b) const + { + return two_pair_compare () (a.pair, b.pair); + } +}; + struct CircuitsCompareByName + : public two_pair_compare > { - bool operator() (const std::pair &a, const std::pair &b) - { - if ((a.first == 0) != (b.first == 0)) { - return (a.first == 0) > (b.first == 0); - } - if (a.first != 0 && a.first->name () != b.first->name ()) { - return a.first->name () < b.first->name (); - } - if ((a.second == 0) != (b.second == 0)) { - return (a.second == 0) > (b.second == 0); - } - if (a.second != 0 && a.second->name () != b.second->name ()) { - return a.second->name () < b.second->name (); - } - return false; - } + // .. nothing yet .. }; -struct SortNetTerminalsByTerminalId +struct SortNetTerminals + : public two_pair_compare > { - bool operator() (const std::pair &a, const std::pair &b) - { - if ((a.first == 0) != (b.first == 0)) { - return (a.first == 0) > (b.first == 0); - } - if (a.first != 0 && a.first->terminal_id () != b.first->terminal_id ()) { - return a.first->terminal_id () < b.first->terminal_id (); - } - if ((a.second == 0) != (b.second == 0)) { - return (a.second == 0) > (b.second == 0); - } - if (a.second != 0 && a.second->terminal_id () != b.second->terminal_id ()) { - return a.second->terminal_id () < b.second->terminal_id (); - } - return false; - } + // .. nothing yet .. }; -template -struct sort_data_pairs_by_pin_name +struct SortNetPins + : public two_pair_compare > { - bool operator() (const std::pair &a, const std::pair &b) - { - if ((a.first == 0) != (b.first == 0)) { - return (a.first == 0) > (b.first == 0); - } - if (a.first != 0 && a.first->pin ()->expanded_name () != b.first->pin ()->expanded_name ()) { - return a.first->pin ()->expanded_name () < b.first->pin ()->expanded_name (); - } - if ((a.second == 0) != (b.second == 0)) { - return (a.second == 0) > (b.second == 0); - } - if (a.second != 0 && a.second->pin ()->expanded_name () != b.second->pin ()->expanded_name ()) { - return a.second->pin ()->expanded_name () < b.second->pin ()->expanded_name (); - } - return false; - } + // .. nothing yet .. }; -template -struct sort_pair_data_by_expanded_name +struct SortNetSubCircuitPins + : public two_pair_compare > { - bool operator() (const PairData &a, const PairData &b) const - { - if ((a.pair.first == 0) != (b.pair.first == 0)) { - return (a.pair.first == 0) > (b.pair.first == 0); - } - if (a.pair.first != 0 && a.pair.first->expanded_name () != b.pair.first->expanded_name ()) { - return a.pair.first->expanded_name () < b.pair.first->expanded_name (); - } - if ((a.pair.second == 0) != (b.pair.second == 0)) { - return (a.pair.second == 0) > (b.pair.second == 0); - } - if (a.pair.second != 0 && a.pair.second->expanded_name () != b.pair.second->expanded_name ()) { - return a.pair.second->expanded_name () < b.pair.second->expanded_name (); - } - return false; - } + // .. nothing yet .. }; } @@ -272,10 +315,10 @@ NetlistCrossReference::end_circuit (const db::Circuit *, const db::Circuit *, bo { mp_per_circuit_data->status = matching ? Match : NoMatch; - std::sort (mp_per_circuit_data->devices.begin (), mp_per_circuit_data->devices.end (), sort_pair_data_by_expanded_name ()); - std::sort (mp_per_circuit_data->pins.begin (), mp_per_circuit_data->pins.end (), sort_pair_data_by_expanded_name ()); - std::sort (mp_per_circuit_data->subcircuits.begin (), mp_per_circuit_data->subcircuits.end (), sort_pair_data_by_expanded_name ()); - std::sort (mp_per_circuit_data->nets.begin (), mp_per_circuit_data->nets.end (), sort_pair_data_by_expanded_name ()); + std::sort (mp_per_circuit_data->devices.begin (), mp_per_circuit_data->devices.end (), pair_data_compare > ()); + std::sort (mp_per_circuit_data->pins.begin (), mp_per_circuit_data->pins.end (), pair_data_compare > ()); + std::sort (mp_per_circuit_data->subcircuits.begin (), mp_per_circuit_data->subcircuits.end (), pair_data_compare > ()); + std::sort (mp_per_circuit_data->nets.begin (), mp_per_circuit_data->nets.end (), pair_data_compare > ()); m_current_circuits = std::pair (0, 0); mp_per_circuit_data = 0; @@ -442,7 +485,7 @@ NetlistCrossReference::build_terminal_refs (const std::pairsecond)); } - std::sort (data.terminals.begin (), data.terminals.end (), SortNetTerminalsByTerminalId ()); + std::sort (data.terminals.begin (), data.terminals.end (), SortNetTerminals ()); } void @@ -486,7 +529,7 @@ NetlistCrossReference::build_pin_refs (const std::pairsecond)); } - std::sort (data.pins.begin (), data.pins.end (), sort_data_pairs_by_pin_name ()); + std::sort (data.pins.begin (), data.pins.end (), SortNetPins ()); } void @@ -539,7 +582,7 @@ NetlistCrossReference::build_subcircuit_pin_refs (const std::pairsecond)); } - std::sort (data.subcircuit_pins.begin (), data.subcircuit_pins.end (), sort_data_pairs_by_pin_name ()); + std::sort (data.subcircuit_pins.begin (), data.subcircuit_pins.end (), SortNetSubCircuitPins ()); } void diff --git a/src/db/db/dbNetlistCrossReference.h b/src/db/db/dbNetlistCrossReference.h index b854d98cc..9e379efad 100644 --- a/src/db/db/dbNetlistCrossReference.h +++ b/src/db/db/dbNetlistCrossReference.h @@ -59,6 +59,8 @@ public: struct NetPairData { + typedef db::Net object_type; + NetPairData (const db::Net *a, const db::Net *b, Status s) : pair (a, b), status (s) { } NetPairData () : pair (0, 0), status (None) { } @@ -68,6 +70,8 @@ public: struct DevicePairData { + typedef db::Device object_type; + DevicePairData (const db::Device *a, const db::Device *b, Status s) : pair (a, b), status (s) { } DevicePairData () : pair (0, 0), status (None) { } @@ -77,6 +81,8 @@ public: struct PinPairData { + typedef db::Pin object_type; + PinPairData (const db::Pin *a, const db::Pin *b, Status s) : pair (a, b), status (s) { } PinPairData () : pair (0, 0), status (None) { } @@ -86,6 +92,8 @@ public: struct SubCircuitPairData { + typedef db::SubCircuit object_type; + SubCircuitPairData (const db::SubCircuit *a, const db::SubCircuit *b, Status s) : pair (a, b), status (s) { } SubCircuitPairData () : pair (0, 0), status (None) { } diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index f686e42fc..336369636 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -483,8 +483,8 @@ TEST(1_SimpleInverter) " terminal $1[G]:$2[G]\n" " terminal $2[G]:$1[G]\n" " net OUT:OUT [Match]\n" - " terminal $2[D]:$1[S]\n" " terminal $1[D]:$2[D]\n" + " terminal $2[D]:$1[S]\n" " net VDD:VDD [Match]\n" " terminal $1[S]:$2[S]\n" " net VSS:VSS [Match]\n" @@ -606,9 +606,9 @@ TEST(1_SimpleInverterSkippedDevices) " terminal $3[G]:$1[G]\n" " net OUT:OUT [Mismatch]\n" " terminal (null):$3[A]\n" + " terminal $1[D]:$4[D]\n" " terminal $2[A]:$2[A]\n" " terminal $3[D]:$1[S]\n" - " terminal $1[D]:$4[D]\n" " net VDD:VDD [Match]\n" " terminal $1[S]:$4[S]\n" " net VSS:VSS [Match]\n" @@ -658,15 +658,15 @@ TEST(1_SimpleInverterSkippedDevices) " net IN:IN [Match]\n" " terminal (null):$2[B]\n" " terminal (null):$3[B]\n" - " terminal $2[B]:(null)\n" " terminal $1[G]:$4[G]\n" + " terminal $2[B]:(null)\n" " terminal $3[G]:$1[G]\n" " net OUT:OUT [Match]\n" " terminal (null):$2[A]\n" " terminal (null):$3[A]\n" + " terminal $1[D]:$4[D]\n" " terminal $2[A]:(null)\n" " terminal $3[D]:$1[S]\n" - " terminal $1[D]:$4[D]\n" " net VDD:VDD [Match]\n" " terminal $1[S]:$4[S]\n" " net VSS:VSS [Match]\n" @@ -1677,16 +1677,16 @@ TEST(11_MismatchingSubcircuits) " net IN:IN [Match]\n" " subcircuit_pin $1[$0]:$2[$1]\n" " net INT:INT [Match]\n" - " subcircuit_pin $2[$0]:$1[$1]\n" " subcircuit_pin $1[$1]:$2[$3]\n" + " subcircuit_pin $2[$0]:$1[$1]\n" " net OUT:OUT [Match]\n" " subcircuit_pin $2[$1]:$1[$3]\n" " net VDD:VDD [Match]\n" - " subcircuit_pin $2[$2]:$1[$0]\n" " subcircuit_pin $1[$2]:$2[$0]\n" + " subcircuit_pin $2[$2]:$1[$0]\n" " net VSS:VSS [Match]\n" - " subcircuit_pin $2[$3]:$1[$2]\n" " subcircuit_pin $1[$3]:$2[$2]\n" + " subcircuit_pin $2[$3]:$1[$2]\n" " subcircuit $1:$2 [Match]\n" " subcircuit $2:$1 [Match]\n" ); @@ -1986,18 +1986,18 @@ TEST(14_Subcircuit2NandMismatchNoSwap) " pin $3:$3 [Match]\n" " pin $4:$4 [Match]\n" " net A:A [Match]\n" - " terminal $3[G]:$3[G]\n" " terminal $1[G]:$1[G]\n" + " terminal $3[G]:$3[G]\n" " net B:B [Match]\n" - " terminal $4[G]:$4[G]\n" " terminal $2[G]:$2[G]\n" + " terminal $4[G]:$4[G]\n" " net INT:INT [Match]\n" - " terminal $4[S]:$4[S]\n" " terminal $3[D]:$3[D]\n" + " terminal $4[S]:$4[S]\n" " net OUT:OUT [Match]\n" - " terminal $4[D]:$4[D]\n" " terminal $1[D]:$1[D]\n" " terminal $2[D]:$2[D]\n" + " terminal $4[D]:$4[D]\n" " net VDD:VDD [Match]\n" " terminal $1[S]:$1[S]\n" " terminal $2[S]:$2[S]\n" @@ -2025,8 +2025,8 @@ TEST(14_Subcircuit2NandMismatchNoSwap) " net INT:IN1 [Mismatch]\n" " pin (null):$0\n" " subcircuit_pin (null):$2[$1]\n" - " subcircuit_pin $2[$1]:$1[$1]\n" " subcircuit_pin $1[$2]:(null)\n" + " subcircuit_pin $2[$1]:$1[$1]\n" " net OUT:OUT [Match]\n" " subcircuit_pin $2[$2]:$1[$2]\n" " net VDD:VDD [Mismatch]\n"