From 2569527c3cd8f9ca6ce27e8e75aa8383a8fe32d0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 8 Aug 2022 23:27:22 +0200 Subject: [PATCH] WIP: Schematic netlist participates in net highlighting if applicable --- src/layui/layui/layNetlistBrowserModel.cc | 68 +++++++++++++++++++++++ src/layui/layui/layNetlistBrowserModel.h | 3 +- src/layui/layui/layNetlistBrowserPage.cc | 48 +++++++++++++--- 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/layui/layui/layNetlistBrowserModel.cc b/src/layui/layui/layNetlistBrowserModel.cc index 68b2e5e90..82ffa4f81 100644 --- a/src/layui/layui/layNetlistBrowserModel.cc +++ b/src/layui/layui/layNetlistBrowserModel.cc @@ -101,6 +101,74 @@ NetlistObjectsPath::second () const return p; } +static bool +translate_circuit (const db::Circuit *&a, const db::NetlistCrossReference &xref) +{ + if (a) { + a = xref.other_circuit_for (a); + if (! a) { + return false; + } + } + return true; +} + +static bool +translate_subcircuit (const db::SubCircuit *&a, const db::NetlistCrossReference &xref) +{ + if (a) { + a = xref.other_subcircuit_for (a); + if (! a) { + return false; + } + } + return true; +} + +static bool +translate_device (const db::Device *&a, const db::NetlistCrossReference &xref) +{ + if (a) { + a = xref.other_device_for (a); + if (! a) { + return false; + } + } + return true; +} + +static bool +translate_net (const db::Net *&a, const db::NetlistCrossReference &xref) +{ + if (a) { + a = xref.other_net_for (a); + if (! a) { + return false; + } + } + return true; +} + +bool +NetlistObjectsPath::translate (NetlistObjectsPath &p, const db::NetlistCrossReference &xref) +{ + if (! translate_circuit (p.root.first, xref) || ! translate_circuit (p.root.second, xref)) { + return false; + } + for (NetlistObjectsPath::path_type::iterator i = p.path.begin (); i != p.path.end (); ++i) { + if (! translate_subcircuit (i->first, xref) || ! translate_subcircuit (i->second, xref)) { + return false; + } + } + if (! translate_device (p.device.first, xref) || ! translate_device (p.device.second, xref)) { + return false; + } + if (! translate_net (p.net.first, xref) || ! translate_net (p.net.second, xref)) { + return false; + } + return true; +} + // ---------------------------------------------------------------------------------- // Implementation of the item classes diff --git a/src/layui/layui/layNetlistBrowserModel.h b/src/layui/layui/layNetlistBrowserModel.h index e904bb405..8e7f0290c 100644 --- a/src/layui/layui/layNetlistBrowserModel.h +++ b/src/layui/layui/layNetlistBrowserModel.h @@ -183,8 +183,9 @@ public: return ! root.first && ! root.second; } - static NetlistObjectsPath from_first(const NetlistObjectPath &p); + static NetlistObjectsPath from_first (const NetlistObjectPath &p); static NetlistObjectsPath from_second (const NetlistObjectPath &p); + static bool translate (NetlistObjectsPath &p, const db::NetlistCrossReference &xref); NetlistObjectPath first () const; NetlistObjectPath second () const; diff --git a/src/layui/layui/layNetlistBrowserPage.cc b/src/layui/layui/layNetlistBrowserPage.cc index ae3d67517..705b43000 100644 --- a/src/layui/layui/layNetlistBrowserPage.cc +++ b/src/layui/layui/layNetlistBrowserPage.cc @@ -484,22 +484,24 @@ NetlistBrowserPage::select_path (const lay::NetlistObjectsPath &path) } else { NetlistBrowserModel *model; + db::LayoutToNetlist *l2ndb = mp_database.get (); + db::LayoutVsSchematic *lvsdb = dynamic_cast (l2ndb); model = dynamic_cast (nl_directory_tree->model ()); if (model) { nl_directory_tree->setCurrentIndex (model->index_from_path (path)); } -/* - TODO: to support path selection in schematic, we had to translate the netlist circuits - into reference circuits first using the xref translation (if available) - This does not work: - model = dynamic_cast (sch_directory_tree->model ()); - if (model) { - sch_directory_tree->setCurrentIndex (model->index_from_path (path)); + if (model && lvsdb && lvsdb->cross_ref ()) { + lay::NetlistObjectsPath sch_path = path; + // Note: translation helps generating a schematic-netlist index to + // naviate to the schematic netlist in case of probing for example (only + // works if all path components can be translated) + if (lay::NetlistObjectsPath::translate (sch_path, *lvsdb->cross_ref ())) { + sch_directory_tree->setCurrentIndex (model->index_from_path (sch_path)); + } } -*/ model = dynamic_cast (xref_directory_tree->model ()); if (model) { @@ -622,7 +624,35 @@ NetlistBrowserPage::nl_selection_changed () void NetlistBrowserPage::sch_selection_changed () { - selection_changed (sch_hierarchy_tree, sch_directory_tree); + QTreeView *directory_tree = sch_directory_tree; + + NetlistBrowserModel *model = dynamic_cast (directory_tree->model ()); + tl_assert (model != 0); + + db::LayoutToNetlist *l2ndb = mp_database.get (); + db::LayoutVsSchematic *lvsdb = dynamic_cast (l2ndb); + if (! lvsdb || ! lvsdb->cross_ref ()) { + return; + } + + QModelIndexList selected = directory_tree->selectionModel ()->selectedIndexes (); + + std::vector selected_paths; + selected_paths.reserve (selected.size ()); + for (QModelIndexList::const_iterator i = selected.begin (); i != selected.end (); ++i) { + if (i->column () == 0) { + selected_paths.push_back (model->path_from_index (*i)); + // translate the schematic paths to layout paths (if available) + if (! lay::NetlistObjectsPath::translate (selected_paths.back (), *lvsdb->cross_ref ())) { + selected_paths.pop_back (); + } + } + } + + QModelIndex current = directory_tree->selectionModel ()->currentIndex (); + highlight (model->path_from_index (current), selected_paths); + + selection_changed_event (); } void