diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 80b1f836b..057402473 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -895,9 +895,9 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s // produce a cell for vias std::auto_ptr rule_based_vg; - std::auto_ptr geo_based_vg; + std::auto_ptr geo_based_vg; - std::auto_ptr via_generator; + std::auto_ptr via_generator; std::set seen_layers; std::vector routing_layers; @@ -992,7 +992,7 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s } else if ((is_polygon = test ("POLYGON")) || test ("RECT")) { if (! geo_based_vg.get ()) { - geo_based_vg.reset (new GeometryBasedViaGenerator ()); + geo_based_vg.reset (new GeometryBasedLayoutGenerator ()); } std::string ln = get (); @@ -1000,9 +1000,9 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s if (m_lef_importer.is_routing_layer (ln)) { if (routing_layers.size () == 0) { - geo_based_vg->set_bottom_layer (ln); + geo_based_vg->set_maskshift_layer (0, ln); } else if (routing_layers.size () == 1) { - geo_based_vg->set_top_layer (ln); + geo_based_vg->set_maskshift_layer (2, ln); } if (seen_layers.find (ln) == seen_layers.end ()) { @@ -1012,7 +1012,7 @@ DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double s } else if (m_lef_importer.is_cut_layer (ln)) { - geo_based_vg->set_cut_layer (ln); + geo_based_vg->set_maskshift_layer (1, ln); } @@ -1267,6 +1267,11 @@ DEFImporter::read_components (std::list > std::string inst_name = get (); std::string model = get (); + db::FTrans ft; + db::Vector d; + bool is_placed = false; + std::string maskshift; + std::pair ct = m_lef_importer.macro_by_name (model); while (test ("+")) { @@ -1277,15 +1282,13 @@ DEFImporter::read_components (std::list > db::Point pt = get_point (scale); test (")"); - db::FTrans ft = get_orient (false /*mandatory*/); - db::Vector d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left (); + ft = get_orient (false /*mandatory*/); + d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left (); + is_placed = true; - 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); - } + } else if (test ("MASKSHIFT")) { + + maskshift = get (); } else { while (! peek ("+") && ! peek ("-") && ! peek (";")) { @@ -1297,6 +1300,15 @@ 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 { + warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model); + } + } + } } @@ -1467,9 +1479,9 @@ DEFImporter::do_read (db::Layout &layout) } else if (test ("COMPONENTMASKSHIFT")) { - warn (tl::to_string (tr ("Component mask shift not supported currently"))); + m_component_maskshift.clear (); while (! at_end () && ! test (";")) { - take (); + m_component_maskshift.push_back (get ()); } } else if (test ("COMPONENTS")) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h index dc9e36488..2675bccef 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h @@ -66,6 +66,7 @@ private: std::map > m_nondefault_widths; std::map m_via_desc; std::map m_styles; + std::vector m_component_maskshift; void read_polygon (db::Polygon &poly, double scale); void read_rect (db::Polygon &poly, double scale); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 6ac750f72..08e3d1ea8 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -76,7 +76,7 @@ static bool is_hex_digit (char c) return (cup >= 'A' && cup <= 'F') || (c >= '0' && c <= '9'); } -static int hex_value (char c) +static unsigned int hex_value (char c) { char cup = toupper (c); if (cup >= 'A' && cup <= 'F') { @@ -88,16 +88,42 @@ static int hex_value (char c) } } +static std::vector string2masks (const std::string &s) +{ + std::vector res; + res.reserve (s.size ()); + + for (const char *cp = s.c_str (); *cp; ++cp) { + if (! is_hex_digit (*cp)) { + throw tl::Exception ("Not a hex string: " + s); + } + res.push_back (hex_value (*cp)); + } + + return res; +} + +static unsigned int mask (const std::vector &masks, unsigned int index) +{ + if (index < (unsigned int) masks.size ()) { + return masks [index]; + } else { + return 0; + } +} + // ----------------------------------------------------------------------------------- // RuleBasedViaGenerator implementation RuleBasedViaGenerator::RuleBasedViaGenerator () - : LEFDEFViaGenerator (), m_bottom_mask (0), m_cut_mask (0), m_top_mask (0), m_rows (1), m_columns (1) + : LEFDEFLayoutGenerator (), m_bottom_mask (0), m_cut_mask (0), m_top_mask (0), m_rows (1), m_columns (1) { } void -RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) +RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) { + unsigned int mask_bottom = mask (masks, 0), mask_cut = mask (masks, 1), mask_top = mask (masks, 2); + if (mask_bottom == 0) { mask_bottom = m_bottom_mask; } @@ -238,31 +264,27 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d // ----------------------------------------------------------------------------------- // GeometryBasedViaGenerator implementation -GeometryBasedViaGenerator::GeometryBasedViaGenerator () - : LEFDEFViaGenerator () +GeometryBasedLayoutGenerator::GeometryBasedLayoutGenerator () + : LEFDEFLayoutGenerator () { } unsigned int -GeometryBasedViaGenerator::mask_for (const std::string &ln, unsigned int m, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) const +GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, const std::vector &masks, const LEFDEFNumberOfMasks *nm) const { - if (m == 0 || ! nm) { + for (std::vector::const_iterator l = m_maskshift_layers.begin (); l != m_maskshift_layers.end (); ++l) { - if (ln == m_bottom_layer) { - return mask_bottom; - } else if (ln == m_cut_layer) { - return mask_cut; - } else if (ln == m_top_layer) { - return mask_top; - } + if (*l == ln) { - } else { + unsigned int mm = mask (masks, (unsigned int) (l - m_maskshift_layers.begin ())); + + if (m == 0 || ! nm) { + m = mm; + } else if (m > 0) { + m = (m + mm - 2) % nm->number_of_masks (ln) + 1; + } + + break; - if (ln == m_bottom_layer) { - return mask_bottom > 0 ? ((m + mask_bottom - 2) % nm->number_of_masks (m_bottom_layer) + 1) : m; - } else if (ln == m_cut_layer) { - return mask_cut > 0 ? ((m + mask_cut - 2) % nm->number_of_masks (m_cut_layer) + 1) : m; - } else if (ln == m_top_layer) { - return mask_top > 0 ? ((m + mask_top - 2) % nm->number_of_masks (m_top_layer) + 1) : m; } } @@ -271,11 +293,11 @@ GeometryBasedViaGenerator::mask_for (const std::string &ln, unsigned int m, unsi } void -GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) +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, mask_bottom, mask_cut, mask_top, nm)); + 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); } @@ -284,7 +306,7 @@ GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layou 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, mask_bottom, mask_cut, mask_top, nm)); + 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); } @@ -293,13 +315,13 @@ GeometryBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layou } void -GeometryBasedViaGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask) +GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, const db::Polygon &poly, unsigned int mask) { m_polygons [ln].push_back (std::make_pair (mask, poly)); } void -GeometryBasedViaGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask) +GeometryBasedLayoutGenerator::add_box (const std::string &ln, const db::Box &box, unsigned int mask) { m_boxes [ln].push_back (std::make_pair (mask, box)); } @@ -687,7 +709,7 @@ LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout LEFDEFReaderState::~LEFDEFReaderState () { - for (std::map::const_iterator i = m_via_generators.begin (); i != m_via_generators.end (); ++i) { + for (std::map::const_iterator i = m_via_generators.begin (); i != m_via_generators.end (); ++i) { delete i->second; } @@ -1166,7 +1188,7 @@ LEFDEFReaderState::finish (db::Layout &layout) } void -LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFViaGenerator *generator) +LEFDEFReaderState::register_via_cell (const std::string &vn, LEFDEFLayoutGenerator *generator) { if (m_via_generators.find (vn) != m_via_generators.end ()) { delete m_via_generators [vn]; @@ -1183,10 +1205,10 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned db::Cell *cell = 0; - std::map::const_iterator g = m_via_generators.find (vn); + std::map::const_iterator g = m_via_generators.find (vn); if (g != m_via_generators.end ()) { - LEFDEFViaGenerator *vg = g->second; + LEFDEFLayoutGenerator *vg = g->second; std::string mask_suffix; if (mask_bottom > 0 || mask_cut > 0 || mask_top > 0) { @@ -1201,7 +1223,13 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned std::string cn = mp_tech_comp->via_cellname_prefix () + vn + mask_suffix; cell = &layout.cell (layout.add_cell (cn.c_str ())); - vg->create_cell (*this, layout, *cell, mask_bottom, mask_cut, mask_top, nm); + std::vector masks; + masks.reserve (3); + masks.push_back (mask_bottom); + masks.push_back (mask_cut); + masks.push_back (mask_top); + + vg->create_cell (*this, layout, *cell, masks, nm); } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index ca1007e6c..4b9ca747d 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -876,25 +876,25 @@ public: /** * @brief Provides a via generator base class */ -class DB_PLUGIN_PUBLIC LEFDEFViaGenerator +class DB_PLUGIN_PUBLIC LEFDEFLayoutGenerator { public: - LEFDEFViaGenerator () { } - virtual ~LEFDEFViaGenerator () { } + LEFDEFLayoutGenerator () { } + virtual ~LEFDEFLayoutGenerator () { } - virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) = 0; + virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) = 0; }; /** * @brief Provides a via generator implementation for rule-based vias */ class DB_PLUGIN_PUBLIC RuleBasedViaGenerator - : public LEFDEFViaGenerator + : public LEFDEFLayoutGenerator { public: RuleBasedViaGenerator (); - virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm); + virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm); void set_cutsize (const db::Vector &cutsize) { m_cutsize = cutsize; } void set_cutspacing (const db::Vector &cutspacing) { m_cutspacing = cutspacing; } @@ -927,26 +927,31 @@ private: /** * @brief Provides a geometry-based via generator implementation */ -class DB_PLUGIN_PUBLIC GeometryBasedViaGenerator - : public LEFDEFViaGenerator +class DB_PLUGIN_PUBLIC GeometryBasedLayoutGenerator + : public LEFDEFLayoutGenerator { public: - GeometryBasedViaGenerator (); + GeometryBasedLayoutGenerator (); - virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *num_cut_masks); + virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *num_cut_masks); 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 set_bottom_layer (const std::string &ln) { m_bottom_layer = ln; } - void set_cut_layer (const std::string &ln) { m_cut_layer = ln; } - void set_top_layer (const std::string &ln) { m_top_layer = ln; } + + void set_maskshift_layers (const std::vector &ln) { m_maskshift_layers = ln; } + + void set_maskshift_layer (unsigned int l, const std::string &s) + { + m_maskshift_layers.resize (l + 1, std::string ()); + m_maskshift_layers[l] = s; + } private: std::map > > m_polygons; std::map > > m_boxes; - std::string m_bottom_layer, m_cut_layer, m_top_layer; + std::vector m_maskshift_layers; - unsigned int mask_for (const std::string &ln, unsigned int m, unsigned int mask_bottom, unsigned int mask_cut, unsigned int mask_top, const LEFDEFNumberOfMasks *nm) const; + unsigned int mask_for (const std::string &ln, unsigned int m, const std::vector &masks, const LEFDEFNumberOfMasks *nm) const; }; /** @@ -1002,7 +1007,7 @@ public: * * The generator is capable of creating a via for a specific mask configuration */ - void register_via_cell (const std::string &vn, LEFDEFViaGenerator *generator); + void register_via_cell (const std::string &vn, LEFDEFLayoutGenerator *generator); /** * @brief Gets the via cell for the given via name or 0 if no such via is registered @@ -1065,7 +1070,7 @@ private: std::map m_default_number; std::map m_via_cells; const LEFDEFReaderOptions *mp_tech_comp; - std::map m_via_generators; + std::map m_via_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); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index c4060aec4..a27651b0a 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -538,7 +538,7 @@ LEFImporter::read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &via_desc, } void -LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &via_desc, const std::string &n, double dbu) +LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &via_desc, const std::string &n, double dbu) { // ignore resistance spec if (test ("RESISTANCE")) { @@ -559,9 +559,9 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi if (m_routing_layers.find (layer_name) != m_routing_layers.end ()) { if (routing_layers.size () == 0) { - vg->set_bottom_layer (layer_name); + lg->set_maskshift_layer (0, layer_name); } else if (routing_layers.size () == 1) { - vg->set_top_layer (layer_name); + lg->set_maskshift_layer (2, layer_name); } if (seen_layers.find (layer_name) == seen_layers.end ()) { @@ -570,7 +570,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi } } else { - vg->set_cut_layer (layer_name); + lg->set_maskshift_layer (1, layer_name); } while (! at_end () && ! test (";")) { @@ -597,7 +597,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi db::Polygon p; p.assign_hull (points.begin (), points.end ()); - vg->add_polygon (layer_name, p, mask); + lg->add_polygon (layer_name, p, mask); expect (";"); @@ -619,7 +619,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &vi } db::Box b (points [0], points [1]); - vg->add_box (layer_name, b, mask); + lg->add_box (layer_name, b, mask); expect (";"); @@ -667,7 +667,7 @@ LEFImporter::read_viadef (Layout &layout) read_viadef_by_rule (vg.get (), via_desc, n, layout.dbu ()); reader_state ()->register_via_cell (n, vg.release ()); } else { - std::auto_ptr vg (new GeometryBasedViaGenerator ()); + std::auto_ptr vg (new GeometryBasedLayoutGenerator ()); read_viadef_by_geometry (vg.get (), via_desc, n, layout.dbu ()); reader_state ()->register_via_cell (n, vg.release ()); } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index b1f75eb60..d05d1b345 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -141,11 +141,13 @@ private: 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); 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); - void read_viadef_by_geometry (GeometryBasedViaGenerator *vg, ViaDesc &desc, const std::string &n, double dbu); + void read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &desc, const std::string &n, double dbu); void read_layer (Layout &layout); void read_macro (Layout &layout); };