diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 11105b085..2e18707ee 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -77,7 +77,8 @@ LEFDEFReaderOptions::LEFDEFReaderOptions () m_special_routing_suffix (""), m_special_routing_datatype (0), m_separate_groups (false), - m_consider_map_file (true) + m_consider_map_file (true), + m_macro_resolution_mode (0) { // .. nothing yet .. } @@ -125,6 +126,7 @@ LEFDEFReaderOptions::LEFDEFReaderOptions (const LEFDEFReaderOptions &d) m_special_routing_datatype (d.m_special_routing_datatype), m_separate_groups (d.m_separate_groups), m_consider_map_file (d.m_consider_map_file), + m_macro_resolution_mode (d.m_macro_resolution_mode), m_lef_files (d.m_lef_files) { // .. nothing yet .. diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 40838f89d..bb41ade22 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -525,6 +525,23 @@ public: m_consider_map_file = f; } + /** + * @brief Specify the LEF macro resolution strategy + * Values are: + * 0: propduce LEF geometry unless a FOREIGN cell is specified (default) + * 1: produce LEF geometry always and ignore FOREIGN + * 2: produce a placeholder cell always (even if FOREIGN isn't given) + */ + unsigned int macro_resolution_mode () const + { + return m_macro_resolution_mode; + } + + void set_macro_resolution_mode (unsigned int m) + { + m_macro_resolution_mode = m; + } + private: bool m_read_all_layers; db::LayerMap m_layer_map; @@ -568,6 +585,7 @@ private: int m_special_routing_datatype; bool m_separate_groups; bool m_consider_map_file; + unsigned int m_macro_resolution_mode; std::vector m_lef_files; }; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc index 4caffcf97..b919fb0c7 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc @@ -180,6 +180,9 @@ private: if (is_lef_format (*e)) { std::string lp = tl::combine_path (input_dir, *e); + + tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Reading LEF file: ")) + lp); + tl::InputStream lef_stream (lp); tl::log << tl::to_string (tr ("Reading")) << " " << lp; importer.read_lef (lef_stream, layout, state); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 2d20ff902..0cb8fc40d 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -853,7 +853,7 @@ LEFImporter::read_macro (Layout &layout) } - if (! foreign_cell) { + if (options ().macro_resolution_mode () == 1 || (! foreign_cell && options ().macro_resolution_mode () != 2)) { // actually implement the real cell @@ -866,6 +866,22 @@ LEFImporter::read_macro (Layout &layout) m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&cell, db::Trans ()))); + } else if (! foreign_cell) { + + // macro resolution mode #2 (always create a MACRO reference, no LEF geometry) + + db::cell_index_type ci; + std::pair c = layout.cell_by_name (mn.c_str ()); + if (c.first) { + ci = c.second; + } else { + ci = layout.add_cell (mn.c_str ()); + layout.cell (ci).set_ghost_cell (true); + } + + layout.delete_cell (cell.cell_index ()); + m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&layout.cell (ci), db::Trans ()))); + } else if (foreign_name != mn) { warn ("FOREIGN name differs from MACRO name in macro: " + mn); diff --git a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc index 14336a90b..b41e96977 100644 --- a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc +++ b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc @@ -480,6 +480,25 @@ gsi::Class decl_lefdef_config ("db", "LEFDEFReaderConfi "\n" "This property has been added in version 0.26.5.\n" ) + + gsi::method ("macro_resolution_mode", &db::LEFDEFReaderOptions::macro_resolution_mode, + "@brief Gets the macro resolution mode.\n" + "This property describes the way LEF macros are turned into GDS cells. There " + "are three modes available:\n" + "\n" + "@ul\n" + " @li 0: propduce LEF geometry unless a FOREIGN cell is specified (default) @/li\n" + " @li 1: produce LEF geometry always and ignore FOREIGN @/li\n" + " @li 2: produce a placeholder cell always (even if FOREIGN isn't given) @/li\n" + "@/ul\n" + "\n" + "This property has been added in version 0.26.5.\n" + ) + + gsi::method ("macro_resolution_mode=", &db::LEFDEFReaderOptions::set_macro_resolution_mode, gsi::arg ("mode"), + "@brief Sets the macro resolution mode.\n" + "See \\macro_resolution_mode for details about this property.\n" + "\n" + "This property has been added in version 0.26.5.\n" + ) + gsi::method ("lef_files", &db::LEFDEFReaderOptions::lef_files, "@brief Gets the list technology LEF files to additionally import\n" "Returns a list of path names for technology LEF files to read in addition to the primary file. " diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 30090da2b..f6f70c009 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -335,6 +335,18 @@ TEST(108_scanchain) TEST(109_foreigncell) { run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef+def:in.def", "au.oas.gz", default_options (), false); + + db::LEFDEFReaderOptions options = default_options (); + + run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in2.lef+def:in.def", "au_default.oas.gz", options, false); + + options.set_macro_resolution_mode (1); + + run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in2.lef+def:in.def", "au_ignore_foreign.oas.gz", options, false); + + options.set_macro_resolution_mode (2); + + run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef+def:in.def", "au_always_foreign.oas.gz", options, false); } TEST(110_lefpins) diff --git a/testdata/lefdef/foreigncell/au_ignore_foreign.oas.gz b/testdata/lefdef/foreigncell/au_ignore_foreign.oas.gz new file mode 100644 index 000000000..44831e8e5 Binary files /dev/null and b/testdata/lefdef/foreigncell/au_ignore_foreign.oas.gz differ diff --git a/testdata/lefdef/foreigncell/in2.lef b/testdata/lefdef/foreigncell/in2.lef new file mode 100644 index 000000000..3ff311146 --- /dev/null +++ b/testdata/lefdef/foreigncell/in2.lef @@ -0,0 +1,47 @@ +MACRO macro1 + CLASS CORE ; + ORIGIN 0.000 0.000 ; + SIZE 0.384 BY 0.480 ; + PIN Z + PORT + LAYER M1 ; + RECT 0.306 0.357 0.318 0.403 ; + RECT 0.318 0.115 0.352 0.403 ; + VIA 0.336 0.167 square ; + VIA 0.336 0.351 square ; + END + END Z +END macro1 + +MACRO macro2 + CLASS CORE ; + FOREIGN foreign2 -0.15 0.25 ; + ORIGIN 0.000 0.000 ; + SIZE 0.384 BY 0.480 ; + PIN Z + PORT + LAYER M1 ; + RECT 0.306 0.357 0.318 0.403 ; + RECT 0.318 0.115 0.352 0.403 ; + VIA 0.336 0.167 square ; + VIA 0.336 0.351 square ; + END + END Z +END macro2 + +MACRO macro3 + CLASS CORE ; + FOREIGN macro3 ; + ORIGIN 0.000 0.000 ; + SIZE 0.384 BY 0.480 ; + PIN Z + PORT + LAYER M1 ; + RECT 0.306 0.357 0.318 0.403 ; + RECT 0.318 0.115 0.352 0.403 ; + VIA 0.336 0.167 square ; + VIA 0.336 0.351 square ; + END + END Z +END macro3 +