mirror of https://github.com/KLayout/klayout.git
WIP: netlist browser - net object paths, single + pairs, tests
This commit is contained in:
parent
2762daf14f
commit
a10d56e6b6
|
|
@ -36,6 +36,67 @@
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
// NetlistObjectPath implementation
|
||||||
|
|
||||||
|
NetlistObjectsPath
|
||||||
|
NetlistObjectsPath::from_first (const NetlistObjectPath &p)
|
||||||
|
{
|
||||||
|
NetlistObjectsPath pp;
|
||||||
|
pp.root.first = p.root;
|
||||||
|
for (NetlistObjectPath::path_iterator i = p.path.begin (); i != p.path.end (); ++i) {
|
||||||
|
pp.path.push_back (std::make_pair (*i, (const db::SubCircuit *) 0));
|
||||||
|
}
|
||||||
|
pp.device.first = p.device;
|
||||||
|
pp.net.first = p.net;
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlistObjectsPath
|
||||||
|
NetlistObjectsPath::from_second (const NetlistObjectPath &p)
|
||||||
|
{
|
||||||
|
NetlistObjectsPath pp;
|
||||||
|
pp.root.second = p.root;
|
||||||
|
for (NetlistObjectPath::path_iterator i = p.path.begin (); i != p.path.end (); ++i) {
|
||||||
|
pp.path.push_back (std::make_pair ((const db::SubCircuit *) 0, *i));
|
||||||
|
}
|
||||||
|
pp.device.second = p.device;
|
||||||
|
pp.net.second = p.net;
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlistObjectPath
|
||||||
|
NetlistObjectsPath::first () const
|
||||||
|
{
|
||||||
|
NetlistObjectPath p;
|
||||||
|
p.root = root.first;
|
||||||
|
for (NetlistObjectsPath::path_iterator i = path.begin (); i != path.end (); ++i) {
|
||||||
|
if (! i->first) {
|
||||||
|
return NetlistObjectPath ();
|
||||||
|
}
|
||||||
|
p.path.push_back (i->first);
|
||||||
|
}
|
||||||
|
p.device = device.first;
|
||||||
|
p.net = net.first;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlistObjectPath
|
||||||
|
NetlistObjectsPath::second () const
|
||||||
|
{
|
||||||
|
NetlistObjectPath p;
|
||||||
|
p.root = root.second;
|
||||||
|
for (NetlistObjectsPath::path_iterator i = path.begin (); i != path.end (); ++i) {
|
||||||
|
if (! i->second) {
|
||||||
|
return NetlistObjectPath ();
|
||||||
|
}
|
||||||
|
p.path.push_back (i->second);
|
||||||
|
}
|
||||||
|
p.device = device.second;
|
||||||
|
p.net = net.second;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// NetColorizer implementation
|
// NetColorizer implementation
|
||||||
|
|
||||||
|
|
@ -2435,10 +2496,10 @@ NetlistBrowserModel::data (const QModelIndex &index, int role) const
|
||||||
return QVariant ();
|
return QVariant ();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetlistObjectPath
|
NetlistObjectsPath
|
||||||
NetlistBrowserModel::netpath_from_index (const QModelIndex &index) const
|
NetlistBrowserModel::path_from_index (const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
NetlistObjectPath np;
|
NetlistObjectsPath np;
|
||||||
np.net = net_from_index (index, false);
|
np.net = net_from_index (index, false);
|
||||||
np.device = device_from_index (index, false);
|
np.device = device_from_index (index, false);
|
||||||
|
|
||||||
|
|
@ -2463,7 +2524,7 @@ NetlistBrowserModel::netpath_from_index (const QModelIndex &index) const
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex
|
QModelIndex
|
||||||
NetlistBrowserModel::index_from_netpath (const NetlistObjectPath &path)
|
NetlistBrowserModel::index_from_path (const NetlistObjectsPath &path)
|
||||||
{
|
{
|
||||||
QModelIndex index = index_from_circuit (path.root);
|
QModelIndex index = index_from_circuit (path.root);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,14 +179,22 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An object describing the instantiation path of a net
|
* @brief An object describing the instantiation path of a net, a device or a (sub)circuit pair
|
||||||
|
*
|
||||||
|
* This object applies to pairs of these objects. A class providing a path for a single
|
||||||
|
* object is NetlistObjectPath
|
||||||
*/
|
*/
|
||||||
struct LAYBASIC_PUBLIC NetlistObjectPath
|
struct LAYBASIC_PUBLIC NetlistObjectPath
|
||||||
{
|
{
|
||||||
typedef std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> > path_type;
|
typedef std::list<const db::SubCircuit *> path_type;
|
||||||
typedef path_type::const_iterator path_iterator;
|
typedef path_type::const_iterator path_iterator;
|
||||||
|
|
||||||
NetlistObjectPath () { }
|
NetlistObjectPath () : root (0), net (0), device (0) { }
|
||||||
|
|
||||||
|
bool is_null () const
|
||||||
|
{
|
||||||
|
return ! root;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator== (const NetlistObjectPath &other) const
|
bool operator== (const NetlistObjectPath &other) const
|
||||||
{
|
{
|
||||||
|
|
@ -198,6 +206,46 @@ struct LAYBASIC_PUBLIC NetlistObjectPath
|
||||||
return ! operator== (other);
|
return ! operator== (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const db::Circuit *root;
|
||||||
|
std::list<const db::SubCircuit *> path;
|
||||||
|
const db::Net *net;
|
||||||
|
const db::Device *device;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An object describing the instantiation path of a net, a device or a (sub)circuit pair
|
||||||
|
*
|
||||||
|
* This object applies to pairs of these objects. A class providing a path for a single
|
||||||
|
* object is NetlistObjectPath
|
||||||
|
*/
|
||||||
|
struct LAYBASIC_PUBLIC NetlistObjectsPath
|
||||||
|
{
|
||||||
|
typedef std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> > path_type;
|
||||||
|
typedef path_type::const_iterator path_iterator;
|
||||||
|
|
||||||
|
NetlistObjectsPath () { }
|
||||||
|
|
||||||
|
bool is_null () const
|
||||||
|
{
|
||||||
|
return ! root.first && ! root.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NetlistObjectsPath from_first(const NetlistObjectPath &p);
|
||||||
|
static NetlistObjectsPath from_second (const NetlistObjectPath &p);
|
||||||
|
|
||||||
|
NetlistObjectPath first () const;
|
||||||
|
NetlistObjectPath second () const;
|
||||||
|
|
||||||
|
bool operator== (const NetlistObjectsPath &other) const
|
||||||
|
{
|
||||||
|
return root == other.root && path == other.path && net == other.net && device == other.device;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!= (const NetlistObjectsPath &other) const
|
||||||
|
{
|
||||||
|
return ! operator== (other);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<const db::Circuit *, const db::Circuit *> root;
|
std::pair<const db::Circuit *, const db::Circuit *> root;
|
||||||
std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> > path;
|
std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> > path;
|
||||||
std::pair<const db::Net *, const db::Net *> net;
|
std::pair<const db::Net *, const db::Net *> net;
|
||||||
|
|
@ -292,8 +340,18 @@ public:
|
||||||
QIcon icon_for_connection (const std::pair<const db::Net *, const db::Net *> &net) const;
|
QIcon icon_for_connection (const std::pair<const db::Net *, const db::Net *> &net) const;
|
||||||
|
|
||||||
QModelIndex index_from_url (const QString &url) const;
|
QModelIndex index_from_url (const QString &url) const;
|
||||||
NetlistObjectPath netpath_from_index (const QModelIndex &index) const;
|
|
||||||
QModelIndex index_from_netpath (const NetlistObjectPath &path);
|
NetlistObjectsPath path_from_index (const QModelIndex &index) const;
|
||||||
|
NetlistObjectPath spath_from_index (const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return path_from_index (index).first ();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex index_from_path (const NetlistObjectsPath &path);
|
||||||
|
QModelIndex index_from_path (const NetlistObjectPath &path)
|
||||||
|
{
|
||||||
|
return index_from_path (NetlistObjectsPath::from_first (path));
|
||||||
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void colors_changed ();
|
void colors_changed ();
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ NetlistBrowserPage::current_index_changed (const QModelIndex &index)
|
||||||
|
|
||||||
add_to_history (index, true);
|
add_to_history (index, true);
|
||||||
|
|
||||||
NetlistObjectPath path = netlist_model->netpath_from_index (index);
|
NetlistObjectsPath path = netlist_model->path_from_index (index);
|
||||||
QModelIndex circuit_index = tree_model->index_from_netpath (path);
|
QModelIndex circuit_index = tree_model->index_from_netpath (path);
|
||||||
|
|
||||||
m_signals_enabled = false;
|
m_signals_enabled = false;
|
||||||
|
|
@ -460,7 +460,7 @@ NetlistBrowserPage::selection_changed ()
|
||||||
tl_assert (model != 0);
|
tl_assert (model != 0);
|
||||||
|
|
||||||
QModelIndex current = directory_tree->selectionModel ()->currentIndex ();
|
QModelIndex current = directory_tree->selectionModel ()->currentIndex ();
|
||||||
highlight (model->netpath_from_index (current));
|
highlight (model->path_from_index (current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -517,7 +517,7 @@ NetlistBrowserPage::navigate_to (const QModelIndex &index, bool fwd)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lay::NetlistObjectPath path = netlist_model->netpath_from_index (index);
|
lay::NetlistObjectsPath path = netlist_model->path_from_index (index);
|
||||||
QModelIndex circuit_index = tree_model->index_from_netpath (path);
|
QModelIndex circuit_index = tree_model->index_from_netpath (path);
|
||||||
hierarchy_tree->setCurrentIndex (circuit_index);
|
hierarchy_tree->setCurrentIndex (circuit_index);
|
||||||
|
|
||||||
|
|
@ -874,7 +874,7 @@ NetlistBrowserPage::setup_trees ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NetlistBrowserPage::highlight (const NetlistObjectPath &path)
|
NetlistBrowserPage::highlight (const NetlistObjectsPath &path)
|
||||||
{
|
{
|
||||||
if (path != m_current_path) {
|
if (path != m_current_path) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ private:
|
||||||
bool m_enable_updates;
|
bool m_enable_updates;
|
||||||
bool m_update_needed;
|
bool m_update_needed;
|
||||||
// @@@ TODO: make multiple ...
|
// @@@ TODO: make multiple ...
|
||||||
lay::NetlistObjectPath m_current_path;
|
lay::NetlistObjectsPath m_current_path;
|
||||||
// @@@ TODO: remove
|
// @@@ TODO: remove
|
||||||
std::vector<const db::Net *> m_current_nets;
|
std::vector<const db::Net *> m_current_nets;
|
||||||
std::vector<const db::Device *> m_current_devices;
|
std::vector<const db::Device *> m_current_devices;
|
||||||
|
|
@ -251,7 +251,7 @@ private:
|
||||||
void navigate_to (const QModelIndex &index, bool forward = true);
|
void navigate_to (const QModelIndex &index, bool forward = true);
|
||||||
void adjust_view ();
|
void adjust_view ();
|
||||||
void clear_markers ();
|
void clear_markers ();
|
||||||
void highlight (const lay::NetlistObjectPath &path);
|
void highlight (const lay::NetlistObjectsPath &path);
|
||||||
std::vector<const db::Net *> selected_nets ();
|
std::vector<const db::Net *> selected_nets ();
|
||||||
std::vector<const db::Device *> selected_devices ();
|
std::vector<const db::Device *> selected_devices ();
|
||||||
std::vector<const db::SubCircuit *> selected_subcircuits ();
|
std::vector<const db::SubCircuit *> selected_subcircuits ();
|
||||||
|
|
|
||||||
|
|
@ -270,13 +270,13 @@ static bool is_compatible (const std::pair<const db::Circuit *, const db::Circui
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex
|
QModelIndex
|
||||||
NetlistBrowserTreeModel::index_from_netpath (const NetlistObjectPath &path) const
|
NetlistBrowserTreeModel::index_from_netpath (const NetlistObjectsPath &path) const
|
||||||
{
|
{
|
||||||
QModelIndex idx;
|
QModelIndex idx;
|
||||||
|
|
||||||
idx = index_from_circuits (path.root);
|
idx = index_from_circuits (path.root);
|
||||||
|
|
||||||
for (NetlistObjectPath::path_iterator p = path.path.begin (); p != path.path.end () && idx.isValid (); ++p) {
|
for (NetlistObjectsPath::path_iterator p = path.path.begin (); p != path.path.end () && idx.isValid (); ++p) {
|
||||||
|
|
||||||
std::pair<const db::Circuit *, const db::Circuit *> sc (p->first ? p->first->circuit_ref () : 0, p->second ? p->second->circuit_ref (): 0);
|
std::pair<const db::Circuit *, const db::Circuit *> sc (p->first ? p->first->circuit_ref () : 0, p->second ? p->second->circuit_ref (): 0);
|
||||||
std::pair<const db::Circuit *, const db::Circuit *> circuit = circuits_from_index (idx);
|
std::pair<const db::Circuit *, const db::Circuit *> circuit = circuits_from_index (idx);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
class IndexedNetlistModel;
|
class IndexedNetlistModel;
|
||||||
struct NetlistObjectPath;
|
struct NetlistObjectsPath;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// NetlistBrowserTreeModel definition
|
// NetlistBrowserTreeModel definition
|
||||||
|
|
@ -78,7 +78,7 @@ public:
|
||||||
|
|
||||||
std::pair<const db::Circuit *, const db::Circuit *> circuits_from_index (const QModelIndex &index) const;
|
std::pair<const db::Circuit *, const db::Circuit *> circuits_from_index (const QModelIndex &index) const;
|
||||||
QModelIndex index_from_circuits (const std::pair<const db::Circuit *, const db::Circuit *> &circuits) const;
|
QModelIndex index_from_circuits (const std::pair<const db::Circuit *, const db::Circuit *> &circuits) const;
|
||||||
QModelIndex index_from_netpath (const NetlistObjectPath &path) const;
|
QModelIndex index_from_netpath (const NetlistObjectsPath &path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetlistBrowserTreeModel (const NetlistBrowserTreeModel &);
|
NetlistBrowserTreeModel (const NetlistBrowserTreeModel &);
|
||||||
|
|
|
||||||
|
|
@ -417,8 +417,8 @@ TEST (3)
|
||||||
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
||||||
EXPECT_EQ (root != 0, true);
|
EXPECT_EQ (root != 0, true);
|
||||||
|
|
||||||
lay::NetlistObjectPath path;
|
lay::NetlistObjectsPath path;
|
||||||
EXPECT_EQ (model->index_from_netpath (path).isValid (), false);
|
EXPECT_EQ (model->index_from_path (path).isValid (), false);
|
||||||
|
|
||||||
path.root.first = root;
|
path.root.first = root;
|
||||||
|
|
||||||
|
|
@ -427,7 +427,7 @@ TEST (3)
|
||||||
|
|
||||||
path.net.first = net;
|
path.net.first = net;
|
||||||
|
|
||||||
QModelIndex index = model->index_from_netpath (path);
|
QModelIndex index = model->index_from_path (path);
|
||||||
EXPECT_EQ (index.isValid (), true);
|
EXPECT_EQ (index.isValid (), true);
|
||||||
|
|
||||||
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "FB");
|
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "FB");
|
||||||
|
|
@ -444,7 +444,7 @@ TEST (4)
|
||||||
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
||||||
EXPECT_EQ (root != 0, true);
|
EXPECT_EQ (root != 0, true);
|
||||||
|
|
||||||
lay::NetlistObjectPath path;
|
lay::NetlistObjectsPath path;
|
||||||
path.root.first = root;
|
path.root.first = root;
|
||||||
|
|
||||||
db::SubCircuit *sc1 = root->begin_subcircuits ().operator-> ();
|
db::SubCircuit *sc1 = root->begin_subcircuits ().operator-> ();
|
||||||
|
|
@ -456,8 +456,124 @@ TEST (4)
|
||||||
|
|
||||||
path.net.first = net;
|
path.net.first = net;
|
||||||
|
|
||||||
QModelIndex index = model->index_from_netpath (path);
|
QModelIndex index = model->index_from_path (path);
|
||||||
EXPECT_EQ (index.isValid (), true);
|
EXPECT_EQ (index.isValid (), true);
|
||||||
|
|
||||||
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "NOUT");
|
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "NOUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Netlist object path: single vs. pairs - first
|
||||||
|
TEST (5)
|
||||||
|
{
|
||||||
|
db::LayoutVsSchematic lvs;
|
||||||
|
lvs.load (tl::testsrc () + "/testdata/lay/lvsdb_browser.lvsdb");
|
||||||
|
|
||||||
|
lay::NetColorizer colorizer;
|
||||||
|
std::auto_ptr<lay::NetlistBrowserModel> model (new lay::NetlistBrowserModel (0, &lvs, &colorizer));
|
||||||
|
QModelIndex idx;
|
||||||
|
|
||||||
|
db::Circuit *root = lvs.netlist ()->circuit_by_name ("INV2PAIR");
|
||||||
|
EXPECT_EQ (root != 0, true);
|
||||||
|
db::Circuit *sc = lvs.netlist ()->circuit_by_name ("INV2");
|
||||||
|
EXPECT_EQ (sc != 0, true);
|
||||||
|
|
||||||
|
lay::NetlistObjectPath path;
|
||||||
|
EXPECT_EQ (path.is_null (), true);
|
||||||
|
path.root = root;
|
||||||
|
EXPECT_EQ (path.is_null (), false);
|
||||||
|
|
||||||
|
idx = model->index_from_path (path);
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "INV2PAIR|INV2PAIR");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).first (), true);
|
||||||
|
|
||||||
|
path.net = root->net_by_cluster_id (5);
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_first (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "$5|4");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).first (), true);
|
||||||
|
|
||||||
|
path.path.push_back (root->subcircuit_by_id (1));
|
||||||
|
EXPECT_EQ (path.path.back () != 0, true);
|
||||||
|
EXPECT_EQ (path.path.back ()->expanded_name (), "$1");
|
||||||
|
EXPECT_EQ (path.path.back ()->circuit_ref ()->name (), "INV2");
|
||||||
|
|
||||||
|
path.net = 0;
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_first (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
// A pure subcircuit path addresses the "Circuit" representative node of the subcircuit
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::DisplayRole).toString ()), "Circuit");
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (model->parent (idx), Qt::UserRole).toString ()), "INV2|$1");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).first (), true);
|
||||||
|
|
||||||
|
path.net = sc->net_by_cluster_id (2);
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_first (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "IN|2");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).first (), true);
|
||||||
|
|
||||||
|
path.net = 0;
|
||||||
|
path.device = sc->device_by_id (1);
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_first (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "$1|$1|PMOS|PMOS");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).first (), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Netlist object path: single vs. pairs - second
|
||||||
|
TEST (6)
|
||||||
|
{
|
||||||
|
db::LayoutVsSchematic lvs;
|
||||||
|
lvs.load (tl::testsrc () + "/testdata/lay/lvsdb_browser.lvsdb");
|
||||||
|
|
||||||
|
lay::NetColorizer colorizer;
|
||||||
|
std::auto_ptr<lay::NetlistBrowserModel> model (new lay::NetlistBrowserModel (0, &lvs, &colorizer));
|
||||||
|
QModelIndex idx;
|
||||||
|
|
||||||
|
db::Circuit *root = lvs.reference_netlist ()->circuit_by_name ("INV2PAIR");
|
||||||
|
EXPECT_EQ (root != 0, true);
|
||||||
|
db::Circuit *sc = lvs.reference_netlist ()->circuit_by_name ("INV2");
|
||||||
|
EXPECT_EQ (sc != 0, true);
|
||||||
|
|
||||||
|
lay::NetlistObjectPath path;
|
||||||
|
EXPECT_EQ (path.is_null (), true);
|
||||||
|
path.root = root;
|
||||||
|
EXPECT_EQ (path.is_null (), false);
|
||||||
|
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_second (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "INV2PAIR|INV2PAIR");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).second (), true);
|
||||||
|
|
||||||
|
path.net = root->net_by_name ("4");
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_second (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "$5|4");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).second (), true);
|
||||||
|
|
||||||
|
path.path.push_back (root->subcircuit_by_name ("$2"));
|
||||||
|
EXPECT_EQ (path.path.back () != 0, true);
|
||||||
|
EXPECT_EQ (path.path.back ()->expanded_name (), "$2");
|
||||||
|
EXPECT_EQ (path.path.back ()->circuit_ref ()->name (), "INV2");
|
||||||
|
|
||||||
|
path.net = 0;
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_second (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
// A pure subcircuit path addresses the "Circuit" representative node of the subcircuit
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::DisplayRole).toString ()), "Circuit");
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (model->parent (idx), Qt::UserRole).toString ()), "INV2|$2");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).second (), true);
|
||||||
|
|
||||||
|
path.net = sc->net_by_name ("2");
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_second (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "IN|2");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).second (), true);
|
||||||
|
|
||||||
|
path.net = 0;
|
||||||
|
path.device = sc->device_by_id (1);
|
||||||
|
idx = model->index_from_path (lay::NetlistObjectsPath::from_second (path));
|
||||||
|
EXPECT_EQ (idx.isValid (), true);
|
||||||
|
EXPECT_EQ (tl::to_string (model->data (idx, Qt::UserRole).toString ()), "$1|$1|PMOS|PMOS");
|
||||||
|
EXPECT_EQ (path == model->path_from_index (idx).second (), true);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue