From 956a27ec69815fbc7fb8926faa7c8576d3de844a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 29 Aug 2022 19:51:19 +0200 Subject: [PATCH] First implementation --- src/db/db/dbDeepEdges.cc | 267 ++++++++++++++++++++++-------- src/db/db/dbDeepEdges.h | 2 +- src/db/db/dbLocalOperation.cc | 43 +++-- src/db/db/dbLocalOperation.h | 9 +- src/db/db/dbNetlistCompareCore.cc | 2 +- 5 files changed, 234 insertions(+), 89 deletions(-) diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index afd4b747f..f5855af70 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -797,12 +797,21 @@ DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const return dl_out; } -DeepLayer -DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const +std::pair +DeepEdges::edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t mode, bool include_borders) const { - DeepLayer dl_out (deep_layer ().derived ()); + std::vector output_layers; - db::EdgeToPolygonLocalOperation op (outside, include_borders); + DeepLayer dl_out (deep_layer ().derived ()); + output_layers.push_back (dl_out.layer ()); + + DeepLayer dl_out2; + if (mode == EdgePolygonOp::Both) { + dl_out2 = DeepLayer (deep_layer ().derived ()); + output_layers.push_back (dl_out2.layer ()); + } + + db::EdgeToPolygonLocalOperation op (mode, include_borders); db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); proc.set_base_verbosity (base_verbosity ()); @@ -810,9 +819,9 @@ DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_b proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ()); proc.set_max_vertex_count (deep_layer ().store ()->max_vertex_count ()); - proc.run (&op, deep_layer ().layer (), other->deep_layer ().layer (), dl_out.layer ()); + proc.run (&op, deep_layer ().layer (), other->deep_layer ().layer (), output_layers); - return dl_out; + return std::make_pair (dl_out, dl_out2); } EdgesDelegate *DeepEdges::intersections (const Edges &other) const @@ -855,31 +864,6 @@ EdgesDelegate *DeepEdges::and_with (const Edges &other) const } } -EdgesDelegate *DeepEdges::and_with (const Region &other) const -{ - const DeepRegion *other_deep = dynamic_cast (other.delegate ()); - - if (empty ()) { - - // Nothing to do - return new EmptyEdges (); - - } else if (other.empty ()) { - - // Nothing to do - return clone (); - - } else if (! other_deep) { - - return AsIfFlatEdges::not_with (other); - - } else { - - return new DeepEdges (edge_region_op (other_deep, false /*outside*/, true /*include borders*/)); - - } -} - EdgesDelegate *DeepEdges::not_with (const Edges &other) const { const DeepEdges *other_deep = dynamic_cast (other.delegate ()); @@ -905,6 +889,31 @@ EdgesDelegate *DeepEdges::not_with (const Edges &other) const } } +EdgesDelegate *DeepEdges::and_with (const Region &other) const +{ + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty ()) { + + // Nothing to do + return new EmptyEdges (); + + } else if (other.empty ()) { + + // Nothing to do + return clone (); + + } else if (! other_deep) { + + return AsIfFlatEdges::and_with (other); + + } else { + + return new DeepEdges (edge_region_op (other_deep, EdgePolygonOp::Inside, true /*include borders*/).first); + + } +} + EdgesDelegate *DeepEdges::not_with (const Region &other) const { const DeepRegion *other_deep = dynamic_cast (other.delegate ()); @@ -925,23 +934,36 @@ EdgesDelegate *DeepEdges::not_with (const Region &other) const } else { - return new DeepEdges (edge_region_op (other_deep, true /*outside*/, true /*include borders*/)); + return new DeepEdges (edge_region_op (other_deep, EdgePolygonOp::Outside, true /*include borders*/).first); } } std::pair -DeepEdges::andnot_with (const Edges &) const +DeepEdges::andnot_with (const Edges &other) const { - // @@@ - return std::pair(); -} + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); -std::pair -DeepEdges::andnot_with (const Region &) const -{ - // @@@ - return std::pair(); + if (empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), new EmptyEdges ()); + + } else if (other.empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), clone ()); + + } else if (! other_deep) { + + return AsIfFlatEdges::andnot_with (other); + + } else { + + auto res = edge_region_op (other_deep, EdgePolygonOp::Both, true /*include borders*/); + return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second)); + + } } EdgesDelegate *DeepEdges::xor_with (const Edges &other) const @@ -1037,11 +1059,11 @@ EdgesDelegate *DeepEdges::inside_part (const Region &other) const } else if (! other_deep) { - return AsIfFlatEdges::not_with (other); + return AsIfFlatEdges::inside_part (other); } else { - return new DeepEdges (edge_region_op (other_deep, false /*outside*/, false /*include borders*/)); + return new DeepEdges (edge_region_op (other_deep, db::EdgePolygonOp::Inside, false /*include borders*/).first); } } @@ -1062,19 +1084,39 @@ EdgesDelegate *DeepEdges::outside_part (const Region &other) const } else if (! other_deep) { - return AsIfFlatEdges::not_with (other); + return AsIfFlatEdges::outside_part (other); } else { - return new DeepEdges (edge_region_op (other_deep, true /*outside*/, false /*include borders*/)); + return new DeepEdges (edge_region_op (other_deep, db::EdgePolygonOp::Outside, false /*include borders*/).first); } } -std::pair DeepEdges::inside_outside_part_pair (const Region &) const +std::pair DeepEdges::inside_outside_part_pair (const Region &other) const { - // @@@ - return std::pair(); + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), new EmptyEdges ()); + + } else if (other.empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), clone ()); + + } else if (! other_deep) { + + return AsIfFlatEdges::inside_outside_part_pair (other); + + } else { + + auto res = edge_region_op (other_deep, EdgePolygonOp::Both, false /*include borders*/); + return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second)); + + } } RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const @@ -1177,8 +1219,10 @@ class Edge2EdgeInteractingLocalOperation : public local_operation { public: - Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, bool inverse) - : m_mode (mode), m_inverse (inverse) + enum output_mode_t { Normal, Inverse, Both }; + + Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode) + : m_mode (mode), m_output_mode (output_mode) { // .. nothing yet .. } @@ -1191,9 +1235,15 @@ public: virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - tl_assert (results.size () == 1); + tl_assert (results.size () == (m_output_mode == Both ? 2 : 1)); + std::unordered_set &result = results.front (); + std::unordered_set *result2 = 0; + if (m_output_mode == Both) { + result2 = &results[1]; + } + db::box_scanner scanner; std::set others; @@ -1212,17 +1262,25 @@ public: scanner.insert (o.operator-> (), 1); } - if (m_inverse) { + if (m_output_mode == Inverse || m_output_mode == Both) { std::unordered_set interacting; edge_interaction_filter > filter (interacting, m_mode); scanner.process (filter, 1, db::box_convert ()); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + const db::Edge &subject = interactions.subject_shape (i->first); if (interacting.find (subject) == interacting.end ()) { + if (m_output_mode != Both) { + result.insert (subject); + } else { + result2->insert (subject); + } + } else if (m_output_mode == Both) { result.insert (subject); } + } } else { @@ -1236,7 +1294,7 @@ public: virtual OnEmptyIntruderHint on_empty_intruder_hint () const { - if (m_inverse) { + if (m_output_mode != Normal) { return Copy; } else { return Drop; @@ -1250,7 +1308,7 @@ public: private: EdgeInteractionMode m_mode; - bool m_inverse; + output_mode_t m_output_mode; }; class Edge2EdgePullLocalOperation @@ -1311,8 +1369,10 @@ class Edge2PolygonInteractingLocalOperation : public local_operation { public: - Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, bool inverse) - : m_mode (mode), m_inverse (inverse) + enum output_mode_t { Normal, Inverse, Both }; + + Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode) + : m_mode (mode), m_output_mode (output_mode) { // .. nothing yet .. } @@ -1325,9 +1385,15 @@ public: virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - tl_assert (results.size () == 1); + tl_assert (results.size () == size_t (m_output_mode == Both ? 2 : 1)); + std::unordered_set &result = results.front (); + std::unordered_set *result2 = 0; + if (m_output_mode == Both) { + result2 = &results[1]; + } + db::box_scanner2 scanner; std::set others; @@ -1348,17 +1414,26 @@ public: scanner.insert2 (& heap.back (), 1); } - if (m_inverse) { + if (m_output_mode == Inverse || m_output_mode == Both) { std::unordered_set interacting; edge_to_region_interaction_filter > filter (&interacting, m_mode); scanner.process (filter, 1, db::box_convert (), db::box_convert ()); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + const db::Edge &subject = interactions.subject_shape (i->first); + if (interacting.find (subject) == interacting.end ()) { + if (m_output_mode != Both) { + result.insert (subject); + } else { + result2->insert (subject); + } + } else if (m_output_mode == Both) { result.insert (subject); } + } } else { @@ -1371,7 +1446,7 @@ public: virtual OnEmptyIntruderHint on_empty_intruder_hint () const { - if (m_inverse) { + if (m_output_mode != Normal) { return Copy; } else { return Drop; @@ -1385,7 +1460,7 @@ public: private: EdgeInteractionMode m_mode; - bool m_inverse; + output_mode_t m_output_mode; }; struct ResultInserter @@ -1481,7 +1556,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod DeepLayer dl_out (edges.derived ()); - db::Edge2PolygonInteractingLocalOperation op (mode, inverse); + db::Edge2PolygonInteractingLocalOperation op (mode, inverse ? db::Edge2PolygonInteractingLocalOperation::Inverse : db::Edge2PolygonInteractingLocalOperation::Normal); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); proc.set_base_verbosity (base_verbosity ()); @@ -1492,6 +1567,38 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod return new db::DeepEdges (dl_out); } +std::pair +DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteractionMode mode) const +{ + std::unique_ptr dr_holder; + const db::DeepRegion *other_deep = dynamic_cast (other.delegate ()); + if (! other_deep) { + // if the other region isn't deep, turn into a top-level only deep region to facilitate re-hierarchization + dr_holder.reset (new db::DeepRegion (other, const_cast (*deep_layer ().store ()))); + other_deep = dr_holder.get (); + } + + const db::DeepLayer &edges = merged_deep_layer (); + + DeepLayer dl_out (edges.derived ()); + DeepLayer dl_out2 (edges.derived ()); + + std::vector output_layers; + output_layers.reserve (2); + output_layers.push_back (dl_out.layer ()); + output_layers.push_back (dl_out2.layer ()); + + db::Edge2PolygonInteractingLocalOperation op (mode, db::Edge2PolygonInteractingLocalOperation::Both); + + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (edges.store ()->threads ()); + + proc.run (&op, edges.layer (), other_deep->deep_layer ().layer (), output_layers); + + return std::make_pair (new db::DeepEdges (dl_out), new db::DeepEdges (dl_out2)); +} + EdgesDelegate * DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse) const { @@ -1507,7 +1614,7 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode DeepLayer dl_out (edges.derived ()); - db::Edge2EdgeInteractingLocalOperation op (mode, inverse); + db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); proc.set_base_verbosity (base_verbosity ()); @@ -1519,17 +1626,35 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode } std::pair -DeepEdges::selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const +DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode) const { - // @@@ - return std::pair(); -} + std::unique_ptr dr_holder; + const db::DeepEdges *other_deep = dynamic_cast (other.delegate ()); + if (! other_deep) { + // if the other edge collection isn't deep, turn into a top-level only deep edge collection to facilitate re-hierarchization + dr_holder.reset (new db::DeepEdges (other, const_cast (*deep_layer ().store ()))); + other_deep = dr_holder.get (); + } -std::pair -DeepEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode) const -{ - // @@@ - return std::pair(); + const db::DeepLayer &edges = merged_deep_layer (); + + DeepLayer dl_out (edges.derived ()); + DeepLayer dl_out2 (edges.derived ()); + + std::vector output_layers; + output_layers.reserve (2); + output_layers.push_back (dl_out.layer ()); + output_layers.push_back (dl_out2.layer ()); + + db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both); + + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (edges.store ()->threads ()); + + proc.run (&op, edges.layer (), other_deep->deep_layer ().layer (), output_layers); + + return std::make_pair (new db::DeepEdges (dl_out), new db::DeepEdges (dl_out2)); } RegionDelegate *DeepEdges::pull_generic (const Region &other) const diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index a39eb4a60..1bd84c16f 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -182,7 +182,7 @@ private: void ensure_merged_edges_valid () const; const DeepLayer &merged_deep_layer () const; DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const; - DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const; + std::pair edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t op, bool include_borders) const; EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const; virtual EdgesDelegate *pull_generic (const Edges &edges) const; virtual RegionDelegate *pull_generic (const Region ®ion) const; diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index f7b9b8651..bb28dda7f 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -20,12 +20,11 @@ */ - +#include "dbLocalOperation.h" #include "dbHierProcessor.h" #include "dbBoxScanner.h" #include "dbRecursiveShapeIterator.h" #include "dbBoxConvert.h" -#include "dbEdgeProcessor.h" #include "dbPolygonGenerators.h" #include "dbPolygonTools.h" #include "dbLocalOperationUtils.h" @@ -366,10 +365,16 @@ EdgeBoolAndOrNotLocalOperation::description () const void EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - tl_assert (results.size () == 1); + tl_assert (results.size () == size_t (m_op == EdgeAndNot ? 2 : 1)); + std::unordered_set &result = results.front (); - EdgeBooleanClusterCollector > cluster_collector (&result, m_op); + std::unordered_set *result2 = 0; + if (results.size () > 1) { + result2 = &results[1]; + } + + EdgeBooleanClusterCollector > cluster_collector (&result, m_op, result2); db::box_scanner scanner; @@ -381,7 +386,7 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const } bool any_subject = false; - bool is_and = (m_op == EdgeAnd || m_op == EdgeIntersections); + bool is_and = (m_op == EdgeAnd || m_op == EdgeAndNot || m_op == EdgeIntersections); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { @@ -416,8 +421,8 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const // --------------------------------------------------------------------------------------------- // EdgeToPolygonLocalOperation implementation -EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool include_borders) - : m_outside (outside), m_include_borders (include_borders) +EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders) + : m_op (op), m_include_borders (include_borders) { // .. nothing yet .. } @@ -425,21 +430,33 @@ EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool inc OnEmptyIntruderHint EdgeToPolygonLocalOperation::on_empty_intruder_hint () const { - return m_outside ? Copy : Drop; + return (m_op == EdgePolygonOp::Inside) ? Copy : Drop; } std::string EdgeToPolygonLocalOperation::description () const { - return tl::to_string (m_outside ? tr ("Edge to polygon AND/INSIDE") : tr ("Edge to polygons NOT/OUTSIDE")); + if (m_op == EdgePolygonOp::Inside) { + return tl::to_string (tr ("Edge to polygon AND/INSIDE")); + } else if (m_op == EdgePolygonOp::Outside) { + return tl::to_string (tr ("Edge to polygon NOT/OUTSIDE")); + } else { + return tl::to_string (tr ("Edge to polygon ANDNOT/INOUTSIDE")); + } } void EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - tl_assert (results.size () == 1); + tl_assert (results.size () == size_t (m_op == EdgePolygonOp::Both ? 2 : 1)); + std::unordered_set &result = results.front (); + std::unordered_set *result2 = 0; + if (results.size () > 1) { + result2 = &results[1]; + } + db::EdgeProcessor ep; std::set others; @@ -456,8 +473,10 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh const db::Edge &subject = interactions.subject_shape (i->first); if (i->second.empty ()) { // shortcut (outside: keep, otherwise: drop) - if (m_outside) { + if (m_op == db::EdgePolygonOp::Outside) { result.insert (subject); + } else if (m_op == db::EdgePolygonOp::Both) { + result2->insert (subject); } } else { ep.insert (subject, 1); @@ -475,7 +494,7 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh } db::EdgeToEdgeSetGenerator cc (result); - db::EdgePolygonOp op (m_outside ? db::EdgePolygonOp::Outside : db::EdgePolygonOp::Inside, m_include_borders); + db::EdgePolygonOp op (m_op, m_include_borders); ep.process (cc, op); } diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 263e58bf0..d3391be95 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -29,6 +29,7 @@ #include "dbLayout.h" #include "dbEdgeBoolean.h" +#include "dbEdgeProcessor.h" #include #include @@ -187,7 +188,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation : public local_operation { public: - EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op); + EdgeBoolAndOrNotLocalOperation (db::EdgeBoolOp op); virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; @@ -197,7 +198,7 @@ public: virtual db::Coord dist () const { return 1; } private: - EdgeBoolOp m_op; + db::EdgeBoolOp m_op; }; /** @@ -210,7 +211,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation : public local_operation { public: - EdgeToPolygonLocalOperation (bool outside, bool include_borders); + EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders); virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; @@ -220,7 +221,7 @@ public: virtual db::Coord dist () const { return m_include_borders ? 1 : 0; } private: - bool m_outside; + db::EdgePolygonOp::mode_t m_op; bool m_include_borders; }; diff --git a/src/db/db/dbNetlistCompareCore.cc b/src/db/db/dbNetlistCompareCore.cc index 9dfe56018..bb6b3a4f0 100644 --- a/src/db/db/dbNetlistCompareCore.cc +++ b/src/db/db/dbNetlistCompareCore.cc @@ -1181,7 +1181,7 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo } return tentative ? failed_match : 0; - } else if ((! n->has_any_other () && ! n_other->has_any_other ()) || (n->has_unknown_other () && n_other->has_unknown_other ())) { // @@@ + } else if ((! n->has_any_other () && ! n_other->has_any_other ()) || (n->has_unknown_other () && n_other->has_unknown_other ())) { // in tentative mode, reject this choice if both nets are named and // their names differ -> this favors net matching by name