Don't error out on missing MACRO in LEF, but create a dummy macro with size 0,0 instead and issue a warning. This will place nicely with N, but not with other orientations.

This commit is contained in:
Matthias Koefferlein 2025-05-28 18:58:28 +02:00
parent a2ac8d45de
commit ad444c5552
5 changed files with 36 additions and 7 deletions

View File

@ -1594,6 +1594,7 @@ DEFImporter::read_styles (double scale)
}
}
void
DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::string, CellInstArray> > &instances, double scale)
{
@ -1607,9 +1608,26 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
bool is_placed = false;
std::string maskshift;
std::map<std::string, MacroDesc>::const_iterator m = reader_state ()->lef_importer ().macros ().find (model);
if (m == reader_state ()->lef_importer ().macros ().end ()) {
error (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
const MacroDesc *m = 0;
std::map<std::string, MacroDesc>::const_iterator im = reader_state ()->lef_importer ().macros ().find (model);
if (im == reader_state ()->lef_importer ().macros ().end ()) {
warn (tl::sprintf (tl::to_string (tr ("Macro not found in LEF file: %s - creating dummy macro")), model));
// create a dummy macro definition (no FOREIGN, size 0x0 etc.)
GeometryBasedLayoutGenerator *mg = new GeometryBasedLayoutGenerator ();
reader_state ()->register_macro_cell (model, mg);
MacroDesc macro_desc;
macro_desc.bbox = db::Box (db::Point (), db::Point ());
m = reader_state ()->lef_importer ().insert_macro (model, macro_desc);
} else {
m = &im->second;
}
while (test ("+")) {
@ -1621,7 +1639,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
test (")");
ft = get_orient (false /*mandatory*/);
d = pt - m->second.bbox.transformed (ft).lower_left ();
d = pt - m->bbox.transformed (ft).lower_left ();
is_placed = true;
} else if (test ("UNPLACED")) {
@ -1633,7 +1651,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
test (")");
ft = get_orient (false /*mandatory*/);
d = pt - m->second.bbox.transformed (ft).lower_left ();
d = pt - m->bbox.transformed (ft).lower_left ();
is_placed = true;
}
@ -1654,7 +1672,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
if (is_placed) {
std::pair<db::Cell *, db::Trans> ct = reader_state ()->macro_cell (model, layout, m_component_maskshift, string2masks (maskshift), m->second, &reader_state ()->lef_importer ());
std::pair<db::Cell *, db::Trans> ct = reader_state ()->macro_cell (model, layout, m_component_maskshift, string2masks (maskshift), *m, &reader_state ()->lef_importer ());
if (ct.first) {
db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second);
instances.push_back (std::make_pair (inst_name, inst));

View File

@ -122,7 +122,7 @@ public:
}
/**
* @brief Gets the
* @brief Gets the macros map
*
* The map maps the macro name to the macro description.
*/
@ -131,6 +131,14 @@ public:
return m_macros;
}
/**
* @brief Inserts a macro description for a name
*/
const MacroDesc *insert_macro (const std::string &mn, const MacroDesc &m)
{
return &m_macros.insert (std::make_pair (mn, m)).first->second;
}
/**
* @brief Finishes reading a LEF file
*

View File

@ -521,6 +521,9 @@ TEST(109_foreigncell)
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);
// no macros -> warning
run_test (_this, "foreigncell", "gds:macros.gds+lef:in_tech.lef+def:in.def", "au_no_macros.oas.gz", options, false);
}
TEST(110_lefpins)

Binary file not shown.

BIN
testdata/lefdef/foreigncell/macros.gds vendored Normal file

Binary file not shown.