diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 7c64a60b5..39af6db91 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -38,7 +38,10 @@ namespace db { -// the iterator provides the hierarchical selection (enabling/disabling cells etc.) +// ----------------------------------------------------------------------------------------------- +// LayoutToNetlist implementation + +// Note: the iterator provides the hierarchical selection (enabling/disabling cells etc.) LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter) : m_iter (iter), m_layout_index (0), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0), m_include_floating_subcircuits (false) @@ -877,279 +880,39 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region return res.release (); } -void -LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const db::ICplxTrans &tr) const -{ - const db::Circuit *circuit = net.circuit (); - tl_assert (circuit != 0); - - build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, tr); -} - -void -LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map &lmap, const db::Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const db::ICplxTrans &tr) const -{ - db::Cell *target_cell = &tc; - - if (net_cell_name_prefix) { - - const db::connected_clusters &ccl = m_net_clusters.clusters_per_cell (ci); - - bool any_connections = circuit_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty (); - if (! any_connections) { - - StopOnFirst sof; - std::map sof_lmap; - for (std::map::const_iterator l = lmap.begin (); l != lmap.end (); ++l) { - if (l->second) { - sof_lmap.insert (std::make_pair (layer_of (*l->second), &sof)); - } - } - - bool consider_cell = ! deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, sof_lmap, tr, 0); - if (! consider_cell) { - // shortcut if cell is empty -> no net cell will be produced - return; - } - - } - - // make a specific cell for the net if requested - - target_cell = &target.cell (target.add_cell ((std::string (net_cell_name_prefix) + net->expanded_name ()).c_str ())); - tc.insert (db::CellInstArray (db::CellInst (target_cell->cell_index ()), db::Trans ())); - - } - - std::map target_lmap; - for (std::map::const_iterator l = lmap.begin (); l != lmap.end (); ++l) { - if (l->second) { - target_lmap.insert (std::make_pair (layer_of (*l->second), &target_cell->shapes (l->first))); - } - } - - deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, target_lmap, tr, netname_propid); - - if (hier_mode != BNH_SubcircuitCells && ! device_cell_name_prefix) { - return; - } - - // NOTE: we propagate the magnification part of tr down, but keep the rotation/translation part in the instance - // (we want to avoid magnified instances) - db::ICplxTrans tr_wo_mag = tr * db::ICplxTrans (1.0 / tr.mag ()); - db::ICplxTrans tr_mag (tr.mag ()); - - const db::connected_clusters &clusters = m_net_clusters.clusters_per_cell (ci); - typedef db::connected_clusters::connections_type connections_type; - const connections_type &connections = clusters.connections_for_cluster (cid); - for (connections_type::const_iterator c = connections.begin (); c != connections.end (); ++c) { - - db::cell_index_type subci = c->inst_cell_index (); - size_t subcid = c->id (); - - CellReuseTableKey cmap_key (subci, netname_propid, subcid); - - cell_reuse_table_type::const_iterator cm = reuse_table.find (cmap_key); - if (cm == reuse_table.end ()) { - - const char *name_prefix = 0; - if (mp_netlist->device_abstract_by_cell_index (subci)) { - name_prefix = device_cell_name_prefix; - } else { - name_prefix = circuit_cell_name_prefix; - } - - if (name_prefix) { - - std::string cell_name = internal_layout ()->cell_name (subci); - - db::cell_index_type target_ci = target.add_cell ((std::string (name_prefix) + cell_name).c_str ()); - cm = reuse_table.insert (std::make_pair (cmap_key, target_ci)).first; - - build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, reuse_table, tr_mag); - - } else { - cm = reuse_table.insert (std::make_pair (cmap_key, std::numeric_limits::max ())).first; - } - - } - - if (cm->second != std::numeric_limits::max ()) { - db::CellInstArray ci (db::CellInst (cm->second), tr_wo_mag * c->inst_trans ()); - ci.transform_into (tr_mag); - target_cell->insert (ci); - } - - } -} - -db::properties_id_type -LayoutToNetlist::make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const -{ - if (net_prop_mode == NoProperties) { - - return 0; - - } else if (! netname_prop.is_nil () || (net_prop_mode == AllProperties && net.begin_properties () != net.end_properties ())) { - - db::PropertiesRepository::properties_set propset; - - // add the user properties too (TODO: make this configurable?) - for (db::Net::property_iterator p = net.begin_properties (); p != net.end_properties (); ++p) { - db::property_names_id_type key_propnameid = ly.properties_repository ().prop_name_id (p->first); - propset.insert (std::make_pair (key_propnameid, p->second)); - } - - if (! netname_prop.is_nil ()) { - db::property_names_id_type name_propnameid = ly.properties_repository ().prop_name_id (netname_prop); - if (net_prop_mode == NetNameAndIDOnly) { - std::vector l; - l.reserve (2); - l.push_back (tl::Variant (net.expanded_name ())); - l.push_back (tl::Variant (reinterpret_cast (&net))); - propset.insert (std::make_pair (name_propnameid, tl::Variant (l))); - } else if (net_prop_mode == NetIDOnly) { - propset.insert (std::make_pair (name_propnameid, tl::Variant (reinterpret_cast (&net)))); - } else { - propset.insert (std::make_pair (name_propnameid, tl::Variant (net.expanded_name ()))); - } - } - - return ly.properties_repository ().properties_id (propset); - - } else { - - return 0; - - } -} - void LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &lmap, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix) const { - if (! m_netlist_extracted) { - throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); - } + NetBuilder builder (&target, this); + builder.set_hier_mode (hier_mode); + builder.set_cell_name_prefix (cell_name_prefix); + builder.set_device_cell_name_prefix (device_cell_name_prefix); - cell_reuse_table_type cell_reuse_table; - - double mag = internal_layout ()->dbu () / target.dbu (); - - db::properties_id_type netname_propid = make_netname_propid (target, net_prop_mode, netname_prop, net); - build_net_rec (net, target, target_cell, lmap, 0, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag)); + builder.build_net (target_cell, net, lmap, net_prop_mode, netname_prop); } void LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const { - build_nets (0, cmap, target, lmap, net_cell_name_prefix, net_prop_mode, netname_prop, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix); -} + NetBuilder builder (&target, cmap, this); + builder.set_hier_mode (hier_mode); + builder.set_net_cell_name_prefix (net_cell_name_prefix); + builder.set_cell_name_prefix (circuit_cell_name_prefix); + builder.set_device_cell_name_prefix (device_cell_name_prefix); -void -LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const -{ - if (! cmap.has_mapping (circuit_cell)) { - - const db::Cell &cc = internal_layout ()->cell (circuit_cell); - - for (db::Cell::parent_inst_iterator p = cc.begin_parent_insts (); ! p.at_end (); ++p) { - - db::CellInstArray ci = p->child_inst ().cell_inst (); - for (db::CellInstArray::iterator ia = ci.begin (); ! ia.at_end(); ++ia) { - - db::ICplxTrans tr_parent = ci.complex_trans (*ia) * tr; - build_net_rec (net, target, p->parent_cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, tr_parent); - - } - - } - - } else { - - double mag = internal_layout ()->dbu () / target.dbu (); - - db::cell_index_type target_ci = cmap.cell_mapping (circuit_cell); - build_net_rec (net, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, db::ICplxTrans (mag) * tr); - - } + builder.build_nets (0, lmap, net_prop_mode, netname_prop); } void LayoutToNetlist::build_nets (const std::vector *nets, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const { - if (! m_netlist_extracted) { - throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); - } + NetBuilder builder (&target, cmap, this); + builder.set_hier_mode (hier_mode); + builder.set_net_cell_name_prefix (net_cell_name_prefix); + builder.set_cell_name_prefix (circuit_cell_name_prefix); + builder.set_device_cell_name_prefix (device_cell_name_prefix); - std::set net_set; - if (nets) { - net_set.insert (nets->begin (), nets->end ()); - } - - cell_reuse_table_type cell_reuse_table; - - const db::Netlist *netlist = mp_netlist.get (); - for (db::Netlist::const_circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) { - - bool is_top_circuit = c->begin_parents () == c->end_parents (); - - for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { - - // exclude local nets in recursive mode except if they are explicitly selected - if (! nets && hier_mode != BNH_Disconnected && ! is_top_circuit && n->pin_count () > 0) { - continue; - } - - if (! nets || net_set.find (n.operator-> ()) != net_set.end ()) { - db::properties_id_type netname_propid = make_netname_propid (target, net_prop_mode, netname_prop, *n); - build_net_rec (*n, target, c->cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans ()); - } - - } - - if (hier_mode != BNH_Disconnected && ! nets) { - - // With recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will - // get lost if there is no connection to this pin from the outside. Hence we need to deliver nets from - // subcircuits as part of the circuit which calls the subcircuit - but NOT in a subcircuit cell, because - // this will just apply to nets from certain instances. But the net cell name will be formed as "subcircuit:net" - // - // In explicit selection mode we don't care about this as nets are explicitly taken or not. - - const db::Circuit &circuit = *c; - for (db::Circuit::const_subcircuit_iterator sc = circuit.begin_subcircuits (); sc != circuit.end_subcircuits (); ++sc) { - - const db::SubCircuit &subcircuit = *sc; - for (db::Circuit::const_pin_iterator p = subcircuit.circuit_ref ()->begin_pins (); p != subcircuit.circuit_ref ()->end_pins (); ++p) { - - if (! subcircuit.net_for_pin (p->id ())) { - - const db::Net *n = subcircuit.circuit_ref ()->net_for_pin (p->id ()); - if (n) { - - double dbu = target.dbu (); - db::ICplxTrans tr = db::CplxTrans (dbu).inverted () * subcircuit.trans () * db::CplxTrans (dbu); - - db::properties_id_type netname_propid = make_netname_propid (target, net_prop_mode, netname_prop, *n); - - if (net_cell_name_prefix) { - std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":"; - build_net_rec (*n, target, c->cell_index (), cmap, lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr); - } else { - build_net_rec (*n, target, c->cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr); - } - - } - - } - - } - - } - - } - - } + builder.build_nets (nets, lmap, net_prop_mode, netname_prop); } db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::DPoint &point, std::vector *sc_path_out, db::Circuit *initial_circuit) @@ -1708,4 +1471,357 @@ void LayoutToNetlist::set_generator (const std::string &g) m_generator = g; } +// ----------------------------------------------------------------------------------------------- +// NetBuilder implementation + +NetBuilder::NetBuilder () + : m_hier_mode (BNH_Flatten), m_has_net_cell_name_prefix (false), m_has_cell_name_prefix (false), m_has_device_cell_name_prefix (false) +{ + // .. nothing yet .. +} + +NetBuilder::NetBuilder (db::Layout *target, const db::CellMapping &cmap, const db::LayoutToNetlist *source) + : mp_target (target), m_cmap (cmap), mp_source (const_cast (source)), + m_hier_mode (BNH_Flatten), m_has_net_cell_name_prefix (false), m_has_cell_name_prefix (false), m_has_device_cell_name_prefix (false) +{ + // .. nothing yet .. +} + +NetBuilder::NetBuilder (db::Layout *target, const db::LayoutToNetlist *source) + : mp_target (target), mp_source (const_cast (source)), + m_hier_mode (BNH_Flatten), m_has_net_cell_name_prefix (false), m_has_cell_name_prefix (false), m_has_device_cell_name_prefix (false) +{ + // .. nothing yet .. +} + +NetBuilder::NetBuilder (const db::NetBuilder &other) +{ + operator=(other); +} + +NetBuilder::NetBuilder (db::NetBuilder &&other) +{ + operator=(other); +} + +NetBuilder & +NetBuilder::operator= (const db::NetBuilder &other) +{ + if (this != &other) { + mp_target = other.mp_target; + mp_source = other.mp_source; + m_cmap = other.m_cmap; + m_reuse_table = other.m_reuse_table; + m_hier_mode = other.m_hier_mode; + m_has_net_cell_name_prefix = other.m_has_net_cell_name_prefix; + m_net_cell_name_prefix = other.m_net_cell_name_prefix; + m_has_cell_name_prefix = other.m_has_cell_name_prefix; + m_cell_name_prefix = other.m_cell_name_prefix; + m_has_device_cell_name_prefix = other.m_has_device_cell_name_prefix; + m_device_cell_name_prefix = other.m_device_cell_name_prefix; + } + + return *this; +} + +NetBuilder & +NetBuilder::operator= (db::NetBuilder &&other) +{ + if (this != &other) { + mp_target = other.mp_target; + other.mp_target.reset (0); + mp_source = other.mp_source; + other.mp_source.reset (0); + m_cmap.swap (other.m_cmap); + m_reuse_table.swap (other.m_reuse_table); + std::swap (m_hier_mode, other.m_hier_mode); + std::swap (m_has_net_cell_name_prefix, other.m_has_net_cell_name_prefix); + m_net_cell_name_prefix.swap (other.m_net_cell_name_prefix); + std::swap (m_has_cell_name_prefix, other.m_has_cell_name_prefix); + m_cell_name_prefix.swap (other.m_cell_name_prefix); + std::swap (m_has_device_cell_name_prefix, other.m_has_device_cell_name_prefix); + m_device_cell_name_prefix.swap (other.m_device_cell_name_prefix); + } + + return *this; +} + +void +NetBuilder::build_net (db::Cell &target_cell, const db::Net &net, const std::map &lmap, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop) const +{ + tl_assert (mp_target.get ()); + tl_assert (mp_source.get ()); + + if (! mp_source->is_netlist_extracted ()) { + throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); + } + + double mag = mp_source->internal_layout ()->dbu () / mp_target->dbu (); + + db::properties_id_type netname_propid = make_netname_propid (target (), net_prop_mode, netname_prop, net); + build_net_rec (net, target_cell, lmap, std::string (), netname_propid, db::ICplxTrans (mag)); +} + +void +NetBuilder::build_all_nets (const std::map &lmap, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop) const +{ + tl_assert (mp_target.get ()); + tl_assert (mp_source.get ()); + + build_nets (0, lmap, net_prop_mode, netname_prop); +} + +void +NetBuilder::build_nets (const std::vector *nets, const std::map &lmap, NetPropertyMode prop_mode, const tl::Variant &netname_prop) const +{ + tl_assert (mp_target.get ()); + tl_assert (mp_source.get ()); + + if (! mp_source->is_netlist_extracted ()) { + throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); + } + + std::set net_set; + if (nets) { + net_set.insert (nets->begin (), nets->end ()); + } + + const db::Netlist *netlist = mp_source->netlist (); + for (db::Netlist::const_circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) { + + bool is_top_circuit = c->begin_parents () == c->end_parents (); + + for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { + + // exclude local nets in recursive mode except if they are explicitly selected + if (! nets && m_hier_mode != BNH_Disconnected && ! is_top_circuit && n->pin_count () > 0) { + continue; + } + + if (! nets || net_set.find (n.operator-> ()) != net_set.end ()) { + db::properties_id_type netname_propid = make_netname_propid (target (), prop_mode, netname_prop, *n); + build_net_rec (*n, c->cell_index (), lmap, std::string (), netname_propid, db::ICplxTrans ()); + } + + } + + if (m_hier_mode != BNH_Disconnected && ! nets) { + + // With recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will + // get lost if there is no connection to this pin from the outside. Hence we need to deliver nets from + // subcircuits as part of the circuit which calls the subcircuit - but NOT in a subcircuit cell, because + // this will just apply to nets from certain instances. But the net cell name will be formed as "subcircuit:net" + // + // In explicit selection mode we don't care about this as nets are explicitly taken or not. + + const db::Circuit &circuit = *c; + for (db::Circuit::const_subcircuit_iterator sc = circuit.begin_subcircuits (); sc != circuit.end_subcircuits (); ++sc) { + + const db::SubCircuit &subcircuit = *sc; + for (db::Circuit::const_pin_iterator p = subcircuit.circuit_ref ()->begin_pins (); p != subcircuit.circuit_ref ()->end_pins (); ++p) { + + if (! subcircuit.net_for_pin (p->id ())) { + + const db::Net *n = subcircuit.circuit_ref ()->net_for_pin (p->id ()); + if (n) { + + double dbu = mp_target->dbu (); + db::ICplxTrans tr = db::CplxTrans (dbu).inverted () * subcircuit.trans () * db::CplxTrans (dbu); + + db::properties_id_type netname_propid = make_netname_propid (target (), prop_mode, netname_prop, *n); + + build_net_rec (*n, c->cell_index (), lmap, subcircuit.expanded_name () + ":", netname_propid, tr); + + } + + } + + } + + } + + } + + } +} + +void +NetBuilder::build_net_rec (const db::Net &net, db::Cell &target_cell, const std::map &lmap, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const db::ICplxTrans &tr) const +{ + const db::Circuit *circuit = net.circuit (); + tl_assert (circuit != 0); + + build_net_rec (circuit->cell_index (), net.cluster_id (), target_cell, lmap, &net, add_net_cell_name_prefix, netname_propid, tr); +} + +void +NetBuilder::build_net_rec (db::cell_index_type ci, size_t cid, db::Cell &tc, const std::map &lmap, const db::Net *net, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const db::ICplxTrans &tr) const +{ + db::Cell *target_cell = &tc; + + if (net && m_has_net_cell_name_prefix) { + + const db::connected_clusters &ccl = mp_source->net_clusters ().clusters_per_cell (ci); + + bool any_connections = m_has_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty (); + if (! any_connections) { + + StopOnFirst sof; + std::map sof_lmap; + for (std::map::const_iterator l = lmap.begin (); l != lmap.end (); ++l) { + if (l->second) { + sof_lmap.insert (std::make_pair (mp_source->layer_of (*l->second), &sof)); + } + } + + bool consider_cell = ! deliver_shapes_of_net (m_hier_mode == BNH_Flatten, mp_source->netlist (), mp_source->net_clusters (), ci, cid, sof_lmap, tr, 0); + if (! consider_cell) { + // shortcut if cell is empty -> no net cell will be produced + return; + } + + } + + // make a specific cell for the net if requested + + target_cell = &target ().cell (target ().add_cell ((m_net_cell_name_prefix + add_net_cell_name_prefix + net->expanded_name ()).c_str ())); + tc.insert (db::CellInstArray (db::CellInst (target_cell->cell_index ()), db::Trans ())); + + } + + std::map target_lmap; + for (std::map::const_iterator l = lmap.begin (); l != lmap.end (); ++l) { + if (l->second) { + target_lmap.insert (std::make_pair (mp_source->layer_of (*l->second), &target_cell->shapes (l->first))); + } + } + + deliver_shapes_of_net (m_hier_mode == BNH_Flatten, mp_source->netlist (), mp_source->net_clusters (), ci, cid, target_lmap, tr, netname_propid); + + if (m_hier_mode != BNH_SubcircuitCells && ! m_has_device_cell_name_prefix) { + return; + } + + // NOTE: we propagate the magnification part of tr down, but keep the rotation/translation part in the instance + // (we want to avoid magnified instances) + db::ICplxTrans tr_wo_mag = tr * db::ICplxTrans (1.0 / tr.mag ()); + db::ICplxTrans tr_mag (tr.mag ()); + + const db::connected_clusters &clusters = mp_source->net_clusters ().clusters_per_cell (ci); + typedef db::connected_clusters::connections_type connections_type; + const connections_type &connections = clusters.connections_for_cluster (cid); + for (connections_type::const_iterator c = connections.begin (); c != connections.end (); ++c) { + + db::cell_index_type subci = c->inst_cell_index (); + size_t subcid = c->id (); + + CellReuseTableKey cmap_key (subci, netname_propid, subcid); + + cell_reuse_table_type::const_iterator cm = m_reuse_table.find (cmap_key); + if (cm == m_reuse_table.end ()) { + + bool has_name_prefix = false; + std::string name_prefix; + if (mp_source->netlist ()->device_abstract_by_cell_index (subci)) { + name_prefix = m_device_cell_name_prefix; + has_name_prefix = m_has_device_cell_name_prefix; + } else { + name_prefix = m_cell_name_prefix; + has_name_prefix = m_has_cell_name_prefix; + } + + if (has_name_prefix) { + + std::string cell_name = mp_source->internal_layout ()->cell_name (subci); + + db::cell_index_type target_ci = target ().add_cell ((name_prefix + cell_name).c_str ()); + cm = m_reuse_table.insert (std::make_pair (cmap_key, target_ci)).first; + + build_net_rec (subci, subcid, target ().cell (target_ci), lmap, 0, std::string (), netname_propid, tr_mag); + + } else { + cm = m_reuse_table.insert (std::make_pair (cmap_key, std::numeric_limits::max ())).first; + } + + } + + if (cm->second != std::numeric_limits::max ()) { + db::CellInstArray ci (db::CellInst (cm->second), tr_wo_mag * c->inst_trans ()); + ci.transform_into (tr_mag); + target_cell->insert (ci); + } + + } +} + +void +NetBuilder::build_net_rec (const db::Net &net, db::cell_index_type circuit_cell, const std::map &lmap, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const ICplxTrans &tr) const +{ + if (! m_cmap.has_mapping (circuit_cell)) { + + const db::Cell &cc = mp_source->internal_layout ()->cell (circuit_cell); + + for (db::Cell::parent_inst_iterator p = cc.begin_parent_insts (); ! p.at_end (); ++p) { + + db::CellInstArray ci = p->child_inst ().cell_inst (); + for (db::CellInstArray::iterator ia = ci.begin (); ! ia.at_end(); ++ia) { + + db::ICplxTrans tr_parent = ci.complex_trans (*ia) * tr; + build_net_rec (net, p->parent_cell_index (), lmap, add_net_cell_name_prefix, netname_propid, tr_parent); + + } + + } + + } else { + + double mag = mp_source->internal_layout ()->dbu () / mp_target->dbu (); + + db::cell_index_type target_ci = m_cmap.cell_mapping (circuit_cell); + build_net_rec (net, target ().cell (target_ci), lmap, add_net_cell_name_prefix, netname_propid, db::ICplxTrans (mag) * tr); + + } +} + +db::properties_id_type +NetBuilder::make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const +{ + if (net_prop_mode == NPM_NoProperties) { + + return 0; + + } else if (! netname_prop.is_nil () || (net_prop_mode == NPM_AllProperties && net.begin_properties () != net.end_properties ())) { + + db::PropertiesRepository::properties_set propset; + + // add the user properties too (TODO: make this configurable?) + for (db::Net::property_iterator p = net.begin_properties (); p != net.end_properties (); ++p) { + db::property_names_id_type key_propnameid = ly.properties_repository ().prop_name_id (p->first); + propset.insert (std::make_pair (key_propnameid, p->second)); + } + + if (! netname_prop.is_nil ()) { + db::property_names_id_type name_propnameid = ly.properties_repository ().prop_name_id (netname_prop); + if (net_prop_mode == NPM_NetNameAndIDOnly) { + std::vector l; + l.reserve (2); + l.push_back (tl::Variant (net.expanded_name ())); + l.push_back (tl::Variant (reinterpret_cast (&net))); + propset.insert (std::make_pair (name_propnameid, tl::Variant (l))); + } else if (net_prop_mode == NPM_NetIDOnly) { + propset.insert (std::make_pair (name_propnameid, tl::Variant (reinterpret_cast (&net)))); + } else { + propset.insert (std::make_pair (name_propnameid, tl::Variant (net.expanded_name ()))); + } + } + + return ly.properties_repository ().properties_id (propset); + + } else { + + return 0; + + } +} + } diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index 15a4824c7..0058587f4 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -32,6 +32,62 @@ namespace db { +class NetlistBuilder; + +/** + * @brief An enum describing the way how net information is attached to shapes as properties in "build_nets" + */ +enum NetPropertyMode +{ + /** + * @brief Do no generate properties + */ + NPM_NoProperties, + + /** + * @brief Attach all net properties plus the net name (if a "netname_prop" is specified to "build_nets") + */ + NPM_AllProperties, + + /** + * @brief Attach net name only (if a "netname_prop" is specified to "build_nets") + */ + NPM_NetNameOnly, + + /** + * @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name + */ + NPM_NetIDOnly, + + /** + * @brief Like NetNameOnly, but use a tuple of name and ID + */ + NPM_NetNameAndIDOnly, +}; + +/** + * @brief An enum describing the way the net hierarchy is mapped + */ +enum BuildNetHierarchyMode +{ + /** + * @brief Flatten the net + * Collects all shapes of a net and puts that into the net cell or circuit cell + */ + BNH_Flatten = 0, + /** + * @brief Build a net hierarchy adding cells for each subcircuit on the net + * Uses the circuit_cell_prefix to build the subcircuit cell names + */ + BNH_SubcircuitCells = 1, + /** + * @brief No hierarchy + * Just output the shapes of the net belonging to the circuit cell. + * Connections are not indicated! + */ + BNH_Disconnected = 2 +}; + /** * @brief A generic framework for extracting netlists from layouts * @@ -703,60 +759,6 @@ public: */ void shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to, properties_id_type propid = 0) const; - /** - * @brief An enum describing the way how net information is attached to shapes as properties in "build_nets" - */ - enum NetPropertyMode - { - /** - * @brief Do no generate properties - */ - NoProperties, - - /** - * @brief Attach all net properties plus the net name (if a "netname_prop" is specified to "build_nets") - */ - AllProperties, - - /** - * @brief Attach net name only (if a "netname_prop" is specified to "build_nets") - */ - NetNameOnly, - - /** - * @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name - */ - NetIDOnly, - - /** - * @brief Like NetNameOnly, but use a tuple of name and ID - */ - NetNameAndIDOnly, - }; - - /** - * @brief An enum describing the way the net hierarchy is mapped - */ - enum BuildNetHierarchyMode - { - /** - * @brief Flatten the net - * Collects all shapes of a net and puts that into the net cell or circuit cell - */ - BNH_Flatten = 0, - /** - * @brief Build a net hierarchy adding cells for each subcircuit on the net - * Uses the circuit_cell_prefix to build the subcircuit cell names - */ - BNH_SubcircuitCells = 1, - /** - * @brief No hierarchy - * Just output the shapes of the net belonging to the circuit cell. - * Connections are not indicated! - */ - BNH_Disconnected = 2 - }; - /** * @brief Builds a net representation in the given layout and cell * @@ -980,6 +982,133 @@ private: std::list > m_joined_nets; std::list > > m_joined_nets_per_cell; + void init (); + void ensure_netlist (); + size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster &test_cluster, std::vector &rev_inst_path); + db::DeepLayer deep_layer_of (const ShapeCollection &coll) const; + void ensure_layout () const; + std::string make_new_name (const std::string &stem = std::string ()); + db::CellMapping make_cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector *nets, bool with_device_cells); + void connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b); + size_t connect_global_impl (const db::ShapeCollection &l, const std::string &gn); + + // implementation of NetlistManipulationCallbacks + virtual size_t link_net_to_parent_circuit (const Net *subcircuit_net, Circuit *parent_circuit, const DCplxTrans &trans); + virtual void link_nets (const db::Net *net, const db::Net *with); +}; + +/** + * @brief An object building nets (net-to-layout) + * + * This object can be used to persist netlist builder information - e.g. reusing net cells when building individual + * layers from nets. In this case, build nets with a layer selection and call the build_net function many times. + */ + +class DB_PUBLIC NetBuilder +{ +public: + /** + * @brief Default constructor + */ + NetBuilder (); + + /** + * @brief Constructs a net builder with a target layout, a cell mapping table and a LayoutToNetlist source + * + * @param target The target layout + * @param cmap The cell mapping from the internal layout (inside LayoutToNetlist) to the target - use LayoutInfo::cell_mapping_into to generate this map + * @param source The LayoutToNetlist source. + * + * A cell map needs to be supplied only if intending to build many nets in hierarchical mode from multiple circuits. + */ + NetBuilder (db::Layout *target, const db::CellMapping &cmap, const db::LayoutToNetlist *source); + + /** + * @brief Constructs a net builder with a source only + * + * @param source The LayoutToNetlist source. + * + * This net builder can be used to build single nets into dedicated target cells. + */ + NetBuilder (db::Layout *target, const db::LayoutToNetlist *source); + + /** + * @brief Copy constructor + */ + NetBuilder (const db::NetBuilder &other); + + /** + * @brief Move constructor + */ + NetBuilder (db::NetBuilder &&other); + + /** + * @brief Assignment + */ + NetBuilder &operator= (const db::NetBuilder &other); + + /** + * @brief Move + */ + NetBuilder &operator= (db::NetBuilder &&other); + + /** + * @brief Sets the net-to-hierarchy generation mode + */ + void set_hier_mode (BuildNetHierarchyMode hm) + { + m_hier_mode = hm; + } + + /** + * @brief Sets or resets the net cell name prefix + * + * Pass 0 to this string value to reset it. + */ + void set_net_cell_name_prefix (const char *s) + { + m_has_net_cell_name_prefix = (s != 0); + m_net_cell_name_prefix = std::string (s ? s : ""); + } + + /** + * @brief Sets or resets the circuit cell name prefix + * + * Pass 0 to this string value to reset it. + */ + void set_cell_name_prefix (const char *s) + { + m_has_cell_name_prefix = (s != 0); + m_cell_name_prefix = std::string (s ? s : ""); + } + + /** + * @brief Sets or resets the device cell name prefix + * + * Pass 0 to this string value to reset it. + */ + void set_device_cell_name_prefix (const char *s) + { + m_has_device_cell_name_prefix = (s != 0); + m_device_cell_name_prefix = std::string (s ? s : ""); + } + + /** + * @brief See \LayoutToNetlist for details of this function + */ + void build_net (db::Cell &target_cell, const db::Net &net, const std::map &lmap, NetPropertyMode prop_mode, const tl::Variant &netname_prop) const; + + /** + * @brief See \LayoutToNetlist for details of this function + */ + void build_all_nets (const std::map &lmap, NetPropertyMode prop_mode, const tl::Variant &netname_prop) const; + + /** + * @brief See \LayoutToNetlist for details of this function + */ + void build_nets (const std::vector *nets, const std::map &lmap, NetPropertyMode prop_mode, const tl::Variant &netname_prop) const; + +private: struct CellReuseTableKey { CellReuseTableKey (db::cell_index_type _cell_index, db::properties_id_type _netname_propid, size_t _cluster_id) @@ -1009,23 +1138,27 @@ private: typedef std::map cell_reuse_table_type; - void init (); - void ensure_netlist (); - size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster &test_cluster, std::vector &rev_inst_path); - void build_net_rec (const db::Net &net, db::Layout &target, cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const; - void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const; - void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const; - db::DeepLayer deep_layer_of (const ShapeCollection &coll) const; - void ensure_layout () const; - std::string make_new_name (const std::string &stem = std::string ()); - db::properties_id_type make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const; - db::CellMapping make_cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector *nets, bool with_device_cells); - void connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b); - size_t connect_global_impl (const db::ShapeCollection &l, const std::string &gn); + tl::weak_ptr mp_target; + db::CellMapping m_cmap; + tl::weak_ptr mp_source; + mutable cell_reuse_table_type m_reuse_table; + BuildNetHierarchyMode m_hier_mode; + bool m_has_net_cell_name_prefix; + std::string m_net_cell_name_prefix; + bool m_has_cell_name_prefix; + std::string m_cell_name_prefix; + bool m_has_device_cell_name_prefix; + std::string m_device_cell_name_prefix; - // implementation of NetlistManipulationCallbacks - virtual size_t link_net_to_parent_circuit (const Net *subcircuit_net, Circuit *parent_circuit, const DCplxTrans &trans); - virtual void link_nets (const db::Net *net, const db::Net *with); + void build_net_rec (const db::Net &net, cell_index_type circuit_cell, const std::map &lmap, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const ICplxTrans &tr) const; + void build_net_rec (const db::Net &net, db::Cell &target_cell, const std::map &lmap, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const ICplxTrans &tr) const; + void build_net_rec (db::cell_index_type ci, size_t cid, db::Cell &target_cell, const std::map &lmap, const Net *net, const std::string &add_net_cell_name_prefix, db::properties_id_type netname_propid, const ICplxTrans &tr) const; + db::properties_id_type make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const; + + db::Layout &target () const + { + return const_cast (*mp_target); + } }; /** diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index 37e26fd98..4fe246750 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -66,27 +66,27 @@ static db::Cell *l2n_internal_top_cell (db::LayoutToNetlist *l2n) return const_cast (l2n->internal_top_cell ()); } -static void build_net (const db::LayoutToNetlist *l2n, const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const tl::Variant &netname_prop, db::LayoutToNetlist::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) +static void build_net (const db::LayoutToNetlist *l2n, const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const tl::Variant &netname_prop, db::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) { std::string p = circuit_cell_name_prefix.to_string (); std::string dp = device_cell_name_prefix.to_string (); - l2n->build_net (net, target, target_cell, lmap, db::LayoutToNetlist::AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : p.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); + l2n->build_net (net, target, target_cell, lmap, db::NPM_AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : p.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); } -static void build_all_nets (const db::LayoutToNetlist *l2n, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const tl::Variant &net_cell_name_prefix, const tl::Variant &netname_prop, db::LayoutToNetlist::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) +static void build_all_nets (const db::LayoutToNetlist *l2n, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const tl::Variant &net_cell_name_prefix, const tl::Variant &netname_prop, db::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) { std::string cp = circuit_cell_name_prefix.to_string (); std::string np = net_cell_name_prefix.to_string (); std::string dp = device_cell_name_prefix.to_string (); - l2n->build_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), db::LayoutToNetlist::AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); + l2n->build_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), db::NPM_AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); } -static void build_nets (const db::LayoutToNetlist *l2n, const std::vector &nets, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const tl::Variant &net_cell_name_prefix, const tl::Variant &netname_prop, db::LayoutToNetlist::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) +static void build_nets (const db::LayoutToNetlist *l2n, const std::vector &nets, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const tl::Variant &net_cell_name_prefix, const tl::Variant &netname_prop, db::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix) { std::string cp = circuit_cell_name_prefix.to_string (); std::string np = net_cell_name_prefix.to_string (); std::string dp = device_cell_name_prefix.to_string (); - l2n->build_nets (&nets, cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), db::LayoutToNetlist::AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); + l2n->build_nets (&nets, cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), db::NPM_AllProperties, netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); } static std::vector l2n_layer_names (const db::LayoutToNetlist *l2n) @@ -585,7 +585,7 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "all subcircuits too.\n" "\"prop_id\" is an optional properties ID. If given, this property set will be attached to the shapes." ) + - gsi::method_ext ("build_net", &build_net, gsi::arg ("net"), gsi::arg ("target"), gsi::arg ("target_cell"), gsi::arg ("lmap"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::LayoutToNetlist::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), + gsi::method_ext ("build_net", &build_net, gsi::arg ("net"), gsi::arg ("target"), gsi::arg ("target_cell"), gsi::arg ("lmap"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), "@brief Builds a net representation in the given layout and cell\n" "\n" "This method puts the shapes of a net into the given target cell using a variety of options\n" @@ -615,7 +615,7 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "@param cell_name_prefix Chooses recursive mode if non-null\n" "@param device_cell_name_prefix See above\n" ) + - gsi::method_ext ("build_all_nets", &build_all_nets, gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::LayoutToNetlist::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), + gsi::method_ext ("build_all_nets", &build_all_nets, gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), "@brief Builds a full hierarchical representation of the nets\n" "\n" "This method copies all nets into cells corresponding to the circuits. It uses the 'cmap'\n" @@ -657,7 +657,7 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "@param net_cell_name_prefix See method description\n" "@param device_cell_name_prefix See above\n" ) + - gsi::method_ext ("build_nets", &build_nets, gsi::arg ("nets"), gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::LayoutToNetlist::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), + gsi::method_ext ("build_nets", &build_nets, gsi::arg ("nets"), gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"), "@brief Like \\build_all_nets, but with the ability to select some nets." ) + gsi::method ("probe_net", (db::Net *(db::LayoutToNetlist::*) (const db::Region &, const db::DPoint &, std::vector *, db::Circuit *)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"), gsi::arg ("sc_path_out", (std::vector *) 0, "nil"), gsi::arg ("initial_circuit", (db::Circuit *) 0, "nil"), @@ -836,14 +836,14 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "This class has been introduced in version 0.26." ); -gsi::EnumIn decl_dbLayoutToNetlist_BuildNetHierarchyMode ("db", "BuildNetHierarchyMode", - gsi::enum_const ("BNH_Flatten", db::LayoutToNetlist::BNH_Flatten, +gsi::EnumIn decl_dbLayoutToNetlist_BuildNetHierarchyMode ("db", "BuildNetHierarchyMode", + gsi::enum_const ("BNH_Flatten", db::BNH_Flatten, "@brief This constant tells \\build_net and \\build_all_nets to flatten the nets (used for the \"hier_mode\" parameter)." ) + - gsi::enum_const ("BNH_Disconnected", db::LayoutToNetlist::BNH_Disconnected, + gsi::enum_const ("BNH_Disconnected", db::BNH_Disconnected, "@brief This constant tells \\build_net and \\build_all_nets to produce local nets without connections to subcircuits (used for the \"hier_mode\" parameter)." ) + - gsi::enum_const ("BNH_SubcircuitCells", db::LayoutToNetlist::BNH_SubcircuitCells, + gsi::enum_const ("BNH_SubcircuitCells", db::BNH_SubcircuitCells, "@brief This constant tells \\build_net and \\build_all_nets to produce a hierarchy of subcircuit cells per net (used for the \"hier_mode\" parameter)." ), "@brief This class represents the LayoutToNetlist::BuildNetHierarchyMode enum\n" diff --git a/src/db/unit_tests/dbHierNetsProcessorTests.cc b/src/db/unit_tests/dbHierNetsProcessorTests.cc index c95d73f3e..0e581e9ea 100644 --- a/src/db/unit_tests/dbHierNetsProcessorTests.cc +++ b/src/db/unit_tests/dbHierNetsProcessorTests.cc @@ -124,7 +124,7 @@ TEST(0_Develop) lmap_write [wvia1 = ly2.insert_layer (db::LayerProperties (16, 0))] = l2n.layer_by_name ("via1"); lmap_write [wmetal2 = ly2.insert_layer (db::LayerProperties (17, 0))] = l2n.layer_by_name ("metal2"); - l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::LayoutToNetlist::NetNameAndIDOnly, tl::Variant (1), db::LayoutToNetlist::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/); + l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::NPM_NetNameAndIDOnly, tl::Variant (1), db::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/); unsigned int out1 = ly2.insert_layer (db::LayerProperties (1000, 0)); unsigned int out2 = ly2.insert_layer (db::LayerProperties (1001, 0)); diff --git a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc index e413080d3..0d56d2dae 100644 --- a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc @@ -74,7 +74,7 @@ TEST(1_ReaderBasic) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1"); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2"); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_Disconnected, 0, "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -104,7 +104,7 @@ TEST(1_ReaderBasic) db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets); - l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_"); + l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_Disconnected, 0, "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -134,7 +134,7 @@ TEST(1_ReaderBasic) db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets); - l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Flatten, 0, "DEVICE_"); + l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_Flatten, 0, "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -164,7 +164,7 @@ TEST(1_ReaderBasic) db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets); - l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -195,7 +195,7 @@ TEST(1_ReaderBasic) db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets); - l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0); + l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -226,7 +226,7 @@ TEST(1_ReaderBasic) db::CellMapping cm = l2n.const_cell_mapping_into (ly2, top2); - l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_nets (&nets, cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -305,7 +305,7 @@ TEST(1c_ReaderBasicShortWithProps) db::CellMapping cm = l2n.cell_mapping_into (ly2, top2); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::AllProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_AllProperties, tl::Variant (), db::BNH_Disconnected, 0, "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -361,7 +361,7 @@ TEST(2_ReaderWithGlobalNets) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1"); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2"); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -417,7 +417,7 @@ TEST(3_ReaderAbsoluteCoordinates) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1"); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2"); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -463,7 +463,7 @@ TEST(4_ReaderCombinedDevices) std::map lmap = l2n.create_layermap (ly2, 1000); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index 1a8d0dc62..74130f436 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -395,7 +395,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, 0, db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, 0); + l2n.build_all_nets (cm, ly2, lmap, 0, db::NPM_NoProperties, tl::Variant (), db::BNH_Disconnected, 0, 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -421,7 +421,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, 0); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_Disconnected, 0, 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -447,7 +447,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, 0, db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0); + l2n.build_all_nets (cm, ly2, lmap, 0, db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -473,7 +473,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, 0, db::LayoutToNetlist::AllProperties, tl::Variant (42), db::LayoutToNetlist::BNH_Flatten, 0, 0); + l2n.build_all_nets (cm, ly2, lmap, 0, db::NPM_AllProperties, tl::Variant (42), db::BNH_Flatten, 0, 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -499,7 +499,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, 0, db::LayoutToNetlist::AllProperties, tl::Variant (42), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0); + l2n.build_all_nets (cm, ly2, lmap, 0, db::NPM_AllProperties, tl::Variant (42), db::BNH_SubcircuitCells, "CIRCUIT_", 0); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -525,7 +525,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -636,7 +636,7 @@ TEST(1_BasicExtraction) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); diff --git a/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc b/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc index 1fa588897..68cac78b0 100644 --- a/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc @@ -207,7 +207,7 @@ TEST(1_WriterBasic) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_Disconnected, 0, "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); @@ -440,7 +440,7 @@ TEST(2_WriterWithGlobalNets) lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get (); lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get (); - l2n.build_all_nets (cm, ly2, lmap, "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + l2n.build_all_nets (cm, ly2, lmap, "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); std::string au = tl::testdata (); au = tl::combine_path (au, "algo"); diff --git a/src/layui/layui/layNetlistBrowserPage.cc b/src/layui/layui/layNetlistBrowserPage.cc index 55659a919..faf4d4000 100644 --- a/src/layui/layui/layNetlistBrowserPage.cc +++ b/src/layui/layui/layNetlistBrowserPage.cc @@ -1781,9 +1781,9 @@ NetlistBrowserPage::export_nets (const std::vector *nets) database->build_nets (nets, cm, target_layout, lm, dialog->net_prefix ().empty () ? 0 : dialog->net_prefix ().c_str (), - db::LayoutToNetlist::AllProperties, + db::NPM_AllProperties, dialog->net_propname (), - dialog->produce_circuit_cells () ? db::LayoutToNetlist::BNH_SubcircuitCells : db::LayoutToNetlist::BNH_Flatten, + dialog->produce_circuit_cells () ? db::BNH_SubcircuitCells : db::BNH_Flatten, dialog->produce_circuit_cells () ? dialog->circuit_cell_prefix ().c_str () : 0, dialog->produce_device_cells () ? dialog->device_cell_prefix ().c_str () : 0); diff --git a/src/plugins/tools/net_tracer/unit_tests/dbTraceAllNets.cc b/src/plugins/tools/net_tracer/unit_tests/dbTraceAllNets.cc index c1d293a8a..cf894f538 100644 --- a/src/plugins/tools/net_tracer/unit_tests/dbTraceAllNets.cc +++ b/src/plugins/tools/net_tracer/unit_tests/dbTraceAllNets.cc @@ -78,7 +78,7 @@ void run_test (tl::TestBase *_this, const std::string &file, const db::NetTracer db::Cell &top_cell = layout_nets.cell (layout_nets.add_cell ("NETS")); db::CellMapping cm = l2ndb.cell_mapping_into (layout_nets, top_cell); - l2ndb.build_all_nets (cm, layout_nets, l2ndb.create_layermap (layout_nets, 1000), "NET_", db::LayoutToNetlist::NoProperties, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0); + l2ndb.build_all_nets (cm, layout_nets, l2ndb.create_layermap (layout_nets, 1000), "NET_", db::NPM_NoProperties, tl::Variant (), db::BNH_SubcircuitCells, "CIRCUIT_", 0); std::string fn (tl::testdata ()); fn += "/net_tracer/";