From 149c97217258a87a7de1803fc3dcd27592a94652 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 29 May 2024 22:36:33 +0200 Subject: [PATCH] Enhancing 'blend-mode' 0 (buddy tools) such that it will not generate instance duplicates --- src/buddies/src/bd/bdReaderOptions.cc | 7 +++++-- src/db/db/dbCommonReader.cc | 8 +++++++- src/db/db/dbInstances.h | 15 ++++++++++++++- testdata/gds/collect_add_au.gds | Bin 13406 -> 13292 bytes 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index ebeaaf870..fb1d05445 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -197,10 +197,13 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "--" + m_long_prefix + "blend-mode=mode", &m_cell_conflict_resolution, "Specifies how cell conflicts are resolved when using file concatenation", "When concatenating files with '+', the reader will handle cells with identical names according to this mode:\n" "\n" - "* 0: joins everything (unsafe)\n" + "* 0: joins everything (usually unsafe)\n" "* 1: overwrite\n" "* 2: skip new cell\n" - "* 3: rename cell (safe, default)" + "* 3: rename cell (safe, default)\n" + "\n" + "Mode 0 is a safe solution for the 'same hierarchy, different layers' case. Mode 3 is a safe solution for " + "joining multiple files into one and combining the hierarchy tree of all files as distinct separate trees.\n" ) ; } diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index dc87204c9..fb4f5dfe7 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -245,10 +245,16 @@ CommonReaderBase::merge_cell (db::Layout &layout, db::cell_index_type target_cel db::Cell &target_cell = layout.cell (target_cell_index); target_cell.set_ghost_cell (src_cell.is_ghost_cell () && target_cell.is_ghost_cell ()); + // avoid generating duplicates + std::set current; + for (db::Cell::const_iterator i = target_cell.begin (); ! i.at_end (); ++i) { + current.insert (*i); + } + // copy over the instances for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++i) { // NOTE: cell indexed may be invalid because we delete subcells without update() - if (layout.is_valid_cell_index (i->cell_index ())) { + if (layout.is_valid_cell_index (i->cell_index ()) && current.find (*i) == current.end ()) { target_cell.insert (*i); } } diff --git a/src/db/db/dbInstances.h b/src/db/db/dbInstances.h index 595a5f7d0..975904e28 100644 --- a/src/db/db/dbInstances.h +++ b/src/db/db/dbInstances.h @@ -1977,7 +1977,20 @@ OverlappingInstanceIteratorTraits::instance_from_stable_iter (const Iter &iter) // box tree iterators deliver pointers, not iterators. Use instance_from_pointer to do this conversion. return mp_insts->instance_from_pointer (&*iter); } - + +/** + * @brief A compare function for db::Instance that uses "less" for value compare + * + * In contrast, "operator<" will compare the instance reference, not value. + */ +struct InstanceCompareFunction +{ + bool operator() (const db::Instance &a, const db::Instance &b) const + { + return a.less (b); + } +}; + } #endif diff --git a/testdata/gds/collect_add_au.gds b/testdata/gds/collect_add_au.gds index ec52fb206812965fa59b229753e871bc520c7aa4..b021521a81c58832235cef4463c2658404635fe8 100644 GIT binary patch delta 954 zcmcbY@g`k~fsKKQDS|GSB3u;*gmjKOKjRjeFkjKE}u>_Y#|g+bw-o1J7u$)u>~UlOz?QGr6faWG2W@$01{*;EzLQfr7piR{t=tv9X0t-pwjAxmJM>hh_~$Tu!;9 zh|6O=N>_21R;K(KmyF6u>@u4}RLdE$OHF>DwrsM3y3S+)4NlxXbeWvXB{TV~F8AaM z>Yg|Z($l~bL{5`?d8NPx%+bJQz%PxX(m2D|(Q)zy0a-kOETuIchr`Zk&BYESZXK>s)nJv;`6IAnqhaHYj<2Dp5hW!N&g#L!KSoq<7y6=&X@ Q%wseeyQQ1A7+Ej^041TBdjJ3c