diff --git a/src/db/db/dbHierarchyBuilder.cc b/src/db/db/dbHierarchyBuilder.cc index 0d9465d04..88039a4b4 100644 --- a/src/db/db/dbHierarchyBuilder.cc +++ b/src/db/db/dbHierarchyBuilder.cc @@ -154,6 +154,7 @@ HierarchyBuilder::reset () m_initial_pass = true; mp_initial_cell = 0; + m_cells_to_be_filled.clear (); m_cell_map.clear (); m_cells_seen.clear (); m_cell_stack.clear (); @@ -206,9 +207,15 @@ void HierarchyBuilder::enter_cell (const RecursiveShapeIterator * /*iter*/, const db::Cell * /*cell*/, const db::Box & /*region*/, const box_tree_type * /*complex_region*/) { tl_assert (m_cm_entry != m_cell_map.end () && m_cm_entry != cell_map_type::const_iterator ()); + m_cells_seen.insert (m_cm_entry->first); - m_cell_stack.push_back (std::make_pair (m_cm_new_entry, &mp_target->cell (m_cm_entry->second))); + bool new_cell = (m_cells_to_be_filled.find (m_cm_entry->second) != m_cells_to_be_filled.end ()); + if (new_cell) { + m_cells_to_be_filled.erase (m_cm_entry->second); + } + + m_cell_stack.push_back (std::make_pair (new_cell, &mp_target->cell (m_cm_entry->second))); } void @@ -230,6 +237,7 @@ HierarchyBuilder::new_inst (const RecursiveShapeIterator *iter, const db::CellIn db::cell_index_type new_cell = mp_target->add_cell (iter->layout ()->cell_name (inst.object ().cell_index ())); m_cm_entry = m_cell_map.insert (std::make_pair (key, new_cell)).first; m_cm_new_entry = true; + m_cells_to_be_filled.insert (new_cell); } // for new cells, create this instance @@ -277,6 +285,7 @@ HierarchyBuilder::new_inst_member (const RecursiveShapeIterator *iter, const db: db::cell_index_type new_cell = mp_target->add_cell ((std::string (iter->layout ()->cell_name (inst.object ().cell_index ())) + suffix).c_str ()); m_cm_entry = m_cell_map.insert (std::make_pair (key, new_cell)).first; m_cm_new_entry = true; + m_cells_to_be_filled.insert (new_cell); } // for a new cell, create this instance diff --git a/src/db/db/dbHierarchyBuilder.h b/src/db/db/dbHierarchyBuilder.h index 7a2c23f84..5e0da406f 100644 --- a/src/db/db/dbHierarchyBuilder.h +++ b/src/db/db/dbHierarchyBuilder.h @@ -248,6 +248,7 @@ private: db::RecursiveShapeIterator m_source; cell_map_type m_cell_map; std::set m_cells_seen; + std::set m_cells_to_be_filled; cell_map_type::const_iterator m_cm_entry; bool m_cm_new_entry; unsigned int m_target_layer; diff --git a/src/db/unit_tests/dbHierarchyBuilderTests.cc b/src/db/unit_tests/dbHierarchyBuilderTests.cc index 55e0d6e76..317b5883f 100644 --- a/src/db/unit_tests/dbHierarchyBuilderTests.cc +++ b/src/db/unit_tests/dbHierarchyBuilderTests.cc @@ -467,3 +467,34 @@ TEST(5_CompareRecursiveShapeIterators) } } +TEST(6_DisjunctLayersPerHierarchyBranch) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/hierarchy_builder_l4.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::Layout target; + db::HierarchyBuilder builder (&target); + + for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) { + + unsigned int li1 = (*li).first; + unsigned int target_layer = target.insert_layer (*(*li).second); + builder.set_target_layer (target_layer); + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1); + + iter.push (&builder); + + } + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/hierarchy_builder_au_l4.gds"); +} + diff --git a/testdata/algo/hierarchy_builder_au_l4.gds b/testdata/algo/hierarchy_builder_au_l4.gds new file mode 100644 index 000000000..ecabac16a Binary files /dev/null and b/testdata/algo/hierarchy_builder_au_l4.gds differ diff --git a/testdata/algo/hierarchy_builder_l4.gds b/testdata/algo/hierarchy_builder_l4.gds new file mode 100644 index 000000000..f44e7261f Binary files /dev/null and b/testdata/algo/hierarchy_builder_l4.gds differ