From 96e3570c6d0d29784b4be7172ca9501b05b2c6f8 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 17:28:58 +0100 Subject: [PATCH 1/5] LEF/DEF: preparations for FILLS support, UI rearrangement. --- src/buddies/src/bd/bdReaderOptions.cc | 17 + src/buddies/src/bd/bdReaderOptions.h | 3 + .../lefdef/db_plugin/dbDEFImporter.cc | 2 + .../lefdef/db_plugin/dbDEFImporter.h | 1 + .../lefdef/db_plugin/dbLEFDEFImporter.cc | 47 + .../lefdef/db_plugin/dbLEFDEFImporter.h | 75 + .../lefdef/db_plugin/dbLEFDEFPlugin.cc | 7 + .../lefdef/db_plugin/gsiDeclDbLEFDEF.cc | 88 + .../LEFDEFTechnologyComponentEditor.ui | 2426 +++++++++-------- .../lay_plugin/layLEFDEFImportDialogs.cc | 9 + .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 10 + 11 files changed, 1505 insertions(+), 1180 deletions(-) diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index 925212796..270d6f97b 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -97,6 +97,9 @@ GenericReaderOptions::GenericReaderOptions () m_lefdef_produce_lef_pins = load_options.get_option_by_name ("lefdef_config.produce_lef_pins").to_bool (); m_lefdef_lef_pins_suffix = load_options.get_option_by_name ("lefdef_config.lef_pins_suffix_str").to_string (); m_lefdef_lef_pins_datatype = load_options.get_option_by_name ("lefdef_config.lef_pins_datatype_str").to_string (); + m_lefdef_produce_fills = load_options.get_option_by_name ("lefdef_config.produce_fills").to_bool (); + m_lefdef_fills_suffix = load_options.get_option_by_name ("lefdef_config.fills_suffix_str").to_string (); + m_lefdef_fills_datatype = load_options.get_option_by_name ("lefdef_config.fills_datatype_str").to_string (); m_lefdef_produce_obstructions = load_options.get_option_by_name ("lefdef_config.produce_obstructions").to_bool (); m_lefdef_obstruction_suffix = load_options.get_option_by_name ("lefdef_config.obstructions_suffix").to_string (); m_lefdef_obstruction_datatype = load_options.get_option_by_name ("lefdef_config.obstructions_datatype").to_int (); @@ -500,6 +503,20 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "The LEF pin geometry generation and layer mapping is designed in the same way than via geometry mapping. " "See '--" + m_long_prefix + "lefdef-produce-via-geometry' for a description of the mapping scheme.\n" ) + << tl::arg (group + + "#!--" + m_long_prefix + "lefdef-dont-produce-fills", &m_lefdef_produce_fills, "Skips fills when producing geometry", + "If this option is given, no fill geometry will be produced." + ) + << tl::arg (group + + "#--" + m_long_prefix + "lefdef-fills-suffix", &m_lefdef_fills_suffix, "Specifies the fill geometry layer suffix in pattern-based mode", + "The fill geometry generation and layer mapfillg is designed in the same way than via geometry mapfillg. " + "See '--" + m_long_prefix + "lefdef-via-geometry-suffix' for a description of the mapfillg scheme.\n" + ) + << tl::arg (group + + "#--" + m_long_prefix + "lefdef-fills-datatype", &m_lefdef_fills_datatype, "Specifies the fill geometry layer datatype in pattern-based mode", + "The fill geometry generation and layer mapfillg is designed in the same way than via geometry mapfillg. " + "See '--" + m_long_prefix + "lefdef-produce-via-geometry' for a description of the mapfillg scheme.\n" + ) << tl::arg (group + "#!--" + m_long_prefix + "lefdef-dont-produce-routing", &m_lefdef_produce_routing, "Skips routing when producing geometry", "If this option is given, no routing geometry will be produced." diff --git a/src/buddies/src/bd/bdReaderOptions.h b/src/buddies/src/bd/bdReaderOptions.h index ac4cf2acf..2f877dc00 100644 --- a/src/buddies/src/bd/bdReaderOptions.h +++ b/src/buddies/src/bd/bdReaderOptions.h @@ -161,6 +161,9 @@ private: bool m_lefdef_produce_lef_pins; std::string m_lefdef_lef_pins_suffix; std::string m_lefdef_lef_pins_datatype; + bool m_lefdef_produce_fills; + std::string m_lefdef_fills_suffix; + std::string m_lefdef_fills_datatype; bool m_lefdef_produce_obstructions; std::string m_lefdef_obstruction_suffix; int m_lefdef_obstruction_datatype; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 68ec18f34..bc97a32da 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1426,10 +1426,12 @@ DEFImporter::do_read (db::Layout &layout) take (); } } else if (test ("FILLS")) { + // read over FILLS statements while (! test ("END") || ! test ("FILLS")) { take (); } + } else if (test ("SCANCHAINS")) { // read over SCANCHAINS statements while (! test ("END") || ! test ("SCANCHAINS")) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h index cbfb9c83a..c5f26970b 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h @@ -82,6 +82,7 @@ private: void read_regions (std::map > ®ions, double scale); void read_groups (std::list &groups, double scale); void read_blockages (db::Layout &layout, db::Cell &design, double scale); + void read_fills (db::Layout &layout, db::Cell &design, double scale); void read_nets (db::Layout &layout, db::Cell &design, double scale, bool specialnets); void read_vias (db::Layout &layout, db::Cell &design, double scale); void read_pins (db::Layout &layout, db::Cell &design, double scale); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 615b8f556..97f75ce09 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -425,6 +425,9 @@ LEFDEFReaderOptions::LEFDEFReaderOptions () m_produce_lef_pins (true), m_lef_pins_suffix (".PIN"), m_lef_pins_datatype (2), + m_produce_fills (true), + m_fills_suffix (".FILL"), + m_fills_datatype (5), m_produce_obstructions (true), m_obstructions_suffix (".OBS"), m_obstructions_datatype (3), @@ -489,6 +492,11 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions & m_lef_pins_suffixes = d.m_lef_pins_suffixes; m_lef_pins_datatype = d.m_lef_pins_datatype; m_lef_pins_datatypes = d.m_lef_pins_datatypes; + m_produce_fills = d.m_produce_fills; + m_fills_suffix = d.m_fills_suffix; + m_fills_suffixes = d.m_fills_suffixes; + m_fills_datatype = d.m_fills_datatype; + m_fills_datatypes = d.m_fills_datatypes; m_produce_obstructions = d.m_produce_obstructions; m_obstructions_suffix = d.m_obstructions_suffix; m_obstructions_datatype = d.m_obstructions_datatype; @@ -711,6 +719,30 @@ LEFDEFReaderOptions::lef_pins_datatype_str () const return get_datatypes (this, &LEFDEFReaderOptions::lef_pins_datatype, &LEFDEFReaderOptions::lef_pins_datatype_per_mask, max_mask_number ()); } +void +LEFDEFReaderOptions::set_fills_suffix_str (const std::string &s) +{ + set_suffixes (this, &LEFDEFReaderOptions::clear_fills_suffixes_per_mask, &LEFDEFReaderOptions::set_fills_suffix, &LEFDEFReaderOptions::set_fills_suffix_per_mask, s); +} + +std::string +LEFDEFReaderOptions::fills_suffix_str () const +{ + return get_suffixes (this, &LEFDEFReaderOptions::fills_suffix, &LEFDEFReaderOptions::fills_suffix_per_mask, max_mask_number ()); +} + +void +LEFDEFReaderOptions::set_fills_datatype_str (const std::string &s) +{ + set_datatypes (this, &LEFDEFReaderOptions::clear_fills_datatypes_per_mask, &LEFDEFReaderOptions::set_fills_datatype, &LEFDEFReaderOptions::set_fills_datatype_per_mask, s); +} + +std::string +LEFDEFReaderOptions::fills_datatype_str () const +{ + return get_datatypes (this, &LEFDEFReaderOptions::fills_datatype, &LEFDEFReaderOptions::fills_datatype_per_mask, max_mask_number ()); +} + void LEFDEFReaderOptions::set_routing_suffix_str (const std::string &s) { @@ -835,6 +867,8 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout) std::map purpose_translation; purpose_translation ["LEFPIN"] = LEFPins; purpose_translation ["PIN"] = Pins; + purpose_translation ["FILL"] = Fills; + purpose_translation ["FILLOPC"] = FillsOPC; purpose_translation ["LEFOBS"] = Obstructions; purpose_translation ["SPNET"] = SpecialRouting; purpose_translation ["NET"] = Routing; @@ -1091,6 +1125,10 @@ static std::string purpose_to_name (LayerPurpose purpose) return "LABEL"; case Pins: return "PIN"; + case Fills: + return "FILL"; + case FillsOPC: + return "FILLOPC"; case LEFPins: return "LEFPIN"; case Obstructions: @@ -1262,6 +1300,10 @@ std::set LEFDEFReaderState::open_layer_uncached(db::Layout &layout case Pins: produce = mp_tech_comp->produce_pins (); break; + case Fills: + case FillsOPC: + produce = mp_tech_comp->produce_fills (); + break; case LEFPins: produce = mp_tech_comp->produce_lef_pins (); break; @@ -1303,6 +1345,11 @@ std::set LEFDEFReaderState::open_layer_uncached(db::Layout &layout name_suffix = mp_tech_comp->pins_suffix_per_mask (mask); dt = mp_tech_comp->pins_datatype_per_mask (mask); break; + case Fills: + case FillsOPC: + name_suffix = mp_tech_comp->fills_suffix_per_mask (mask); + dt = mp_tech_comp->fills_datatype_per_mask (mask); + break; case LEFPins: name_suffix = mp_tech_comp->lef_pins_suffix_per_mask (mask); dt = mp_tech_comp->lef_pins_datatype_per_mask (mask); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 9ae66d983..7a85c62b1 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -476,6 +476,72 @@ public: set_per_mask_value (m_lef_pins_datatypes, mask, s); } + bool produce_fills () const + { + return m_produce_fills; + } + + void set_produce_fills (bool f) + { + m_produce_fills = f; + } + + const std::string &fills_suffix () const + { + return m_fills_suffix; + } + + void set_fills_suffix (const std::string &s) + { + m_fills_suffix = s; + } + + int fills_datatype () const + { + return m_fills_datatype; + } + + void set_fills_datatype (int s) + { + m_fills_datatype = s; + } + + void set_fills_suffix_str (const std::string &s); + std::string fills_suffix_str () const; + + void set_fills_datatype_str (const std::string &s); + std::string fills_datatype_str () const; + + void clear_fills_suffixes_per_mask () + { + m_fills_suffixes.clear (); + } + + void clear_fills_datatypes_per_mask () + { + m_fills_datatypes.clear (); + } + + const std::string &fills_suffix_per_mask (unsigned int mask) const + { + return per_mask_value (m_fills_suffixes, m_fills_suffix, mask); + } + + void set_fills_suffix_per_mask (unsigned int mask, const std::string &s) + { + set_per_mask_value (m_fills_suffixes, mask, s); + } + + int fills_datatype_per_mask (unsigned int mask) const + { + return per_mask_value (m_fills_datatypes, m_fills_datatype, mask); + } + + void set_fills_datatype_per_mask (unsigned int mask, int s) + { + set_per_mask_value (m_fills_datatypes, mask, s); + } + bool produce_obstructions () const { return m_produce_obstructions; @@ -707,6 +773,8 @@ public: get_max_mask_number (mm, m_pins_datatypes); get_max_mask_number (mm, m_lef_pins_suffixes); get_max_mask_number (mm, m_lef_pins_datatypes); + get_max_mask_number (mm, m_fills_suffixes); + get_max_mask_number (mm, m_fills_datatypes); get_max_mask_number (mm, m_routing_suffixes); get_max_mask_number (mm, m_routing_datatypes); get_max_mask_number (mm, m_special_routing_suffixes); @@ -841,6 +909,11 @@ private: int m_lef_pins_datatype; std::map m_lef_pins_suffixes; std::map m_lef_pins_datatypes; + bool m_produce_fills; + std::string m_fills_suffix; + int m_fills_datatype; + std::map m_fills_suffixes; + std::map m_fills_datatypes; bool m_produce_obstructions; std::string m_obstructions_suffix; int m_obstructions_datatype; @@ -875,6 +948,8 @@ enum LayerPurpose { Routing = 0, // from DEF only Pins, // from DEF + Fills, // from DEF + FillsOPC, // from DEF SpecialRouting, // from DEF only LEFPins, // from LEF ViaGeometry, // from LEF+DEF diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc index 6a099a0cb..30d50f357 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc @@ -339,6 +339,13 @@ class LEFDEFFormatDeclaration // new: tl::make_member (&LEFDEFReaderOptions::lef_pins_suffix_str, &LEFDEFReaderOptions::set_lef_pins_suffix_str, "special-lef_pins-suffix-string") + tl::make_member (&LEFDEFReaderOptions::lef_pins_datatype_str, &LEFDEFReaderOptions::set_lef_pins_datatype_str, "special-lef_pins-datatype-string") + + tl::make_member (&LEFDEFReaderOptions::produce_fills, &LEFDEFReaderOptions::set_produce_fills, "produce-fills") + + // for backward compatibility + tl::make_member (&LEFDEFReaderOptions::set_fills_suffix, "special-fills-suffix") + + tl::make_member (&LEFDEFReaderOptions::set_fills_datatype, "special-fills-datatype") + + // new: + tl::make_member (&LEFDEFReaderOptions::fills_suffix_str, &LEFDEFReaderOptions::set_fills_suffix_str, "special-fills-suffix-string") + + tl::make_member (&LEFDEFReaderOptions::fills_datatype_str, &LEFDEFReaderOptions::set_fills_datatype_str, "special-fills-datatype-string") + tl::make_member (&LEFDEFReaderOptions::produce_obstructions, &LEFDEFReaderOptions::set_produce_obstructions, "produce-obstructions") + tl::make_member (&LEFDEFReaderOptions::obstructions_suffix, &LEFDEFReaderOptions::set_obstructions_suffix, "obstructions-suffix") + tl::make_member (&LEFDEFReaderOptions::obstructions_datatype, &LEFDEFReaderOptions::set_obstructions_datatype, "obstructions-datatype") + diff --git a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc index 99533c8fc..44b1279e7 100644 --- a/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc +++ b/src/plugins/streamers/lefdef/db_plugin/gsiDeclDbLEFDEF.cc @@ -502,6 +502,94 @@ gsi::Class decl_lefdef_config ("db", "LEFDEFReaderConfi gsi::method ("lef_pins_datatype_str=", &db::LEFDEFReaderOptions::set_lef_pins_datatype_str, gsi::arg ("datatype"), "@hide" ) + + gsi::method ("produce_fills", &db::LEFDEFReaderOptions::produce_fills, + "@brief Gets a value indicating whether fill geometries shall be produced.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("produce_fills=", &db::LEFDEFReaderOptions::set_produce_fills, gsi::arg ("produce"), + "@brief Sets a value indicating whether fill geometries shall be produced.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("fills_suffix", &db::LEFDEFReaderOptions::fills_suffix, + "@brief Gets the fill geometry layer name suffix.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("fills_suffix=", &db::LEFDEFReaderOptions::set_fills_suffix, gsi::arg ("suffix"), + "@brief Sets the fill geometry layer name suffix.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("fills_datatype", &db::LEFDEFReaderOptions::fills_datatype, + "@brief Gets the fill geometry layer datatype value.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("fills_datatype=", &db::LEFDEFReaderOptions::set_fills_datatype, gsi::arg ("datatype"), + "@brief Sets the fill geometry layer datatype value.\n" + "See \\produce_via_geometry for details about the layer production rules." + "\n\n" + "Fill support has been introduced in version 0.27." + ) + + gsi::method ("clear_fills_suffixes_per_mask", &db::LEFDEFReaderOptions::clear_fills_suffixes_per_mask, + "@brief Clears the fill layer name suffix per mask.\n" + "See \\produce_via_geometry for details about this property.\n" + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("clear_fill_datatypes_per_mask", &db::LEFDEFReaderOptions::clear_fills_datatypes_per_mask, + "@brief Clears the fill layer datatypes per mask.\n" + "See \\produce_via_geometry for details about this property.\n" + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("fills_suffix_per_mask", &db::LEFDEFReaderOptions::fills_suffix_per_mask, gsi::arg ("mask"), + "@brief Gets the fill geometry layer name suffix per mask.\n" + "See \\produce_via_geometry for details about the layer production rules." + "The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)." + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("set_fills_suffix_per_mask", &db::LEFDEFReaderOptions::set_fills_suffix_per_mask, gsi::arg ("mask"), gsi::arg ("suffix"), + "@brief Sets the fill geometry layer name suffix per mask.\n" + "See \\produce_via_geometry for details about the layer production rules." + "The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)." + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("fills_datatype", &db::LEFDEFReaderOptions::fills_datatype_per_mask, + "@brief Gets the fill geometry layer datatype value per mask.\n" + "See \\produce_via_geometry for details about the layer production rules." + "The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)." + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("set_fills_datatype_per_mask", &db::LEFDEFReaderOptions::set_fills_datatype_per_mask, gsi::arg ("mask"), gsi::arg ("datatype"), + "@brief Sets the fill geometry layer datatype value.\n" + "See \\produce_via_geometry for details about the layer production rules." + "The mask number is a zero-based mask index (0: MASK 1, 1: MASK 2 ...)." + "\n\n" + "Mask specific rules have been introduced in version 0.27." + ) + + gsi::method ("fills_suffix_str", &db::LEFDEFReaderOptions::fills_suffix_str, + "@hide" + ) + + gsi::method ("fills_suffix_str=", &db::LEFDEFReaderOptions::set_fills_suffix_str, gsi::arg ("suffix"), + "@hide" + ) + + gsi::method ("fills_datatype_str", &db::LEFDEFReaderOptions::fills_datatype_str, + "@hide" + ) + + gsi::method ("fills_datatype_str=", &db::LEFDEFReaderOptions::set_fills_datatype_str, gsi::arg ("datatype"), + "@hide" + ) + gsi::method ("produce_obstructions", &db::LEFDEFReaderOptions::produce_obstructions, "@brief Gets a value indicating whether obstruction markers shall be produced.\n" "See \\produce_via_geometry for details about the layer production rules." diff --git a/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui b/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui index 73212cb25..1c8979355 100644 --- a/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui +++ b/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui @@ -33,1222 +33,1301 @@ 9 - - - - 0 - 0 - - - - LEF Files - - - true - - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - - - - - - 0 - 0 - - - - - 16 - 120 - - - - - 16777215 - 16777215 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - Delete selected files - - - ... - - - - :/clear.png:/clear.png - - - - - - - - 0 - 0 - - - - QAbstractItemView::ExtendedSelection - - - - - - - Move selected files down - - - ... - - - - :/down.png:/down.png - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - Add LEF file - - - ... - - - - :/add.png:/add.png - - - - - - - Move selected files up - - - ... - - - - :/up.png:/up.png - - - - - - - - - - for DEF: also read all LEF files in the same directory than the DEF file - - - - - - - - - - Options - - - true - - - - 4 - - - 4 - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Groups - - - - - - - Layout DBU - - - - - - - Produce a parent cell per group - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - Produce LEF geometry - - - - - - - LEF import into DEF - - - - - - - Via cell name prefix - - - - - - - - 1 - 0 - - - - µm - - - - - - - - - - Global Production Rules (specify what objects to produce and on what layers) - - - true - - - - 9 - - - 4 - - - 9 - - - 4 - - - 6 - - - - - - 50 - false - false - - - - Net names - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - As properties with name ... - - - - - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - - - - - 0 - 0 - - - - - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - <html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html> - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - - - - - 0 - 0 - - - - - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - Blockages (2*) - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 50 - false - false - false - - - - Produce ... - - - - - - - Inst names - - - - - - - - 1 - 0 - - - - On layer with spec ... - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Produce ... - - - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Regions (2*) - - - - - - - Pin names - - - - - - - - 0 - 0 - - - - Die area (2*) - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - <html><body>(<a href="int:/about/layer_specs.xml">See here for the layer specification</a>)</body></html> - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - + - 0 + 2 - + - Layer Map File + LEF Files - - - + + + - Layer map file + for DEF: also read all LEF files in the same directory than the DEF file - - - - ... + + + + Qt::Vertical - - false + + QSizePolicy::Fixed + + + + 20 + 6 + + + + + + + + Additional LEF files - - - - - - - If a layer map file is given, pattern based rules are ignored. -If used inside a technology, the file will be looked up relative to the technology's base path. -Otherwise it's looked up relative to the LEF or DEF file. - -(2*) Die area, Blockage and Region layers in map file will have priority over global production rules above. - - - true + + + + + 0 + 0 + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16 + 120 + + + + + 16777215 + 16777215 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + Delete selected files + + + ... + + + + :/clear.png:/clear.png + + + + + + + + 0 + 0 + + + + QAbstractItemView::ExtendedSelection + + + + + + + Move selected files down + + + ... + + + + :/down.png:/down.png + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Add LEF file + + + ... + + + + :/add.png:/add.png + + + + + + + Move selected files up + + + ... + + + + :/up.png:/up.png + + + + + + + - - + + + + + Options + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Layout DBU + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + µm + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Groups + + + + + + + Produce a parent cell per group + + + + + + + Via cell name prefix + + + + + + + + 0 + 0 + + + + + + + + LEF import into DEF + + + + + + + Produce LEF geometry + + + + + + + + Qt::Vertical 20 - 278 + 40 - + - Pattern Based Layer Production Rules + Production - - - 0 - - - 0 - - - 0 - - - 0 - + - - - QFrame::NoFrame + + + Global Production Rules (specify what objects to produce and on what layers) - + true - - - - 0 - 0 - 616 - 375 - + + + 9 - - - - - - 0 - 0 - + + 4 + + + 9 + + + 4 + + + 6 + + + + + + 50 + false + false + + + + Net names + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + As properties with name ... + + + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + <html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html> + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + + + + 0 + 0 + + + + + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + Blockages (2*) + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 50 + false + false + false + + + + Produce ... + + + + + + + Inst names + + + + + + + + 1 + 0 + + + + On layer with spec ... + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Produce ... + + + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Regions (2*) + + + + + + + Pin names + + + + + + + + 0 + 0 + + + + Die area (2*) + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + <html><body>(<a href="int:/about/layer_specs.xml">See here for the layer specification</a>)</body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 0 + + + + Layer Map File + + + + + + Layer map file - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - Special routing (*) - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - Routing (*) - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - Via geometry (*) - - - - - - - Pin labels - - - - - - - LEF Pins (*) - - - - - - - Layer name -suffix ... - - - - - - - Pins (*) - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - GDS data- -type ... - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - Blockages - - - - - - - Obstructions - - - - - - - - 0 - 0 - - - - - - - :/right.png - - - - - - - - 0 - 0 - - - - - - - - Layer name -suffix ... - - - - - - - GDS data- -type ... - - - - - - - Qt::Vertical - - - - - - + + - (*) Separate suffixes or datatypes can be given for different masks, using the following notation: -"x,1:y,2:z ..." (which will use x by default, y for MASK 1, z for MASK 2 etc.) + ... + + + false + + + + + + + + + + If a layer map file is given, pattern based rules are ignored. +If used inside a technology, the file will be looked up relative to the technology's base path. +Otherwise it's looked up relative to the LEF or DEF file. + +(2*) Die area, Blockage and Region layers in map file will have priority over global production rules above. true + + + + Qt::Vertical + + + + 20 + 278 + + + + + + + + + Pattern Based Layer Production Rules + + + + 0 + + + 0 + + + 0 + + + 0 + - - - - 0 - 1 - + + + QFrame::NoFrame - - Layer Mapping (filter/modify layers, assign GDS layer/datatypes) - - + true - - - 9 + + + + 0 + 0 + 609 + 591 + - - 4 - - - 9 - - - 4 - - - - - Read all layers (additionally to the ones in the mapping table) - - - - - - - - 0 - 1 - - - - - 16 - 0 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - - Qt::Horizontal - - - - + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + Fills (*) + + + + + + + Layer name +suffix ... + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + LEF Pins (*) + + + + + + + Layer name +suffix ... + + + + + + + + + + :/right.png + + + + + + + Via geometry (*) + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + GDS data- +type ... + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + Pins (*) + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + Special routing (*) + + + + + + + Obstructions + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + Pin labels + + + + + + + GDS data- +type ... + + + + + + + Routing (*) + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + + + + Blockages + + + + + + + + 0 + 0 + + + + + + + :/right.png + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + (*) Separate suffixes or datatypes can be given for different masks, using the following notation: +"x,1:y,2:z ..." (which will use x by default, y for MASK 1, z for MASK 2 etc.) + + + true + + + + + + + + 0 + 1 + + + + Layer Mapping (filter/modify layers, assign GDS layer/datatypes) + + + true + + + + 9 + + + 4 + + + 9 + + + 4 + + + + + Read all layers (additionally to the ones in the mapping table) + + + + + + + + 0 + 1 + + + + + 16 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + Qt::Horizontal + + + + + + + + @@ -1273,15 +1352,6 @@ type ... - lef_files - add_lef_file - del_lef_files - move_lef_files_up - move_lef_files_down - dbu - prefix_via_cellname - separate_groups - produce_lef_geo produce_net_names net_prop_name produce_inst_names @@ -1294,7 +1364,6 @@ type ... placement_blockage_layer produce_regions region_layer - layer_map_mode produce_via_geometry suffix_via_geometry datatype_via_geometry @@ -1316,9 +1385,6 @@ type ... produce_labels suffix_labels datatype_labels - produce_blockages - suffix_blockages - datatype_blockages mapfile_path browse_mapfile diff --git a/src/plugins/streamers/lefdef/lay_plugin/layLEFDEFImportDialogs.cc b/src/plugins/streamers/lefdef/lay_plugin/layLEFDEFImportDialogs.cc index 4c64e034f..1ebe6c8b8 100644 --- a/src/plugins/streamers/lefdef/lay_plugin/layLEFDEFImportDialogs.cc +++ b/src/plugins/streamers/lefdef/lay_plugin/layLEFDEFImportDialogs.cc @@ -354,6 +354,7 @@ LEFDEFReaderOptionsEditor::LEFDEFReaderOptionsEditor (QWidget *parent) connect (produce_via_geometry, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); connect (produce_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); connect (produce_lef_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); + connect (produce_fills, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); connect (produce_obstructions, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); connect (produce_blockages, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); connect (produce_routing, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ())); @@ -493,6 +494,9 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con data->set_produce_lef_pins (produce_lef_pins->isChecked ()); data->set_lef_pins_suffix_str (tl::to_string (suffix_lef_pins->text ())); data->set_lef_pins_datatype_str (tl::to_string (datatype_lef_pins->text ())); + data->set_produce_fills (produce_fills->isChecked ()); + data->set_fills_suffix_str (tl::to_string (suffix_fills->text ())); + data->set_fills_datatype_str (tl::to_string (datatype_fills->text ())); data->set_produce_obstructions (produce_obstructions->isChecked ()); data->set_obstructions_suffix (tl::to_string (suffix_obstructions->text ())); data->set_obstructions_datatype (datatype_obstructions->text ().toInt ()); @@ -556,6 +560,9 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options produce_lef_pins->setChecked (data->produce_lef_pins ()); suffix_lef_pins->setText (tl::to_qstring (data->lef_pins_suffix_str ())); datatype_lef_pins->setText (tl::to_qstring (data->lef_pins_datatype_str ())); + produce_fills->setChecked (data->produce_fills ()); + suffix_fills->setText (tl::to_qstring (data->fills_suffix_str ())); + datatype_fills->setText (tl::to_qstring (data->fills_datatype_str ())); produce_obstructions->setChecked (data->produce_obstructions ()); suffix_obstructions->setText (tl::to_qstring (data->obstructions_suffix ())); datatype_obstructions->setText (QString::number (data->obstructions_datatype ())); @@ -604,6 +611,7 @@ LEFDEFReaderOptionsEditor::checkbox_changed () suffix_via_geometry->setEnabled (produce_via_geometry->isChecked ()); suffix_pins->setEnabled (produce_pins->isChecked ()); suffix_lef_pins->setEnabled (produce_lef_pins->isChecked ()); + suffix_fills->setEnabled (produce_fills->isChecked ()); suffix_obstructions->setEnabled (produce_obstructions->isChecked ()); suffix_blockages->setEnabled (produce_blockages->isChecked ()); suffix_routing->setEnabled (produce_routing->isChecked ()); @@ -612,6 +620,7 @@ LEFDEFReaderOptionsEditor::checkbox_changed () datatype_via_geometry->setEnabled (produce_via_geometry->isChecked ()); datatype_pins->setEnabled (produce_pins->isChecked ()); datatype_lef_pins->setEnabled (produce_lef_pins->isChecked ()); + datatype_fills->setEnabled (produce_fills->isChecked ()); datatype_obstructions->setEnabled (produce_obstructions->isChecked ()); datatype_blockages->setEnabled (produce_blockages->isChecked ()); datatype_routing->setEnabled (produce_routing->isChecked ()); diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 884253775..83e1b3f37 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -752,6 +752,16 @@ TEST(119_multimapping) ) } +TEST(120_simplefill) +{ + run_test (_this, "fill", "lef:simple.lef+def:simple.def+map:simple.map", "simple_au.oas.gz", default_options (), false); +} + +TEST(121_fillwithmask) +{ + run_test (_this, "fill", "lef:with_mask.lef+def:with_mask.def+map:with_mask.map", "with_mask_au.oas.gz", default_options (), false); +} + TEST(200_lefdef_plugin) { db::Layout ly; From 898dbf07e9a62bca60e2020ba822bae7117004a3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 18:27:25 +0100 Subject: [PATCH 2/5] Implemented FILLS support for LEF/DEF --- .../lefdef/db_plugin/dbDEFImporter.cc | 107 +++++++++++++++++- .../lefdef/db_plugin/dbDEFImporter.h | 2 +- .../LEFDEFTechnologyComponentEditor.ui | 26 ++++- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 4 +- testdata/lefdef/fill/simple.def | 14 +++ testdata/lefdef/fill/simple.lef | 29 +++++ testdata/lefdef/fill/simple.map | 4 + testdata/lefdef/fill/simple_au.oas.gz | Bin 0 -> 545 bytes testdata/lefdef/fill/with_mask.def | 14 +++ testdata/lefdef/fill/with_mask.lef | 15 +++ testdata/lefdef/fill/with_mask.map | 4 + testdata/lefdef/fill/with_mask_au.oas.gz | Bin 0 -> 557 bytes 12 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 testdata/lefdef/fill/simple.def create mode 100644 testdata/lefdef/fill/simple.lef create mode 100644 testdata/lefdef/fill/simple.map create mode 100644 testdata/lefdef/fill/simple_au.oas.gz create mode 100644 testdata/lefdef/fill/with_mask.def create mode 100644 testdata/lefdef/fill/with_mask.lef create mode 100644 testdata/lefdef/fill/with_mask.map create mode 100644 testdata/lefdef/fill/with_mask_au.oas.gz diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index bc97a32da..b0deb624b 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1243,6 +1243,101 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) } } +void +DEFImporter::read_fills (db::Layout &layout, db::Cell &design, double scale) +{ + std::map , std::vector > geometry; + + while (test ("-")) { + + if (test ("LAYER")) { + + std::string ln = get (); + + unsigned int mask = 0; + bool opc = false; + + while (test ("+")) { + + if (test ("MASK")) { + mask = get_mask (get_long ()); + } else if (test ("OPC")) { + opc = true; + } else { + error (tl::to_string (tr ("'MASK' or 'OPC' keyword expected"))); + } + + } + + std::vector polygons; + + while (! test (";")) { + + if (test ("RECT")) { + + test ("("); + db::Point pt1 = get_point (scale); + test (")"); + + test ("("); + db::Point pt2 = get_point (scale); + test (")"); + + polygons.push_back (db::Polygon (db::Box (pt1, pt2))); + + } else if (test ("POLYGON")) { + + std::vector points; + + double x = 0.0, y = 0.0; + + while (test ("(")) { + + if (! test ("*")) { + x = get_double (); + } + if (! test ("*")) { + y = get_double (); + } + points.push_back (db::Point (db::DPoint (x * scale, y * scale))); + expect (")"); + + } + + polygons.push_back (db::Polygon ()); + polygons.back ().assign_hull (points.begin (), points.end ()); + + } else { + error (tl::to_string (tr ("'RECT' or 'POLYGON' keyword expected"))); + } + + } + + std::set dl = open_layer (layout, ln, opc ? FillsOPC : Fills, mask); + if (! dl.empty ()) { + for (std::vector::const_iterator p = polygons.begin (); p != polygons.end (); ++p) { + for (std::set::const_iterator l = dl.begin (); l != dl.end (); ++l) { + design.shapes (*l).insert (*p); + } + } + } + + } else if (test ("VIA")) { + + // TODO: implement + warn (tl::to_string (tr ("VIA not supported on fills currently"))); + + while (! at_end () && ! test (";")) { + take (); + } + + } else { + error (tl::to_string (tr ("'LAYER' or 'VIA' keyword expected"))); + } + + } +} + void DEFImporter::read_styles (double scale) { @@ -1427,10 +1522,14 @@ DEFImporter::do_read (db::Layout &layout) } } else if (test ("FILLS")) { - // read over FILLS statements - while (! test ("END") || ! test ("FILLS")) { - take (); - } + // Read FILLS statements + get_long (); + expect (";"); + + read_fills (layout, design, scale); + + expect ("END"); + expect ("FILLS"); } else if (test ("SCANCHAINS")) { // read over SCANCHAINS statements diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h index c5f26970b..5fee51f1c 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.h @@ -82,10 +82,10 @@ private: void read_regions (std::map > ®ions, double scale); void read_groups (std::list &groups, double scale); void read_blockages (db::Layout &layout, db::Cell &design, double scale); - void read_fills (db::Layout &layout, db::Cell &design, double scale); void read_nets (db::Layout &layout, db::Cell &design, double scale, bool specialnets); void read_vias (db::Layout &layout, db::Cell &design, double scale); void read_pins (db::Layout &layout, db::Cell &design, double scale); + void read_fills (db::Layout &layout, db::Cell &design, double scale); void read_styles (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); diff --git a/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui b/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui index 1c8979355..0db23b7f8 100644 --- a/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui +++ b/src/plugins/streamers/lefdef/lay_plugin/LEFDEFTechnologyComponentEditor.ui @@ -714,7 +714,7 @@ - 0 + 1 @@ -1352,6 +1352,17 @@ type ... + tabWidget + read_lef_with_def + lef_files + add_lef_file + del_lef_files + move_lef_files_up + move_lef_files_down + dbu + separate_groups + prefix_via_cellname + produce_lef_geo produce_net_names net_prop_name produce_inst_names @@ -1364,6 +1375,10 @@ type ... placement_blockage_layer produce_regions region_layer + layer_map_mode + mapfile_path + browse_mapfile + scrollArea produce_via_geometry suffix_via_geometry datatype_via_geometry @@ -1373,6 +1388,9 @@ type ... produce_lef_pins suffix_lef_pins datatype_lef_pins + produce_fills + suffix_fills + datatype_fills produce_obstructions suffix_obstructions datatype_obstructions @@ -1385,8 +1403,10 @@ type ... produce_labels suffix_labels datatype_labels - mapfile_path - browse_mapfile + produce_blockages + suffix_blockages + datatype_blockages + read_all_cbx diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 83e1b3f37..099b25960 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -754,12 +754,12 @@ TEST(119_multimapping) TEST(120_simplefill) { - run_test (_this, "fill", "lef:simple.lef+def:simple.def+map:simple.map", "simple_au.oas.gz", default_options (), false); + run_test (_this, "fill", "map:simple.map+lef:simple.lef+def:simple.def", "simple_au.oas.gz", default_options (), false); } TEST(121_fillwithmask) { - run_test (_this, "fill", "lef:with_mask.lef+def:with_mask.def+map:with_mask.map", "with_mask_au.oas.gz", default_options (), false); + 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(200_lefdef_plugin) diff --git a/testdata/lefdef/fill/simple.def b/testdata/lefdef/fill/simple.def new file mode 100644 index 000000000..1e33f486a --- /dev/null +++ b/testdata/lefdef/fill/simple.def @@ -0,0 +1,14 @@ +VERSION 5.8 ; +DESIGN test ; +DIEAREA ( 0 0 ) ( 4000 7000 ) ; +FILLS 2 ; +- LAYER M1 + RECT ( 1000 2000 ) ( 1500 4000 ) + RECT ( 1000 4500 ) ( 1500 6500 ) ; +- LAYER M2 + RECT ( 1000 2000 ) ( 1500 4000 ) + POLYGON ( 1000 500 ) ( 2000 1500 ) ( 3000 1500 ) ( 3000 500 ) ; +- LAYER M2 + OPC + RECT ( 3000 2000 ) ( 3500 4000 ) ; +END FILLS +END DESIGN diff --git a/testdata/lefdef/fill/simple.lef b/testdata/lefdef/fill/simple.lef new file mode 100644 index 000000000..0587b8c54 --- /dev/null +++ b/testdata/lefdef/fill/simple.lef @@ -0,0 +1,29 @@ +VERSION 5.8 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; +UNITS + DATABASE MICRONS 2000 ; +END UNITS +MANUFACTURINGGRID 0.000500 ; + +LAYER M1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + PITCH 100 ; + WIDTH 50 ; + SPACING 50 ; +END M1 + +LAYER VIA1 + TYPE CUT ; +END VIA1 + +LAYER M2 + TYPE ROUTING ; + DIRECTION VERTICAL ; + PITCH 100 ; + WIDTH 50 ; + SPACING 50 ; +END M2 + +END LIBRARY diff --git a/testdata/lefdef/fill/simple.map b/testdata/lefdef/fill/simple.map new file mode 100644 index 000000000..0f013c547 --- /dev/null +++ b/testdata/lefdef/fill/simple.map @@ -0,0 +1,4 @@ +DIEAREA ALL 100 0 +M1 FILL 10 1 +M2 FILL 20 2 +M2 FILLOPC 20 3 diff --git a/testdata/lefdef/fill/simple_au.oas.gz b/testdata/lefdef/fill/simple_au.oas.gz new file mode 100644 index 0000000000000000000000000000000000000000..c6ca9c9eb9a987510b7f66b6ac6786a01fe4dbc6 GIT binary patch literal 545 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>u#}`0moS4#Zg&6B5FbxJSLPIE1|DP% zH@mN)o|~tS4>K1tBM&kMC}RYX5n*Nm${;x0Tu_dGfHSiQGcykwpO---IfY??{0%cv zdoD&srUmjZ*e~!ekmqJNA}l1TEyBdY+)>+5+gAI6T~q@iy+B@6i1~vaQ^QCG3=9BO C5xwI8 literal 0 HcmV?d00001 diff --git a/testdata/lefdef/fill/with_mask.def b/testdata/lefdef/fill/with_mask.def new file mode 100644 index 000000000..5a45925e6 --- /dev/null +++ b/testdata/lefdef/fill/with_mask.def @@ -0,0 +1,14 @@ +VERSION 5.8 ; +DESIGN test ; +DIEAREA ( 0 0 ) ( 4000 7000 ) ; +FILLS 2 ; +- LAYER M1 + MASK 1 + RECT ( 1000 2000 ) ( 1500 4000 ) + RECT ( 1000 4500 ) ( 1500 6500 ) ; +- LAYER M2 + MASK 2 + RECT ( 1000 2000 ) ( 1500 4000 ) + POLYGON ( 1000 500 ) ( 2000 1500 ) ( 3000 1500 ) ( 3000 500 ) ; +- LAYER M2 + MASK 2 + OPC + RECT ( 3000 2000 ) ( 3500 4000 ) ; +END FILLS +END DESIGN diff --git a/testdata/lefdef/fill/with_mask.lef b/testdata/lefdef/fill/with_mask.lef new file mode 100644 index 000000000..412e7e915 --- /dev/null +++ b/testdata/lefdef/fill/with_mask.lef @@ -0,0 +1,15 @@ +VERSION 5.8 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; +UNITS + DATABASE MICRONS 2000 ; +END UNITS + +LAYER M1 + TYPE ROUTING ; +END M1 +LAYER M2 + TYPE ROUTING ; +END M2 + +END LIBRARY diff --git a/testdata/lefdef/fill/with_mask.map b/testdata/lefdef/fill/with_mask.map new file mode 100644 index 000000000..e2137e9fa --- /dev/null +++ b/testdata/lefdef/fill/with_mask.map @@ -0,0 +1,4 @@ +DIEAREA ALL 100 0 +M1 FILL:MASK:1 10 1 +M2 FILL:MASK:2 20 2 +M2 FILLOPC:MASK:2 20 3 diff --git a/testdata/lefdef/fill/with_mask_au.oas.gz b/testdata/lefdef/fill/with_mask_au.oas.gz new file mode 100644 index 0000000000000000000000000000000000000000..946e28973695b10e059f9b780053048df697f9f8 GIT binary patch literal 557 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>u#}`0moS4#Zg&6B5FbxJSLPIE1|DP% zH>auV86h>K%Sf7h_H~Twg?job4P7MZCmXNc2Nz8^a6QNA?6QyObsI$ HFfafB=6S$% literal 0 HcmV?d00001 From eda1992a7d26d0e4805089cf1479f8836228b948 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 21:00:55 +0100 Subject: [PATCH 3/5] 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 From fe2d4eb570785a578769897bbd63c6f0464db85b Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 21:07:13 +0100 Subject: [PATCH 4/5] Bugfix: LEF/DEF FILLS options were not active in buddy scripts. --- src/buddies/src/bd/bdReaderOptions.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index 270d6f97b..57c31cd95 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -741,6 +741,9 @@ GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const load_options.set_option_by_name ("lefdef_config.produce_lef_pins", m_lefdef_produce_lef_pins); load_options.set_option_by_name ("lefdef_config.lef_pins_suffix_str", m_lefdef_lef_pins_suffix); load_options.set_option_by_name ("lefdef_config.lef_pins_datatype_str", m_lefdef_lef_pins_datatype); + load_options.set_option_by_name ("lefdef_config.produce_fills", m_lefdef_produce_fills); + load_options.set_option_by_name ("lefdef_config.fills_suffix_str", m_lefdef_fills_suffix); + load_options.set_option_by_name ("lefdef_config.fills_datatype_str", m_lefdef_fills_datatype); load_options.set_option_by_name ("lefdef_config.produce_obstructions", m_lefdef_produce_obstructions); load_options.set_option_by_name ("lefdef_config.obstructions_suffix", m_lefdef_obstruction_suffix); load_options.set_option_by_name ("lefdef_config.obstructions_datatype", m_lefdef_obstruction_datatype); From 3db1db831fe021a630f6585c48af59af99a4a995 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 21 Feb 2021 21:23:45 +0100 Subject: [PATCH 5/5] Test update after update of LEF/DEF reader. --- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 22 +++++++++++------- testdata/lefdef/mapfile/au.oas.gz | Bin 1043 -> 1213 bytes testdata/lefdef/masks-2/au.oas.gz | Bin 3190 -> 3290 bytes testdata/ruby/dbReaders.rb | 12 ++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 75e473fe1..560712df3 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -291,7 +291,7 @@ TEST(16) run_test (_this, "def7", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new.oas.gz", options); options.set_placement_blockage_layer ("PLACEMENT_BLK (60/0)"); - run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au_with_map_file-new.oas.gz", options); + run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au2_with_map_file-new.oas.gz", options); } TEST(17) @@ -332,7 +332,7 @@ TEST(21) TEST(22) { db::LEFDEFReaderOptions opt = default_options (); - run_test (_this, "def13", "map:test.map+lef:test.lef_5.8+def:top.def.gz", "au.oas.gz", opt); + run_test (_this, "def13", "map:test.map+lef:test.lef_5.8+def:top.def.gz", "au2.oas.gz", opt); } TEST(100) @@ -710,20 +710,26 @@ TEST(117_mapfile_all) EXPECT_EQ (lm_read.to_string (), "layer_map(" "'OUTLINE : OUTLINE (1/0)';" - "'+M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/...\\' (1/5)';" + "'+M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/SPNET/...\\' (1/5)';" "'+M1.NET;M1.SPNET : \\'M1.NET/SPNET\\' (16/0)';" "'+M1.NET : M1.NET (18/0)';" - "'+M1.BLK;M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/...\\' (22/2)';" - "'+\\'M1.NET:1\\';\\'M1.PIN:1\\';\\'M1.SPNET:1\\';\\'M1.VIA:1\\' : \\'M1.NET:1/...\\' (6/0)';" + "'+M1.BLK;M1.FILL;M1.FILLOPC;M1.LEFOBS;M1.LEFPIN;M1.NET;M1.PIN;M1.SPNET;M1.VIA : \\'M1.NET/PIN/FILL/...\\' (22/2)';" + "'+\\'M1.NET:1\\';\\'M1.PIN:1\\';\\'M1.SPNET:1\\';\\'M1.VIA:1\\' : \\'M1.NET:1/PIN:1/...\\' (6/0)';" "'+\\'M1.NET:1\\' : \\'M1.NET:1\\' (7/0)';" "'+M1.PIN : M1.PIN (3/0)';" "'+M1.PIN : M1.PIN (4/0)';" - "'+M1.VIA : M1.VIA (20/0)';" - "'+M1.VIA : M1.VIA (21/0)';" + "'+M1.FILL : M1.FILL (14/0)';" + "'+M1.FILL : M1.FILL (15/0)';" + "'+M1.FILL : M1.FILL (17/0)';" + "'+M1.FILLOPC : M1.FILLOPC (9/0)';" + "'\\'M1.FILLOPC:1\\' : \\'M1.FILLOPC:1\\' (10/0)';" + "'\\'M1.FILLOPC:2\\' : \\'M1.FILLOPC:2\\' (11/0)';" + "'\\'M1.VIA:SIZE0.05X0.05\\' : \\'M1.VIA:SIZE0.05X0.05\\' (20/0)';" + "'\\'M1.VIA:SIZE3X3\\' : \\'M1.VIA:SIZE3X3\\' (21/0)';" "'+M1.LABEL : M1.LABEL (26/0)';" "'+M1.LABEL : M1.LABEL (27/0)';" "'+M1.LABEL : M1.LABEL (28/1)';" - "'+M1.BLK : M1.BLOCKAGE (13/0)';" + "'+M1.BLK : M1.BLK (13/0)';" "'M1_TEXT.LABEL : M1_TEXT.LABEL (29/0)'" ")" ) diff --git a/testdata/lefdef/mapfile/au.oas.gz b/testdata/lefdef/mapfile/au.oas.gz index 942c568de6f272436bf824a5f90b385709a0b28e..bf3c4bea7585299965d8ea76b58a552e58947610 100644 GIT binary patch delta 382 zcmbQtv6pkg4Sg|Rg8+X$Ki3fb08c;t-~bRyPfw4TiNDmi6quhI($EK0eGm z%rh8yP1cpO7dI#*u*sPLg9#`J)@X=DBQI1Vn%w4S HrX7p`L26Vs delta 212 zcmdnXIhkX^4P^meg8+X$Ki3fb08c-CJv}{UE@lQE6w%4-jFyv+F!t1Q`x@#w`S?3~ zJG#3v^Ds|m=xc~>9W&56?84kIVI%{YK~`ZGpWMSdZSo|Ru*o&7Ad8I9 zEn)>*giRP|5kwftB36h+*u*D4W0^Mj4Qt%wPi(*-4D)m}K(~qs6ofb=xDgUa)-i#D z5UvGPX0iv{s>ylmNs}u$AQoZ-A`8?)Y!YA#AreT&vcN3FCNudQ`>M@fIP931c~*!_ RHs#i3=KG<%Ih9+G5ddQpjTry{ delta 474 zcmca5`AuSj0Mq0JOe-b}Flhzw`5FZH>jilFSsCi<>FF^uGUxGN5#vUP89~)uVnk91 z7o62Y`P*#YcXhM_K*b*j-v9Fli#s&*(U zi{Ruv>?xBsaIBcDzyUEFIUrb|hNFpr4Tp$93}=BEjwZM{jMIUMneT`4