Modified reader scheme for FOREIGNCELL

This commit is contained in:
Matthias Koefferlein
2020-04-24 23:21:27 +02:00
parent c7de542070
commit f6140055d6
15 changed files with 135 additions and 27 deletions
@@ -1145,7 +1145,7 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
std::string inst_name = get ();
std::string model = get ();
db::Cell *cell = m_lef_importer.macro_by_name (model);
std::pair<db::Cell *, db::Trans> ct = m_lef_importer.macro_by_name (model);
while (test ("+")) {
@@ -1158,8 +1158,8 @@ DEFImporter::read_components (std::list<std::pair<std::string, CellInstArray> >
db::FTrans ft = get_orient (false /*mandatory*/);
db::Vector d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left ();
if (cell) {
db::CellInstArray inst (db::CellInst (cell->cell_index ()), db::Trans (ft.rot (), d));
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));
} else {
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
@@ -105,14 +105,14 @@ LEFImporter::layer_width (const std::string &layer, const std::string &nondefaul
}
}
db::Cell *
std::pair<db::Cell *, db::Trans>
LEFImporter::macro_by_name (const std::string &name) const
{
std::map<std::string, db::Cell *>::const_iterator m = m_macros_by_name.find (name);
std::map<std::string, std::pair<db::Cell *, db::Trans> >::const_iterator m = m_macros_by_name.find (name);
if (m != m_macros_by_name.end ()) {
return m->second;
} else {
return 0;
return std::make_pair ((db::Cell *) 0, db::Trans ());
}
}
@@ -726,9 +726,9 @@ LEFImporter::read_macro (Layout &layout)
std::string mn = get ();
set_cellname (mn);
db::Cell &cell = layout.cell (layout.add_cell (mn.c_str ()));
m_macros_by_name.insert (std::make_pair (mn, &cell));
db::Cell &cell = layout.cell (layout.add_cell ());
db::Cell *foreign_cell = 0;
db::Trans foreign_trans;
db::Point origin;
db::Vector size;
@@ -811,13 +811,12 @@ LEFImporter::read_macro (Layout &layout)
} else if (test ("FOREIGN")) {
std::string cn = get ();
if (cn == mn) {
// rename out macro placeholder cell so we don't create a recursive hierarchy
layout.rename_cell (cell.cell_index (), ("LEF_" + mn).c_str ());
if (foreign_cell) {
error ("Duplicate FOREIGN definition");
}
std::string cn = get ();
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (cn.c_str ());
if (c.first) {
@@ -836,7 +835,8 @@ LEFImporter::read_macro (Layout &layout)
expect (";");
cell.insert (db::CellInstArray (db::CellInst (ci), (db::Trans (origin - db::Point ()) * db::Trans (ft)).inverted ()));
foreign_cell = &layout.cell (ci);
foreign_trans = (db::Trans (origin - db::Point ()) * db::Trans (ft)).inverted ();
} else if (test ("OBS")) {
@@ -851,9 +851,26 @@ LEFImporter::read_macro (Layout &layout)
}
std::pair <bool, unsigned int> dl = open_layer (layout, std::string (), Outline);
if (dl.first) {
cell.shapes (dl.second).insert (db::Box (-origin, -origin + size));
if (! foreign_cell) {
// actually implement the real cell
layout.rename_cell (cell.cell_index (), mn.c_str ());
std::pair <bool, unsigned int> dl = open_layer (layout, std::string (), Outline);
if (dl.first) {
cell.shapes (dl.second).insert (db::Box (-origin, -origin + size));
}
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&cell, db::Trans ())));
} else {
// use FOREIGN cell instead of new one
layout.delete_cell (cell.cell_index ());
m_macros_by_name.insert (std::make_pair (mn, std::make_pair (foreign_cell, foreign_trans)));
}
m_macro_bboxes_by_name.insert (std::make_pair (mn, db::Box (-origin, -origin + size)));
@@ -63,7 +63,7 @@ public:
* Returns 0 if the name is not a valid macro name. Otherwise it returns the pointer
* to the corresponding db::Cell object.
*/
db::Cell *macro_by_name (const std::string &macro_name) const;
std::pair<db::Cell *, db::Trans> macro_by_name (const std::string &macro_name) const;
/**
* @brief Get the cell bbox for the given macro name
@@ -125,7 +125,7 @@ private:
std::map<std::string, std::pair<double, double> > m_default_widths;
std::map<std::string, double> m_default_ext;
std::map<std::string, std::pair<double, double> > m_min_widths;
std::map<std::string, db::Cell *> m_macros_by_name;
std::map<std::string, std::pair<db::Cell *, db::Trans> > m_macros_by_name;
std::map<std::string, db::Box> m_macro_bboxes_by_name;
std::map<std::string, ViaDesc> m_vias;
std::set<std::string> m_routing_layers, m_cut_layers;
@@ -334,15 +334,18 @@ TEST(108_scanchain)
TEST(109_foreigncell)
{
run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au.oas.gz", default_options (), false);
run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef+def:in.def", "au.oas.gz", default_options (), false);
}
TEST(110_lefpins)
{
db::LEFDEFReaderOptions options = default_options ();
options.set_produce_lef_pins (false);
run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au_no_lefpins.oas.gz", options, false);
run_test (_this, "lefpins", "lef:in_tech.lef+lef:in.lef+def:in.def", "au_no_lefpins.oas.gz", options, false);
options.set_produce_lef_pins (true);
options.set_lef_pins_datatype (10);
options.set_lef_pins_suffix (".LEFPIN");
run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au_lefpins_mapped.oas.gz", options, false);
run_test (_this, "lefpins", "lef:in_tech.lef+lef:in.lef+def:in.def", "au_lefpins_mapped.oas.gz", options, false);
}