WIP: provide a LEF reader mode where all macros are read. For DEF only those macros which are used are read.

This commit is contained in:
Matthias Koefferlein 2020-08-23 01:29:10 +02:00
parent dcc99060fc
commit af7d8bba89
7 changed files with 140 additions and 80 deletions

View File

@ -64,6 +64,12 @@ DEFImporter::read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReader
m_lef_importer.read (stream, layout, state); m_lef_importer.read (stream, layout, state);
} }
void
DEFImporter::finish_lef (db::Layout &layout)
{
m_lef_importer.finish_lef (layout);
}
void void
DEFImporter::read_polygon (db::Polygon &poly, double scale) DEFImporter::read_polygon (db::Polygon &poly, double scale)
{ {
@ -1274,6 +1280,11 @@ 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 = m_lef_importer.macros ().find (model);
if (m == m_lef_importer.macros ().end ()) {
error (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
}
while (test ("+")) { while (test ("+")) {
if (test ("PLACED") || test ("FIXED") || test ("COVER")) { if (test ("PLACED") || test ("FIXED") || test ("COVER")) {
@ -1283,7 +1294,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_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left (); d = pt - m->second.bbox.transformed (ft).lower_left ();
is_placed = true; is_placed = true;
} else if (test ("MASKSHIFT")) { } else if (test ("MASKSHIFT")) {
@ -1302,19 +1313,10 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
if (is_placed) { if (is_placed) {
std::map<std::string, MacroDesc>::const_iterator m = m_lef_importer.macros ().find (model); std::pair<db::Cell *, db::Trans> ct = reader_state ()->macro_cell (model, layout, string2masks (maskshift), m->second, &m_lef_importer);
if (m == m_lef_importer.macros ().end ()) { if (ct.first) {
db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second);
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model); instances.push_back (std::make_pair (inst_name, inst));
} else {
std::pair<db::Cell *, db::Trans> ct = reader_state ()->macro_cell (model, layout, string2masks (maskshift), m->second, &m_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

@ -58,6 +58,11 @@ public:
*/ */
void read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state); void read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderState &state);
/**
* @brief Provided for test purposes
*/
void finish_lef (Layout &layout);
protected: protected:
void do_read (db::Layout &layout); void do_read (db::Layout &layout);

View File

@ -140,6 +140,8 @@ private:
tl::log << tl::to_string (tr ("Reading")) << " " << m_stream.source (); tl::log << tl::to_string (tr ("Reading")) << " " << m_stream.source ();
importer.read (m_stream, layout, state); importer.read (m_stream, layout, state);
importer.finish_lef (layout);
} else { } else {
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Reading DEF file"))); tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Reading DEF file")));

View File

@ -188,26 +188,30 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
test (")"); test (")");
} }
db::Coord iw = db::coord_traits<db::Coord>::rounded (w / dbu); if (lg) {
db::Path p (points.begin (), points.end (), iw, iw / 2, iw / 2, false);
if (iterate) { db::Coord iw = db::coord_traits<db::Coord>::rounded (w / dbu);
db::Path p (points.begin (), points.end (), iw, iw / 2, iw / 2, false);
std::vector<db::Trans> ti = get_iteration (dbu); if (iterate) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) { std::vector<db::Trans> ti = get_iteration (dbu);
db::Path pt = p.transformed (*t);
lg->add_path (layer_name, purpose, pt, mask, prop_id); for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
if (collect_boxes_for_labels) { db::Path pt = p.transformed (*t);
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box (); lg->add_path (layer_name, purpose, pt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box ();
}
} }
}
} else { } else {
lg->add_path (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
}
lg->add_path (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
} }
} }
@ -233,25 +237,29 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
test (")"); test (")");
} }
db::Polygon p; if (lg) {
p.assign_hull (points.begin (), points.end ());
if (iterate) { db::Polygon p;
p.assign_hull (points.begin (), points.end ());
std::vector<db::Trans> ti = get_iteration (dbu); if (iterate) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
db::Polygon pt = p.transformed (*t); std::vector<db::Trans> ti = get_iteration (dbu);
lg->add_polygon (layer_name, purpose, pt, mask, prop_id); for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
if (collect_boxes_for_labels) { db::Polygon pt = p.transformed (*t);
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box (); lg->add_polygon (layer_name, purpose, pt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = pt.box ();
}
} }
}
} else { } else {
lg->add_polygon (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
}
lg->add_polygon (layer_name, purpose, p, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = p.box ();
} }
} }
@ -279,25 +287,29 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
} }
db::Box b (points [0], points [1]); if (lg) {
if (iterate) { db::Box b (points [0], points [1]);
std::vector<db::Trans> ti = get_iteration (dbu); if (iterate) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) { std::vector<db::Trans> ti = get_iteration (dbu);
db::Box bt = b.transformed (*t);
lg->add_box (layer_name, purpose, bt, mask, prop_id); for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
if (collect_boxes_for_labels) { db::Box bt = b.transformed (*t);
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = bt; lg->add_box (layer_name, purpose, bt, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = bt;
}
} }
}
} else { } else {
lg->add_box (layer_name, purpose, b, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = b;
}
lg->add_box (layer_name, purpose, b, mask, prop_id);
if (collect_boxes_for_labels) {
collect_boxes_for_labels->insert (std::make_pair (layer_name, db::Box ())).first->second = b;
} }
} }
@ -333,17 +345,21 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
std::string vn = get (); std::string vn = get ();
if (iterate) { if (lg) {
if (iterate) {
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
lg->add_via (vn, *t * db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
}
} else {
lg->add_via (vn, db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
std::vector<db::Trans> ti = get_iteration (dbu);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
lg->add_via (vn, *t * db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
} }
} else {
lg->add_via (vn, db::Trans (points [0]), mask_bottom, mask_cut, mask_top);
} }
expect (";"); expect (";");
@ -850,18 +866,24 @@ LEFImporter::read_macro (Layout &layout)
} }
*/ */
db::properties_id_type prop_id = 0; if (reader_state ()->tech_comp ()->produce_lef_pins ()) {
if (produce_pin_props ()) {
db::PropertiesRepository::properties_set props;
props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label)));
prop_id = layout.properties_repository ().properties_id (props);
}
std::map <std::string, db::Box> boxes_for_labels; db::properties_id_type prop_id = 0;
read_geometries (mg, layout.dbu (), LEFPins, &boxes_for_labels, prop_id); if (produce_pin_props ()) {
db::PropertiesRepository::properties_set props;
props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label)));
prop_id = layout.properties_repository ().properties_id (props);
}
for (std::map <std::string, db::Box>::const_iterator b = boxes_for_labels.begin (); b != boxes_for_labels.end (); ++b) { std::map <std::string, db::Box> boxes_for_labels;
mg->add_text (b->first, Label, db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ())), 0, 0); read_geometries (mg, layout.dbu (), LEFPins, &boxes_for_labels, prop_id);
for (std::map <std::string, db::Box>::const_iterator b = boxes_for_labels.begin (); b != boxes_for_labels.end (); ++b) {
mg->add_text (b->first, Label, db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ())), 0, 0);
}
} else {
read_geometries (0, layout.dbu (), LEFPins, 0, 0);
} }
expect ("END"); expect ("END");
@ -907,7 +929,12 @@ LEFImporter::read_macro (Layout &layout)
} else if (test ("OBS")) { } else if (test ("OBS")) {
read_geometries (mg, layout.dbu (), Obstructions); if (reader_state ()->tech_comp ()->produce_obstructions ()) {
read_geometries (mg, layout.dbu (), Obstructions);
} else {
read_geometries (0, layout.dbu (), Obstructions);
}
expect ("END"); expect ("END");
} else if (test ("FIXEDMASK")) { } else if (test ("FIXEDMASK")) {
@ -1037,5 +1064,13 @@ LEFImporter::do_read (db::Layout &layout)
} }
} }
void
LEFImporter::finish_lef (db::Layout &layout)
{
for (std::map<std::string, MacroDesc>::const_iterator m = m_macros.begin (); m != m_macros.end (); ++m) {
reader_state ()->macro_cell (m->first, layout, std::vector<unsigned int> (), m->second, this);
}
}
} }

