From 473c90f99db58868b88a747336fc4c82821f3367 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 27 Dec 2018 19:06:16 +0100 Subject: [PATCH] WIP: some refactoring: splitting of big methods, documentation --- src/db/db/dbNetlistExtractor.cc | 146 ++++++++++++++++++-------------- src/db/db/dbNetlistExtractor.h | 45 ++++++++++ 2 files changed, 129 insertions(+), 62 deletions(-) diff --git a/src/db/db/dbNetlistExtractor.cc b/src/db/db/dbNetlistExtractor.cc index 47c60afbf..05d492366 100644 --- a/src/db/db/dbNetlistExtractor.cc +++ b/src/db/db/dbNetlistExtractor.cc @@ -99,83 +99,26 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect circuit->add_net (net); if (! clusters.is_root (*c)) { - // a non-root cluster makes a pin - db::Pin pin (net->name ()); - size_t pin_id = circuit->add_pin (pin).id (); - net->add_pin (db::NetPinRef (pin_id)); + size_t pin_id = make_pin (circuit, net); c2p.insert (std::make_pair (*c, pin_id)); - circuit->connect_pin (pin_id, net); - } - const connected_clusters_type::connections_type &connections = clusters.connections_for_cluster (*c); - for (connected_clusters_type::connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) { - - db::SubCircuit *subcircuit = 0; - db::cell_index_type ccid = i->inst ().inst_ptr.cell_index (); - - std::map::const_iterator j = subcircuits.find (i->inst ()); - if (j == subcircuits.end ()) { - - // make subcircuit if required - - std::map::const_iterator k = circuits.find (ccid); - tl_assert (k != circuits.end ()); // because we walk bottom-up - - subcircuit = new db::SubCircuit (k->second); - db::CplxTrans dbu_trans (layout.dbu ()); - subcircuit->set_trans (dbu_trans * i->inst ().complex_trans () * dbu_trans.inverted ()); - circuit->add_subcircuit (subcircuit); - subcircuits.insert (std::make_pair (i->inst (), subcircuit)); - - } else { - subcircuit = j->second; - } - - // create the pin connection to the subcircuit - std::map >::const_iterator icc2p = pins_per_cluster.find (ccid); - tl_assert (icc2p != pins_per_cluster.end ()); - std::map::const_iterator ip = icc2p->second.find (i->id ()); - tl_assert (ip != icc2p->second.end ()); - subcircuit->connect_pin (ip->second, net); - - } + // make subcircuit connections (also make the subcircuits if required) from the connections of the clusters + make_and_connect_subcircuits (circuit, clusters, *c, net, subcircuits, circuits, pins_per_cluster, layout.dbu ()); // collect the properties - we know that the cluster attributes are property ID's because the // cluster processor converts shape property IDs to attributes const local_cluster_type &lc = clusters.cluster_by_id (*c); for (local_cluster_type::attr_iterator a = lc.begin_attr (); a != lc.end_attr (); ++a) { - const db::PropertiesRepository::properties_set &ps = layout.properties_repository ().properties (*a); for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) { - if (terminal_annot_name_id.first && j->first == terminal_annot_name_id.second) { - - if (j->second.is_user ()) { - const db::NetlistProperty *np = &j->second.to_user (); - const db::DeviceTerminalProperty *tp = dynamic_cast (np); - if (tp) { - db::Device *device = circuit->device_by_id (tp->device_id ()); - tl_assert (device != 0); - device->connect_terminal (tp->terminal_id (), net); - } - } - + make_device_terminal_from_property (j->second, circuit, net); } else if (text_annot_name_id.first && j->first == text_annot_name_id.second) { - - std::string n = j->second.to_string (); - if (! n.empty ()) { - if (! net->name ().empty ()) { - n = net->name () + "," + n; - } - net->set_name (n); - } - + make_net_name_from_property (j->second, net); } - } - } } @@ -183,4 +126,83 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect } } +void NetlistExtractor::make_and_connect_subcircuits (db::Circuit *circuit, + const connected_clusters_type &clusters, + size_t cid, + db::Net *net, + std::map &subcircuits, + const std::map &circuits, + const std::map > &pins_per_cluster, + double dbu) +{ + const connected_clusters_type::connections_type &connections = clusters.connections_for_cluster (cid); + for (connected_clusters_type::connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) { + + db::SubCircuit *subcircuit = 0; + db::cell_index_type ccid = i->inst ().inst_ptr.cell_index (); + + std::map::const_iterator j = subcircuits.find (i->inst ()); + if (j == subcircuits.end ()) { + + // make subcircuit if required + + std::map::const_iterator k = circuits.find (ccid); + tl_assert (k != circuits.end ()); // because we walk bottom-up + + subcircuit = new db::SubCircuit (k->second); + db::CplxTrans dbu_trans (dbu); + subcircuit->set_trans (dbu_trans * i->inst ().complex_trans () * dbu_trans.inverted ()); + circuit->add_subcircuit (subcircuit); + subcircuits.insert (std::make_pair (i->inst (), subcircuit)); + + } else { + subcircuit = j->second; + } + + // create the pin connection to the subcircuit + std::map >::const_iterator icc2p = pins_per_cluster.find (ccid); + tl_assert (icc2p != pins_per_cluster.end ()); + std::map::const_iterator ip = icc2p->second.find (i->id ()); + tl_assert (ip != icc2p->second.end ()); + subcircuit->connect_pin (ip->second, net); + + } +} + +size_t NetlistExtractor::make_pin (db::Circuit *circuit, db::Net *net) +{ + db::Pin pin (net->name ()); + + size_t pin_id = circuit->add_pin (pin).id (); + net->add_pin (db::NetPinRef (pin_id)); + + circuit->connect_pin (pin_id, net); + + return pin_id; +} + +void NetlistExtractor::make_device_terminal_from_property (const tl::Variant &v, db::Circuit *circuit, db::Net *net) +{ + if (v.is_user ()) { + const db::NetlistProperty *np = &v.to_user (); + const db::DeviceTerminalProperty *tp = dynamic_cast (np); + if (tp) { + db::Device *device = circuit->device_by_id (tp->device_id ()); + tl_assert (device != 0); + device->connect_terminal (tp->terminal_id (), net); + } + } +} + +void NetlistExtractor::make_net_name_from_property (const tl::Variant &v, db::Net *net) +{ + std::string n = v.to_string (); + if (! n.empty ()) { + if (! net->name ().empty ()) { + n = net->name () + "," + n; + } + net->set_name (n); + } +} + } diff --git a/src/db/db/dbNetlistExtractor.h b/src/db/db/dbNetlistExtractor.h index ba1902b2b..b95953ecf 100644 --- a/src/db/db/dbNetlistExtractor.h +++ b/src/db/db/dbNetlistExtractor.h @@ -26,11 +26,16 @@ #include "dbCommon.h" #include "dbHierNetworkProcessor.h" +#include + namespace db { class DeepShapeStore; class Netlist; +class Circuit; +class SubCircuit; +class Net; /** * @brief The Netlist Extractor @@ -88,6 +93,46 @@ public: private: hier_clusters_type m_net_clusters; + + void make_device_terminal_from_property (const tl::Variant &v, db::Circuit *circuit, db::Net *net); + void make_net_name_from_property (const tl::Variant &v, db::Net *net); + + /** + * @brief Make a pin connection from clusters + * + * Non-root clusters make a pin. This function creates the pin inside the given circuit. It + * returns the new pin's ID. + */ + size_t make_pin (db::Circuit *circuit, db::Net *net); + + /** + * @brief Turns the connections of a cluster into subcircuit instances + * + * Walks through the connections of a cluster and turns the connections into subcircuit pin + * connections. This will also create new subcircuit instances. + * + * Needs: + * - circuit: the current circuit that is worked on + * - clusters: the connected clusters from the net extraction step (nets plus + * connections to child cell clusters inside the current cell) + * - cid: the current cluster ID in "clusters" + * - net: the net being built + * - circuits: a lookup table of circuits vs. cell index (reverse lookup) + * - pins_per_cluster: a per-cell, reverse lookup table for the pin id per child cell clusters + * (used to find the pin ID of a subcircuit from the child cell cluster ID) + * - dbu: the database unit (used to compute the micron-unit transformation of the child + * cell) + * Updates: + * - subcircuits: An cell instance to SubCircuit lookup table + */ + void make_and_connect_subcircuits (db::Circuit *circuit, + const connected_clusters_type &clusters, + size_t cid, + db::Net *net, + std::map &subcircuits, + const std::map &circuits, + const std::map > &pins_per_cluster, + double dbu); }; }