WIP: debugged cross-reference model

This commit is contained in:
Matthias Koefferlein 2019-05-22 23:47:38 +02:00
parent f1fc16d55f
commit 57f9efa611
4 changed files with 185 additions and 36 deletions

View File

@ -39,12 +39,15 @@ NetlistCrossReference::~NetlistCrossReference ()
const NetlistCrossReference::PerCircuitData *
NetlistCrossReference::per_circuit_data_for (const std::pair<const db::Circuit *, const db::Circuit *> &circuits) const
{
per_circuit_data_iterator i = m_per_circuit_data.find (circuits);
if (i == m_per_circuit_data.end ()) {
return 0;
} else {
return & i->second;
std::map<const db::Circuit *, PerCircuitData *>::const_iterator i = m_data_refs.find (circuits.first);
if (i != m_data_refs.end ()) {
return i->second;
}
i = m_data_refs.find (circuits.second);
if (i != m_data_refs.end ()) {
return i->second;
}
return 0;
}
const db::Net *
@ -77,6 +80,7 @@ NetlistCrossReference::clear ()
mp_netlist_b.reset (0);
m_circuits.clear ();
m_per_circuit_data.clear ();
m_data_refs.clear ();
m_per_net_data.clear ();
m_other_circuit.clear ();
m_other_net.clear ();
@ -228,18 +232,17 @@ struct SortNetSubCircuitPins
void
NetlistCrossReference::gen_end_netlist (const db::Netlist *, const db::Netlist *)
{
m_circuits.reserve (m_per_circuit_data.size ());
for (per_circuit_data_iterator i = begin_per_circuit_data (); i != end_per_circuit_data (); ++i) {
m_circuits.push_back (i->first);
}
std::sort (m_circuits.begin (), m_circuits.end (), CircuitsCompareByName ());
}
void
NetlistCrossReference::establish_pair (const db::Circuit *a, const db::Circuit *b)
{
mp_per_circuit_data = & m_per_circuit_data [std::make_pair (a, b)];
m_circuits.push_back (std::make_pair (a, b));
m_per_circuit_data.push_back (PerCircuitData ());
mp_per_circuit_data = & m_per_circuit_data.back ();
m_data_refs [a] = mp_per_circuit_data;
m_data_refs [b] = mp_per_circuit_data;
if (a) {
m_other_circuit [a] = b;
@ -423,7 +426,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 (), SortNetTerminals ());
std::stable_sort (data.terminals.begin (), data.terminals.end (), SortNetTerminals ());
}
void
@ -454,7 +457,6 @@ NetlistCrossReference::build_pin_refs (const std::pair<const db::Net *, const db
prb = b->second;
// remove the entry so we won't find it again
p2r_b.erase (b);
break;
}
}
@ -467,7 +469,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 (), SortNetPins ());
std::stable_sort (data.pins.begin (), data.pins.end (), SortNetPins ());
}
void
@ -520,7 +522,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 (), SortNetSubCircuitPins ());
std::stable_sort (data.subcircuit_pins.begin (), data.subcircuit_pins.end (), SortNetSubCircuitPins ());
}
void

View File

@ -237,19 +237,7 @@ public:
size_t circuit_count () const
{
return m_per_circuit_data.size ();
}
typedef std::map<std::pair<const db::Circuit *, const db::Circuit *>, PerCircuitData>::const_iterator per_circuit_data_iterator;
per_circuit_data_iterator begin_per_circuit_data () const
{
return m_per_circuit_data.begin ();
}
per_circuit_data_iterator end_per_circuit_data () const
{
return m_per_circuit_data.end ();
return m_circuits.size ();
}
const PerCircuitData *per_circuit_data_for (const std::pair<const db::Circuit *, const db::Circuit *> &circuits) const;
@ -282,7 +270,8 @@ public:
private:
tl::weak_ptr<db::Netlist> mp_netlist_a, mp_netlist_b;
std::vector<std::pair<const db::Circuit *, const db::Circuit *> > m_circuits;
std::map<std::pair<const db::Circuit *, const db::Circuit *>, PerCircuitData> m_per_circuit_data;
std::list<PerCircuitData> m_per_circuit_data;
std::map<const db::Circuit *, PerCircuitData *> m_data_refs;
mutable std::map<std::pair<const db::Net *, const db::Net *>, PerNetData> m_per_net_data;
std::map<const db::Circuit *, const db::Circuit *> m_other_circuit;
std::map<const db::Net *, const db::Net *> m_other_net;

