From e0eac2147b6fa8a5aab002012c5c2977d277bcd4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 27 Mar 2021 00:44:48 +0100 Subject: [PATCH] Refining the display enhancements for terminals in netlist browser. --- .../laybasic/layNetlistBrowserModel.cc | 141 ++++++++++-------- 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.cc b/src/laybasic/laybasic/layNetlistBrowserModel.cc index 72568aa67..b160ac73a 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserModel.cc @@ -513,56 +513,90 @@ static std::pairterminal_def () : 0, termrefs.second ? termrefs.second->terminal_def () : 0); } -static std::pair terminal_defs_from_device_classes (IndexedNetlistModel *model, const std::pair &device_classes, const std::pair &devices, size_t terminal_id) +static std::vector > terminal_defs_from_device_classes (IndexedNetlistModel *model, const std::pair &device_classes, const std::pair &devices) { - const db::DeviceTerminalDefinition *td1 = 0, *td2 = 0; - if (device_classes.first && device_classes.first->terminal_definitions ().size () > terminal_id) { - td1 = &device_classes.first->terminal_definitions () [terminal_id]; + std::vector > result; + + std::map >, std::vector > > > nets; + + size_t n1 = 0; + if (device_classes.first) { + n1 = device_classes.first->terminal_definitions ().size (); } + size_t n2 = 0; if (device_classes.second) { + n2 = device_classes.second->terminal_definitions ().size (); + } - size_t second_terminal_id = terminal_id; + for (size_t i = 0; i < n1 || i < n2; ++i) { - // Because of terminal swapping we need to look up the second terminal by looking for equivalent terminals which carry the corresponding net - if (td1 && devices.first && devices.second) { + if (i < n2) { + const db::DeviceTerminalDefinition &td = device_classes.second->terminal_definitions () [i]; + size_t id = td.id (); + size_t id_norm = device_classes.second->normalize_terminal_id (id); + nets [id_norm].second.push_back (std::make_pair (&td, devices.second->net_for_terminal (id))); + } - size_t td1_id_norm = device_classes.first->normalize_terminal_id (td1->id ()); - const db::Net *n2 = model->second_net_for (devices.first->net_for_terminal (terminal_id)); + if (i < n1) { + const db::DeviceTerminalDefinition &td = device_classes.first->terminal_definitions () [i]; + size_t id = td.id (); + size_t id_norm = device_classes.first->normalize_terminal_id (id); + nets [id_norm].first.push_back (std::make_pair (&td, devices.first->net_for_terminal (id))); + } - // this scheme makes a guess what terminal to use when a pair of terminals does not connect - // to matching nets - std::set n2_excluded; - if (! n2) { - for (size_t i = 0; i < device_classes.first->terminal_definitions ().size (); ++i) { - const db::DeviceTerminalDefinition &td = device_classes.first->terminal_definitions () [i]; - if (device_classes.first->normalize_terminal_id (td.id ()) == td1_id_norm) { - const db::Net *n2x = model->second_net_for (devices.first->net_for_terminal (td.id ())); - if (n2x) { - n2_excluded.insert (n2x); - } - } - } + } + + for (std::map >, std::vector > > >::iterator n = nets.begin (); n != nets.end (); ++n) { + + std::vector > &nn1 = n->second.first; + std::vector > &nn2 = n->second.second; + + if (nn2.empty ()) { + + for (std::vector >::const_iterator i = nn1.begin (); i != nn1.end (); ++i) { + result.push_back (std::make_pair (i->first, (const db::DeviceTerminalDefinition *) 0)); } - for (size_t i = 0; i < device_classes.second->terminal_definitions ().size (); ++i) { - const db::DeviceTerminalDefinition &td = device_classes.second->terminal_definitions () [i]; - if (device_classes.second->normalize_terminal_id (td.id ()) == td1_id_norm) { - const db::Net *n2_actual = devices.second->net_for_terminal (i); - if ((! n2 || n2_actual == n2) && n2_excluded.find (n2_actual) == n2_excluded.end ()) { - second_terminal_id = i; - break; + } else if (nn1.empty ()) { + + for (std::vector >::const_iterator j = nn2.begin (); j != nn2.end (); ++j) { + result.push_back (std::make_pair ((const db::DeviceTerminalDefinition *) 0, j->first)); + } + + } else { + + std::vector >::iterator w = nn1.begin (); + for (std::vector >::const_iterator i = nn1.begin (); i != nn1.end (); ++i) { + + bool found = false; + + for (std::vector >::iterator j = nn2.begin (); j != nn2.end () && ! found; ++j) { + const db::Net *n2 = model->second_net_for (i->second); + if (n2 == j->second) { + result.push_back (std::make_pair (i->first, j->first)); + nn2.erase (j); + found = true; } } + + if (! found) { + *w++ = *i; + } + + } + + nn1.erase (w, nn1.end ()); + + for (size_t i = 0; i < nn1.size () && i < nn2.size (); ++i) { + result.push_back (std::make_pair (nn1 [i].first, nn2 [i].first)); } } - td2 = &device_classes.second->terminal_definitions () [second_terminal_id]; - } - return std::make_pair (td1, td2); + return result; } static @@ -601,24 +635,6 @@ static std::string combine_search_strings (const std::string &s1, const std::str } } -static size_t rows_for (const db::Device *device) -{ - if (! device || ! device->device_class ()) { - return 0; - } else { - return device->device_class ()->terminal_definitions ().size (); - } -} - -static size_t rows_for (const db::NetTerminalRef *ref) -{ - if (! ref || ! ref->device_class ()) { - return 0; - } else { - return ref->device_class ()->terminal_definitions ().size (); - } -} - static QIcon icon_for_net () { static QIcon icon; @@ -1981,12 +1997,14 @@ CircuitNetDeviceTerminalItemData::do_ensure_children (NetlistBrowserModel *model return; } - size_t n = std::max (rows_for (m_tp.first), rows_for (m_tp.second)); - for (size_t i = 0; i < n; ++i) { - std::pair device_classes = device_classes_from_devices (dp ()); - std::pair termdefs = terminal_defs_from_device_classes (model->indexer (), device_classes, dp (), i); - IndexedNetlistModel::net_pair nets = nets_from_device_terminals (dp (), termdefs); - push_back (new CircuitNetDeviceTerminalOthersItemData (this, nets, termdefs)); + std::pair devices = dp (); + std::pair device_classes = device_classes_from_devices (devices); + + std::vector > tp = terminal_defs_from_device_classes (model->indexer (), device_classes, devices); + + for (std::vector >::const_iterator i = tp.begin (); i != tp.end (); ++i) { + IndexedNetlistModel::net_pair nets = nets_from_device_terminals (dp (), *i); + push_back (new CircuitNetDeviceTerminalOthersItemData (this, nets, *i)); } } @@ -2336,10 +2354,13 @@ CircuitDeviceItemData::CircuitDeviceItemData (NetlistModelItemData *parent, cons void CircuitDeviceItemData::do_ensure_children (NetlistBrowserModel *model) { - size_t n = std::max (rows_for (dp ().first), rows_for (dp ().second)); - for (size_t i = 0; i < n; ++i) { - std::pair tp = terminal_defs_from_device_classes (model->indexer (), device_classes_from_devices (dp ()), dp (), i); - push_back (new CircuitDeviceTerminalItemData (this, tp)); + std::pair devices = dp (); + std::pair device_classes = device_classes_from_devices (devices); + + std::vector > tp = terminal_defs_from_device_classes (model->indexer (), device_classes, devices); + + for (std::vector >::const_iterator i = tp.begin (); i != tp.end (); ++i) { + push_back (new CircuitDeviceTerminalItemData (this, *i)); } }