diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 26ab0ebca..682eb4293 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -608,16 +608,16 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region } 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, std::map, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const +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, cmap, tr); + 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, std::map, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const +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; @@ -673,8 +673,10 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout & db::cell_index_type subci = c->inst_cell_index (); size_t subcid = c->id (); - std::map, db::cell_index_type>::const_iterator cm = cmap.find (std::make_pair (subci, subcid)); - if (cm == cmap.end ()) { + 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)) { @@ -688,12 +690,12 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout & 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 = cmap.insert (std::make_pair (std::make_pair (subci, subcid), target_ci)).first; + 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, cmap, tr_mag); + 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 = cmap.insert (std::make_pair (std::make_pair (subci, subcid), std::numeric_limits::max ())).first; + cm = reuse_table.insert (std::make_pair (cmap_key, std::numeric_limits::max ())).first; } } @@ -730,12 +732,12 @@ LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &ta throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); } - std::map, db::cell_index_type> cell_map; + cell_reuse_table_type cell_reuse_table; double mag = internal_layout ()->dbu () / target.dbu (); db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, net); - build_net_rec (net, target, target_cell, lmap, 0, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag)); + 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)); } void @@ -745,7 +747,7 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); } - std::map, db::cell_index_type> cell_map; + cell_reuse_table_type cell_reuse_table; double mag = internal_layout ()->dbu () / target.dbu (); const db::Netlist *netlist = mp_netlist.get (); @@ -767,7 +769,7 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target } db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n); - build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag)); + build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag)); } @@ -796,9 +798,9 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target if (net_cell_name_prefix) { std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":"; - build_net_rec (*n, target, target.cell (target_ci), lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr); + build_net_rec (*n, target, target.cell (target_ci), 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, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr); + build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr); } } diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index fc5cabc77..fd86500ca 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -675,10 +675,39 @@ private: bool m_is_flat; db::DeepLayer m_dummy_layer; + struct CellReuseTableKey + { + CellReuseTableKey (db::cell_index_type _cell_index, db::properties_id_type _netname_propid, size_t _cluster_id) + : cell_index (_cell_index), netname_propid (_netname_propid), cluster_id (_cluster_id) + { + // .. nothing yet .. + } + + bool operator< (const CellReuseTableKey &other) const + { + if (cell_index != other.cell_index) { + return cell_index < other.cell_index; + } + if (netname_propid != other.netname_propid) { + return netname_propid < other.netname_propid; + } + if (cluster_id != other.cluster_id) { + return cluster_id < other.cluster_id; + } + return false; + } + + db::cell_index_type cell_index; + db::properties_id_type netname_propid; + size_t cluster_id; + }; + + typedef std::map cell_reuse_table_type; + void init (); 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, 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, std::map, db::cell_index_type> &cmap, 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, std::map, db::cell_index_type> &cmap, 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 db::Region ®ion) const; void ensure_layout () const; std::string make_new_name (const std::string &stem = std::string ()); diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index 9d4a39438..1c9bdc953 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -488,6 +488,33 @@ TEST(1_BasicExtraction) db::compare_layouts (_this, ly2, au); } + { + db::Layout ly2; + ly2.dbu (ly.dbu ()); + db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP")); + + db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/); + + std::map lmap; + lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = &rpsd; + lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = &rnsd; + lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = rpoly.get (); + lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = rdiff_cont.get (); + lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = rpoly_cont.get (); + lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = rmetal1.get (); + 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, tl::Variant (42), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0); + + std::string au = tl::testsrc (); + au = tl::combine_path (au, "testdata"); + au = tl::combine_path (au, "algo"); + au = tl::combine_path (au, "device_extract_au1_rebuild_pr.gds"); + + db::compare_layouts (_this, ly2, au); + } + { db::Layout ly2; ly2.dbu (ly.dbu ()); diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.cc b/src/laybasic/laybasic/layNetlistBrowserDialog.cc index 8a72b5280..fb7e32bc6 100644 --- a/src/laybasic/laybasic/layNetlistBrowserDialog.cc +++ b/src/laybasic/laybasic/layNetlistBrowserDialog.cc @@ -194,7 +194,7 @@ NetlistBrowserDialog::probe_net (const db::DPoint &p, bool trace_path) db::DBox start_search_box = db::DBox (p, p).enlarged (db::DVector (l, l)); - // @@@ not used yet .. + // TODO: not used yet .. db::DBox stop_search_box; if (trace_path) { stop_search_box = db::DBox (m_mouse_first_point, m_mouse_first_point).enlarged (db::DVector (l, l)); diff --git a/testdata/algo/device_extract_au1_rebuild_pr.gds b/testdata/algo/device_extract_au1_rebuild_pr.gds new file mode 100644 index 000000000..36c92dfb0 Binary files /dev/null and b/testdata/algo/device_extract_au1_rebuild_pr.gds differ