diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 117d88b20..989081b88 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1127,9 +1127,9 @@ DEFImporter::read_vias (db::Layout &layout, db::Cell & /*design*/, double scale) if (vd.m1.empty () && vd.m2.empty ()) { // analyze the layers to find the metals - if (routing_layers.size () == 2) { - vd.m1 = routing_layers[0]; - vd.m2 = routing_layers[1]; + if (routing_layers.size () == 2 || routing_layers.size () == 1) { + vd.m1 = routing_layers.front (); + vd.m2 = routing_layers.back (); } else { warn (tl::to_string (tr ("Cannot determine routing layers for via: ")) + n); } @@ -1244,18 +1244,36 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) } else if (test ("VIA")) { - // TODO: implement - warn (tl::to_string (tr ("VIA not supported on pins currently"))); + // TODO: clarify - VIA on pins is regarded VIA purpose, not PIN and gives a separate cell - get (); + std::string vn = get (); + unsigned int mask = 0; if (test ("MASK")) { - get_mask (get_long ()); + mask = get_mask (get_long ()); } - test ("("); - db::Vector d = get_vector (scale); - test (")"); + while (test ("(")) { + + db::Vector pt = get_vector (scale); + test (")"); + + unsigned int mask_top = (mask / 100) % 10; + unsigned int mask_cut = (mask / 10) % 10; + unsigned int mask_bottom = mask % 10; + + std::map::const_iterator vd = m_via_desc.find (vn); + if (vd != m_via_desc.end ()) { + std::string nondefaultrule; + db::Cell *cell = reader_state ()->via_cell (vn, nondefaultrule, layout, mask_bottom, mask_cut, mask_top, &m_lef_importer); + if (cell) { + design.insert (db::CellInstArray (db::CellInst (cell->cell_index ()), db::Trans (pt))); + } + } else { + warn (tl::to_string (tr ("Invalid via name: ")) + vn); + } + + } } else { while (! peek ("+") && ! peek ("-") && ! peek (";")) { @@ -1408,13 +1426,49 @@ DEFImporter::read_fills (db::Layout &layout, db::Cell &design, double scale) } else if (test ("VIA")) { - // TODO: implement - warn (tl::to_string (tr ("VIA not supported on fills currently"))); + // TODO: clarify - VIA on fill is regarded VIA purpose, not PIN and gives a separate cell - while (! at_end () && ! test (";")) { - take (); + std::string vn = get (); + + unsigned int mask = 0; + while (test ("+")) { + if (test ("MASK")) { + mask = get_mask (get_long ()); + } else if (test ("OPC")) { + // ignore + } else { + error (tl::to_string (tr ("Expected 'MASK' or 'OPC' inside fill/VIA definition"))); + } } + if (peek ("+") && test ("MASK")) { + mask = get_mask (get_long ()); + } + + unsigned int mask_top = (mask / 100) % 10; + unsigned int mask_cut = (mask / 10) % 10; + unsigned int mask_bottom = mask % 10; + + while (test ("(")) { + + db::Vector pt = get_vector (scale); + test (")"); + + std::map::const_iterator vd = m_via_desc.find (vn); + if (vd != m_via_desc.end ()) { + std::string nondefaultrule; + db::Cell *cell = reader_state ()->via_cell (vn, nondefaultrule, layout, mask_bottom, mask_cut, mask_top, &m_lef_importer); + if (cell) { + design.insert (db::CellInstArray (db::CellInst (cell->cell_index ()), db::Trans (pt))); + } + } else { + warn (tl::to_string (tr ("Invalid via name: ")) + vn); + } + + } + + test (";"); + } else { error (tl::to_string (tr ("'LAYER' or 'VIA' keyword expected"))); } diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index c97677899..328feedcc 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -420,7 +420,7 @@ TEST(def16) { db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def16", "lef:a.lef+def:a.def", "au.oas.gz", opt); + run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au.oas.gz", opt); } TEST(100) diff --git a/testdata/lefdef/specialnets_geo/au.oas.gz b/testdata/lefdef/specialnets_geo/au.oas.gz index dced1c01d..72437372a 100644 Binary files a/testdata/lefdef/specialnets_geo/au.oas.gz and b/testdata/lefdef/specialnets_geo/au.oas.gz differ diff --git a/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz b/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz index 021f51106..dfb6a9b0b 100644 Binary files a/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz and b/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz differ diff --git a/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz b/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz index 70d7ce494..244696cf0 100644 Binary files a/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz and b/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz differ diff --git a/testdata/lefdef/viasize/au.oas.gz b/testdata/lefdef/viasize/au.oas.gz index 944161a0c..1901dad32 100644 Binary files a/testdata/lefdef/viasize/au.oas.gz and b/testdata/lefdef/viasize/au.oas.gz differ diff --git a/testdata/lefdef/viasize2/au.oas.gz b/testdata/lefdef/viasize2/au.oas.gz index 5da4dd619..c1ab0c221 100644 Binary files a/testdata/lefdef/viasize2/au.oas.gz and b/testdata/lefdef/viasize2/au.oas.gz differ