View File

@ -115,13 +115,20 @@ static IndexedNetlistModel::circuit_pair get_parent_of (const Pair &pair, const
typename std::map<Pair, IndexedNetlistModel::circuit_pair>::iterator i = cache.find (pair);
if (i == cache.end ()) {
for (db::NetlistCrossReference::per_circuit_data_iterator c = cross_ref->begin_per_circuit_data (); c != cross_ref->end_per_circuit_data (); ++c) {
for (db::NetlistCrossReference::circuits_iterator c = cross_ref->begin_circuits (); c != cross_ref->end_circuits (); ++c) {
const db::NetlistCrossReference::PerCircuitData *data = cross_ref->per_circuit_data_for (*c);
typedef DataGetter<typename Pair::first_type> getter_type;
typedef typename getter_type::iterator_type iterator_type;
iterator_type b = getter_type ().begin (c->second);
iterator_type e = getter_type ().end (c->second);
iterator_type b = getter_type ().begin (*data);
iterator_type e = getter_type ().end (*data);
for (iterator_type j = b; j != e; ++j) {
cache.insert (std::make_pair (j->pair, c->first));
cache.insert (std::make_pair (j->pair, *c));
if (j->pair.first) {
cache.insert (std::make_pair (Pair (j->pair.first, 0), *c));
}
if (j->pair.second) {
cache.insert (std::make_pair (Pair (0, j->pair.second), *c));
}
}
}
@ -210,15 +217,22 @@ template <class Pair, class Iter>
static size_t get_index_of (const Pair &pair, Iter begin, Iter end, std::map<Pair, size_t> &cache)
{
typename std::map<Pair, size_t>::iterator i = cache.find (pair);
if (i != cache.end ()) {
if (i == cache.end ()) {
size_t index = 0;
for (Iter j = begin; j != end; ++j, ++index) {
cache.insert (std::make_pair (j->pair, index));
if (j->pair.first) {
cache.insert (std::make_pair (Pair (j->pair.first, 0), index));
}
if (j->pair.second) {
cache.insert (std::make_pair (Pair (0, j->pair.second), index));
}
}
i = cache.find (pair);
tl_assert (i != cache.end ());
}
return i->second;
@ -228,15 +242,22 @@ static size_t get_index_of (const Pair &pair, Iter begin, Iter end, std::map<Pai
size_t NetlistCrossReferenceModel::circuit_index (const circuit_pair &circuits) const
{
typename std::map<circuit_pair, size_t>::iterator i = m_index_of_circuits.find (circuits);
if (i != m_index_of_circuits.end ()) {
if (i == m_index_of_circuits.end ()) {
size_t index = 0;
for (db::NetlistCrossReference::circuits_iterator j = mp_cross_ref->begin_circuits (); j != mp_cross_ref->end_circuits (); ++j, ++index) {
m_index_of_circuits.insert (std::make_pair (*j, index));
if (j->first) {
m_index_of_circuits.insert (std::make_pair (circuit_pair (j->first, 0), index));
}
if (j->second) {
m_index_of_circuits.insert (std::make_pair (circuit_pair (0, j->second), index));
}
}
i = m_index_of_circuits.find (circuits);
tl_assert (i != m_index_of_circuits.end ());
}
return i->second;

View File

@ -243,8 +243,145 @@ TEST (2)
QModelIndex inv2Index = model->index (1, 0, QModelIndex ());
// INV2 circuit node
EXPECT_EQ (model->hasChildren (inv2Index), true);
EXPECT_EQ (model->rowCount (inv2Index), 14);
// ...
// first of pins in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Index), Qt::UserRole).toString ()), "$0|$0");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Index), Qt::DisplayRole).toString ()), "$0/$0");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2Index), Qt::DisplayRole).toString ()), "$0");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2Index), Qt::DisplayRole).toString ()), "$0");
// INV2, pin 0 node
QModelIndex inv2Pin0Index = model->index (0, 0, inv2Index);
EXPECT_EQ (model->hasChildren (inv2Pin0Index), true);
EXPECT_EQ (model->rowCount (inv2Pin0Index), 1);
// INV2, pin 0 has one net node
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Pin0Index), Qt::UserRole).toString ()), "$1|1");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Pin0Index), Qt::DisplayRole).toString ()), "$1/1");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2Pin0Index), Qt::DisplayRole).toString ()), "<a href='int:net?id=9'>$1/1</a>");
std::pair<const db::Net *, const db::Net *> nets = model->net_from_index (model->index_from_id ((void *) 9, 0));
EXPECT_EQ (nets.first != 0, true);
if (nets.first != 0) {
EXPECT_EQ (nets.first->expanded_name (), "$1");
}
EXPECT_EQ (nets.second != 0, true);
if (nets.second != 0) {
EXPECT_EQ (nets.second->expanded_name (), "1");
}
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2Pin0Index), Qt::DisplayRole).toString ()), "<a href='int:net?id=9'>$1/1</a>");
// first of nets in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (6, 0, inv2Index), Qt::UserRole).toString ()), "$1|1");
EXPECT_EQ (tl::to_string (model->data (model->index (6, 0, inv2Index), Qt::DisplayRole).toString ()), "$1/1");
EXPECT_EQ (tl::to_string (model->data (model->index (6, 1, inv2Index), Qt::DisplayRole).toString ()), "$1 (2)");
EXPECT_EQ (tl::to_string (model->data (model->index (6, 2, inv2Index), Qt::DisplayRole).toString ()), "1 (2)");
// INV2, net 1 node
QModelIndex inv2Net0Index = model->index (6, 0, inv2Index);
EXPECT_EQ (model->hasChildren (inv2Net0Index), true);
EXPECT_EQ (model->rowCount (inv2Net0Index), 2);
// INV2, net 1 has one pin and one terminal at BULK
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Net0Index), Qt::UserRole).toString ()), "B|B|PMOS|PMOS|$1|$1");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Net0Index), Qt::DisplayRole).toString ()), "B/B - PMOS/PMOS");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2Net0Index), Qt::DisplayRole).toString ()), "<a href='int:device?id=17'>$1/$1</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2Net0Index), Qt::DisplayRole).toString ()), "<a href='int:device?id=17'>$1/$1</a>");
// This terminal connects to a device with four other terminals ..
QModelIndex inv2Net0TerminalIndex = model->index (0, 0, inv2Net0Index);
EXPECT_EQ (model->hasChildren (inv2Net0TerminalIndex), true);
EXPECT_EQ (model->rowCount (inv2Net0TerminalIndex), 4);
// .. whose second terminal is gate
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::UserRole).toString ()), "G|G|IN|2");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "G/G");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 1, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "<a href='int:net?id=73'>IN/2</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 2, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "<a href='int:net?id=73'>IN/2</a>");
// The Pin
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0Index), Qt::UserRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0Index), Qt::DisplayRole).toString ()), "<a href='int:pin?id=5'>$0/$0</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 1, inv2Net0Index), Qt::DisplayRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 2, inv2Net0Index), Qt::DisplayRole).toString ()), "");
// This pin does not have children
QModelIndex inv2Net0PinIndex = model->index (1, 0, inv2Net0Index);
EXPECT_EQ (model->hasChildren (inv2Net0PinIndex), false);
EXPECT_EQ (model->rowCount (inv2Net0PinIndex), 0);
// second of nets in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (7, 0, inv2Index), Qt::UserRole).toString ()), "BULK|6");
EXPECT_EQ (tl::to_string (model->data (model->index (7, 0, inv2Index), Qt::DisplayRole).toString ()), "BULK/6");
EXPECT_EQ (tl::to_string (model->data (model->index (7, 1, inv2Index), Qt::DisplayRole).toString ()), "BULK (2)");
EXPECT_EQ (tl::to_string (model->data (model->index (7, 2, inv2Index), Qt::DisplayRole).toString ()), "6 (2)");
// first of devices in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (12, 0, inv2Index), Qt::UserRole).toString ()), "$1|$1|PMOS|PMOS");
EXPECT_EQ (tl::to_string (model->data (model->index (12, 0, inv2Index), Qt::DisplayRole).toString ()), "PMOS/PMOS");
EXPECT_EQ (tl::to_string (model->data (model->index (12, 1, inv2Index), Qt::DisplayRole).toString ()), "$1 - PMOS [L=0.25, W=3.5]");
EXPECT_EQ (tl::to_string (model->data (model->index (12, 2, inv2Index), Qt::DisplayRole).toString ()), "$1 - PMOS [L=0.25, W=3.5]");
QModelIndex inv2PairIndex = model->index (2, 0, QModelIndex ());
// INV2PAIR circuit node
EXPECT_EQ (model->hasChildren (inv2PairIndex), true);
EXPECT_EQ (model->rowCount (inv2PairIndex), 18);
// first of pins in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairIndex), Qt::UserRole).toString ()), "$4");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairIndex), Qt::DisplayRole).toString ()), "-/$4");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2PairIndex), Qt::DisplayRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2PairIndex), Qt::DisplayRole).toString ()), "$4");
// INV2, pin 0 node
QModelIndex inv2PairPin0Index = model->index (0, 0, inv2PairIndex);
EXPECT_EQ (model->hasChildren (inv2PairPin0Index), true);
EXPECT_EQ (model->rowCount (inv2PairPin0Index), 1);
// INV2, pin 0 has one net node
// The pin isnt't connected to any net, left side because there is no match, right side because the pin isn't connected
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairPin0Index), Qt::UserRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairPin0Index), Qt::DisplayRole).toString ()), "-/-");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2PairPin0Index), Qt::DisplayRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2PairPin0Index), Qt::DisplayRole).toString ()), "");
// first of nets in INV2 circuit
EXPECT_EQ (tl::to_string (model->data (model->index (8, 0, inv2PairIndex), Qt::UserRole).toString ()), "$4");
EXPECT_EQ (tl::to_string (model->data (model->index (8, 0, inv2PairIndex), Qt::DisplayRole).toString ()), "$4/-");
EXPECT_EQ (tl::to_string (model->data (model->index (8, 1, inv2PairIndex), Qt::DisplayRole).toString ()), "$4 (3)");
EXPECT_EQ (tl::to_string (model->data (model->index (8, 2, inv2PairIndex), Qt::DisplayRole).toString ()), "");
// This net has only left side which has one pin and two subcircuits
QModelIndex inv2PairNet0Index = model->index (8, 0, inv2PairIndex);
EXPECT_EQ (model->hasChildren (inv2PairNet0Index), true);
EXPECT_EQ (model->rowCount (inv2PairNet0Index), 3);
// The pin
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairNet0Index), Qt::UserRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairNet0Index), Qt::DisplayRole).toString ()), "<a href='int:pin?id=38'>$3/-</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2PairNet0Index), Qt::DisplayRole).toString ()), "");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2PairNet0Index), Qt::DisplayRole).toString ()), "");
// This pin does not have children
QModelIndex inv2PairNet0Pin0Index = model->index (0, 0, inv2PairNet0Index);
EXPECT_EQ (model->hasChildren (inv2PairNet0Pin0Index), false);
EXPECT_EQ (model->rowCount (inv2PairNet0Pin0Index), 0);
// The first subcircuit
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2PairNet0Index), Qt::UserRole).toString ()), "OUT|INV2|$1");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2PairNet0Index), Qt::DisplayRole).toString ()), "<a href='int:pin?id=101'>OUT/-</a> - <a href='int:circuit?id=1'>INV2/-</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 1, inv2PairNet0Index), Qt::DisplayRole).toString ()), "<a href='int:subcircuit?id=46'>$1/-</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (1, 2, inv2PairNet0Index), Qt::DisplayRole).toString ()), "");
// This subcircuit has 6 other pins
QModelIndex inv2PairNet0SubCircuit0Index = model->index (1, 0, inv2PairNet0Index);
EXPECT_EQ (model->hasChildren (inv2PairNet0SubCircuit0Index), true);
EXPECT_EQ (model->rowCount (inv2PairNet0SubCircuit0Index), 6);
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairNet0SubCircuit0Index), Qt::UserRole).toString ()), "$1");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2PairNet0SubCircuit0Index), Qt::DisplayRole).toString ()), "<a href='int:pin?id=5'>$0/$0</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 1, inv2PairNet0SubCircuit0Index), Qt::DisplayRole).toString ()), "<a href='int:net?id=170'>$7/-</a>");
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2PairNet0SubCircuit0Index), Qt::DisplayRole).toString ()), "<a href='int:net?id=170'>$7/-</a>");
}