View File

@ -57,11 +57,6 @@ public:
*/ */
~LEFImporter (); ~LEFImporter ();
/**
* @brief Get the cell bbox for the given macro name
*/
db::Box macro_bbox_by_name (const std::string &macro_name) const;
/** /**
* @brief Get the width for a layer with the given name * @brief Get the width for a layer with the given name
* *
@ -128,6 +123,14 @@ public:
return m_macros; return m_macros;
} }
/**
* @brief Finishes reading a LEF file
*
* This method will create all the macros, so they become visible.
* When reading a LEF as component for a DEF, this method will not be called.
*/
void finish_lef (db::Layout &layout);
protected: protected:
void do_read (db::Layout &layout); void do_read (db::Layout &layout);

View File

@ -65,6 +65,8 @@ static db::LayerMap run_test (tl::TestBase *_this, const char *lef_dir, const ch
db::LEFDEFReaderState ld (&options, layout, fn_path); db::LEFDEFReaderState ld (&options, layout, fn_path);
db::DEFImporter imp; db::DEFImporter imp;
bool any_def = false;
bool any_lef = false;
while (! ex.at_end ()) { while (! ex.at_end ()) {
@ -85,6 +87,8 @@ static db::LayerMap run_test (tl::TestBase *_this, const char *lef_dir, const ch
tl::InputStream stream (fn); tl::InputStream stream (fn);
imp.read (stream, layout, ld); imp.read (stream, layout, ld);
any_def = true;
} else if (ex.test ("lef:")) { } else if (ex.test ("lef:")) {
std::string fn = fn_path, f; std::string fn = fn_path, f;
@ -94,6 +98,8 @@ static db::LayerMap run_test (tl::TestBase *_this, const char *lef_dir, const ch
tl::InputStream stream (fn); tl::InputStream stream (fn);
imp.read_lef (stream, layout, ld); imp.read_lef (stream, layout, ld);
any_lef = true;
} else if (ex.test ("gds:")) { } else if (ex.test ("gds:")) {
std::string fn = fn_path, f; std::string fn = fn_path, f;
@ -116,6 +122,8 @@ static db::LayerMap run_test (tl::TestBase *_this, const char *lef_dir, const ch
lo.set_options (options); lo.set_options (options);
reader.read (layout, lo); reader.read (layout, lo);
any_def = true;
} else { } else {
break; break;
@ -128,6 +136,10 @@ static db::LayerMap run_test (tl::TestBase *_this, const char *lef_dir, const ch
} }
if (! any_def && any_lef) {
imp.finish_lef (layout);
}
ld.finish (layout); ld.finish (layout);
// normalize the layout by writing to OASIS and reading from .. // normalize the layout by writing to OASIS and reading from ..
@ -198,7 +210,8 @@ TEST(1)
TEST(2) TEST(2)
{ {
run_test (_this, "lef2", "lef:in.lef", "au.oas.gz", default_options ()); // Also tests ability of plugin to properly read LEF
run_test (_this, "lef2", "read:in.lef", "au.oas.gz", default_options ());
} }
TEST(3) TEST(3)

Binary file not shown.