WIP: netlist cross reference - refactoring of sorting, more robust

This commit is contained in:
Matthias Koefferlein 2019-05-16 23:26:49 +02:00
parent 95caca1dd5
commit 65ea72c569
3 changed files with 139 additions and 88 deletions

View File

@ -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 <class Obj>
struct by_name_value_compare
{
int operator() (const Obj &a, const Obj &b) const
{
return string_value_compare (a.name (), b.name ());
}
};
template <class Obj>
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 <class Obj>
struct net_object_compare;
template <>
struct net_object_compare<db::NetTerminalRef>
{
int operator() (const db::NetTerminalRef &a, const db::NetTerminalRef &b) const
{
int ct = by_expanded_name_value_compare<db::Device> () (*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<db::NetSubcircuitPinRef>
{
int operator() (const db::NetSubcircuitPinRef &a, const db::NetSubcircuitPinRef &b) const
{
int ct = by_expanded_name_value_compare<db::SubCircuit> () (*a.subcircuit (), *b.subcircuit ());
if (ct == 0) {
return by_expanded_name_value_compare<db::Pin> () (*a.pin (), *b.pin ());
} else {
return ct;
}
}
};
template <>
struct net_object_compare<db::NetPinRef>
{
int operator() (const db::NetPinRef &a, const db::NetPinRef &b) const
{
return by_expanded_name_value_compare<db::Pin> () (*a.pin (), *b.pin ());
}
};
template <class Obj, class ValueCompare>
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 <class Obj, class ValueCompare>
struct two_pair_compare
{
bool operator() (const std::pair<const Obj *, const Obj *> &a, const std::pair<const Obj *, const Obj *> &b)
{
int ct = two_pointer_compare<Obj, ValueCompare> () (a.first, b.first);
if (ct != 0) {
return ct < 0;
}
return two_pointer_compare<Obj, ValueCompare> () (a.second, b.second) < 0;
}
};
template <class PairData, class ValueCompare>
struct pair_data_compare
{
bool operator () (const PairData &a, const PairData &b) const
{
return two_pair_compare<typename PairData::object_type, ValueCompare> () (a.pair, b.pair);
}
};
struct CircuitsCompareByName
: public two_pair_compare<db::Circuit, by_name_value_compare<db::Circuit> >
{
bool operator() (const std::pair<const db::Circuit *, const db::Circuit *> &a, const std::pair<const db::Circuit *, const db::Circuit *> &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<db::NetTerminalRef, net_object_compare<db::NetTerminalRef> >
{
bool operator() (const std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *> &a, const std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *> &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 <class Data>
struct sort_data_pairs_by_pin_name
struct SortNetPins
: public two_pair_compare<db::NetPinRef, net_object_compare<db::NetPinRef> >
{
bool operator() (const std::pair<const Data *, const Data *> &a, const std::pair<const Data *, const Data *> &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 <class PairData>
struct sort_pair_data_by_expanded_name
struct SortNetSubCircuitPins
: public two_pair_compare<db::NetSubcircuitPinRef, net_object_compare<db::NetSubcircuitPinRef> >
{
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<DevicePairData> ());
std::sort (mp_per_circuit_data->pins.begin (), mp_per_circuit_data->pins.end (), sort_pair_data_by_expanded_name<PinPairData> ());
std::sort (mp_per_circuit_data->subcircuits.begin (), mp_per_circuit_data->subcircuits.end (), sort_pair_data_by_expanded_name<SubCircuitPairData> ());
std::sort (mp_per_circuit_data->nets.begin (), mp_per_circuit_data->nets.end (), sort_pair_data_by_expanded_name<NetPairData> ());
std::sort (mp_per_circuit_data->devices.begin (), mp_per_circuit_data->devices.end (), pair_data_compare<DevicePairData, by_expanded_name_value_compare<db::Device> > ());
std::sort (mp_per_circuit_data->pins.begin (), mp_per_circuit_data->pins.end (), pair_data_compare<PinPairData, by_expanded_name_value_compare<db::Pin> > ());
std::sort (mp_per_circuit_data->subcircuits.begin (), mp_per_circuit_data->subcircuits.end (), pair_data_compare<SubCircuitPairData, by_expanded_name_value_compare<db::SubCircuit> > ());
std::sort (mp_per_circuit_data->nets.begin (), mp_per_circuit_data->nets.end (), pair_data_compare<NetPairData, by_expanded_name_value_compare<db::Net> > ());
m_current_circuits = std::pair<const db::Circuit *, const db::Circuit *> (0, 0);
mp_per_circuit_data = 0;
@ -442,7 +485,7 @@ NetlistCrossReference::build_terminal_refs (const std::pair<const db::Net *, con
data.terminals.push_back (std::make_pair ((const db::NetTerminalRef *) 0, b->second));
}
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::pair<const db::Net *, const db
data.pins.push_back (std::make_pair ((const db::NetPinRef *) 0, b->second));
}
std::sort (data.pins.begin (), data.pins.end (), sort_data_pairs_by_pin_name<db::NetPinRef> ());
std::sort (data.pins.begin (), data.pins.end (), SortNetPins ());
}
void
@ -539,7 +582,7 @@ NetlistCrossReference::build_subcircuit_pin_refs (const std::pair<const db::Net
data.subcircuit_pins.push_back (std::make_pair ((const db::NetSubcircuitPinRef *) 0, b->second));
}
std::sort (data.subcircuit_pins.begin (), data.subcircuit_pins.end (), sort_data_pairs_by_pin_name<db::NetSubcircuitPinRef> ());
std::sort (data.subcircuit_pins.begin (), data.subcircuit_pins.end (), SortNetSubCircuitPins ());
}
void

View File

@ -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) { }

View File

@ -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"