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 void
DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::string, CellInstArray> > &instances, double scale) 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; bool is_placed = false;
std::string maskshift; std::string maskshift;
std::map<std::string, MacroDesc>::const_iterator m = reader_state ()->lef_importer ().macros ().find (model); const MacroDesc *m = 0;
if (m == reader_state ()->lef_importer ().macros ().end ()) {
error (tl::to_string (tr ("Macro not found in LEF file: ")) + model); 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 ("+")) { while (test ("+")) {
@ -1621,7 +1639,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
test (")"); test (")");
ft = get_orient (false /*mandatory*/); 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; is_placed = true;
} else if (test ("UNPLACED")) { } else if (test ("UNPLACED")) {
@ -1633,7 +1651,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
test (")"); test (")");
ft = get_orient (false /*mandatory*/); 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; is_placed = true;
} }
@ -1654,7 +1672,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
if (is_placed) { 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) { if (ct.first) {
db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second); 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)); 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. * The map maps the macro name to the macro description.
*/ */
@ -131,6 +131,14 @@ public:
return m_macros; 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 * @brief Finishes reading a LEF file
* *

View File

@ -521,6 +521,9 @@ TEST(109_foreigncell)
options.set_macro_resolution_mode (2); 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); 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) TEST(110_lefpins)

Binary file not shown.

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

Binary file not shown.