Some refactoring.

This commit is contained in:
Matthias Koefferlein 2021-07-18 16:54:27 +02:00
parent 2f3e113db0
commit d018805c23
1 changed files with 201 additions and 206 deletions

View File

@ -668,6 +668,40 @@ struct CompareData
tl::RelativeProgress *progress;
};
// --------------------------------------------------------------------------------------------------------------------
// A generic triplet of object category and two IDs
// Used as a key for device terminal edges and subcircuit edges
class CatAndIds
{
public:
CatAndIds (size_t cat, size_t id1, size_t id2)
: m_cat (cat), m_id1 (id1), m_id2 (id2)
{ }
bool operator== (const CatAndIds &other) const
{
return m_cat == other.m_cat && m_id1 == other.m_id1 && m_id2 == other.m_id2;
}
bool operator< (const CatAndIds &other) const
{
if (m_cat != other.m_cat) {
return m_cat < other.m_cat;
}
if (m_id1 != other.m_id1) {
return m_id1 < other.m_id1;
}
if (m_id2 != other.m_id2) {
return m_id2 < other.m_id2;
}
return false;
}
private:
size_t m_cat, m_id1, m_id2;
};
// --------------------------------------------------------------------------------------------------------------------
// NetGraphNode definition and implementation
@ -676,6 +710,156 @@ static size_t translate_terminal_id (size_t tid, const db::Device *device)
return device->device_class () ? device->device_class ()->normalize_terminal_id (tid) : tid;
}
/**
* @brief Represents one transition within a net graph edge
*
* Each transition connects two pins of subcircuits or terminals of devices.
* An edge is basically a collection of transitions.
*/
class Transition
{
public:
Transition (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id)
{
m_ptr = (void *) device;
m_cat = device_category;
m_id1 = terminal1_id;
m_id2 = terminal2_id;
}
Transition (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id)
{
m_ptr = (void *) subcircuit;
m_cat = subcircuit_category;
m_id1 = std::numeric_limits<size_t>::max () - pin1_id;
m_id2 = pin2_id;
}
CatAndIds make_key () const
{
return CatAndIds (m_cat, m_id1, m_id2);
}
bool operator< (const Transition &other) const
{
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
return is_for_subcircuit () < other.is_for_subcircuit ();
}
if (is_for_subcircuit ()) {
if ((subcircuit () != 0) != (other.subcircuit () != 0)) {
return (subcircuit () != 0) < (other.subcircuit () != 0);
}
if (subcircuit () != 0) {
SubCircuitCompare scc;
if (! scc.equals (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()))) {
return scc (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()));
}
}
} else {
if ((device () != 0) != (other.device () != 0)) {
return (device () != 0) < (other.device () != 0);
}
if (device () != 0) {
DeviceCompare dc;
if (! dc.equals (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()))) {
return dc (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()));
}
}
}
if (m_id1 != other.m_id1) {
return m_id1 < other.m_id1;
}
return m_id2 < other.m_id2;
}
bool operator== (const Transition &other) const
{
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
return false;
}
if (is_for_subcircuit ()) {
if ((subcircuit () != 0) != (other.subcircuit () != 0)) {
return false;
}
if (subcircuit () != 0) {
SubCircuitCompare scc;
if (! scc.equals (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()))) {
return false;
}
}
} else {
if ((device () != 0) != (other.device () != 0)) {
return false;
}
if (device () != 0) {
DeviceCompare dc;
if (! dc.equals (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()))) {
return false;
}
}
}
return (m_id1 == other.m_id1 && m_id2 == other.m_id2);
}
std::string to_string () const
{
if (is_for_subcircuit ()) {
const db::SubCircuit *sc = subcircuit ();
size_t pin_id = std::numeric_limits<size_t>::max () - m_id1;
const db::Circuit *c = sc->circuit_ref ();
return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)";
} else {
size_t term_id1 = m_id1;
size_t term_id2 = m_id2;
const db::Device *d = device ();
const db::DeviceClass *dc = d->device_class ();
return std::string ("D") + d->expanded_name () + " " + dc->name () + " "
+ "(" + dc->terminal_definitions () [term_id1].name () + ")->(" + dc->terminal_definitions () [term_id2].name () + ")";
}
}
inline bool is_for_subcircuit () const
{
return m_id1 > std::numeric_limits<size_t>::max () / 2;
}
const db::Device *device () const
{
return (const db::Device *) m_ptr;
}
const db::SubCircuit *subcircuit () const
{
return (const db::SubCircuit *) m_ptr;
}
size_t cat () const
{
return m_cat;
}
private:
void *m_ptr;
size_t m_cat;
size_t m_id1, m_id2;
};
/**
* @brief A node within the net graph
*
@ -691,166 +875,6 @@ static size_t translate_terminal_id (size_t tid, const db::Device *device)
class NetGraphNode
{
public:
/**
* @brief Represents one transition within an edge_iterator
*
* Each transition connects two pins of subcircuits or terminals
* of devices.
* An edge is basically a collection of transitions.
*/
struct Transition
{
Transition (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id)
{
device_pair ().first = device;
device_pair ().second = device_category;
m_id1 = terminal1_id;
m_id2 = terminal2_id;
}
Transition (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id)
{
subcircuit_pair ().first = subcircuit;
subcircuit_pair ().second = subcircuit_category;
m_id1 = std::numeric_limits<size_t>::max () - pin1_id;
m_id2 = pin2_id;
}
size_t id1 () const
{
return m_id1;
}
size_t id2 () const
{
return m_id2;
}
bool operator< (const Transition &other) const
{
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
return is_for_subcircuit () < other.is_for_subcircuit ();
}
if (is_for_subcircuit ()) {
if ((subcircuit_pair ().first != 0) != (other.subcircuit_pair ().first != 0)) {
return (subcircuit_pair ().first != 0) < (other.subcircuit_pair ().first != 0);
}
if (subcircuit_pair ().first != 0) {
SubCircuitCompare scc;
if (! scc.equals (subcircuit_pair (), other.subcircuit_pair ())) {
return scc (subcircuit_pair (), other.subcircuit_pair ());
}
}
} else {
if ((device_pair ().first != 0) != (other.device_pair ().first != 0)) {
return (device_pair ().first != 0) < (other.device_pair ().first != 0);
}
if (device_pair ().first != 0) {
DeviceCompare dc;
if (! dc.equals (device_pair (), other.device_pair ())) {
return dc (device_pair (), other.device_pair ());
}
}
}
if (m_id1 != other.m_id1) {
return m_id1 < other.m_id1;
}
return m_id2 < other.m_id2;
}
bool operator== (const Transition &other) const
{
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
return false;
}
if (is_for_subcircuit ()) {
if ((subcircuit_pair ().first != 0) != (other.subcircuit_pair ().first != 0)) {
return false;
}
if (subcircuit_pair ().first != 0) {
SubCircuitCompare scc;
if (! scc.equals (subcircuit_pair (), other.subcircuit_pair ())) {
return false;
}
}
} else {
if ((device_pair ().first != 0) != (other.device_pair ().first != 0)) {
return false;
}
if (device_pair ().first != 0) {
DeviceCompare dc;
if (! dc.equals (device_pair (), other.device_pair ())) {
return false;
}
}
}
return (m_id1 == other.m_id1 && m_id2 == other.m_id2);
}
std::string to_string () const
{
if (is_for_subcircuit ()) {
const db::SubCircuit *sc = subcircuit_pair ().first;
size_t pin_id = std::numeric_limits<size_t>::max () - m_id1;
const db::Circuit *c = sc->circuit_ref ();
return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)";
} else {
size_t term_id1 = m_id1;
size_t term_id2 = m_id2;
const db::Device *d = device_pair ().first;
const db::DeviceClass *dc = d->device_class ();
return std::string ("D") + d->expanded_name () + " " + dc->name () + " "
+ "(" + dc->terminal_definitions () [term_id1].name () + ")->(" + dc->terminal_definitions () [term_id2].name () + ")";
}
}
inline bool is_for_subcircuit () const
{
return m_id1 > std::numeric_limits<size_t>::max () / 2;
}
std::pair<const db::Device *, size_t> &device_pair ()
{
return *reinterpret_cast<std::pair<const db::Device *, size_t> *> ((void *) &m_ref);
}
const std::pair<const db::Device *, size_t> &device_pair () const
{
return *reinterpret_cast<const std::pair<const db::Device *, size_t> *> ((const void *) &m_ref);
}
std::pair<const db::SubCircuit *, size_t> &subcircuit_pair ()
{
return *reinterpret_cast<std::pair<const db::SubCircuit *, size_t> *> ((void *) &m_ref);
}
const std::pair<const db::SubCircuit *, size_t> &subcircuit_pair () const
{
return *reinterpret_cast<const std::pair<const db::SubCircuit *, size_t> *> ((const void *) &m_ref);
}
private:
char m_ref [sizeof (std::pair<const void *, size_t>)];
size_t m_id1, m_id2;
};
typedef std::pair<std::vector<Transition>, std::pair<size_t, const db::Net *> > edge_type;
static void swap_edges (edge_type &e1, edge_type &e2)
@ -953,7 +977,7 @@ public:
edge_iterator find_edge (const std::vector<Transition> &edge) const
{
edge_iterator res = std::lower_bound (begin (), end (), edge, NetGraphNode::EdgeToEdgeOnlyCompare ());
edge_iterator res = std::lower_bound (begin (), end (), edge, EdgeToEdgeOnlyCompare ());
if (res == end () || res->first != edge) {
return end ();
} else {
@ -1373,9 +1397,9 @@ NetGraphNode::expand_subcircuit_nodes (NetGraph *graph)
for (std::vector<Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
tl_assert (t->is_for_subcircuit ());
if (! sc) {
sc = t->subcircuit_pair ().first;
sc = t->subcircuit ();
} else {
tl_assert (sc == t->subcircuit_pair ().first);
tl_assert (sc == t->subcircuit ());
}
}
@ -1542,35 +1566,6 @@ struct NodeRange
// --------------------------------------------------------------------------------------------------------------------
struct CatAndIds
{
public:
CatAndIds (size_t _cat, size_t _id1, size_t _id2)
: cat (_cat), id1 (_id1), id2 (_id2)
{ }
bool operator== (const CatAndIds &other) const
{
return cat == other.cat && id1 == other.id1 && id2 == other.id2;
}
bool operator< (const CatAndIds &other) const
{
if (cat != other.cat) {
return cat < other.cat;
}
if (id1 != other.id1) {
return id1 < other.id1;
}
if (id2 != other.id2) {
return id2 < other.id2;
}
return false;
}
size_t cat, id1, id2;
};
template <class Obj>
class generic_mapper_for_target_node
{
@ -1659,9 +1654,9 @@ public:
size_t ni = e.second.first;
std::set<std::pair<CatAndIds, const Device *> > &dev = for_node_nc (ni);
for (std::vector<NetGraphNode::Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
for (std::vector<Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
if (! j->is_for_subcircuit ()) {
dev.insert (std::make_pair (CatAndIds (j->device_pair ().second, j->id1 (), j->id2 ()), j->device_pair ().first));
dev.insert (std::make_pair (j->make_key (), j->device ()));
}
}
}
@ -1686,9 +1681,9 @@ public:
size_t ni = e.second.first;
std::set<std::pair<CatAndIds, const SubCircuit *> > &sc = for_node_nc (ni);
for (std::vector<NetGraphNode::Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
for (std::vector<Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
if (j->is_for_subcircuit ()) {
sc.insert (std::make_pair (CatAndIds (j->subcircuit_pair ().second, j->id1 (), j->id2 ()), j->subcircuit_pair ().first));
sc.insert (std::make_pair (j->make_key (), j->subcircuit ()));
}
}
}
@ -1903,21 +1898,21 @@ NetGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, Ci
*/
static bool edges_are_compatible (const NetGraphNode::edge_type &e, const NetGraphNode::edge_type &e_other, const DeviceEquivalenceTracker &device_eq, const SubCircuitEquivalenceTracker &sc_eq)
{
std::vector<NetGraphNode::Transition>::const_iterator t1 = e.first.begin (), tt1 = e.first.end ();
std::vector<NetGraphNode::Transition>::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end ();
std::vector<Transition>::const_iterator t1 = e.first.begin (), tt1 = e.first.end ();
std::vector<Transition>::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end ();
std::vector<void *> p1, p2;
while (t1 != tt1 && t2 != tt2) {
std::vector<NetGraphNode::Transition>::const_iterator t10 = t1, t20 = t2;
std::vector<Transition>::const_iterator t10 = t1, t20 = t2;
p1.clear ();
while (t1 != tt1 && *t1 == *t10) {
if (t1->is_for_subcircuit ()) {
p1.push_back ((void *) sc_eq.other (t1->subcircuit_pair ().first));
p1.push_back ((void *) sc_eq.other (t1->subcircuit ()));
} else {
p1.push_back ((void *) device_eq.other (t1->device_pair ().first));
p1.push_back ((void *) device_eq.other (t1->device ()));
}
++t1;
}
@ -1925,9 +1920,9 @@ static bool edges_are_compatible (const NetGraphNode::edge_type &e, const NetGra
p2.clear ();
while (t2 != tt2 && *t2 == *t20) {
if (t2->is_for_subcircuit ()) {
p2.push_back ((void *) (sc_eq.other (t2->subcircuit_pair ().first) ? t2->subcircuit_pair ().first : 0));
p2.push_back ((void *) (sc_eq.other (t2->subcircuit ()) ? t2->subcircuit () : 0));
} else {
p2.push_back ((void *) (device_eq.other (t2->device_pair ().first) ? t2->device_pair ().first : 0));
p2.push_back ((void *) (device_eq.other (t2->device ()) ? t2->device () : 0));
}
++t2;
}
@ -2004,7 +1999,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
first = false;
}
tl::info << indent (depth) << " " << (nn->net () ? nn->net ()->expanded_name ().c_str() : "(null)") << " via: " << tl::noendl;
for (std::vector<NetGraphNode::Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
for (std::vector<Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
tl::info << (t != i->second->first.begin () ? "; " : "") << t->to_string() << tl::noendl;
}
tl::info << "";
@ -2019,7 +2014,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
first = false;
}
tl::info << indent(depth) << " " << (nn->net() ? nn->net()->expanded_name().c_str() : "(null)") << " via: " << tl::noendl;
for (std::vector<NetGraphNode::Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
for (std::vector<Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
tl::info << (t != i->second->first.begin () ? "; " : "") << t->to_string() << tl::noendl;
}
tl::info << "";
@ -2079,7 +2074,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
static bool has_subcircuits (db::NetGraphNode::edge_iterator e, db::NetGraphNode::edge_iterator ee)
{
while (e != ee) {
for (std::vector<NetGraphNode::Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
for (std::vector<Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
if (t->is_for_subcircuit ()) {
return true;
}