From eda1992a7d26d0e4805089cf1479f8836228b948 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 21:00:55 +0100 Subject: [PATCH] Added VIA size selectors for LEF/DEF .map files. --- .../lefdef/db_plugin/dbDEFImporter.cc | 14 +- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 193 +++++++++--------- .../lefdef/db_plugin/dbLEFDEFImporter.h | 66 +++++- .../lefdef/db_plugin/dbLEFImporter.cc | 12 +- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 5 + testdata/lefdef/viasize/au.oas.gz | Bin 0 -> 863 bytes testdata/lefdef/viasize/test.def | 35 ++++ testdata/lefdef/viasize/test.lef | 24 +++ testdata/lefdef/viasize/test.map | 8 + 9 files changed, 253 insertions(+), 104 deletions(-) create mode 100644 testdata/lefdef/viasize/au.oas.gz create mode 100644 testdata/lefdef/viasize/test.def create mode 100644 testdata/lefdef/viasize/test.lef create mode 100644 testdata/lefdef/viasize/test.map diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index b0deb624b..c5a7e6626 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -893,8 +893,16 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool } } +template +static db::DVector +via_size (double dbu, const Shape &shape) +{ + db::Box box = db::box_convert () (shape); + return db::DVector (box.width () * dbu, box.height () * dbu); +} + void -DEFImporter::read_vias (db::Layout & /*layout*/, db::Cell & /*design*/, double scale) +DEFImporter::read_vias (db::Layout &layout, db::Cell & /*design*/, double scale) { while (test ("-")) { @@ -1036,13 +1044,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, ViaGeometry, poly, mask, 0); + geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0, via_size (layout.dbu (), poly)); } else { db::Polygon poly; read_rect (poly, scale); - geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0); + geo_based_vg->add_polygon (ln, ViaGeometry, poly, mask, 0, via_size (layout.dbu (), poly)); } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 97f75ce09..31cd62093 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -110,6 +110,66 @@ static unsigned int mask (const std::vector &masks, unsigned int i } } +static std::string purpose_to_name (LayerPurpose purpose) +{ + switch (purpose) { + case Outline: + return "OUTLINE"; + case Regions: + return "REGION"; + case PlacementBlockage: + return "BLOCKAGE"; + case Routing: + return "NET"; + case SpecialRouting: + return "SPNET"; + case ViaGeometry: + return "VIA"; + case Label: + return "LABEL"; + case Pins: + return "PIN"; + case Fills: + return "FILL"; + case FillsOPC: + return "FILLOPC"; + case LEFPins: + return "LEFPIN"; + case Obstructions: + return "LEFOBS"; + case Blockage: + return "BLK"; + case All: + return "ALL"; + } + + return std::string (); +} + +static std::string +layer_spec_to_name (const std::string &layer_name, LayerPurpose purpose, unsigned int mask, const db::DVector &via_size) +{ + std::string ps = purpose_to_name (purpose); + + std::string n = layer_name; + if (! n.empty ()) { + n += "."; + } + n += ps; + + if (mask > 0) { + n += ":"; + n += tl::to_string (mask); + } + + if (via_size != db::DVector ()) { + n += ":SIZE"; + n += tl::sprintf ("%.12gX%.12g", via_size.x (), via_size.y ()); + } + + return n; +} + // ----------------------------------------------------------------------------------- // RuleBasedViaGenerator implementation @@ -144,12 +204,12 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d std::set dl; - dl = reader.open_layer (layout, m_bottom_layer, ViaGeometry, mask_bottom); + dl = reader.open_layer (layout, m_bottom_layer, ViaGeometry, mask_bottom, via_box.enlarged (m_be)); 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); + dl = reader.open_layer (layout, m_top_layer, ViaGeometry, mask_top, via_box.enlarged (m_te)); 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))); } @@ -248,7 +308,7 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d cm = (mask_cut + r + c - 1) % num_cut_masks + 1; } - dl = reader.open_layer (layout, m_cut_layer, ViaGeometry, cm); + dl = reader.open_layer (layout, m_cut_layer, ViaGeometry, cm, vb); for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { cell.shapes (*l).insert (db::Polygon (vb)); } @@ -313,12 +373,12 @@ GeometryBasedLayoutGenerator::combine_maskshifts (const std::string &ln, unsigne void GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector *ext_msl, const std::vector &masks, const LEFDEFNumberOfMasks *nm) { - for (std::map >, db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) { + for (std::map , db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) { 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); + unsigned int mask = mask_for (g->first.first, g->first.second.mask, mshift, nm); - std::set dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask); + std::set dl = reader.open_layer (layout, g->first.first, g->first.second.purpose, mask, g->first.second.via_size); for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { cell.shapes (*l).insert (g->second); } @@ -363,27 +423,27 @@ static db::Shape insert_shape (db::Shapes &shapes, const Shape &shape, db::prope } void -GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id) +GeometryBasedLayoutGenerator::add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size) { - insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], poly, prop_id); + insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], poly, prop_id); } void -GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id) +GeometryBasedLayoutGenerator::add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size) { - insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], box, prop_id); + insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], 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) +GeometryBasedLayoutGenerator::add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, db::properties_id_type prop_id, const db::DVector &via_size) { - insert_shape (m_shapes [std::make_pair (ln, std::make_pair (purpose, mask))], path, prop_id); + insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask, via_size))], 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); + insert_shape (m_shapes [std::make_pair (ln, LayerDetailsKey (purpose, mask))], text, prop_id); } void @@ -876,12 +936,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) purpose_translation ["BLOCKAGE"] = Blockage; purpose_translation ["ALL"] = All; - std::map purpose_translation_rev; - for (std::map::const_iterator i = purpose_translation.begin (); i != purpose_translation.end (); ++i) { - purpose_translation_rev.insert (std::make_pair (i->second, i->first)); - } - - std::map >, std::vector > layer_map; + std::map, std::vector > layer_map; while (! ts.at_end ()) { @@ -896,7 +951,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) std::string w1, w2; std::vector layers, datatypes; - size_t max_purpose_str = 10; + size_t max_purpose_str = 15; if (! ex.try_read_word (w1) || ! ex.try_read_word (w2, "._$,/:") || ! try_read_layers (ex, layers) || ! try_read_layers (ex, datatypes)) { tl::warn << tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d not understood - skipped")), path, ts.line_number ()); @@ -907,7 +962,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) for (std::vector::const_iterator l = layers.begin (); l != layers.end (); ++l) { for (std::vector::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) { - layer_map [std::make_pair (std::string (), std::make_pair (Outline, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "OUTLINE")); + layer_map [std::make_pair (std::string (), LayerDetailsKey (Outline))].push_back (db::LayerProperties (*l, *d, "OUTLINE")); } } @@ -915,7 +970,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) for (std::vector::const_iterator l = layers.begin (); l != layers.end (); ++l) { for (std::vector::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) { - layer_map [std::make_pair (std::string (), std::make_pair (Regions, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "REGIONS")); + layer_map [std::make_pair (std::string (), LayerDetailsKey (Regions))].push_back (db::LayerProperties (*l, *d, "REGIONS")); } } @@ -923,7 +978,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) for (std::vector::const_iterator l = layers.begin (); l != layers.end (); ++l) { for (std::vector::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) { - layer_map [std::make_pair (std::string (), std::make_pair (PlacementBlockage, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, "PLACEMENT_BLK")); + layer_map [std::make_pair (std::string (), LayerDetailsKey (PlacementBlockage))].push_back (db::LayerProperties (*l, *d, "PLACEMENT_BLK")); } } @@ -949,7 +1004,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) for (std::vector::const_iterator ln = layer_names.begin (); ln != layer_names.end (); ++ln) { for (std::vector::const_iterator l = layers.begin (); l != layers.end (); ++l) { for (std::vector::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) { - layer_map [std::make_pair (*ln, std::make_pair (Label, (unsigned int) 0))].push_back (db::LayerProperties (*l, *d, final_name)); + layer_map [std::make_pair (*ln, LayerDetailsKey (Label))].push_back (db::LayerProperties (*l, *d, final_name)); } } } @@ -968,7 +1023,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) // "(M1,PINS): M1.NET/PINS" // (separating, translating and recombing the purposes) - std::set > translated_purposes; + std::set translated_purposes; std::vector purposes = tl::split (w2, ","); std::reverse (purposes.begin (), purposes.end ()); @@ -982,6 +1037,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) std::string ps; ex.read_word_or_quoted (ps); + db::DVector via_size; std::map::const_iterator i = purpose_translation.find (ps); if (i != purpose_translation.end ()) { @@ -997,9 +1053,11 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) } else if (i->second == ViaGeometry) { if (ex.test (":SIZE:")) { - std::string sz; - ex.read_word (sz); - tl::warn << tl::sprintf (tl::to_string (tr ("Reading layer map file %s, line %d: VIA size constraint ignored for layer %s")), path, ts.line_number (), w1); + double sx = 0.0, sy = 0.0; + ex.read (sx); + ex.test("X"); + ex.read (sy); + via_size = db::DVector (sx, sy); } } @@ -1018,13 +1076,13 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) for (std::map::const_iterator p = purpose_translation.begin (); p != purpose_translation.end (); ++p) { if (p->second != All) { - translated_purposes.insert (std::make_pair (p->second, mask)); + translated_purposes.insert (LayerDetailsKey (p->second, mask, via_size)); } } } else { - translated_purposes.insert (std::make_pair (i->second, mask)); + translated_purposes.insert (LayerDetailsKey (i->second, mask, via_size)); } @@ -1033,19 +1091,15 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) // create a visual description string for the combined purposes std::string purpose_str; - for (std::set >::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) { + for (std::set::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) { if (p != translated_purposes.begin ()) { purpose_str += "/"; } - std::string ps = purpose_translation_rev [p->first]; - if (p->second > 0) { - ps += ":"; - ps += tl::to_string (p->second); - } + std::string ps = layer_spec_to_name (std::string (), p->purpose, p->mask, p->via_size); - if ((purpose_str + ps).size () > max_purpose_str) { + if (p != translated_purposes.begin () && (purpose_str + ps).size () > max_purpose_str) { purpose_str += "..."; break; } else { @@ -1056,7 +1110,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) std::string final_name = w1 + "." + purpose_str; - for (std::set >::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) { + for (std::set::const_iterator p = translated_purposes.begin (); p != translated_purposes.end (); ++p) { for (std::vector::const_iterator l = layers.begin (); l != layers.end (); ++l) { for (std::vector::const_iterator d = datatypes.begin (); d != datatypes.end (); ++d) { layer_map [std::make_pair (w1, *p)].push_back (db::LayerProperties (*l, *d, final_name)); @@ -1077,7 +1131,7 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) m_layer_map.clear (); db::DirectLayerMapping lm (&layout); - for (std::map >, std::vector >::const_iterator i = layer_map.begin (); i != layer_map.end (); ++i) { + for (std::map, std::vector >::const_iterator i = layer_map.begin (); i != layer_map.end (); ++i) { for (std::vector::const_iterator j = i->second.begin (); j != i->second.end (); ++j) { unsigned int layer = lm.map_layer (*j).second; m_layers [i->first].insert (layer); @@ -1087,9 +1141,13 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) } std::set -LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask) +LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPurpose purpose, unsigned int mask, const db::DVector &via_size) { - std::map >, std::set >::const_iterator nl = m_layers.find (std::make_pair (n, std::make_pair (purpose, mask))); + std::map , std::set >::const_iterator nl; + nl = m_layers.find (std::make_pair (n, LayerDetailsKey (purpose, mask, via_size))); + if (nl == m_layers.end ()) { + nl = m_layers.find (std::make_pair (n, LayerDetailsKey (purpose, mask))); + } if (nl == m_layers.end ()) { std::set ll; @@ -1098,7 +1156,7 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu ll = open_layer_uncached (layout, n, purpose, mask); } - m_layers.insert (std::make_pair (std::make_pair (n, std::make_pair (purpose, mask)), ll)); + m_layers.insert (std::make_pair (std::make_pair (n, LayerDetailsKey (purpose, mask)), ll)); return ll; } else { @@ -1106,42 +1164,6 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu } } -static std::string purpose_to_name (LayerPurpose purpose) -{ - switch (purpose) { - case Outline: - return "OUTLINE"; - case Regions: - return "REGION"; - case PlacementBlockage: - return "BLOCKAGE"; - case Routing: - return "NET"; - case SpecialRouting: - return "SPNET"; - case ViaGeometry: - return "VIA"; - case Label: - return "LABEL"; - case Pins: - return "PIN"; - case Fills: - return "FILL"; - case FillsOPC: - return "FILLOPC"; - case LEFPins: - return "LEFPIN"; - case Obstructions: - return "LEFOBS"; - case Blockage: - return "BLK"; - case All: - return "ALL"; - } - - return std::string (); -} - /** * @brief Implements implicit layer mapping * @@ -1467,24 +1489,13 @@ LEFDEFReaderState::finish (db::Layout &layout) db::LayerMap lm; - for (std::map >, std::set >::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.empty ()) { continue; } - std::string ps = purpose_to_name (l->first.second.first); - - std::string n = l->first.first; - if (! n.empty ()) { - n += "."; - } - n += ps; - - if (l->first.second.second > 0) { - n += ":"; - n += tl::to_string (l->first.second.second); - } + std::string n = layer_spec_to_name (l->first.first, l->first.second.purpose, l->first.second.mask, l->first.second.via_size); for (std::set::const_iterator li = l->second.begin (); li != l->second.end (); ++li) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 7a85c62b1..203451541 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -962,6 +962,46 @@ enum LayerPurpose All // from DEF only }; +/** + * @brief A structure holding the layer details like purpose, mask and via size + */ +struct LayerDetailsKey +{ + LayerDetailsKey () + : purpose (Routing), mask (0) + { } + + LayerDetailsKey (LayerPurpose _purpose, unsigned int _mask = 0, const db::DVector &_via_size = db::DVector ()) + : purpose (_purpose), mask (_mask), via_size (_via_size) + { } + + bool operator< (const LayerDetailsKey &other) const + { + if (purpose != other.purpose) { + return purpose < other.purpose; + } + if (mask != other.mask) { + return mask < other.mask; + } + return via_size.less (other.via_size); + } + + bool operator== (const LayerDetailsKey &other) const + { + if (purpose != other.purpose) { + return false; + } + if (mask != other.mask) { + return false; + } + return via_size.equal (other.via_size); + } + + LayerPurpose purpose; + unsigned int mask; + db::DVector via_size; +}; + /** * @brief An interface for resolving the number of masks from a layer name */ @@ -1054,9 +1094,9 @@ public: virtual std::vector maskshift_layers () const { return m_maskshift_layers; } virtual bool is_fixedmask () const { return m_fixedmask; } - 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_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ()); + void add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ()); + void add_path (const std::string &ln, LayerPurpose purpose, const db::Path &path, unsigned int mask, properties_id_type prop_id, const DVector &via_size = db::DVector ()); 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); @@ -1083,7 +1123,7 @@ private: db::Trans trans; }; - std::map >, db::Shapes> m_shapes; + std::map , db::Shapes> m_shapes; std::list m_vias; std::vector m_maskshift_layers; bool m_fixedmask; @@ -1129,7 +1169,17 @@ public: /** * @brief Create a new layer or return the index of the given layer */ - std::set 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, const DVector &via_size = db::DVector ()); + + /** + * @brief Create a new layer or return the index of the given layer + */ + template + std::set open_layer (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask, const Shape &via_shape) + { + db::Box via_box = db::box_convert () (via_shape); + return open_layer (layout, name, purpose, mask, db::DVector (via_box.width () * layout.dbu (), via_box.height () * layout.dbu ())); + } /** * @brief Registers a layer (assign a new default layer number) @@ -1263,7 +1313,7 @@ private: LEFDEFReaderState (const LEFDEFReaderState &); LEFDEFReaderState &operator= (const LEFDEFReaderState &); - std::map >, std::set > m_layers; + std::map , std::set > m_layers; db::LayerMap m_layer_map; bool m_create_layers; bool m_has_explicit_layer_mapping; @@ -1438,9 +1488,9 @@ protected: /** * @brief Create a new layer or return the index of the given layer */ - std::set 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, const db::DVector &via_size = db::DVector ()) { - return mp_reader_state->open_layer (layout, name, purpose, mask); + return mp_reader_state->open_layer (layout, name, purpose, mask, via_size); } /** diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 4e859aaca..2714a5d52 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -517,6 +517,14 @@ LEFImporter::read_viadef_by_rule (RuleBasedViaGenerator *vg, ViaDesc &via_desc, } } +template +static db::DVector +via_size (double dbu, const Shape &shape) +{ + db::Box box = db::box_convert () (shape); + return db::DVector (box.width () * dbu, box.height () * dbu); +} + void LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc &via_desc, const std::string &n, double dbu) { @@ -577,7 +585,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc db::Polygon p; p.assign_hull (points.begin (), points.end ()); - lg->add_polygon (layer_name, ViaGeometry, p, mask, 0); + lg->add_polygon (layer_name, ViaGeometry, p, mask, 0, via_size (dbu, p)); expect (";"); @@ -599,7 +607,7 @@ LEFImporter::read_viadef_by_geometry (GeometryBasedLayoutGenerator *lg, ViaDesc } db::Box b (points [0], points [1]); - lg->add_box (layer_name, ViaGeometry, b, mask, 0); + lg->add_box (layer_name, ViaGeometry, b, mask, 0, via_size (dbu, b)); expect (";"); diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 099b25960..75e473fe1 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -762,6 +762,11 @@ TEST(121_fillwithmask) run_test (_this, "fill", "map:with_mask.map+lef:with_mask.lef+def:with_mask.def", "with_mask_au.oas.gz", default_options (), false); } +TEST(130_viasize) +{ + run_test (_this, "viasize", "map:test.map+lef:test.lef+def:test.def", "au.oas.gz", default_options (), false); +} + TEST(200_lefdef_plugin) { db::Layout ly; diff --git a/testdata/lefdef/viasize/au.oas.gz b/testdata/lefdef/viasize/au.oas.gz new file mode 100644 index 0000000000000000000000000000000000000000..944161a0c09d7af5eea35af6e955bf85cca7fa95 GIT binary patch literal 863 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>a3p7B7Q~n27qIgM$Gf`(#|H%Y2e<}> zL~^pGl;-AEGQ$-x^M!dj#sjfod~t4KP7V@3C$T6!m7Co^G{nc#&y|^xnSlqH!_DJs zsORSzq8}UpB$?TP(ikE@HAYBkIKgVrM7TLXw(9{2W)7e{3XfY1CTA7w8RcrAXJ8Zo zB7iCxdGN?_OJL|T0c$h?>SW@e|ASubqh%Cs+$fThm zD$2_s_>E}-^8{wW4~!=m8AJ{gk$e}L&6(=nzVe$gJVD3XpfOmJlT#&%FZxt XVY~toW@G{x^M#o~mZ@PR0|o{F;1vXa literal 0 HcmV?d00001 diff --git a/testdata/lefdef/viasize/test.def b/testdata/lefdef/viasize/test.def new file mode 100644 index 000000000..10821b311 --- /dev/null +++ b/testdata/lefdef/viasize/test.def @@ -0,0 +1,35 @@ + +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN chip_top ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 0 0 ) ( 300 300 ) ; +STYLES 2 ; +- STYLE 1 ( 30 10 ) ( 10 30 ) ( -10 30 ) ( -30 10 ) ( -30 -10 ) ( -10 -30 ) ( 10 -30 ) ( 30 -10 ) ; +END STYLES +VIAS 1 ; + - VIA1_small + + RECT M1 ( -20 -15 ) ( 20 15 ) + + RECT VIA1 ( -10 -10 ) ( 10 10 ) + + RECT VIA1 ( -13 -13 ) ( 13 13 ) + + RECT M2 ( -25 -25 ) ( 25 25 ) ; + - VIA1_large + + RECT M1 ( -20 -15 ) ( 20 15 ) + + RECT VIA1 ( -12 -12 ) ( 12 12 ) + + RECT VIA1 ( -13 -13 ) ( 13 13 ) + + RECT M2 ( -25 -25 ) ( 25 25 ) ; +END VIAS +SPECIALNETS 1 ; +- dummy + + ROUTED + RECT M2 ( 350 0 ) ( 250 100 ) + + POLYGON M1 ( 300 0 ) ( 300 50 ) ( 350 50 ) ( 400 100 ) ( 400 0 ) + + ROUTED + POLYGON M2 ( 300 150 ) ( 300 200 ) ( 350 200 ) ( 400 250 ) ( 400 150 ) + + RECT M1 ( 0 0 ) ( 100 200 ) + + ROUTED M1 30 + MASK 2 ( 0 0 15 ) ( 100 0 0 ) VIA1_small ( 100 100 10 ) + + ROUTED M2 50 + SHAPE RING + STYLE 1 ( 0 100 ) ( 100 200 ) ( 200 200 ) + + ROUTED + MASK 2 + RECT M2 ( 250 0 ) ( 150 100 ) + + ROUTED + SHAPE RING + MASK 1 + VIA VIA1_large E ( 200 200 ) +; +END SPECIALNETS +END DESIGN diff --git a/testdata/lefdef/viasize/test.lef b/testdata/lefdef/viasize/test.lef new file mode 100644 index 000000000..da907c86d --- /dev/null +++ b/testdata/lefdef/viasize/test.lef @@ -0,0 +1,24 @@ +VERSION 5.8 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; + +UNITS + DATABASE MICRONS 1000 ; +END UNITS + +MANUFACTURINGGRID 0.001 ; + +LAYER M1 + TYPE ROUTING ; +END M1 + +LAYER VIA1 + TYPE CUT ; +END VIA1 + +LAYER M2 + TYPE ROUTING ; + WIDTH 0.05 ; +END M2 + +END LIBRARY diff --git a/testdata/lefdef/viasize/test.map b/testdata/lefdef/viasize/test.map new file mode 100644 index 000000000..7c58b2c01 --- /dev/null +++ b/testdata/lefdef/viasize/test.map @@ -0,0 +1,8 @@ +# some variations of map file entries +DIEAREA ALL 1 0 +COMP ALL 2 0 +M1 NET,SPNET 7 0 +M2 NET,SPNET 9 0 +VIA1 VIA 8 0 +VIA1 VIA:SIZE:0.02x0.02 8 1 +VIA1 VIA:SIZE:0.024x0.024 8 2