From eb435d5d85515b4b7dbc80c03e894304541a0d13 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 6 Jan 2019 12:53:22 +0100 Subject: [PATCH] WIP: refactoring - separated pins of net into outgoing and subcircuit. --- src/db/db/dbLayoutToNetlist.cc | 54 +++---- src/db/db/dbNetlist.cc | 152 ++++++++++------- src/db/db/dbNetlist.h | 171 +++++++++++++++++--- src/db/db/gsiDeclDbNetlist.cc | 50 ++++-- src/db/unit_tests/dbLayoutToNetlistTests.cc | 2 +- src/db/unit_tests/dbNetlistTests.cc | 50 +++--- testdata/ruby/dbNetlist.rb | 25 ++- 7 files changed, 342 insertions(+), 162 deletions(-) diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 0e2adb5d0..5a3bcfe8a 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -356,46 +356,41 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target continue; } - std::set excluded_nets; - if (circuit_cell_name_prefix) { - for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) { - excluded_nets.insert (c->net_for_pin (p->id ())); - } - } - db::cell_index_type target_ci = cmap.cell_mapping (c->cell_index ()); for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { - if (excluded_nets.find (n.operator-> ()) == excluded_nets.end ()) { + // exlude local nets in recursive mode + if (circuit_cell_name_prefix && n->pin_count () > 0) { + continue; + } - const db::connected_clusters &ccl = m_netex.clusters ().clusters_per_cell (c->cell_index ()); - const db::local_cluster &cl = ccl.cluster_by_id (n->cluster_id ()); + const db::connected_clusters &ccl = m_netex.clusters ().clusters_per_cell (c->cell_index ()); + const db::local_cluster &cl = ccl.cluster_by_id (n->cluster_id ()); - bool any_connections = ! ccl.connections_for_cluster (n->cluster_id ()).empty (); + bool any_connections = ! ccl.connections_for_cluster (n->cluster_id ()).empty (); - bool any_shapes = false; - for (std::map::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) { - any_shapes = ! cl.begin (layer_of (*m->second)).at_end (); - } + bool any_shapes = false; + for (std::map::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) { + any_shapes = ! cl.begin (layer_of (*m->second)).at_end (); + } - if (any_shapes || (circuit_cell_name_prefix && any_connections)) { + if (any_shapes || (circuit_cell_name_prefix && any_connections)) { - db::cell_index_type net_ci = target_ci; + db::cell_index_type net_ci = target_ci; - if (net_cell_name_prefix) { + if (net_cell_name_prefix) { - db::Cell &tc = target.cell (target_ci); - net_ci = target.add_cell ((std::string (net_cell_name_prefix) + n->expanded_name ()).c_str ()); - tc.insert (db::CellInstArray (db::CellInst (net_ci), db::Trans ())); - - } - - build_net_rec (*n, target, target.cell (net_ci), lmap, circuit_cell_name_prefix, cell_map); + db::Cell &tc = target.cell (target_ci); + net_ci = target.add_cell ((std::string (net_cell_name_prefix) + n->expanded_name ()).c_str ()); + tc.insert (db::CellInstArray (db::CellInst (net_ci), db::Trans ())); } + build_net_rec (*n, target, target.cell (net_ci), lmap, circuit_cell_name_prefix, cell_map); + } + } } @@ -484,16 +479,11 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin // follow the path up in the net hierarchy using the transformation and the upper cell index as the // guide line - while (! inst_path.empty () && circuit->is_external_net (net)) { + while (! inst_path.empty () && net->pin_count () > 0) { cell_indexes.pop_back (); - db::Pin *pin = 0; - for (db::Circuit::pin_iterator p = circuit->begin_pins (); p != circuit->end_pins () && ! pin; ++p) { - if (circuit->net_for_pin (p->id ()) == net) { - pin = p.operator-> (); - } - } + const db::Pin *pin = circuit->pin_by_id (net->begin_pins ()->pin_id ()); tl_assert (pin != 0); db::DCplxTrans dtrans = dbu_trans * inst_path.back ().complex_trans () * dbu_trans_inv; diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 505604177..914f6a882 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -191,9 +191,9 @@ SubCircuit::SubCircuit () SubCircuit::~SubCircuit() { - for (std::vector::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) { - if (*p != Net::pin_iterator () && (*p)->net ()) { - (*p)->net ()->erase_pin (*p); + for (std::vector::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) { + if (*p != Net::subcircuit_pin_iterator () && (*p)->net ()) { + (*p)->net ()->erase_subcircuit_pin (*p); } } } @@ -233,10 +233,10 @@ void SubCircuit::set_trans (const db::DCplxTrans &t) m_trans = t; } -void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::pin_iterator iter) +void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::subcircuit_pin_iterator iter) { if (m_pin_refs.size () < pin_id + 1) { - m_pin_refs.resize (pin_id + 1, Net::pin_iterator ()); + m_pin_refs.resize (pin_id + 1, Net::subcircuit_pin_iterator ()); } m_pin_refs [pin_id] = iter; } @@ -255,8 +255,8 @@ void SubCircuit::set_circuit_ref (Circuit *c) const Net *SubCircuit::net_for_pin (size_t pin_id) const { if (pin_id < m_pin_refs.size ()) { - Net::pin_iterator p = m_pin_refs [pin_id]; - if (p != Net::pin_iterator ()) { + Net::subcircuit_pin_iterator p = m_pin_refs [pin_id]; + if (p != Net::subcircuit_pin_iterator ()) { return p->net (); } } @@ -270,15 +270,15 @@ void SubCircuit::connect_pin (size_t pin_id, Net *net) } if (pin_id < m_pin_refs.size ()) { - Net::pin_iterator p = m_pin_refs [pin_id]; - if (p != Net::pin_iterator () && p->net ()) { - p->net ()->erase_pin (p); + Net::subcircuit_pin_iterator p = m_pin_refs [pin_id]; + if (p != Net::subcircuit_pin_iterator () && p->net ()) { + p->net ()->erase_subcircuit_pin (p); } - m_pin_refs [pin_id] = Net::pin_iterator (); + m_pin_refs [pin_id] = Net::subcircuit_pin_iterator (); } if (net) { - net->add_pin (NetPinRef (this, pin_id)); + net->add_subcircuit_pin (NetSubcircuitPinRef (this, pin_id)); } } @@ -333,25 +333,19 @@ NetTerminalRef::device_class () const // NetPinRef class implementation NetPinRef::NetPinRef () - : m_pin_id (0), mp_subcircuit (0), mp_net (0) + : m_pin_id (0), mp_net (0) { // .. nothing yet .. } NetPinRef::NetPinRef (size_t pin_id) - : m_pin_id (pin_id), mp_subcircuit (0), mp_net (0) -{ - // .. nothing yet .. -} - -NetPinRef::NetPinRef (SubCircuit *circuit, size_t pin_id) - : m_pin_id (pin_id), mp_subcircuit (circuit), mp_net (0) + : m_pin_id (pin_id), mp_net (0) { // .. nothing yet .. } NetPinRef::NetPinRef (const NetPinRef &other) - : m_pin_id (other.m_pin_id), mp_subcircuit (other.mp_subcircuit), mp_net (0) + : m_pin_id (other.m_pin_id), mp_net (0) { // .. nothing yet .. } @@ -360,18 +354,51 @@ NetPinRef &NetPinRef::operator= (const NetPinRef &other) { if (this != &other) { m_pin_id = other.m_pin_id; - mp_subcircuit = other.mp_subcircuit; } return *this; } const Pin *NetPinRef::pin () const { - if (! mp_subcircuit) { - if (mp_net && mp_net->circuit ()) { - return mp_net->circuit ()->pin_by_id (m_pin_id); - } - } else if (mp_subcircuit->circuit_ref ()) { + if (mp_net && mp_net->circuit ()) { + return mp_net->circuit ()->pin_by_id (m_pin_id); + } + return 0; +} + +// -------------------------------------------------------------------------------- +// NetSubcircuitPinRef class implementation + +NetSubcircuitPinRef::NetSubcircuitPinRef () + : m_pin_id (0), mp_subcircuit (0), mp_net (0) +{ + // .. nothing yet .. +} + +NetSubcircuitPinRef::NetSubcircuitPinRef (SubCircuit *circuit, size_t pin_id) + : m_pin_id (pin_id), mp_subcircuit (circuit), mp_net (0) +{ + // .. nothing yet .. +} + +NetSubcircuitPinRef::NetSubcircuitPinRef (const NetSubcircuitPinRef &other) + : m_pin_id (other.m_pin_id), mp_subcircuit (other.mp_subcircuit), mp_net (0) +{ + // .. nothing yet .. +} + +NetSubcircuitPinRef &NetSubcircuitPinRef::operator= (const NetSubcircuitPinRef &other) +{ + if (this != &other) { + m_pin_id = other.m_pin_id; + mp_subcircuit = other.mp_subcircuit; + } + return *this; +} + +const Pin *NetSubcircuitPinRef::pin () const +{ + if (mp_subcircuit && mp_subcircuit->circuit_ref ()) { return mp_subcircuit->circuit_ref ()->pin_by_id (m_pin_id); } return 0; @@ -407,6 +434,10 @@ Net &Net::operator= (const Net &other) m_name = other.m_name; m_cluster_id = other.m_cluster_id; + for (const_subcircuit_pin_iterator i = other.begin_subcircuit_pins (); i != other.end_subcircuit_pins (); ++i) { + add_subcircuit_pin (*i); + } + for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) { add_pin (*i); } @@ -436,6 +467,10 @@ void Net::clear () while (! m_pins.empty ()) { erase_pin (begin_pins ()); } + + while (! m_subcircuit_pins.empty ()) { + erase_subcircuit_pin (begin_subcircuit_pins ()); + } } void Net::set_name (const std::string &name) @@ -483,25 +518,37 @@ void Net::add_pin (const NetPinRef &pin) NetPinRef &new_pin = m_pins.back (); new_pin.set_net (this); - if (! pin.subcircuit ()) { - if (mp_circuit) { - mp_circuit->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ()); - } - } else { - new_pin.subcircuit ()->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ()); + if (mp_circuit) { + mp_circuit->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ()); } } +void Net::add_subcircuit_pin (const NetSubcircuitPinRef &pin) +{ + m_subcircuit_pins.push_back (pin); + NetSubcircuitPinRef &new_pin = m_subcircuit_pins.back (); + new_pin.set_net (this); + + tl_assert (pin.subcircuit () != 0); + new_pin.subcircuit ()->set_pin_ref_for_pin (new_pin.pin_id (), --m_subcircuit_pins.end ()); +} + void Net::erase_pin (pin_iterator iter) { - if (iter->subcircuit ()) { - iter->subcircuit ()->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ()); - } else if (mp_circuit) { + if (mp_circuit) { mp_circuit->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ()); } m_pins.erase (iter); } +void Net::erase_subcircuit_pin (subcircuit_pin_iterator iter) +{ + if (iter->subcircuit ()) { + iter->subcircuit ()->set_pin_ref_for_pin (iter->pin_id (), subcircuit_pin_iterator ()); + } + m_subcircuit_pins.erase (iter); +} + void Net::add_terminal (const NetTerminalRef &terminal) { if (! terminal.device ()) { @@ -612,13 +659,13 @@ Circuit &Circuit::operator= (const Circuit &other) } for (Net::const_pin_iterator p = i->begin_pins (); p != i->end_pins (); ++p) { - if (! p->subcircuit ()) { - n->add_pin (NetPinRef (p->pin_id ())); - } else { - std::map::const_iterator m = sc_table.find (p->subcircuit ()); - tl_assert (m != sc_table.end ()); - n->add_pin (NetPinRef (m->second, p->pin_id ())); - } + n->add_pin (NetPinRef (p->pin_id ())); + } + + for (Net::const_subcircuit_pin_iterator p = i->begin_subcircuit_pins (); p != i->end_subcircuit_pins (); ++p) { + std::map::const_iterator m = sc_table.find (p->subcircuit ()); + tl_assert (m != sc_table.end ()); + n->add_subcircuit_pin (NetSubcircuitPinRef (m->second, p->pin_id ())); } } @@ -869,21 +916,6 @@ void Circuit::connect_pin (size_t pin_id, Net *net) } } -bool Circuit::is_external_net (const db::Net *net) const -{ - if (!net || net->pin_count () == 0) { - return false; - } - - for (std::vector::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) { - if (*p != Net::pin_iterator () && (*p)->net () == net) { - return true; - } - } - - return false; -} - void Circuit::purge_nets () { std::vector nets_to_be_purged; @@ -1541,7 +1573,7 @@ void Netlist::make_top_level_pins () // create pins for the named nets and connect them for (Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets (); ++n) { - if (! n->name ().empty () && n->terminal_count () + n->pin_count () > 0) { + if (! n->name ().empty () && n->terminal_count () + n->subcircuit_pin_count () > 0) { Pin pin = circuit->add_pin (n->name ()); circuit->connect_pin (pin.id (), n.operator-> ()); } @@ -1633,7 +1665,7 @@ std::string Netlist::to_string () const #if 0 // for debugging for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { - res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n"; + res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " sc_pins=" + tl::to_string (n->subcircuit_pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n"; } #endif diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index 4c689389d..7d048db5a 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -260,9 +260,7 @@ private: /** * @brief A reference to a pin inside a net * - * A pin belongs to a subcircuit. - * If the subcircuit reference is 0, the pin is a pin of the current circuit - * (upward pin). + * This object describes a connection to an outgoing pin. */ class DB_PUBLIC NetPinRef { @@ -277,11 +275,6 @@ public: */ NetPinRef (size_t pin_id); - /** - * @brief Creates a pin reference to the given pin of the given subcircuit - */ - NetPinRef (SubCircuit *circuit, size_t pin_id); - /** * @brief Copy constructor */ @@ -296,6 +289,95 @@ public: * @brief Comparison */ bool operator< (const NetPinRef &other) const + { + return m_pin_id < other.m_pin_id; + } + + /** + * @brief Equality + */ + bool operator== (const NetPinRef &other) const + { + return (m_pin_id == other.m_pin_id); + } + + /** + * @brief Gets the pin reference (const version) + */ + size_t pin_id () const + { + return m_pin_id; + } + + /** + * @brief Gets the pin reference from the pin id + * If the pin cannot be resolved, null is returned. + */ + const Pin *pin () const; + + /** + * @brief Gets the net the pin lives in + */ + Net *net () + { + return mp_net; + } + + /** + * @brief Gets the net the pin lives in (const version) + */ + const Net *net () const + { + return mp_net; + } + +private: + friend class Net; + + size_t m_pin_id; + Net *mp_net; + + /** + * @brief Sets the net the terminal lives in + */ + void set_net (Net *net) + { + mp_net = net; + } +}; + +/** + * @brief A reference to a pin inside a net + * + * This object describes a connection to a pin of a subcircuit. + */ +class DB_PUBLIC NetSubcircuitPinRef +{ +public: + /** + * @brief Default constructor + */ + NetSubcircuitPinRef (); + + /** + * @brief Creates a pin reference to the given pin of the given subcircuit + */ + NetSubcircuitPinRef (SubCircuit *circuit, size_t pin_id); + + /** + * @brief Copy constructor + */ + NetSubcircuitPinRef (const NetSubcircuitPinRef &other); + + /** + * @brief Assignment + */ + NetSubcircuitPinRef &operator= (const NetSubcircuitPinRef &other); + + /** + * @brief Comparison + */ + bool operator< (const NetSubcircuitPinRef &other) const { if (mp_subcircuit != other.mp_subcircuit) { return mp_subcircuit < other.mp_subcircuit; @@ -306,7 +388,7 @@ public: /** * @brief Equality */ - bool operator== (const NetPinRef &other) const + bool operator== (const NetSubcircuitPinRef &other) const { return (mp_subcircuit == other.mp_subcircuit && m_pin_id == other.m_pin_id); } @@ -388,6 +470,9 @@ public: typedef std::list pin_list; typedef pin_list::const_iterator const_pin_iterator; typedef pin_list::iterator pin_iterator; + typedef std::list subcircuit_pin_list; + typedef subcircuit_pin_list::const_iterator const_subcircuit_pin_iterator; + typedef subcircuit_pin_list::iterator subcircuit_pin_iterator; /** * @brief Constructor @@ -525,6 +610,48 @@ public: return m_pins.end (); } + /** + * @brief Adds a subcircuit pin to this net + */ + void add_subcircuit_pin (const NetSubcircuitPinRef &pin); + + /** + * @brief Erases the given subcircuit pin from this net + */ + void erase_subcircuit_pin (subcircuit_pin_iterator iter); + + /** + * @brief Begin iterator for the pins of the net (const version) + */ + const_subcircuit_pin_iterator begin_subcircuit_pins () const + { + return m_subcircuit_pins.begin (); + } + + /** + * @brief End iterator for the pins of the net (const version) + */ + const_subcircuit_pin_iterator end_subcircuit_pins () const + { + return m_subcircuit_pins.end (); + } + + /** + * @brief Begin iterator for the pins of the net (non-const version) + */ + subcircuit_pin_iterator begin_subcircuit_pins () + { + return m_subcircuit_pins.begin (); + } + + /** + * @brief End iterator for the pins of the net (non-const version) + */ + subcircuit_pin_iterator end_subcircuit_pins () + { + return m_subcircuit_pins.end (); + } + /** * @brief Adds a terminal to this net */ @@ -572,7 +699,7 @@ public: */ bool is_floating () const { - return (m_pins.size () + m_terminals.size ()) < 2; + return (m_pins.size () + m_subcircuit_pins.size () + m_terminals.size ()) < 2; } /** @@ -580,17 +707,25 @@ public: */ bool is_internal () const { - return m_pins.size () == 0 && m_terminals.size () == 2; + return m_pins.size () == 0 && m_subcircuit_pins.size () == 0 && m_terminals.size () == 2; } /** - * @brief Returns the number of pins connected + * @brief Returns the number of outgoing pins connected */ size_t pin_count () const { return m_pins.size (); } + /** + * @brief Returns the number of subcircuit pins connected + */ + size_t subcircuit_pin_count () const + { + return m_subcircuit_pins.size (); + } + /** * @brief Returns the number of terminals connected */ @@ -604,6 +739,7 @@ private: terminal_list m_terminals; pin_list m_pins; + subcircuit_pin_list m_subcircuit_pins; std::string m_name; size_t m_cluster_id; Circuit *mp_circuit; @@ -971,14 +1107,14 @@ private: tl::weak_ptr m_circuit_ref; std::string m_name; db::DCplxTrans m_trans; - std::vector m_pin_refs; + std::vector m_pin_refs; size_t m_id; Circuit *mp_circuit; /** * @brief Sets the pin reference for a specific pin */ - void set_pin_ref_for_pin (size_t ppin_id, Net::pin_iterator iter); + void set_pin_ref_for_pin (size_t ppin_id, Net::subcircuit_pin_iterator iter); /** * @brief Sets the circuit reference @@ -1531,13 +1667,6 @@ public: */ void connect_pin (size_t pin_id, Net *net); - /** - * @brief Returns true, if the net is an external net - * - * External nets are nets which are connected to an outgoing pin. - */ - bool is_external_net (const db::Net *net) const; - /** * @brief Purge unused nets * diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 10957428a..86b357b54 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -236,18 +236,31 @@ Class decl_dbNetPinRef ("db", "NetPinRef", gsi::method ("pin", &db::NetPinRef::pin, "@brief Gets the \\Pin object of the pin the connection is made to." ) + - gsi::method ("subcircuit", (db::SubCircuit *(db::NetPinRef::*) ()) &db::NetPinRef::subcircuit, - "@brief Gets the subcircuit reference.\n" - "If the pin is a pin of a subcircuit, this attribute " - "indicates the subcircuit the net attaches to. The " - "subcircuit lives in the same circuit than the net. " - "If the pin is a outgoing pin of the circuit, this " - "attribute is nil." - ) + gsi::method ("net", (db::Net *(db::NetPinRef::*) ()) &db::NetPinRef::net, "@brief Gets the net this pin reference is attached to" ), - "@brief A connection to a pin of a subcircuit or an outgoing pin of the circuit.\n" + "@brief A connection to an outgoing pin of the circuit.\n" + "This object is used inside a net (see \\Net) to describe the connections a net makes.\n" + "\n" + "This class has been added in version 0.26." +); + +Class decl_dbNetSubcircuitPinRef ("db", "NetSubcircuitPinRef", + gsi::method ("pin_id", &db::NetSubcircuitPinRef::pin_id, + "@brief Gets the ID of the pin the connection is made to." + ) + + gsi::method ("pin", &db::NetSubcircuitPinRef::pin, + "@brief Gets the \\Pin object of the pin the connection is made to." + ) + + gsi::method ("subcircuit", (db::SubCircuit *(db::NetSubcircuitPinRef::*) ()) &db::NetSubcircuitPinRef::subcircuit, + "@brief Gets the subcircuit reference.\n" + "This attribute indicates the subcircuit the net attaches to. The " + "subcircuit lives in the same circuit than the net. " + ) + + gsi::method ("net", (db::Net *(db::NetSubcircuitPinRef::*) ()) &db::NetSubcircuitPinRef::net, + "@brief Gets the net this pin reference is attached to" + ), + "@brief A connection to a pin of a subcircuit.\n" "This object is used inside a net (see \\Net) to describe the connections a net makes.\n" "\n" "This class has been added in version 0.26." @@ -288,10 +301,14 @@ Class decl_dbNet ("db", "Net", "See \\cluster_id= for details about the cluster ID." ) + gsi::iterator ("each_pin", (db::Net::pin_iterator (db::Net::*) ()) &db::Net::begin_pins, (db::Net::pin_iterator (db::Net::*) ()) &db::Net::end_pins, - "@brief Iterates over all pins the net connects.\n" + "@brief Iterates over all outgoing pins the net connects.\n" "Pin connections are described by \\NetPinRef objects. Pin connections " - "are either connections to subcircuit pins or to outgoing pins of the " - "circuit the net lives in." + "are connections to outgoing pins of the circuit the net lives in." + ) + + gsi::iterator ("each_subcircuit_pin", (db::Net::subcircuit_pin_iterator (db::Net::*) ()) &db::Net::begin_subcircuit_pins, (db::Net::subcircuit_pin_iterator (db::Net::*) ()) &db::Net::end_subcircuit_pins, + "@brief Iterates over all subcircuit pins the net connects.\n" + "Subcircuit pin connections are described by \\NetSubcircuitPinRef objects. These are " + "connections to specific pins of subcircuits." ) + gsi::iterator ("each_terminal", (db::Net::terminal_iterator (db::Net::*) ()) &db::Net::begin_terminals, (db::Net::terminal_iterator (db::Net::*) ()) &db::Net::end_terminals, "@brief Iterates over all terminals the net connects.\n" @@ -307,7 +324,10 @@ Class decl_dbNet ("db", "Net", "Internal nets are those which connect exactly two terminals and nothing else (pin_count = 0 and terminal_count == 2)." ) + gsi::method ("pin_count", &db::Net::pin_count, - "@brief Returns the number of pins connected by this net.\n" + "@brief Returns the number of outgoing pins connected by this net.\n" + ) + + gsi::method ("subcircuit_pin_count", &db::Net::subcircuit_pin_count, + "@brief Returns the number of subcircuit pins connected by this net.\n" ) + gsi::method ("terminal_count", &db::Net::terminal_count, "@brief Returns the number of terminals connected by this net.\n" @@ -765,10 +785,6 @@ Class decl_dbCircuit ("db", "Circuit", "@brief Gets the cell index of the circuit\n" "See \\cell_index= for details.\n" ) + - gsi::method ("is_external_net?", &db::Circuit::is_external_net, gsi::arg ("net"), - "@brief Returns true, if the given net is an external one.\n" - "External nets are nets which are connected to an outgoing pin." - ) + gsi::method ("net_for_pin", (db::Net *(db::Circuit::*) (size_t)) &db::Circuit::net_for_pin, gsi::arg ("pin_id"), "@brief Gets the net object attached to a specific pin.\n" "This is the net object inside the circuit which attaches to the given outward-bound pin.\n" diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index f63bdbf78..f4ff086cc 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -144,7 +144,7 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { // only handle nets without outgoing pins - these are local - if (c->is_external_net (n.operator-> ())) { + if (n->pin_count () > 0) { continue; } diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 74e4d2acc..0b88052fa 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -165,12 +165,15 @@ static std::string net2string (const db::Net &n) if (! res.empty ()) { res += ","; } - if (i->subcircuit ()) { - res += i->subcircuit ()->circuit_ref () ? i->subcircuit ()->circuit_ref ()->name () : "(null)"; - res += ":"; - } else { - res += "+"; + res += "+"; + res += i->pin () ? i->pin ()->name () : "(null)"; + } + for (db::Net::const_subcircuit_pin_iterator i = n.begin_subcircuit_pins (); i != n.end_subcircuit_pins (); ++i) { + if (! res.empty ()) { + res += ","; } + res += i->subcircuit ()->circuit_ref () ? i->subcircuit ()->circuit_ref ()->name () : "(null)"; + res += ":"; res += i->pin () ? i->pin ()->name () : "(null)"; } return res; @@ -518,25 +521,25 @@ TEST(4_NetlistSubcircuits) c1->add_net (n1a); n1a->set_name ("n1a"); n1a->add_pin (db::NetPinRef (0)); - n1a->add_pin (db::NetPinRef (sc1, 0)); + n1a->add_subcircuit_pin (db::NetSubcircuitPinRef (sc1, 0)); db::Net *n1b = new db::Net (); c1->add_net (n1b); n1b->set_name ("n1b"); - n1b->add_pin (db::NetPinRef (sc1, 1)); - n1b->add_pin (db::NetPinRef (sc2, 0)); + n1b->add_subcircuit_pin (db::NetSubcircuitPinRef (sc1, 1)); + n1b->add_subcircuit_pin (db::NetSubcircuitPinRef (sc2, 0)); db::Net *n1c = new db::Net (); c1->add_net (n1c); n1c->set_name ("n1c"); - n1c->add_pin (db::NetPinRef (sc2, 1)); + n1c->add_subcircuit_pin (db::NetSubcircuitPinRef (sc2, 1)); n1c->add_pin (db::NetPinRef (1)); EXPECT_EQ (nl2string (*nl), "[c1]\n" "+c1p1,c2:c2p1\n" "c2:c2p2,c2:c2p1\n" - "c2:c2p2,+c1p2\n" + "+c1p2,c2:c2p2\n" "[c2]\n" "D:A,+c2p1\n" "D:B,+c2p2\n" @@ -571,7 +574,7 @@ TEST(4_NetlistSubcircuits) "[c1]\n" "+c1p1,c2:c2p1\n" "c2:c2p2,c2:c2p1\n" - "c2:c2p2,+c1p2\n" + "+c1p2,c2:c2p2\n" "[c2]\n" "D:A,+c2p1\n" "D:B,+c2p2\n" @@ -751,24 +754,25 @@ TEST(8_NetSubCircuitsEditing) n2->set_name ("n2"); c.add_net (n2); - EXPECT_EQ (c.is_external_net (n1), false); + EXPECT_EQ (n1->pin_count (), size_t (0)); c.connect_pin (0, n1); EXPECT_EQ (n1->terminal_count (), size_t (0)); EXPECT_EQ (n1->pin_count (), size_t (1)); EXPECT_EQ (n1->is_floating (), true); EXPECT_EQ (n1->is_internal (), false); - EXPECT_EQ (c.is_external_net (n1), true); + EXPECT_NE (n1->pin_count (), size_t (0)); EXPECT_EQ (c.net_for_pin (0), n1); EXPECT_EQ (c.net_for_pin (1), 0); sc1->connect_pin (0, n1); sc1->connect_pin (1, n2); - EXPECT_EQ (c.is_external_net (n2), false); + EXPECT_EQ (n2->pin_count (), size_t (0)); EXPECT_EQ (n1->terminal_count (), size_t (0)); - EXPECT_EQ (n1->pin_count (), size_t (2)); + EXPECT_EQ (n1->pin_count (), size_t (1)); + EXPECT_EQ (n1->subcircuit_pin_count (), size_t (1)); EXPECT_EQ (n1->is_floating (), false); EXPECT_EQ (n1->is_internal (), false); @@ -814,7 +818,7 @@ TEST(8_NetSubCircuitsEditing) EXPECT_EQ (net2string (*n2), "sc2:A"); c.connect_pin (1, n1); - EXPECT_EQ (net2string (*n1), "sc2:B,+Y"); + EXPECT_EQ (net2string (*n1), "+Y,sc2:B"); EXPECT_EQ (c.net_for_pin (1), n1); delete n1; @@ -849,14 +853,14 @@ TEST(10_NetPinRefBasics) { db::SubCircuit d1, d2; - EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 0), true); - EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 1), false); - EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d2, 0), false); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d1, 0), true); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d1, 1), false); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d2, 0), false); - EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 0), false); - EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 1), true); - EXPECT_EQ (db::NetPinRef (&d1, 1) < db::NetPinRef (&d1, 0), false); - EXPECT_NE ((db::NetPinRef (&d1, 0) < db::NetPinRef (&d2, 0)), (db::NetPinRef (&d2, 0) < db::NetPinRef (&d1, 0))); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d1, 0), false); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d1, 1), true); + EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 1) < db::NetSubcircuitPinRef (&d1, 0), false); + EXPECT_NE ((db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d2, 0)), (db::NetSubcircuitPinRef (&d2, 0) < db::NetSubcircuitPinRef (&d1, 0))); } TEST(11_NetlistCircuitRefs) diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index 39c85f047..4f8a3e1c1 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -330,7 +330,8 @@ class DBNetlist_TestClass < TestBase assert_equal(net.is_internal?, false) sc1.connect_pin(1, net) - assert_equal(net.pin_count, 1) + assert_equal(net.pin_count, 0) + assert_equal(net.subcircuit_pin_count, 1) assert_equal(net.terminal_count, 0) assert_equal(net.is_floating?, true) assert_equal(net.is_internal?, false) @@ -338,16 +339,19 @@ class DBNetlist_TestClass < TestBase assert_equal(sc1.net_for_pin(0).inspect, "nil") sc2.connect_pin(0, net) - assert_equal(net.pin_count, 2) + assert_equal(net.pin_count, 0) + assert_equal(net.subcircuit_pin_count, 2) assert_equal(net.terminal_count, 0) assert_equal(net.is_floating?, false) assert_equal(net.is_internal?, false) cnames = [] - net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name } + net.each_pin { |p| cnames << "+" + p.pin.name } + net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name } assert_equal(cnames, [ "SC1:B", "SC2:A" ]) cnames = [] - net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin_id.to_s } + net.each_pin { |p| cnames << "+" + p.pin.name } + net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin_id.to_s } assert_equal(cnames, [ "SC1:1", "SC2:0" ]) net.each_pin { |p| assert_equal(p.net.name, "NET") } @@ -355,9 +359,10 @@ class DBNetlist_TestClass < TestBase assert_equal(sc1.net_for_pin(1).inspect, "nil") cnames = [] - net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name } + net.each_pin { |p| cnames << "+" + p.pin.name } + net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name } assert_equal(cnames, [ "SC2:A" ]) - net.each_pin { |p| assert_equal(p.net.name, "NET") } + net.each_subcircuit_pin { |p| assert_equal(p.net.name, "NET") } net.clear assert_equal(sc1.net_for_pin(1).inspect, "nil") @@ -510,9 +515,13 @@ class DBNetlist_TestClass < TestBase c.each_net { |n| names << n.name } assert_equal(names, [ "NET1", "NET2" ]) - assert_equal(c.is_external_net?(net1), false) + assert_equal(net1.pin_count, 0) c.connect_pin(pina1, net1) - assert_equal(c.is_external_net?(net1), true) + cnames = [] + net1.each_pin { |p| cnames << "+" + p.pin.name } + net1.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name } + assert_equal(cnames, [ "+A1" ]) + assert_equal(net1.pin_count, 1) c.connect_pin(pinb1.id, net1) c.connect_pin(pina2, net2) c.connect_pin(pinb2.id, net2)