diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 299a24252..eb572ec5a 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -1069,7 +1069,7 @@ void LEFDEFReaderState::ensure_lef_importer (int warn_level) { if (! mp_lef_importer.get ()) { - mp_lef_importer.reset (new db::LEFImporter (warn_level)); + mp_lef_importer.reset (new db::LEFImporter (warn_level, true)); } } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 743612e68..25e8e058f 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -896,6 +896,16 @@ public: m_map_files = f; } + bool skip_duplicate_macros () const + { + return m_skip_duplicate_macros; + } + + void set_skip_duplicate_macros (bool v) + { + m_skip_duplicate_macros = v; + } + std::string single_map_file () const { return m_map_files.empty () ? std::string () : m_map_files.front (); @@ -1055,6 +1065,7 @@ private: bool m_separate_groups; bool m_joined_paths; std::vector m_map_files; + bool m_skip_duplicate_macros; unsigned int m_macro_resolution_mode; bool m_read_lef_with_def; 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 8d3519cda..45a9daab0 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc @@ -142,7 +142,7 @@ LEFDEFReader::read_lefdef (db::Layout &layout, const db::LoadLayoutOptions &opti tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Reading LEF file"))); - db::LEFImporter importer (warn_level ()); + db::LEFImporter importer (warn_level (), effective_options.skip_duplicate_macros ()); for (std::vector::const_iterator l = effective_options.begin_lef_files (); l != effective_options.end_lef_files (); ++l) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index ff4ceb531..03f41f115 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -33,8 +33,9 @@ namespace db // ----------------------------------------------------------------------------------- // LEFImporter implementation -LEFImporter::LEFImporter (int warn_level) - : LEFDEFImporter (warn_level) +LEFImporter::LEFImporter (int warn_level, bool skip_duplicate_macros) + : LEFDEFImporter (warn_level), + m_skip_duplicate_macros (skip_duplicate_macros) { // .. nothing yet .. } @@ -886,7 +887,58 @@ LEFImporter::read_macro (Layout &layout) std::string mn = get (); if (m_macros.find (mn) != m_macros.end ()) { - error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn); + if (m_skip_duplicate_macros) { + // 1. Change error to warning + warn (tl::to_string (tr ("Duplicate MACRO name: ")) + mn + tl::to_string (tr (" (Skipping duplicate)"))); + + // Safe LEF block skipping + while (! at_end ()) { + + if (test ("END")) { + expect (mn); + break; + } else if (test ("PIN")) { + std::string pn = get (); // PIN always has a pin-name -> skip it + //tl::info << tl::to_string (tr ("Found PIN : ")) + pn; + while (! at_end ()) { + if (test ("PORT")) { + //tl::info << tl::to_string (tr ("Found PORT within ")) + pn; + while (! at_end ()) { + if (test ("END")) { + //tl::info << tl::to_string (tr ("Found PORT END within ")) + pn; + break; + } else { + skip_entry (); + } + } + } else if (test ("END")) { + std::string pn = get (); // PIN always has a pin-name -> skip it + //tl::info << tl::to_string (tr ("Found PIN END : ")) + pn; + break; + } else { + skip_entry (); + } + } + } else if (test ("OBS")) { + //tl::info << tl::to_string (tr ("Found OBS")); + while (! at_end ()) { + if (test ("END")) { + //tl::info << tl::to_string (tr ("Found END OBS")); + break; + } else { + skip_entry (); + } + } + } else { + skip_entry (); + } + } + tl::info << tl::to_string (tr ("Successfully skipped duplicate MACRO: ")) + mn; + + return; // Exit early so we don't register or process this duplicate + } else { + error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn); + } } set_cellname (mn); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index 176648099..4d994e504 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -50,7 +50,7 @@ public: /** * @brief Default constructor */ - LEFImporter (int warn_level); + LEFImporter (int warn_level, bool skip_duplicate_macros); /** * @brief Destructor @@ -169,6 +169,8 @@ private: void read_layer (Layout &layout); void read_macro (Layout &layout); void skip_entry (); + + bool m_skip_duplicate_macros; }; } diff --git a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc index 0d1efba6b..04061b6ef 100644 --- a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc +++ b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc @@ -967,6 +967,19 @@ gsi::Class decl_lefdef_config ("db", "LEFDEFReaderConfi "\n" "This property has been added in version 0.27. The ability to supply multiple files has been added in version 0.30.6.\n" ) + + gsi::method ("skip_duplicate_macros", &db::LEFDEFReaderOptions::skip_duplicate_macros, + "@brief Get the setting for wether to skip douplicate LEF Macro definitions.\n" + "This property describes what to do when while reading LEF files douplicate MACRO definitions are " + "discovered. Normally an error is issued and the import fails. When setting this flag to true a" + "warning is issued and the macro definition is skipped. So always the first definition of MACRO is used.\n" + "\n" + "This property has been added in version 0.30.x.\n" + ) + + gsi::method ("skip_duplicate_macros=", &db::LEFDEFReaderOptions::set_skip_duplicate_macros, gsi::arg ("skip_duplicate_macros"), + "@brief Sets mode how to handle douplicate MARCO definitions.\n" + "\n" + "This property has been added in version 0.30.x.\n" + ) + gsi::method ("macro_resolution_mode", &db::LEFDEFReaderOptions::macro_resolution_mode, "@brief Gets the macro resolution mode (LEF macros into DEF).\n" "This property describes the way LEF macros are turned into layout cells when reading DEF. There "