added option to skip duplicate defined LEF MACROS during lef import

This commit is contained in:
Andreas Wiener 2026-06-12 13:31:41 +02:00 committed by Matthias Koefferlein
parent 87060b4364
commit 592d65f9f6
6 changed files with 84 additions and 6 deletions

View File

@ -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));
}
}

View File

@ -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<std::string> m_map_files;
bool m_skip_duplicate_macros;
unsigned int m_macro_resolution_mode;
bool m_read_lef_with_def;
std::vector<std::string> m_lef_files;

View File

@ -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<std::string>::const_iterator l = effective_options.begin_lef_files (); l != effective_options.end_lef_files (); ++l) {

View File

@ -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);

View File

@ -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;
};
}

View File

@ -967,6 +967,19 @@ gsi::Class<db::LEFDEFReaderOptions> 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 "