From 8cc75438b0d4b142974c43fc1b260a1c58e51b38 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 19 Dec 2020 19:42:40 +0100 Subject: [PATCH] WIP: LEF/DEF multi-mapping. --- .../lefdef/db_plugin/dbDEFImporter.cc | 86 +++---- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 210 +++++++++++------- .../lefdef/db_plugin/dbLEFDEFImporter.h | 8 +- 3 files changed, 176 insertions(+), 128 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 4dc1d25ac..3917c4c85 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -157,14 +157,14 @@ DEFImporter::read_diearea (db::Layout &layout, db::Cell &design, double scale) if (points.size () >= 2) { // create outline shape - std::pair dl = open_layer (layout, std::string (), Outline, 0); - if (dl.first) { + std::set dl = open_layer (layout, std::string (), Outline, 0); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { if (points.size () == 2) { - design.shapes (dl.second).insert (db::Box (points [0], points [1])); + design.shapes (*l).insert (db::Box (points [0], points [1])); } else { db::Polygon p; p.assign_hull (points.begin (), points.end ()); - design.shapes (dl.second).insert (p); + design.shapes (*l).insert (p); } } @@ -305,9 +305,9 @@ DEFImporter::read_blockages (db::Layout &layout, db::Cell &design, double scale) db::Polygon p; read_polygon (p, scale); - std::pair dl = open_layer (layout, layer, layer.empty () ? PlacementBlockage : Blockage, 0); - if (dl.first) { - design.shapes (dl.second).insert (p); + std::set dl = open_layer (layout, layer, layer.empty () ? PlacementBlockage : Blockage, 0); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (p); } } else if (test ("RECT")) { @@ -315,9 +315,9 @@ DEFImporter::read_blockages (db::Layout &layout, db::Cell &design, double scale) db::Polygon p; read_rect (p, scale); - std::pair dl = open_layer (layout, layer, layer.empty () ? PlacementBlockage : Blockage, 0); - if (dl.first) { - design.shapes (dl.second).insert (p); + std::set dl = open_layer (layout, layer, layer.empty () ? PlacementBlockage : Blockage, 0); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (p); } } else { @@ -554,17 +554,19 @@ DEFImporter::read_single_net (std::string &nondefaultrule, Layout &layout, db::C test (")"); - std::pair dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); - if (dl.first) { + std::set dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); + if (! dl.empty ()) { db::Point p (x, y); db::Box rect (db::Point (db::DPoint ((x + x1) * scale, (y + y1) * scale)), db::Point (db::DPoint ((x + x2) * scale, (y + y2) * scale))); - if (prop_id != 0) { - design.shapes (dl.second).insert (db::object_with_properties (rect, prop_id)); - } else { - design.shapes (dl.second).insert (rect); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + if (prop_id != 0) { + design.shapes (*l).insert (db::object_with_properties (rect, prop_id)); + } else { + design.shapes (*l).insert (rect); + } } } @@ -615,9 +617,9 @@ DEFImporter::read_single_net (std::string &nondefaultrule, Layout &layout, db::C } if (pts.size () > 1) { - std::pair dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); - if (dl.first) { - produce_routing_geometry (design, style, dl.second, prop_id, pts, ext, w); + std::set dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + produce_routing_geometry (design, style, *l, prop_id, pts, ext, w); } } @@ -803,12 +805,12 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool db::Polygon p; read_polygon (p, scale); - std::pair dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); - if (dl.first) { + std::set dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { if (prop_id != 0) { - design.shapes (dl.second).insert (db::object_with_properties (p, prop_id)); + design.shapes (*l).insert (db::object_with_properties (p, prop_id)); } else { - design.shapes (dl.second).insert (p); + design.shapes (*l).insert (p); } } @@ -821,12 +823,12 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool db::Polygon p; read_rect (p, scale); - std::pair dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); - if (dl.first) { + std::set dl = open_layer (layout, ln, specialnets ? SpecialRouting : Routing, mask); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { if (prop_id != 0) { - design.shapes (dl.second).insert (db::object_with_properties (p, prop_id)); + design.shapes (*l).insert (db::object_with_properties (p, prop_id)); } else { - design.shapes (dl.second).insert (p); + design.shapes (*l).insert (p); } } @@ -1191,8 +1193,8 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) // Produce geometry collected so far for (std::map, std::vector >::const_iterator g = geometry.begin (); g != geometry.end (); ++g) { - std::pair dl = open_layer (layout, g->first.first, Pins, g->first.second); - if (dl.first) { + std::set dl = open_layer (layout, g->first.first, Pins, g->first.second); + if (! dl.empty ()) { db::properties_id_type prop_id = 0; if (produce_pin_props ()) { @@ -1204,21 +1206,27 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) for (std::vector::const_iterator p = g->second.begin (); p != g->second.end (); ++p) { db::Polygon pt = p->transformed (trans); if (prop_id == 0) { - design.shapes (dl.second).insert (pt); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (pt); + } } else { - design.shapes (dl.second).insert (db::PolygonWithProperties (pt, prop_id)); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (db::PolygonWithProperties (pt, prop_id)); + } } } } dl = open_layer (layout, g->first.first, Label, 0); - if (dl.first) { + if (! dl.empty ()) { db::Box bbox; if (! g->second.empty ()) { bbox = g->second.back ().box ().transformed (trans); } - design.shapes (dl.second).insert (db::Text (label.c_str (), db::Trans (db::Vector (bbox.center ())))); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (db::Text (label.c_str (), db::Trans (db::Vector (bbox.center ())))); + } } } @@ -1554,10 +1562,10 @@ DEFImporter::do_read (db::Layout &layout) } else { - std::pair dl = open_layer (layout, std::string (), Regions, 0); - if (dl.first) { + std::set dl = open_layer (layout, std::string (), Regions, 0); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { for (std::vector::const_iterator p = r->second.begin (); p != r->second.end (); ++p) { - group_cell->shapes (dl.second).insert (*p); + group_cell->shapes (*l).insert (*p); } } regions.erase (r); @@ -1597,12 +1605,12 @@ DEFImporter::do_read (db::Layout &layout) if (! regions.empty ()) { - std::pair dl = open_layer (layout, std::string (), Regions, 0); - if (dl.first) { + std::set dl = open_layer (layout, std::string (), Regions, 0); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { for (std::map >::const_iterator r = regions.begin (); r != regions.end (); ++r) { for (std::vector::const_iterator p = r->second.begin (); p != r->second.end (); ++p) { - others_cell->shapes (dl.second).insert (*p); + others_cell->shapes (*l).insert (*p); } } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index f68700609..f8f6b0d4d 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -146,16 +146,16 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)) / 2, (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1)) / 2); db::Box via_box (m_offset - vs, m_offset + vs); - std::pair dl (false, 0); + std::set dl; dl = reader.open_layer (layout, m_bottom_layer, ViaGeometry, mask_bottom); - if (dl.first) { - cell.shapes (dl.second).insert (db::Polygon (via_box.enlarged (m_be).moved (m_bo))); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + cell.shapes (*l).insert (db::Polygon (via_box.enlarged (m_be).moved (m_bo))); } dl = reader.open_layer (layout, m_top_layer, ViaGeometry, mask_top); - if (dl.first) { - cell.shapes (dl.second).insert (db::Polygon (via_box.enlarged (m_te).moved (m_bo))); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + cell.shapes (*l).insert (db::Polygon (via_box.enlarged (m_te).moved (m_bo))); } const char *p = m_pattern.c_str (); @@ -253,8 +253,8 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d } dl = reader.open_layer (layout, m_cut_layer, ViaGeometry, cm); - if (dl.first) { - cell.shapes (dl.second).insert (db::Polygon (vb)); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + cell.shapes (*l).insert (db::Polygon (vb)); } } @@ -322,9 +322,9 @@ GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &la unsigned int mshift = get_maskshift (g->first.first, ext_msl, masks); unsigned int mask = mask_for (g->first.first, g->first.second.second, mshift, nm); - std::pair dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask); - if (dl.first) { - cell.shapes (dl.second).insert (g->second); + std::set dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask); + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + cell.shapes (*l).insert (g->second); } } @@ -809,7 +809,9 @@ void LEFDEFReaderState::map_layer_explicit (const std::string &n, LayerPurpose purpose, const db::LayerProperties &lp, unsigned int layer, unsigned int mask) { tl_assert (m_has_explicit_layer_mapping); - m_layers [std::make_pair (n, std::make_pair (purpose, mask))] = std::make_pair (true, layer); + std::set ll; + ll.insert (layer); + m_layers [std::make_pair (n, std::make_pair (purpose, mask))] = ll; m_layer_map.map (lp, layer); } @@ -1040,13 +1042,13 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) } } -std::pair +std::set LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask) { - std::map >, std::pair >::const_iterator nl = m_layers.find (std::make_pair (n, std::make_pair (purpose, mask))); + std::map >, std::set >::const_iterator nl = m_layers.find (std::make_pair (n, std::make_pair (purpose, mask))); if (nl == m_layers.end ()) { - std::pair ll (false, 0); + std::set ll; if (n.empty () || ! m_has_explicit_layer_mapping) { ll = open_layer_uncached (layout, n, purpose, mask); @@ -1134,8 +1136,7 @@ static std::string purpose_to_name (LayerPurpose purpose) * 4/17 4/17 : 4/11 OUTLINE 4/11 */ -std::pair -LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask) +std::set LEFDEFReaderState::open_layer_uncached(db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask) { if (n.empty ()) { @@ -1154,7 +1155,7 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n } if (! produce) { - return std::make_pair (false, 0); + return std::set (); } db::LayerProperties lp; @@ -1180,35 +1181,55 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n } // employ the layer map to find the target layer - std::pair ll = m_layer_map.first_logical (lp, layout); + std::set ll = m_layer_map.logical (lp, layout); + if (ll.empty () && ! m_create_layers) { + return std::set (); + } - if (ll.first) { + std::set res; + + // map the layers to targets from the layout + // (NOTE: the other readers will do this in advance, but LEF/DEF is too dynamic) + + bool at_least_once = true; + for (std::set::const_iterator l = ll.begin (); l != ll.end () || at_least_once; ++l) { + + at_least_once = false; // If the layer map provides a target, use that one for the layer - const db::LayerProperties *lpp = m_layer_map.target (ll.second); + db::LayerProperties lp_new = lp; + const db::LayerProperties *lpp = (l == ll.end () ? 0 : m_layer_map.target (*l)); if (lpp) { if (! lpp->name.empty ()) { - lp.name = lpp->name; + lp_new.name = lpp->name; } if (lpp->datatype >= 0) { - lp.datatype = lpp->datatype; + lp_new.datatype = lpp->datatype; } if (lpp->layer >= 0) { - lp.layer = lpp->layer; + lp_new.layer = lpp->layer; } } - } else if (! m_create_layers) { - return std::make_pair (false, 0); - } - - for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) { - if ((*l).second->log_equal (lp)) { - return std::make_pair (true, (*l).first); + bool found = false; + for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers () && ! found; ++i) { + if ((*i).second->log_equal (lp_new)) { + found = true; + res.insert ((*i).first); + } } + + if (! found) { + res.insert (layout.insert_layer (lp_new)); + } + + if (l == ll.end ()) { + break; + } + } - return std::make_pair (true, layout.insert_layer (lp)); + return res; } else { @@ -1242,7 +1263,7 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n break; } if (! produce) { - return std::make_pair (false, 0); + return std::set (); } } @@ -1300,48 +1321,63 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n // Route the layer through the layer map, first the decorated name and if there is no mapping, the // undecorated one. - std::pair ll = m_layer_map.first_logical (name, layout); + std::set ll = m_layer_map.logical (name, layout); bool generic_match = false; - if (! ll.first) { - ll = m_layer_map.first_logical (n, layout); + if (ll.empty ()) { + ll = m_layer_map.logical (n, layout); generic_match = true; } else if (n == name) { // no suffix defined in tech component -> treat as generic match and combine datatypes generic_match = true; } - if (ll.first) { + if (ll.empty () && ! m_create_layers) { + return std::set (); + } + + std::set res; + + bool at_least_once = true; + for (std::set::const_iterator l = ll.begin (); l != ll.end () || at_least_once; ++l) { + + at_least_once = false; // If the layer map provides a target, use that one for the layer - // Datatypes from the target and the tech component's x_datatype specification are additive - const db::LayerProperties *lpp = m_layer_map.target (ll.second); + db::LayerProperties lp_new = lp; + const db::LayerProperties *lpp = (l == ll.end () ? 0 : m_layer_map.target (*l)); if (lpp) { - lp = *lpp; - if (lp.datatype < 0) { - lp.datatype = dt; + lp_new = *lpp; + if (lp_new.datatype < 0) { + lp_new.datatype = dt; } else if (generic_match) { - lp.datatype += dt; + lp_new.datatype += dt; } - if (lp.name.empty ()) { - lp.name = name; + if (lp_new.name.empty ()) { + lp_new.name = name; } else if (generic_match) { - lp.name += name_suffix; + lp_new.name += name_suffix; } } - } else if (! m_create_layers) { - return std::make_pair (false, 0); - } - - if (lp.layer >= 0 && lp.datatype >= 0) { - for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) { - if ((*l).second->log_equal (lp)) { - return std::make_pair (true, (*l).first); + bool found = false; + for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers () && ! found; ++i) { + if ((*i).second->log_equal (lp_new)) { + found = true; + res.insert ((*i).first); } } + + if (! found) { + res.insert (layout.insert_layer (lp_new)); + } + + if (l == ll.end ()) { + break; + } + } - return std::make_pair (true, layout.insert_layer (lp)); + return res; } } @@ -1368,42 +1404,14 @@ LEFDEFReaderState::finish (db::Layout &layout) db::LayerMap lm; - for (std::map >, std::pair >::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { + for (std::map >, std::set >::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { - if (! l->second.first) { + if (l->second.empty ()) { continue; } std::string ps = purpose_to_name (l->first.second.first); - unsigned int layer_index = l->second.second; - db::LayerProperties lp = layout.get_properties (layer_index); - - if (lp.layer < 0) { - - std::map::const_iterator n4n = number_for_name.end (); - if (! l->first.first.empty ()) { - n4n = number_for_name.find (l->first.first); - } - - if (n4n == number_for_name.end ()) { - do { - ++lnum; - } while (used_numbers.find (lnum) != used_numbers.end ()); - number_for_name.insert (std::make_pair (l->first.first, lnum)); - lp.layer = lnum; - } else { - lp.layer = n4n->second; - } - - } - - if (lp.datatype < 0) { - lp.datatype = 0; - } - - layout.set_properties (layer_index, lp); - std::string n = l->first.first; if (! n.empty ()) { n += "."; @@ -1415,7 +1423,39 @@ LEFDEFReaderState::finish (db::Layout &layout) n += tl::to_string (l->first.second.second); } - lm.map (db::LayerProperties (n), l->second.second, lp); + for (std::set::const_iterator li = l->second.begin (); li != l->second.end (); ++li) { + + unsigned int layer_index = *li; + db::LayerProperties lp = layout.get_properties (layer_index); + + if (lp.layer < 0) { + + std::map::const_iterator n4n = number_for_name.end (); + if (! l->first.first.empty ()) { + n4n = number_for_name.find (l->first.first); + } + + if (n4n == number_for_name.end ()) { + do { + ++lnum; + } while (used_numbers.find (lnum) != used_numbers.end ()); + number_for_name.insert (std::make_pair (l->first.first, lnum)); + lp.layer = lnum; + } else { + lp.layer = n4n->second; + } + + } + + if (lp.datatype < 0) { + lp.datatype = 0; + } + + layout.set_properties (layer_index, lp); + + lm.mmap (db::LayerProperties (n), layer_index, lp); + + } } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 078361d33..f123490be 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -1054,7 +1054,7 @@ public: /** * @brief Create a new layer or return the index of the given layer */ - std::pair open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask); + std::set open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask); /** * @brief Registers a layer (assign a new default layer number) @@ -1188,7 +1188,7 @@ private: LEFDEFReaderState (const LEFDEFReaderState &); LEFDEFReaderState &operator= (const LEFDEFReaderState &); - std::map >, std::pair > m_layers; + std::map >, std::set > m_layers; db::LayerMap m_layer_map; bool m_create_layers; bool m_has_explicit_layer_mapping; @@ -1201,7 +1201,7 @@ private: std::map m_macro_generators; std::map m_foreign_cells; - std::pair open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask); + std::set 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); db::cell_index_type foreign_cell(Layout &layout, const std::string &name); }; @@ -1364,7 +1364,7 @@ protected: /** * @brief Create a new layer or return the index of the given layer */ - std::pair open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask) + std::set open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask) { return mp_reader_state->open_layer (layout, name, purpose, mask); }