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);
}
void
DEFImporter::finish_lef (db::Layout &layout)
{
m_lef_importer.finish_lef (layout);
}
void
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;
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 ("+")) {
if (test ("PLACED") || test ("FIXED") || test ("COVER")) {
@ -1283,7 +1294,7 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
test (")");
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;
} else if (test ("MASKSHIFT")) {
@ -1302,13 +1313,6 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
if (is_placed) {
std::map<std::string, MacroDesc>::const_iterator m = m_lef_importer.macros ().find (model);
if (m == m_lef_importer.macros ().end ()) {
warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model);
} 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);
@ -1318,8 +1322,6 @@ DEFImporter::read_components (db::Layout &layout, std::list<std::pair<std::strin
}
}
}
}
void

View File

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

View File

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

View File

@ -188,6 +188,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
test (")");
}
if (lg) {
db::Coord iw = db::coord_traits<db::Coord>::rounded (w / dbu);
db::Path p (points.begin (), points.end (), iw, iw / 2, iw / 2, false);
@ -212,6 +214,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
}
}
expect (";");
} else if (test ("POLYGON")) {
@ -233,6 +237,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
test (")");
}
if (lg) {
db::Polygon p;
p.assign_hull (points.begin (), points.end ());
@ -256,6 +262,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
}
}
expect (";");
} else if (test ("RECT")) {
@ -279,6 +287,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
}
if (lg) {
db::Box b (points [0], points [1]);
if (iterate) {
@ -302,6 +312,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
}
}
expect (";");
} else if (test ("VIA")) {
@ -333,6 +345,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
std::string vn = get ();
if (lg) {
if (iterate) {
std::vector<db::Trans> ti = get_iteration (dbu);
@ -346,6 +360,8 @@ LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, Laye
}
}
expect (";");
} else if (test ("PROPERTY")) {
@ -850,6 +866,8 @@ LEFImporter::read_macro (Layout &layout)
}
*/
if (reader_state ()->tech_comp ()->produce_lef_pins ()) {
db::properties_id_type prop_id = 0;
if (produce_pin_props ()) {
db::PropertiesRepository::properties_set props;
@ -864,6 +882,10 @@ LEFImporter::read_macro (Layout &layout)
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");
} else {
@ -907,7 +929,12 @@ LEFImporter::read_macro (Layout &layout)
} else if (test ("OBS")) {
if (reader_state ()->tech_comp ()->produce_obstructions ()) {
read_geometries (mg, layout.dbu (), Obstructions);
} else {
read_geometries (0, layout.dbu (), Obstructions);
}
expect ("END");
} 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 ();
/**
* @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
*
@ -128,6 +123,14 @@ public:
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:
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::DEFImporter imp;
bool any_def = false;
bool any_lef = false;
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);
imp.read (stream, layout, ld);
any_def = true;
} else if (ex.test ("lef:")) {
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);
imp.read_lef (stream, layout, ld);
any_lef = true;
} else if (ex.test ("gds:")) {
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);
reader.read (layout, lo);
any_def = true;
} else {
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);
// normalize the layout by writing to OASIS and reading from ..
@ -198,7 +210,8 @@ TEST(1)
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)

Binary file not shown.