WIP: doc update, robustness of LVS browser model (xref)

This commit is contained in:
Matthias Koefferlein 2019-07-05 23:34:56 +02:00
parent a6a0d9946c
commit 15022709b4
4 changed files with 110 additions and 34 deletions

View File

@ -105,7 +105,7 @@
</p> </p>
<p> <p>
To flatten a circuit from the extracted netlist use To flatten a circuit from the extracted netlist use <class_doc href="Netlist#flatten_circuit"/>:
</p> </p>
<pre>netlist.flatten_circuit("CIRCUIT_NAME")</pre> <pre>netlist.flatten_circuit("CIRCUIT_NAME")</pre>

View File

@ -30,6 +30,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <limits>
namespace db namespace db
{ {
@ -48,6 +49,8 @@ namespace db
namespace lay namespace lay
{ {
const size_t no_netlist_index = std::numeric_limits<size_t>::max ();
/** /**
* @brief An interface to supply the netlist browser model with indexed items * @brief An interface to supply the netlist browser model with indexed items
*/ */

View File

@ -240,89 +240,141 @@ NetlistBrowserModel::~NetlistBrowserModel ()
void * void *
NetlistBrowserModel::make_id_circuit (size_t circuit_index) const NetlistBrowserModel::make_id_circuit (size_t circuit_index) const
{ {
return make_id (circuit_index); if (circuit_index == lay::no_netlist_index) {
return no_id;
} else {
return make_id (circuit_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_pin (size_t circuit_index, size_t pin_index) const NetlistBrowserModel::make_id_circuit_pin (size_t circuit_index, size_t pin_index) const
{ {
return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index); if (circuit_index == lay::no_netlist_index || pin_index == lay::no_netlist_index) {
return no_id;
} else {
return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_pin_net (size_t circuit_index, size_t pin_index, size_t net_index) const NetlistBrowserModel::make_id_circuit_pin_net (size_t circuit_index, size_t pin_index, size_t net_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || pin_index == lay::no_netlist_index || net_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index, mp_indexer->pin_count (circuits), net_index + 1); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index, mp_indexer->pin_count (circuits), net_index + 1);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net (size_t circuit_index, size_t net_index) const NetlistBrowserModel::make_id_circuit_net (size_t circuit_index, size_t net_index) const
{ {
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index) {
return no_id;
} else {
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net_device_terminal (size_t circuit_index, size_t net_index, size_t terminal_ref_index) const NetlistBrowserModel::make_id_circuit_net_device_terminal (size_t circuit_index, size_t net_index, size_t terminal_ref_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index || terminal_ref_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net_device_terminal_others (size_t circuit_index, size_t net_index, size_t terminal_ref_index, size_t other_index) const NetlistBrowserModel::make_id_circuit_net_device_terminal_others (size_t circuit_index, size_t net_index, size_t terminal_ref_index, size_t other_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index || terminal_ref_index == lay::no_netlist_index || other_index == lay::no_netlist_index) {
IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index)); return no_id;
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index, mp_indexer->net_terminal_count (nets), other_index + 1); } else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index, mp_indexer->net_terminal_count (nets), other_index + 1);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net_pin (size_t circuit_index, size_t net_index, size_t pin_index) const NetlistBrowserModel::make_id_circuit_net_pin (size_t circuit_index, size_t net_index, size_t pin_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index || pin_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 2, 4, pin_index); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 2, 4, pin_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net_subcircuit_pin (size_t circuit_index, size_t net_index, size_t pin_ref_index) const NetlistBrowserModel::make_id_circuit_net_subcircuit_pin (size_t circuit_index, size_t net_index, size_t pin_ref_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index || pin_ref_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_net_subcircuit_pin_others (size_t circuit_index, size_t net_index, size_t pin_ref_index, size_t other_index) const NetlistBrowserModel::make_id_circuit_net_subcircuit_pin_others (size_t circuit_index, size_t net_index, size_t pin_ref_index, size_t other_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || net_index == lay::no_netlist_index || pin_ref_index == lay::no_netlist_index || other_index == lay::no_netlist_index) {
IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index)); return no_id;
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index, mp_indexer->net_subcircuit_pin_count (nets), other_index + 1); } else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index, mp_indexer->net_subcircuit_pin_count (nets), other_index + 1);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_subcircuit (size_t circuit_index, size_t subcircuit_index) const NetlistBrowserModel::make_id_circuit_subcircuit (size_t circuit_index, size_t subcircuit_index) const
{ {
return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index); if (circuit_index == lay::no_netlist_index || subcircuit_index == lay::no_netlist_index) {
return no_id;
} else {
return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_subcircuit_pin (size_t circuit_index, size_t subcircuit_index, size_t pin_index) const NetlistBrowserModel::make_id_circuit_subcircuit_pin (size_t circuit_index, size_t subcircuit_index, size_t pin_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || subcircuit_index == lay::no_netlist_index || pin_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index, mp_indexer->subcircuit_count (circuits), pin_index + 1); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index, mp_indexer->subcircuit_count (circuits), pin_index + 1);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_device (size_t circuit_index, size_t device_index) const NetlistBrowserModel::make_id_circuit_device (size_t circuit_index, size_t device_index) const
{ {
return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index); if (circuit_index == lay::no_netlist_index || device_index == lay::no_netlist_index) {
return no_id;
} else {
return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index);
}
} }
void * void *
NetlistBrowserModel::make_id_circuit_device_terminal (size_t circuit_index, size_t device_index, size_t terminal_index) const NetlistBrowserModel::make_id_circuit_device_terminal (size_t circuit_index, size_t device_index, size_t terminal_index) const
{ {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); if (circuit_index == lay::no_netlist_index || device_index == lay::no_netlist_index || terminal_index == lay::no_netlist_index) {
return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index, mp_indexer->device_count (circuits), terminal_index + 1); return no_id;
} else {
IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index));
return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index, mp_indexer->device_count (circuits), terminal_index + 1);
}
} }
bool bool
@ -2238,7 +2290,11 @@ NetlistBrowserModel::subcircuit_from_index (const QModelIndex &index) const
QModelIndex QModelIndex
NetlistBrowserModel::index_from_id (void *id, int column) const NetlistBrowserModel::index_from_id (void *id, int column) const
{ {
if (is_id_circuit (id)) { if (id == no_id) {
return QModelIndex ();
} else if (is_id_circuit (id)) {
return createIndex (circuit_index_from_id (id), column, id); return createIndex (circuit_index_from_id (id), column, id);

View File

@ -393,7 +393,9 @@ size_t NetlistCrossReferenceModel::circuit_index (const circuit_pair &circuits)
} }
i = m_index_of_circuits.find (circuits); i = m_index_of_circuits.find (circuits);
tl_assert (i != m_index_of_circuits.end ()); if (i == m_index_of_circuits.end ()) {
return lay::no_netlist_index;
}
} }
@ -403,35 +405,50 @@ size_t NetlistCrossReferenceModel::circuit_index (const circuit_pair &circuits)
size_t NetlistCrossReferenceModel::net_index (const net_pair &nets) const size_t NetlistCrossReferenceModel::net_index (const net_pair &nets) const
{ {
circuit_pair circuits = parent_of (nets); circuit_pair circuits = parent_of (nets);
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits); const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits);
tl_assert (org_data != 0); if (! org_data) {
return lay::no_netlist_index;
}
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
return get_index_of (nets, org_data->nets.begin (), org_data->nets.end (), data->index_of_nets); return get_index_of (nets, org_data->nets.begin (), org_data->nets.end (), data->index_of_nets);
} }
size_t NetlistCrossReferenceModel::device_index (const device_pair &devices) const size_t NetlistCrossReferenceModel::device_index (const device_pair &devices) const
{ {
circuit_pair circuits = parent_of (devices); circuit_pair circuits = parent_of (devices);
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits); const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits);
tl_assert (org_data != 0); if (! org_data) {
return lay::no_netlist_index;
}
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
return get_index_of (devices, org_data->devices.begin (), org_data->devices.end (), data->index_of_devices); return get_index_of (devices, org_data->devices.begin (), org_data->devices.end (), data->index_of_devices);
} }
size_t NetlistCrossReferenceModel::pin_index (const pin_pair &pins, const circuit_pair &circuits) const size_t NetlistCrossReferenceModel::pin_index (const pin_pair &pins, const circuit_pair &circuits) const
{ {
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits); const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits);
tl_assert (org_data != 0); if (! org_data) {
return lay::no_netlist_index;
}
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
return get_index_of (pins, org_data->pins.begin (), org_data->pins.end (), data->index_of_pins); return get_index_of (pins, org_data->pins.begin (), org_data->pins.end (), data->index_of_pins);
} }
size_t NetlistCrossReferenceModel::subcircuit_index (const subcircuit_pair &subcircuits) const size_t NetlistCrossReferenceModel::subcircuit_index (const subcircuit_pair &subcircuits) const
{ {
circuit_pair circuits = parent_of (subcircuits); circuit_pair circuits = parent_of (subcircuits);
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits); const db::NetlistCrossReference::PerCircuitData *org_data = mp_cross_ref->per_circuit_data_for (circuits);
tl_assert (org_data != 0); if (! org_data) {
return lay::no_netlist_index;
}
PerCircuitCacheData *data = & m_per_circuit_data [circuits];
return get_index_of (subcircuits, org_data->subcircuits.begin (), org_data->subcircuits.end (), data->index_of_subcircuits); return get_index_of (subcircuits, org_data->subcircuits.begin (), org_data->subcircuits.end (), data->index_of_subcircuits);
} }