diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index ea8fd7f76..bd567b83b 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1028,13 +1028,13 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s db::Polygon poly; read_polygon (poly, scale); - geo_based_vg->add_polygon (ln, poly, mask); + geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0); } else { db::Polygon poly; read_rect (poly, scale); - geo_based_vg->add_polygon (ln, poly, mask); + geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0); } @@ -1262,7 +1262,7 @@ DEFImporter::read_styles (double scale) } void -DEFImporter::read_components (std::list > &instances, double scale) +DEFImporter::read_components (db::Layout &layout, std::list > &instances, double scale) { while (test ("-")) { @@ -1274,8 +1274,6 @@ DEFImporter::read_components (std::list > bool is_placed = false; std::string maskshift; - std::pair ct = m_lef_importer.macro_by_name (model); - while (test ("+")) { if (test ("PLACED") || test ("FIXED") || test ("COVER")) { @@ -1303,12 +1301,22 @@ DEFImporter::read_components (std::list > expect (";"); if (is_placed) { - 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 { + + std::map::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 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)); + } + } + } } @@ -1491,7 +1499,7 @@ DEFImporter::do_read (db::Layout &layout) get_long (); expect (";"); - read_components (instances, scale); + read_components (layout, instances, scale); expect ("END"); expect ("COMPONENTS"); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h index 2675bccef..49cbc9acd 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h @@ -81,7 +81,7 @@ private: void read_vias (db::Layout &layout, db::Cell &design, double scale); void read_pins (db::Layout &layout, db::Cell &design, double scale); void read_styles (double scale); - void read_components (std::list > &instances, double scale); + void read_components (Layout &layout, std::list > &instances, double scale); void read_single_net (std::string &nondefaultrule, db::Layout &layout, db::Cell &design, double scale, properties_id_type prop_id, bool specialnets); void produce_routing_geometry (db::Cell &design, const db::Polygon *style, unsigned int layer, properties_id_type prop_id, const std::vector &pts, const std::vector > &ext, std::pair w); }; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 96086bc95..58e5d128f 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -88,7 +88,7 @@ static unsigned int hex_value (char c) } } -static std::vector string2masks (const std::string &s) +std::vector string2masks (const std::string &s) { std::vector res; res.reserve (s.size ()); @@ -100,6 +100,8 @@ static std::vector string2masks (const std::string &s) res.push_back (hex_value (*cp)); } + std::reverse (res.begin (), res.end ()); + return res; } @@ -273,7 +275,7 @@ GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, c { for (std::vector::const_iterator l = m_maskshift_layers.begin (); l != m_maskshift_layers.end (); ++l) { - if (*l == ln) { + if (! l->empty () && *l == ln) { unsigned int mm = mask (masks, (unsigned int) (l - m_maskshift_layers.begin ())); @@ -295,35 +297,79 @@ GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, c void GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) { - for (std::map > >::const_iterator g = m_polygons.begin (); g != m_polygons.end (); ++g) { - for (std::list >::const_iterator i = g->second.begin (); i != g->second.end (); ++i) { - std::pair dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, masks, nm)); - if (dl.first) { - cell.shapes (dl.second).insert (i->second); - } + for (std::map >, db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) { + std::pair dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask_for (g->first.first, g->first.second.second, masks, nm)); + if (dl.first) { + cell.shapes (dl.second).insert (g->second); } } - for (std::map > >::const_iterator g = m_boxes.begin (); g != m_boxes.end (); ++g) { - for (std::list >::const_iterator i = g->second.begin (); i != g->second.end (); ++i) { - std::pair dl = reader.open_layer (layout, g->first, ViaGeometry, mask_for (g->first, i->first, masks, nm)); - if (dl.first) { - cell.shapes (dl.second).insert (i->second); - } + for (std::list::const_iterator v = m_vias.begin (); v != m_vias.end (); ++v) { + + LEFDEFLayoutGenerator *g = reader.via_generator (v->name); + if (! g) { + continue; } + + std::vector msl = g->maskshift_layers (); + msl.resize (3, std::string ()); + + db::Cell *vc = reader.via_cell (v->name, layout, + mask_for (msl [0], v->bottom_mask, masks, nm), + mask_for (msl [1], v->cut_mask, masks, nm), + mask_for (msl [2], v->top_mask, masks, nm), + nm); + + if (vc) { + cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), v->trans)); + } + + } +} + +template +static db::Shape insert_shape (db::Shapes &shapes, const Shape &shape, db::properties_id_type prop_id) +{ + if (prop_id == 0) { + return shapes.insert (shape); + } else { + return shapes.insert (db::object_with_properties (shape, prop_id)); } } void -GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask) +GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id) { - m_polygons [ln].push_back (std::make_pair (mask, poly)); + insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], poly, prop_id); } void -GeometryBasedLayoutGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask) +GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id) { - m_boxes [ln].push_back (std::make_pair (mask, box)); + insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], box, prop_id); +} + +void +GeometryBasedLayoutGenerator::add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, db::properties_id_type prop_id) +{ + insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], path, prop_id); +} + +void +GeometryBasedLayoutGenerator::add_text (const std::string &ln, LayerPurpose purpose, const db::Text &text, unsigned int mask, db::properties_id_type prop_id) +{ + insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], text, prop_id); +} + +void +GeometryBasedLayoutGenerator::add_via (const std::string &vn, const db::Trans &trans, unsigned int bottom_mask, unsigned int cut_mask, unsigned int top_mask) +{ + m_vias.push_back (Via ()); + m_vias.back ().name = vn; + m_vias.back ().trans = trans; + m_vias.back ().bottom_mask = bottom_mask; + m_vias.back ().cut_mask = cut_mask; + m_vias.back ().top_mask = top_mask; } // ----------------------------------------------------------------------------------- @@ -714,6 +760,12 @@ LEFDEFReaderState::~LEFDEFReaderState () } m_via_generators.clear (); + + for (std::map::const_iterator i = m_macro_generators.begin (); i != m_macro_generators.end (); ++i) { + delete i->second; + } + + m_macro_generators.clear (); } void @@ -1196,6 +1248,17 @@ LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFLayoutGenerat m_via_generators [vn] = generator; } +LEFDEFLayoutGenerator * +LEFDEFReaderState::via_generator (const std::string &vn) +{ + std::map::const_iterator g = m_via_generators.find (vn); + if (g != m_via_generators.end ()) { + return g->second; + } else { + return 0; + } +} + db::Cell * LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) { @@ -1242,6 +1305,109 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned } } +void +LEFDEFReaderState::register_macro_cell (const std::string &mn, LEFDEFLayoutGenerator *generator) +{ + if (m_macro_generators.find (mn) != m_macro_generators.end ()) { + delete m_macro_generators [mn]; + } + m_macro_generators [mn] = generator; +} + +LEFDEFLayoutGenerator * +LEFDEFReaderState::macro_generator (const std::string &mn) +{ + std::map::const_iterator g = m_macro_generators.find (mn); + if (g != m_macro_generators.end ()) { + return g->second; + } else { + return 0; + } +} + +std::pair +LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm) +{ + MacroKey mk (mn, masks); + std::map >::const_iterator i = m_macro_cells.find (mk); + if (i != m_macro_cells.end ()) { + tl_assert (! i->second.first || i->second.first->layout () == &layout); + return i->second; + } + + db::Cell *cell = 0; + db::Trans tr; + + std::map::const_iterator g = m_macro_generators.find (mn); + if (g == m_macro_generators.end ()) { + return std::make_pair ((db::Cell *) 0, db::Trans ()); + } + + LEFDEFLayoutGenerator *mg = g->second; + + if (! macro_desc.foreign_name.empty ()) { + + db::cell_index_type ci; + std::pair c = layout.cell_by_name (macro_desc.foreign_name.c_str ()); + if (c.first) { + ci = c.second; + } else { + ci = layout.add_cell (macro_desc.foreign_name.c_str ()); + layout.cell (ci).set_ghost_cell (true); + } + + db::Cell *foreign_cell = &layout.cell (ci); + + if (macro_desc.foreign_name != mn) { + + // create an indirection for renaming the cell + cell = &layout.cell (layout.add_cell (mn.c_str ())); + cell->insert (db::CellInstArray (db::CellInst (foreign_cell->cell_index ()), db::Trans (db::Point () - macro_desc.origin) * macro_desc.foreign_trans)); + + } else { + + // use FOREIGN cell instead of new one + cell = foreign_cell; + tr = db::Trans (db::Point () - macro_desc.origin) * macro_desc.foreign_trans; + + } + + } else if (tech_comp ()->macro_resolution_mode () == 2) { + + // create a ghost cell always + + db::cell_index_type ci; + std::pair c = layout.cell_by_name (mn.c_str ()); + if (c.first) { + ci = c.second; + } else { + ci = layout.add_cell (mn.c_str ()); + layout.cell (ci).set_ghost_cell (true); + } + + cell = &layout.cell (ci); + + } else { + + // actually implement the real cell + + std::string mask_suffix; + for (std::vector::const_iterator m = masks.begin (); m != masks.end (); ++m) { + mask_suffix += "_"; + mask_suffix += tl::to_string (*m); + } + + std::string cn = mn + mask_suffix; + + cell = &layout.cell (layout.add_cell (cn.c_str ())); + mg->create_cell (*this, layout, *cell, masks, nm); + + } + + m_macro_cells [mk] = std::make_pair (cell, tr); + return std::make_pair (cell, tr); +} + // ----------------------------------------------------------------------------------- // LEFDEFImporter implementation diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 94e34b3ca..97f2ecfd0 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -44,6 +44,7 @@ namespace db { class LEFDEFReaderState; +struct MacroDesc; /** * @brief Correct a path relative to the stream and technology @@ -51,6 +52,11 @@ class LEFDEFReaderState; DB_PLUGIN_PUBLIC std::string correct_path (const std::string &fn, const db::Layout &layout, const std::string &base_path); +/** + * @brief Convers a string to a MASKSHIFT index list + */ +std::vector string2masks (const std::string &s); + /** * @brief Generic base class of DXF reader exceptions */ @@ -883,6 +889,7 @@ public: virtual ~LEFDEFLayoutGenerator () { } virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) = 0; + virtual std::vector maskshift_layers () const = 0; }; /** @@ -896,6 +903,15 @@ public: virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm); + virtual std::vector maskshift_layers () const + { + std::vector msl; + msl.push_back (m_bottom_layer); + msl.push_back (m_cut_layer); + msl.push_back (m_top_layer); + return msl; + } + void set_cutsize (const db::Vector &cutsize) { m_cutsize = cutsize; } void set_cutspacing (const db::Vector &cutspacing) { m_cutspacing = cutspacing; } void set_offset (const db::Point &offset) { m_offset = offset; } @@ -931,12 +947,23 @@ class DB_PLUGIN_PUBLIC GeometryBasedLayoutGenerator : public LEFDEFLayoutGenerator { public: + struct Via { + Via () : bottom_mask (0), cut_mask (0), top_mask (0) { } + std::string name; + unsigned int bottom_mask, cut_mask, top_mask; + db::Trans trans; + }; + GeometryBasedLayoutGenerator (); virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *num_cut_masks); + virtual std::vector maskshift_layers () const { return m_maskshift_layers; } - void add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask); - void add_box (const std::string &ln, const db::Box &box, unsigned int mask); + void add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, properties_id_type prop_id); + void add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, properties_id_type prop_id); + void add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, properties_id_type prop_id); + void add_via (const std::string &vn, const db::Trans &trans, unsigned int bottom_mask, unsigned int cut_mask, unsigned int top_mask); + void add_text (const std::string &ln, LayerPurpose purpose, const db::Text &text, unsigned int mask, db::properties_id_type prop_id); void set_maskshift_layers (const std::vector &ln) { m_maskshift_layers = ln; } @@ -949,8 +976,8 @@ public: } private: - std::map > > m_polygons; - std::map > > m_boxes; + std::map >, db::Shapes> m_shapes; + std::list m_vias; std::vector m_maskshift_layers; unsigned int mask_for (const std::string &ln, unsigned int m, const std::vector &masks, const LEFDEFNumberOfMasks *nm) const; @@ -1016,6 +1043,28 @@ public: */ db::Cell *via_cell (const std::string &vn, Layout &layout, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm); + /** + * @brief Gets the via generator for a given via name or 0 if there is no such generator + */ + LEFDEFLayoutGenerator *via_generator (const std::string &vn); + + /** + * @brief Registers a macro generator for the macro with the given name + * + * The generator is capable of creating a macro for a specific mask configuration + */ + void register_macro_cell (const std::string &mn, LEFDEFLayoutGenerator *generator); + + /** + * @brief Gets the macro cell for the given macro name or 0 if no such maco is registered + */ + std::pair macro_cell (const std::string &mn, Layout &layout, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm); + + /** + * @brief Gets the macro generator for a given macro name or 0 if there is no such generator + */ + LEFDEFLayoutGenerator *macro_generator (const std::string &mn); + /** * @brief Get the technology component pointer */ @@ -1060,6 +1109,35 @@ private: unsigned int mask_bottom, mask_cut, mask_top; }; + /** + * @brief A key for the via cache + */ + struct MacroKey + { + MacroKey (const std::string &n, const std::vector &m) + : name (n), masks (m) + { } + + bool operator== (const MacroKey &other) const + { + return name == other.name && masks == other.masks; + } + + bool operator< (const MacroKey &other) const + { + if (name != other.name) { + return name < other.name; + } + if (masks != other.masks) { + return masks < other.masks; + } + return false; + } + + std::string name; + std::vector masks; + }; + // no copying LEFDEFReaderState (const LEFDEFReaderState &); LEFDEFReaderState &operator= (const LEFDEFReaderState &); @@ -1070,9 +1148,11 @@ private: bool m_has_explicit_layer_mapping; int m_laynum; std::map m_default_number; - std::map m_via_cells; const LEFDEFReaderOptions *mp_tech_comp; + std::map m_via_cells; std::map m_via_generators; + std::map > m_macro_cells; + std::map m_macro_generators; std::pair open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask); void map_layer_explicit (const std::string &n, LayerPurpose purpose, const LayerProperties &lp, unsigned int layer, unsigned int mask); @@ -1091,6 +1171,34 @@ struct DB_PLUGIN_PUBLIC ViaDesc std::string m1, m2; }; +/** + * @brief A structure describing a macro + */ +struct DB_PLUGIN_PUBLIC MacroDesc +{ + MacroDesc () { } + + /** + * @brief The name of the FOREIGN cell if present + */ + std::string foreign_name; + + /** + * @brief The transformation of the FOREIGN cell + */ + db::Trans foreign_trans; + + /** + * @brief The origin + */ + db::Point origin; + + /** + * @brief The bounding box + */ + db::Box bbox; +}; + /** * @brief The LEF importer object */ diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index a27651b0a..05dc482cc 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -43,18 +43,7 @@ LEFImporter::~LEFImporter () // .. nothing yet .. } -db::Box -LEFImporter::macro_bbox_by_name (const std::string &name) const -{ - std::map::const_iterator m = m_macro_bboxes_by_name.find (name); - if (m != m_macro_bboxes_by_name.end ()) { - return m->second; - } else { - return db::Box (); - } -} - -double +double LEFImporter::layer_ext (const std::string &layer, double def_ext) const { std::map::const_iterator l = m_default_ext.find (layer); @@ -105,19 +94,8 @@ LEFImporter::layer_width (const std::string &layer, const std::string &nondefaul } } -std::pair -LEFImporter::macro_by_name (const std::string &name) const -{ - std::map >::const_iterator m = m_macros_by_name.find (name); - if (m != m_macros_by_name.end ()) { - return m->second; - } else { - return std::make_pair ((db::Cell *) 0, db::Trans ()); - } -} - std::vector -LEFImporter::get_iteration (db::Layout &layout) +LEFImporter::get_iteration (double dbu) { test ("DO"); long nx = get_long (); @@ -131,7 +109,7 @@ LEFImporter::get_iteration (db::Layout &layout) std::vector t; for (long i = 0; i < nx; ++i) { for (long j = 0; j < ny; ++j) { - t.push_back (db::Trans (db::Vector (db::DVector (dx * i / layout.dbu (), dy * j / layout.dbu ())))); + t.push_back (db::Trans (db::Vector (db::DVector (dx * i / dbu, dy * j / dbu)))); } } return t; @@ -158,10 +136,9 @@ static db::Shape insert_shape (db::Cell &cell, unsigned int layer_id, const Shap } void -LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map *collect_bboxes, db::properties_id_type prop_id) +LEFImporter::read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, LayerPurpose purpose, std::map *collect_boxes_for_labels, db::properties_id_type prop_id) { std::string layer_name; - double dbu = layout.dbu (); double w = 0.0; while (true) { @@ -201,12 +178,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p mask = get_mask (get_long ()); } - int layer_id = -1; - std::pair dl = open_layer (layout, layer_name, purpose, mask); - if (dl.first) { - layer_id = int (dl.second); - } - bool iterate = test ("ITERATE"); while (! peek (";") && ! peek ("DO")) { @@ -221,20 +192,24 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p db::Path p (points.begin (), points.end (), iw, iw / 2, iw / 2, false); if (iterate) { - std::vector ti = get_iteration (layout); - if (layer_id >= 0) { - for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { - db::Shape s = insert_shape (cell, layer_id, p, *t, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); - } + + std::vector ti = get_iteration (dbu); + + for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { + db::Path pt = p.transformed (*t); + 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 if (layer_id >= 0) { - db::Shape s = insert_shape (cell, layer_id, p, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); + + } 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 (); } + } expect (";"); @@ -248,12 +223,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p mask = get_mask (get_long ()); } - int layer_id = -1; - std::pair dl = open_layer (layout, layer_name, purpose, mask); - if (dl.first) { - layer_id = int (dl.second); - } - bool iterate = test ("ITERATE"); while (! peek (";") && ! peek ("DO")) { @@ -268,20 +237,23 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p p.assign_hull (points.begin (), points.end ()); if (iterate) { - std::vector ti = get_iteration (layout); - if (layer_id >= 0) { - for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { - db::Shape s = insert_shape (cell, layer_id, p, *t, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); - } + + std::vector ti = get_iteration (dbu); + for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { + db::Polygon pt = p.transformed (*t); + 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 if (layer_id >= 0) { - db::Shape s = insert_shape (cell, layer_id, p, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); + + } 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 (); } + } expect (";"); @@ -295,39 +267,39 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p mask = get_mask (get_long ()); } - int layer_id = -1; - std::pair dl = open_layer (layout, layer_name, purpose, mask); - if (dl.first) { - layer_id = int (dl.second); - } - bool iterate = test ("ITERATE"); for (int i = 0; i < 2; ++i) { + test ("("); double x = get_double (); double y = get_double (); points.push_back (db::Point (db::DPoint (x / dbu, y / dbu))); test (")"); + } db::Box b (points [0], points [1]); if (iterate) { - std::vector ti = get_iteration (layout); - if (layer_id >= 0) { - for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { - db::Shape s = insert_shape (cell, layer_id, b, *t, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); - } + + std::vector ti = get_iteration (dbu); + + for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { + db::Box bt = b.transformed (*t); + 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 if (layer_id >= 0) { - db::Shape s = insert_shape (cell, layer_id, b, prop_id); - if (collect_bboxes) { - collect_bboxes->insert (std::make_pair (layer_name, db::Box ())).first->second = s.bbox (); + + } 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; } + } expect (";"); @@ -348,12 +320,6 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p unsigned int mask_cut = (mask / 10) % 10; unsigned int mask_top = (mask / 100) % 10; - int layer_id = -1; - std::pair dl = open_layer (layout, layer_name, purpose, mask); - if (dl.first) { - layer_id = int (dl.second); - } - double x = 0.0, y = 0.0; if (test ("(")) { x = get_double (); @@ -366,20 +332,18 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p points.push_back (db::Vector (db::DVector (x / dbu, y / dbu))); std::string vn = get (); - db::Cell *vc = reader_state ()->via_cell (vn, layout, mask_bottom, mask_cut, mask_top, this); - if (! vc) { - warn (tl::to_string (tr ("Unknown via: ")) + vn); - } if (iterate) { - std::vector ti = get_iteration (layout); - if (vc) { - for (std::vector::const_iterator t = ti.begin (); t != ti.end (); ++t) { - cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), *t * db::Trans (points [0]))); - } + + std::vector ti = get_iteration (dbu); + for (std::vector::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 if (vc) { - cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), db::Trans (points [0]))); + + } else { + + lg->add_via (vn, db::Trans (points [0]), mask_bottom, mask_cut, mask_top); + } expect (";"); @@ -597,7 +561,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc db::Polygon p; p.assign_hull (points.begin (), points.end ()); - lg->add_polygon (layer_name, p, mask); + lg->add_polygon (layer_name, ViaGeometry, p, mask, 0); expect (";"); @@ -619,7 +583,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc } db::Box b (points [0], points [1]); - lg->add_box (layer_name, b, mask); + lg->add_box (layer_name, ViaGeometry, b, mask, 0); expect (";"); @@ -823,14 +787,15 @@ LEFImporter::read_macro (Layout &layout) { std::string mn = get (); - if (m_macros_by_name.find (mn) != m_macros_by_name.end ()) { + if (m_macros.find (mn) != m_macros.end ()) { error (tl::to_string (tr ("Duplicate MACRO name: ")) + mn); } set_cellname (mn); - db::Cell &cell = layout.cell (layout.add_cell ()); - db::Cell *foreign_cell = 0; + GeometryBasedLayoutGenerator *mg = new GeometryBasedLayoutGenerator (); + reader_state ()->register_macro_cell (mn, mg); + db::Trans foreign_trans; std::string foreign_name; @@ -892,14 +857,11 @@ LEFImporter::read_macro (Layout &layout) prop_id = layout.properties_repository ().properties_id (props); } - std::map bboxes; - read_geometries (layout, cell, LEFPins, &bboxes, prop_id); + std::map boxes_for_labels; + read_geometries (mg, layout.dbu (), LEFPins, &boxes_for_labels, prop_id); - for (std::map ::const_iterator b = bboxes.begin (); b != bboxes.end (); ++b) { - std::pair dl = open_layer (layout, b->first, Label, 0); - if (dl.first) { - cell.shapes (dl.second).insert (db::Text (label.c_str (), db::Trans (b->second.center () - db::Point ()))); - } + for (std::map ::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); } expect ("END"); @@ -915,10 +877,6 @@ LEFImporter::read_macro (Layout &layout) } else if (test ("FOREIGN")) { - if (foreign_cell) { - error (tl::to_string (tr ("Duplicate FOREIGN definition"))); - } - std::string cn = get (); db::Point vec; @@ -932,26 +890,24 @@ LEFImporter::read_macro (Layout &layout) if (options ().macro_resolution_mode () != 1) { - db::cell_index_type ci; - std::pair c = layout.cell_by_name (cn.c_str ()); - if (c.first) { - ci = c.second; - } else { - ci = layout.add_cell (cn.c_str ()); - layout.cell (ci).set_ghost_cell (true); + if (! foreign_name.empty ()) { + error (tl::to_string (tr ("Duplicate FOREIGN definition"))); } - foreign_cell = &layout.cell (ci); // What is the definition of the FOREIGN transformation? // Guessing: this transformation moves the lower-left origin to 0,0 foreign_trans = db::Trans (db::Point () - vec) * db::Trans (ft); foreign_name = cn; + if (foreign_name != mn) { + warn (tl::to_string (tr ("FOREIGN name differs from MACRO name in macro: ")) + mn); + } + } } else if (test ("OBS")) { - read_geometries (layout, cell, Obstructions); + read_geometries (mg, layout.dbu (), Obstructions); expect ("END"); } else if (test ("FIXEDMASK")) { @@ -967,69 +923,14 @@ LEFImporter::read_macro (Layout &layout) } - if (! foreign_cell) { + mg->add_box (std::string (), Outline, db::Box (-origin, -origin + size), 0, 0); - if (options ().macro_resolution_mode () != 2) { - - // actually implement the real cell - - layout.rename_cell (cell.cell_index (), mn.c_str ()); - - std::pair dl = open_layer (layout, std::string (), Outline, 0); - 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 { - - // macro resolution mode #2 (always create a MACRO reference, no LEF geometry) - - db::cell_index_type ci; - std::pair c = layout.cell_by_name (mn.c_str ()); - if (c.first) { - ci = c.second; - } else { - ci = layout.add_cell (mn.c_str ()); - layout.cell (ci).set_ghost_cell (true); - } - - layout.delete_cell (cell.cell_index ()); - m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&layout.cell (ci), db::Trans ()))); - - } - - } else if (foreign_name != mn) { - - warn (tl::to_string (tr ("FOREIGN name differs from MACRO name in macro: ")) + mn); - - layout.rename_cell (cell.cell_index (), mn.c_str ()); - - // clear imported LEF geometry with a foreign cell, but provide a level of indirection so we have - // both the MACRO and the FOREIGN name - - for (unsigned int l = 0; l < layout.layers (); ++l) { - if (layout.is_valid_layer (l)) { - cell.clear (l); - } - } - - cell.clear_insts (); - - cell.insert (db::CellInstArray (db::CellInst (foreign_cell->cell_index ()), db::Trans (db::Point () - origin) * foreign_trans)); - 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, db::Trans (db::Point () - origin) * foreign_trans))); - - } - - m_macro_bboxes_by_name.insert (std::make_pair (mn, db::Box (-origin, -origin + size))); + MacroDesc macro_desc; + macro_desc.foreign_name = foreign_name; + macro_desc.foreign_trans = foreign_trans; + macro_desc.bbox = db::Box (-origin, -origin + size); + macro_desc.origin = origin; + m_macros.insert (std::make_pair (mn, macro_desc)); reset_cellname (); } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index d05d1b345..ba1f2ce5d 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -57,14 +57,6 @@ public: */ ~LEFImporter (); - /** - * @brief Get the cell for a macro name - * - * Returns 0 if the name is not a valid macro name. Otherwise it returns the pointer - * to the corresponding db::Cell object. - */ - std::pair macro_by_name (const std::string ¯o_name) const; - /** * @brief Get the cell bbox for the given macro name */ @@ -126,6 +118,16 @@ public: return m_vias; } + /** + * @brief Gets the + * + * The map maps the macro name to the macro description. + */ + const std::map ¯os () const + { + return m_macros; + } + protected: void do_read (db::Layout &layout); @@ -134,16 +136,13 @@ private: std::map > m_default_widths; std::map m_default_ext; std::map > m_min_widths; - std::map > m_macros_by_name; - std::map m_macro_bboxes_by_name; + std::map m_macros; std::map m_vias; std::set m_routing_layers, m_cut_layers; std::map m_num_masks; - std::vector get_iteration (db::Layout &layout); - // @@@ - void read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map *collect_bboxes = 0, properties_id_type prop_id = 0); - // void read_geometries (GeometryBasedLayoutGenerator *lg, LayerPurpose purpose, std::map *collect_bboxes = 0, properties_id_type prop_id = 0); + std::vector get_iteration (double dbu); + void read_geometries (GeometryBasedLayoutGenerator *lg, double dbu, LayerPurpose purpose, std::map *collect_bboxes = 0, properties_id_type prop_id = 0); void read_nondefaultrule (Layout &layout); void read_viadef (Layout &layout); void read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &desc, const std::string &n, double dbu);