diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index 0bf21814a..a64de5f72 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -32,34 +32,6 @@ namespace db // --------------------------------------------------------------- // Common reader implementation -DB_PUBLIC void -join_layer_names (std::string &s, const std::string &n) -{ - if (s == n) { - return; - } - - if (! s.empty ()) { - - size_t i = s.find (n); - if (i != std::string::npos && (i == 0 || s.c_str ()[i - 1] == ';')) { - char after = s.c_str ()[i + n.size ()]; - if (after == 0 || after == ';') { - // n is already contained in s - return; - } - } - - s += ";"; - - } - - s += n; -} - -// --------------------------------------------------------------- -// Common reader implementation - static const size_t null_id = std::numeric_limits::max (); CommonReader::CommonReader () diff --git a/src/db/db/dbCommonReader.h b/src/db/db/dbCommonReader.h index cf53f1895..81d361672 100644 --- a/src/db/db/dbCommonReader.h +++ b/src/db/db/dbCommonReader.h @@ -31,9 +31,6 @@ namespace db { -DB_PUBLIC void -join_layer_names (std::string &s, const std::string &n); - /** * @brief The CellConflictResolution enum */ diff --git a/src/db/db/dbReader.cc b/src/db/db/dbReader.cc index fc6f13adb..2ac8add6b 100644 --- a/src/db/db/dbReader.cc +++ b/src/db/db/dbReader.cc @@ -30,6 +30,33 @@ namespace db { +// --------------------------------------------------------------- + +DB_PUBLIC void +join_layer_names (std::string &s, const std::string &n) +{ + if (s == n) { + return; + } + + if (! s.empty ()) { + + size_t i = s.find (n); + if (i != std::string::npos && (i == 0 || s.c_str ()[i - 1] == ';')) { + char after = s.c_str ()[i + n.size ()]; + if (after == 0 || after == ';') { + // n is already contained in s + return; + } + } + + s += ";"; + + } + + s += n; +} + // --------------------------------------------------------------- // ReaderBase implementation diff --git a/src/db/db/dbReader.h b/src/db/db/dbReader.h index bab39df87..65c2ebf0d 100644 --- a/src/db/db/dbReader.h +++ b/src/db/db/dbReader.h @@ -54,6 +54,14 @@ public: { } }; +/** + * @brief Joins layer names into a single, combined layer + * @param s The first layer name and output + * @param n The name to add + */ +DB_PUBLIC void +join_layer_names (std::string &s, const std::string &n); + /** * @brief The generic reader base class */ diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index b4fc56598..e3a90c6ee 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -1359,18 +1359,22 @@ std::set LEFDEFReaderState::open_layer_uncached(db::Layout &layout } } - bool found = false; + int lfound = -1; if (lp_new.layer >= 0 && lp_new.datatype >= 0) { - for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers () && ! found; ++i) { + for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers () && lfound < 0; ++i) { if ((*i).second->log_equal (lp_new)) { - found = true; - res.insert ((*i).first); + lfound = int ((*i).first); } } } - if (! found) { + if (lfound < 0) { res.insert (layout.insert_layer (lp_new)); + } else { + res.insert ((unsigned int) lfound); + db::LayerProperties lp_org = layout.get_properties ((unsigned int) lfound); + join_layer_names (lp_org.name, name); + layout.set_properties ((unsigned int) lfound, lp_org); } if (l == ll.end ()) { diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index c46067119..eba689a5c 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -724,6 +724,24 @@ TEST(118_density) run_test (_this, "density", "read:in.lef", "au.oas.gz", default_options (), false); } +TEST(119_multimapping) +{ + db::LEFDEFReaderOptions options = default_options (); + db::LayerMap lm = db::LayerMap::from_string_file_format ("(M1:1/0)\n(M2:3/0)\n+(M1:100/0)\n+(M2:100/0)\n(VIA1:2/0)"); + options.set_layer_map (lm); + + db::LayerMap lm_read = run_test (_this, "multimap", "def:test.def", "au.oas.gz", options, false); + EXPECT_EQ (lm_read.to_string (), + "layer_map(" + "'OUTLINE : OUTLINE (4/0)';" + "'+M1.VIA : M1 (1/0)';" + "'+M1.VIA;M2.VIA : \\'M1;M2\\' (100/0)';" + "'+M2.VIA : M2 (3/0)';" + "'VIA1.VIA : VIA1 (2/0)'" + ")" + ) +} + TEST(200_lefdef_plugin) { db::Layout ly; diff --git a/testdata/lefdef/multimap/.test.def.swp b/testdata/lefdef/multimap/.test.def.swp new file mode 100644 index 000000000..736b58e7c Binary files /dev/null and b/testdata/lefdef/multimap/.test.def.swp differ diff --git a/testdata/lefdef/multimap/au.oas.gz b/testdata/lefdef/multimap/au.oas.gz new file mode 100644 index 000000000..e1bb4bd44 Binary files /dev/null and b/testdata/lefdef/multimap/au.oas.gz differ diff --git a/testdata/lefdef/multimap/test.def b/testdata/lefdef/multimap/test.def new file mode 100644 index 000000000..6381b8523 --- /dev/null +++ b/testdata/lefdef/multimap/test.def @@ -0,0 +1,28 @@ + +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN chip_top ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 30000 3000 ) ( 10000000 4000 ) ; +VIAS 1 ; + - VIA1_dummy + + RECT M1 ( -200 -140 ) ( 200 140 ) + + RECT VIA1 ( -100 -100 ) ( 100 100 ) + + RECT M2 ( -300 -120 ) ( 300 120 ) ; +END VIAS +SPECIALNETS 1 ; +- dummy + + ROUTED M1 150 + SHAPE IOWIRE ( 40000 3600 ) VIA1_dummy DO 16000 BY 1 STEP 700 0 +; +END SPECIALNETS +SCANCHAINS 77 ; +- chain1_clock1 ++ PARTITION clock1 ++ START block1/bsr_reg_0 Q ++ FLOATING +block1/pgm_cgm_en_reg_reg ( IN SD ) ( OUT QZ ) +block1/start_reset_dd_reg ( IN SD ) ( OUT QZ ) ++ STOP block1/start_reset_d_reg SD ; +END SCANCHAINS +END DESIGN