diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 0c74b0633..88c48749f 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -24,6 +24,7 @@ #include "dbLEFDEFImporter.h" #include "dbLayoutUtils.h" #include "dbTechnology.h" +#include "dbShapeProcessor.h" #include "tlStream.h" #include "tlProgress.h" @@ -480,6 +481,55 @@ GeometryBasedLayoutGenerator::add_via (const std::string &vn, const db::Trans &t m_vias.back ().top_mask = top_mask; } +void +GeometryBasedLayoutGenerator::subtract_overlap_from_outline (const std::set &overlap_layers) +{ + db::Shapes all_overlaps; + + std::vector, db::Shapes>::iterator> to_remove; + for (auto s = m_shapes.begin (); s != m_shapes.end (); ++s) { + if (overlap_layers.find (s->first.first) != overlap_layers.end ()) { + all_overlaps.insert (s->second); + to_remove.push_back (s); + } + } + + for (auto i = to_remove.begin (); i != to_remove.end (); ++i) { + m_shapes.erase (*i); + } + + if (all_overlaps.empty ()) { + return; + } + + for (auto s = m_shapes.begin (); s != m_shapes.end (); ++s) { + + if (s->first.second.purpose != Outline) { + continue; + } + + db::ShapeProcessor proc; + + size_t pn = 0; + for (auto sh = s->second.begin (db::ShapeIterator::All); ! sh.at_end (); ++sh) { + proc.insert (*sh, pn); + pn += 2; + } + + pn = 1; + for (auto sh = all_overlaps.begin (db::ShapeIterator::All); ! sh.at_end (); ++sh) { + proc.insert (*sh, pn); + pn += 2; + } + + db::BooleanOp op (db::BooleanOp::And); + db::ShapeGenerator sg (s->second, true /*clear shapes*/); + db::PolygonGenerator out (sg, true, true); + proc.process (out, op); + + } +} + // ----------------------------------------------------------------------------------- // LEFDEFTechnologyComponent implementation diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 5b9518d1e..9de4f99e3 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -1213,6 +1213,8 @@ public: m_fixedmask = f; } + void subtract_overlap_from_outline (const std::set &overlap_layers); + private: struct Via { Via () : bottom_mask (0), cut_mask (0), top_mask (0) { } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 277bd9861..092812911 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -721,6 +721,8 @@ LEFImporter::read_layer (Layout & /*layout*/) m_routing_layers.insert (ln); } else if (type == "CUT") { m_cut_layers.insert (ln); + } else if (type == "OVERLAP") { + m_overlap_layers.insert (ln); } expect (";"); @@ -1029,6 +1031,7 @@ LEFImporter::read_macro (Layout &layout) } mg->add_box (std::string (), Outline, db::Box (-origin, -origin + size), 0, 0); + mg->subtract_overlap_from_outline (m_overlap_layers); MacroDesc macro_desc; macro_desc.foreign_name = foreign_name; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index 5c6402af4..e07a8386d 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -94,6 +94,14 @@ public: return m_cut_layers.find (layer) != m_cut_layers.end (); } + /** + * @brief Returns true if the given layer is an overlap layer + */ + bool is_overlap_layer (const std::string &layer) const + { + return m_overlap_layers.find (layer) != m_overlap_layers.end (); + } + /** * @brief Returns the number of masks for the given layer */ @@ -141,7 +149,7 @@ private: std::map > m_min_widths; std::map m_macros; std::map m_vias; - std::set m_routing_layers, m_cut_layers; + std::set m_routing_layers, m_cut_layers, m_overlap_layers; std::map m_num_masks; std::vector get_iteration (double dbu); diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 381914855..38962826f 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -1011,3 +1011,10 @@ TEST(209_invalid_split_paths) run_test (_this, "issue-1472", "map:tech.map+lef:tech.lef.gz+def:test.def.gz", "au.oas", default_options (), false); } +// issue-1499 +TEST(210_overlaps) +{ + run_test (_this, "issue-1499", "map:tech.map+lef:tech.lef+lef:blocks.lef+def:top.def", "au.oas", default_options (), false); +} + + diff --git a/testdata/lefdef/issue-1499/au.oas b/testdata/lefdef/issue-1499/au.oas new file mode 100644 index 000000000..02bb44686 Binary files /dev/null and b/testdata/lefdef/issue-1499/au.oas differ diff --git a/testdata/lefdef/issue-1499/blocks.lef b/testdata/lefdef/issue-1499/blocks.lef new file mode 100644 index 000000000..1ac45cb8b --- /dev/null +++ b/testdata/lefdef/issue-1499/blocks.lef @@ -0,0 +1,31 @@ +VERSION 5.8 ; + +MACRO a + ORIGIN 0 0 ; + SIZE 600 BY 600 ; + OBS + LAYER M1 ; + RECT 10 10 590 590 ; + END +END a + +MACRO b + ORIGIN -600 0 ; + SIZE 400 BY 500 ; + OBS + LAYER M1 ; + RECT 610 10 990 490 ; + END +END b + +MACRO c + ORIGIN -500 -500 ; + SIZE 500 BY 500 ; + OBS + LAYER M1 ; + POLYGON 510 610 610 610 610 510 990 510 990 990 510 990 ; + LAYER overlap ; + RECT 500 700 1000 1000 ; + POLYGON 500 600 600 600 600 500 1000 500 1000 700 500 700 ; + END +END c diff --git a/testdata/lefdef/issue-1499/tech.lef b/testdata/lefdef/issue-1499/tech.lef new file mode 100644 index 000000000..606730c96 --- /dev/null +++ b/testdata/lefdef/issue-1499/tech.lef @@ -0,0 +1,12 @@ +VERSION 5.8 ; + +LAYER M1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + WIDTH 0.1 ; + PITCH 0.1 ; +END M1 + +LAYER overlap + TYPE OVERLAP ; +END overlap diff --git a/testdata/lefdef/issue-1499/tech.map b/testdata/lefdef/issue-1499/tech.map new file mode 100644 index 000000000..e848325a6 --- /dev/null +++ b/testdata/lefdef/issue-1499/tech.map @@ -0,0 +1,6 @@ +DIEAREA ALL 1 0 +#BOUNDARY DIEAREA 1 0 +BOUNDARY MACRO 1 0 +#M1 LEFOBS 2 0 +M1 LEFOBS 3 0 +M1 BLOCKAGE 3 0 diff --git a/testdata/lefdef/issue-1499/top.def b/testdata/lefdef/issue-1499/top.def new file mode 100644 index 000000000..1e1cd5c32 --- /dev/null +++ b/testdata/lefdef/issue-1499/top.def @@ -0,0 +1,10 @@ +VERSION 5.8 ; +DESIGN top ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 0 0 ) ( 1000000 1000000 ) ; +COMPONENTS 3 ; +- a a + PLACED ( 0 0 ) N ; +- b b + PLACED ( 600000 0 ) N ; +- c c + PLACED ( 500000 500000 ) N ; +END COMPONENTS +END DESIGN