From 7b7e98d49ab9f64a178dc32317bcb078fc189d1f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 12 Oct 2024 21:44:49 +0200 Subject: [PATCH 1/2] Fixed issue #1877 (rounding introduces DRC error in LEF/DEF via) --- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 6 ++-- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 23 +++++++++++++++ testdata/lefdef/issue-1877/au.oas | Bin 0 -> 589 bytes testdata/lefdef/issue-1877/tech.lef | 27 ++++++++++++++++++ testdata/lefdef/issue-1877/tech.map | 4 +++ testdata/lefdef/issue-1877/test.def | 21 ++++++++++++++ 6 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 testdata/lefdef/issue-1877/au.oas create mode 100644 testdata/lefdef/issue-1877/tech.lef create mode 100644 testdata/lefdef/issue-1877/tech.map create mode 100644 testdata/lefdef/issue-1877/test.def diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index ec404f7c8..75864f591 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -223,8 +223,10 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d // NOTE: missing cuts due to pattern holes don't change mask assignment - db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)) / 2, (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1)) / 2); - db::Box via_box (m_offset - vs, m_offset + vs); + // special rounding to ensure the dimensions are correct for non-even width or height (issue #1877) + db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)), (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1))); + db::Point via_ll = m_offset - db::Vector (vs.x () / 2, vs.y () / 2); + db::Box via_box (via_ll, via_ll + vs); std::set dl; diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 6c1127863..fd890f96b 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -1077,3 +1077,26 @@ TEST(213_no_duplicate_LEF) db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS); } +// issue-1877 (VIA placement rounding) +TEST(214_issue1877) +{ + db::Layout ly; + + std::string fn_path (tl::testdata ()); + fn_path += "/lefdef/issue-1877/"; + + db::LEFDEFReaderOptions lefdef_opt = default_options (); + lefdef_opt.set_map_file ("tech.map"); + lefdef_opt.set_read_lef_with_def (true); + db::LoadLayoutOptions opt; + opt.set_options (lefdef_opt); + + { + tl::InputStream is (fn_path + "test.def"); + db::Reader reader (is); + reader.read (ly, opt); + } + + db::compare_layouts (_this, ly, fn_path + "au.oas", db::WriteOAS); +} + diff --git a/testdata/lefdef/issue-1877/au.oas b/testdata/lefdef/issue-1877/au.oas new file mode 100644 index 0000000000000000000000000000000000000000..3cf8767c57f826e1eb55475039b76f9128fba377 GIT binary patch literal 589 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F; z;|1o9>4KX(8~>b$4qRRSKbqrK6n{_8gJqfX_s419`FTHn{8F5nmXh|s z@mYcQuU%~xzm7=1`nj|11$)J>m+b5f5mi-HXM7yC{#cs0t9OIPW`&Z+6P}6je=a$a zWnvtlZ|BLt%P4Bi#K6cjf#a9uUztu8QA-v^rU$HxEGEi)WD>PyW@LK9{D!$v<~t)d z+g)Y>2;gN9{J_}pk?BB{NHrtF6y*#2Kh864$W>ynHb{Qvsd@J7+8%#T-E%(YCkv)O z$Vf_>2DGt9|Fn-uk9k)=LsNx8U;8CNL50+GNk%5dnM{lfjLM9~jE#(p3=Ja-FfafB DcDnnH literal 0 HcmV?d00001 diff --git a/testdata/lefdef/issue-1877/tech.lef b/testdata/lefdef/issue-1877/tech.lef new file mode 100644 index 000000000..e96c48b57 --- /dev/null +++ b/testdata/lefdef/issue-1877/tech.lef @@ -0,0 +1,27 @@ +VERSION 5.6 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; + +UNITS + DATABASE MICRONS 1000 ; +END UNITS +MANUFACTURINGGRID 0.001 ; + +LAYER METAL_1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + WIDTH 0.6 ; +END METAL_1 + +LAYER VIA_1 + TYPE CUT ; +END VIA_1 + +LAYER METAL_2 + TYPE ROUTING ; + DIRECTION VERTICAL ; + WIDTH 0.6 ; +END METAL_2 + +END LIBRARY + diff --git a/testdata/lefdef/issue-1877/tech.map b/testdata/lefdef/issue-1877/tech.map new file mode 100644 index 000000000..6d3fd1898 --- /dev/null +++ b/testdata/lefdef/issue-1877/tech.map @@ -0,0 +1,4 @@ +DIEAREA ALL 1 0 +METAL_1 ALL 2 0 +VIA_1 ALL 3 0 +METAL_2 ALL 4 0 diff --git a/testdata/lefdef/issue-1877/test.def b/testdata/lefdef/issue-1877/test.def new file mode 100644 index 000000000..cf273a04c --- /dev/null +++ b/testdata/lefdef/issue-1877/test.def @@ -0,0 +1,21 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN dummy_design ; +UNITS DISTANCE MICRONS 1000 ; + +DIEAREA ( 21500 7000 ) ( 26000 9000 ) ; + +VIAS 1 ; + - via1_2_XXXX_XXX_X_X_XXX_XXX + VIARULE MYVIA1_ARRAY + CUTSIZE 246 246 + LAYERS METAL_1 VIA_1 METAL_2 + CUTSPACING 231 231 + ENCLOSURE 62 137 8 61 + ROWCOL 1 8 ; +END VIAS + + +SPECIALNETS 1 ; + - VDD +# ( PIN VDD ) ( * vdd ) + + USE POWER + + ROUTED METAL_1 0 + SHAPE STRIPE ( 23620 7840 ) via1_2_XXXX_XXX_X_X_XXX_XXX ; +END SPECIALNETS + +END DESIGN From dc0f549ab4676ac0ec458c3619c54a91667276b1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 14 Oct 2024 23:41:55 +0200 Subject: [PATCH 2/2] Embedding fix for issue #1892 which is closely related to #1877 --- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 23 +++++++++++-------- .../lefdef/db_plugin/dbLEFDEFImporter.h | 14 +++++++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 75864f591..a8dac54e5 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -225,6 +225,9 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d // special rounding to ensure the dimensions are correct for non-even width or height (issue #1877) db::Vector vs ((m_cutsize.x () * m_columns + m_cutspacing.x () * (m_columns - 1)), (m_cutsize.y () * m_rows + m_cutspacing.y () * (m_rows - 1))); + if (vs.x () % 2 != 0 || vs.y () % 2 != 0) { + reader.warn (tl::sprintf (tl::to_string (tr ("Via has odd width or height (x,y dimension of cut array is %s database units) - this may lead to inaccurate positioning of the via")), vs.to_string ())); + } db::Point via_ll = m_offset - db::Vector (vs.x () / 2, vs.y () / 2); db::Box via_box (via_ll, via_ll + vs); @@ -977,7 +980,7 @@ LEFDEFReaderState::~LEFDEFReaderState () } void -LEFDEFReaderState::common_reader_error (const std::string &msg) +LEFDEFReaderState::error (const std::string &msg) { if (mp_importer) { mp_importer->error (msg); @@ -985,7 +988,7 @@ LEFDEFReaderState::common_reader_error (const std::string &msg) } void -LEFDEFReaderState::common_reader_warn (const std::string &msg, int warn_level) +LEFDEFReaderState::warn (const std::string &msg, int warn_level) { if (mp_importer) { mp_importer->warn (msg, warn_level); @@ -1119,7 +1122,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map::const_iterator l = layers.begin (); l != layers.end (); ++l) { @@ -1178,7 +1181,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::mapsecond == ViaGeometry) { @@ -1286,7 +1289,7 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::mapsecond == All) { @@ -1381,7 +1384,7 @@ LEFDEFReaderState::open_layer (db::Layout &layout, const std::string &n, LayerPu msg += tl::to_string (tr (" Via size ")) + via_size.to_string (); } #endif - common_reader_warn (msg + tl::to_string (tr (" - layer is ignored"))); + warn (msg + tl::to_string (tr (" - layer is ignored"))); } return ll; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 647e3afd2..9720d6edf 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -1354,9 +1354,19 @@ class DB_PLUGIN_PUBLIC LEFDEFReaderState return m_foreign_cells; } + /** + * @brief Issues an error + */ + void error (const std::string &msg); + + /** + * @brief Issues a warning + */ + void warn (const std::string &msg, int warn_level = 1); + protected: - virtual void common_reader_error (const std::string &msg); - virtual void common_reader_warn (const std::string &msg, int warn_level = 1); + virtual void common_reader_error (const std::string &msg) { error (msg); } + virtual void common_reader_warn (const std::string &msg, int warn_level) { warn (msg, warn_level); } private: /**