From 9630bff24086f9b1fcddcb8282a42a7062275c1c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 5 May 2026 23:06:44 +0200 Subject: [PATCH 1/4] A contribution to issue #2345 mitigation With this patch, empty layers can be used to place device terminals on and these shapes are visible on those layers. This allows splitting the terminal shapes and used those shapes to connect down to different substrates. The patch turns EmptyLayer into a DeepLayer when used as terminal layer for device extraction. --- src/db/db/dbEdgePairs.cc | 7 + src/db/db/dbEdgePairs.h | 5 + src/db/db/dbEdges.cc | 7 + src/db/db/dbEdges.h | 5 + src/db/db/dbNetlistDeviceExtractor.cc | 6 +- src/db/db/dbRegion.cc | 7 + src/db/db/dbRegion.h | 5 + src/db/db/dbShapeCollection.h | 5 + src/db/db/dbTexts.cc | 7 + src/db/db/dbTexts.h | 5 + src/lvs/unit_tests/lvsSimpleTests.cc | 6 + testdata/lvs/split_substrate.cir | 13 ++ testdata/lvs/split_substrate.gds | Bin 0 -> 3182 bytes testdata/lvs/split_substrate.l2n | 215 ++++++++++++++++++++++++++ testdata/lvs/split_substrate.lvs | 107 +++++++++++++ 15 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 testdata/lvs/split_substrate.cir create mode 100644 testdata/lvs/split_substrate.gds create mode 100644 testdata/lvs/split_substrate.l2n create mode 100644 testdata/lvs/split_substrate.lvs diff --git a/src/db/db/dbEdgePairs.cc b/src/db/db/dbEdgePairs.cc index cd43514b8..0b5cc36d3 100644 --- a/src/db/db/dbEdgePairs.cc +++ b/src/db/db/dbEdgePairs.cc @@ -103,6 +103,13 @@ EdgePairs::EdgePairs (DeepShapeStore &dss) mp_delegate = new DeepEdgePairs (DeepLayer (&dss, layout_index, dss.layout (layout_index).insert_layer ())); } +void +EdgePairs::convert_to_deep (const db::DeepLayer &layer) +{ + tl_assert (mp_delegate->deep () == 0); + set_delegate (new db::DeepEdgePairs (layer)); +} + void EdgePairs::write (const std::string &fn) const { diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index 7b2b4ed7f..f75d7d773 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -204,6 +204,11 @@ class DB_PUBLIC EdgePairs */ explicit EdgePairs (DeepShapeStore &dss); + /** + * @brief Converts the shape collection to a deep one using the specified layer + */ + virtual void convert_to_deep (const db::DeepLayer &layer); + /** * @brief Writes the edge pair collection to a file * diff --git a/src/db/db/dbEdges.cc b/src/db/db/dbEdges.cc index 1cad75949..1d6b1a72e 100644 --- a/src/db/db/dbEdges.cc +++ b/src/db/db/dbEdges.cc @@ -114,6 +114,13 @@ Edges::Edges (DeepShapeStore &dss) mp_delegate = new DeepEdges (DeepLayer (&dss, layout_index, dss.layout (layout_index).insert_layer ())); } +void +Edges::convert_to_deep (const db::DeepLayer &layer) +{ + tl_assert (mp_delegate->deep () == 0); + set_delegate (new db::DeepEdges (layer)); +} + const db::RecursiveShapeIterator & Edges::iter () const { diff --git a/src/db/db/dbEdges.h b/src/db/db/dbEdges.h index ff8007d19..a12d09c58 100644 --- a/src/db/db/dbEdges.h +++ b/src/db/db/dbEdges.h @@ -264,6 +264,11 @@ class DB_PUBLIC Edges */ explicit Edges (DeepShapeStore &dss); + /** + * @brief Converts the shape collection to a deep one using the specified layer + */ + virtual void convert_to_deep (const db::DeepLayer &layer); + /** * @brief Implementation of the ShapeCollection interface */ diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index 1eb73b68f..9424007b8 100644 --- a/src/db/db/dbNetlistDeviceExtractor.cc +++ b/src/db/db/dbNetlistDeviceExtractor.cc @@ -130,8 +130,10 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo std::pair alias = dss.layer_for_flat (tl::id_of (l->second->get_delegate ())); if (alias.first) { - // use deep layer alias for a given flat one (if found) - layers.push_back (alias.second.layer ()); + // use deep layer alias for a given flat one (if found) and convert layer to a deep one + db::DeepLayer dl = alias.second; + l->second->convert_to_deep (dl); + layers.push_back (dl.layer ()); } else { throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction (device %s): must be of deep region kind")), ld->name, name ())); } diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index f290b87d3..e4d1e1983 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -132,6 +132,13 @@ Region::Region (DeepShapeStore &dss) mp_delegate = new db::DeepRegion (db::DeepLayer (&dss, layout_index, dss.layout (layout_index).insert_layer ())); } +void +Region::convert_to_deep (const db::DeepLayer &layer) +{ + tl_assert (mp_delegate->deep () == 0); + set_delegate (new db::DeepRegion (layer)); +} + void Region::write (const std::string &fn) const { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 655462a01..3a230fdf1 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -256,6 +256,11 @@ class DB_PUBLIC Region */ void write (const std::string &fn) const; + /** + * @brief Converts the shape collection to a deep one using the specified layer + */ + virtual void convert_to_deep (const db::DeepLayer &layer); + /** * @brief Implementation of the ShapeCollection interface */ diff --git a/src/db/db/dbShapeCollection.h b/src/db/db/dbShapeCollection.h index a03c008b2..7f59715ff 100644 --- a/src/db/db/dbShapeCollection.h +++ b/src/db/db/dbShapeCollection.h @@ -102,6 +102,11 @@ class DB_PUBLIC ShapeCollection virtual ShapeCollectionDelegateBase *get_delegate () const = 0; + /** + * @brief Converts the shape collection to a deep one using the specified layer + */ + virtual void convert_to_deep (const db::DeepLayer &layer) = 0; + /** * @brief Applies a PropertyTranslator * diff --git a/src/db/db/dbTexts.cc b/src/db/db/dbTexts.cc index 902a5cf2e..47420fd39 100644 --- a/src/db/db/dbTexts.cc +++ b/src/db/db/dbTexts.cc @@ -99,6 +99,13 @@ Texts::Texts (DeepShapeStore &dss) mp_delegate = new DeepTexts (DeepLayer (&dss, layout_index, dss.layout (layout_index).insert_layer ())); } +void +Texts::convert_to_deep (const db::DeepLayer &layer) +{ + tl_assert (mp_delegate->deep () == 0); + set_delegate (new db::DeepTexts (layer)); +} + void Texts::write (const std::string &fn) const { diff --git a/src/db/db/dbTexts.h b/src/db/db/dbTexts.h index 74441be07..276f9b415 100644 --- a/src/db/db/dbTexts.h +++ b/src/db/db/dbTexts.h @@ -208,6 +208,11 @@ class DB_PUBLIC Texts */ void write (const std::string &fn) const; + /** + * @brief Converts the shape collection to a deep one using the specified layer + */ + virtual void convert_to_deep (const db::DeepLayer &layer); + /** * @brief Implementation of the ShapeCollection interface */ diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 53222d344..e248cee48 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -362,3 +362,9 @@ TEST(63_FlagMissingPorts) run_test (_this, "flag_missing_ports", "flag_missing_ports.gds", false, true, "TOP"); } +// Split substrate - marker and global connection (issue #2345) +TEST(64_SplitSubstrate) +{ + run_test (_this, "split_substrate", "split_substrate.gds", true, false /*no LVS*/); +} + diff --git a/testdata/lvs/split_substrate.cir b/testdata/lvs/split_substrate.cir new file mode 100644 index 000000000..c6971c69e --- /dev/null +++ b/testdata/lvs/split_substrate.cir @@ -0,0 +1,13 @@ +* Extracted by KLayout + +.SUBCKT TOP A Q IOSUB SUBSTRATE +X$1 \$7 \$1 Q IOSUB IOSUB INV +X$2 \$7 A \$1 SUBSTRATE SUBSTRATE INV +.ENDS TOP + +.SUBCKT INV \$2 \$4 \$5 \$1 \$I11 +M$1 \$2 \$4 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U ++ PD=3.45U +M$2 \$1 \$4 \$5 \$I11 NMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U ++ PD=3.45U +.ENDS INV diff --git a/testdata/lvs/split_substrate.gds b/testdata/lvs/split_substrate.gds new file mode 100644 index 0000000000000000000000000000000000000000..e33ad4d0b0cd8968b263a8db891a33c5f469d51a GIT binary patch literal 3182 zcmbW3J!lj`6vyB0-RuEodf%i?>##20Fu>G)1|MN34bI()EP zgFl;4eIsyx}X& z{1I=Nzvqrmln*fm`gMGk@s%3ShtB--w*MdbbHLX;(Y#S=yd{4Q_`2tsH%g7SMX=NnK;vV ze<%NU2hoo6vkQ;&KDVvZI5W+c{AZu@o_!_fKgZMZpW8XlnVk3RD>dFe|1sC2nBNCs z^d7fM1#1vfn{7`B<$=^7Cocw2x&k2*y5Bo}ux11lnoz2%(G>7#L@SDSP@RdT( zlp1Hs{0~1r^_#ckgy0OAvt-UdX%(LZSL7KuJx<$+o}?{)KkIxD_08fio)PkMYE|5~ zF*Od_>+AUWZtBsGY zNYJhrQ!^PrdQAxjK>u#?u&J4?HiugzPIDP zkomc} psd, "G" => pgate, "W" => nwell, + "tS" => psd, "tD" => psd, "tG" => poly }) + +# NMOS transistor device extraction +extract_devices(mos4("NMOS"), { "SD" => nsd, "G" => ngate, "W" => bulk, + "tS" => nsd, "tD" => nsd, "tG" => poly }) + +# Define connectivity for netlist extraction + +# Inter-layer + +soft_connect(diff_cont, psd) +soft_connect(diff_cont, nsd) +soft_connect(diff_cont, ptie) +soft_connect(diff_cont, ntie) +soft_connect(ntie, nwell) +soft_connect(poly_cont, poly) + +connect(diff_cont, metal1) +connect(poly_cont, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# attach labels +connect(poly, poly_lbl) +connect(metal1, metal1_lbl) +connect(metal2, metal2_lbl) + +# Split bulk and ptie into inside and outside iosub +(bulk_io, bulk_reg) = bulk.andnot(iosub) +(ptie_io, ptie_reg) = ptie.andnot(iosub) + +# connect outside to "SUBSTRATE" globally +connect(bulk, bulk_reg) +connect(ptie, ptie_reg) +connect_global(bulk_reg, "SUBSTRATE") +soft_connect_global(ptie_reg, "SUBSTRATE") + +# connect inside to "IOSUB" via polygons +connect(bulk, bulk_io) +connect(ptie, ptie_io) +connect(bulk_io, iosub) +soft_connect(ptie_io, iosub) +connect_global(iosub, "IOSUB") + +# Netlist section (NOTE: we only check log here) +# for debugging: _make_soft_connection_diodes(true) +netlist + +netlist.simplify + + From 838b2409b0f7b3811d4cdae137e9ba7523d79957 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 7 May 2026 00:09:16 +0200 Subject: [PATCH 2/4] Maintaining data_id during modification of layer inside device extractor -> this way, the name-to-layer link is maintained inside the DRC engine --- src/db/db/dbEdgePairs.cc | 2 +- src/db/db/dbEdges.cc | 2 +- src/db/db/dbRegion.cc | 2 +- src/db/db/dbShapeCollection.h | 31 +++++++++++++++++++++- src/db/db/dbTexts.cc | 2 +- src/db/db/gsiDeclDbEdgePairs.cc | 6 ++--- src/db/db/gsiDeclDbEdges.cc | 6 ++--- src/db/db/gsiDeclDbRegion.cc | 6 ++--- src/db/db/gsiDeclDbTexts.cc | 6 ++--- src/drc/drc/built-in-macros/_drc_netter.rb | 4 ++- 10 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/db/db/dbEdgePairs.cc b/src/db/db/dbEdgePairs.cc index 0b5cc36d3..de4b3ab24 100644 --- a/src/db/db/dbEdgePairs.cc +++ b/src/db/db/dbEdgePairs.cc @@ -107,7 +107,7 @@ void EdgePairs::convert_to_deep (const db::DeepLayer &layer) { tl_assert (mp_delegate->deep () == 0); - set_delegate (new db::DeepEdgePairs (layer)); + set_delegate (copy_data_id (new db::DeepEdgePairs (layer))); } void diff --git a/src/db/db/dbEdges.cc b/src/db/db/dbEdges.cc index 1d6b1a72e..f64d23747 100644 --- a/src/db/db/dbEdges.cc +++ b/src/db/db/dbEdges.cc @@ -118,7 +118,7 @@ void Edges::convert_to_deep (const db::DeepLayer &layer) { tl_assert (mp_delegate->deep () == 0); - set_delegate (new db::DeepEdges (layer)); + set_delegate (copy_data_id (new db::DeepEdges (layer))); } const db::RecursiveShapeIterator & diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index e4d1e1983..8e40874fd 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -136,7 +136,7 @@ void Region::convert_to_deep (const db::DeepLayer &layer) { tl_assert (mp_delegate->deep () == 0); - set_delegate (new db::DeepRegion (layer)); + set_delegate (copy_data_id (new db::DeepRegion (layer))); } void diff --git a/src/db/db/dbShapeCollection.h b/src/db/db/dbShapeCollection.h index 7f59715ff..0f48ffef9 100644 --- a/src/db/db/dbShapeCollection.h +++ b/src/db/db/dbShapeCollection.h @@ -75,7 +75,12 @@ class DB_PUBLIC ShapeCollectionDelegateBase : public tl::UniqueId { public: - ShapeCollectionDelegateBase () { } + ShapeCollectionDelegateBase () + : m_data_id (tl::id_of (this)) + { + // .. nothing yet .. + } + virtual ~ShapeCollectionDelegateBase () { } virtual DeepShapeCollectionDelegateBase *deep () { return 0; } @@ -88,6 +93,22 @@ class DB_PUBLIC ShapeCollectionDelegateBase apply_property_translator (db::PropertiesTranslator::make_remove_all ()); } } + + tl::id_type data_id () const + { + return m_data_id; + } + +private: + friend class ShapeCollection; + + tl::id_type m_data_id; + + // used for conversion to deep + void set_data_id (tl::id_type data_id) + { + m_data_id = data_id; + } }; /** @@ -116,6 +137,14 @@ class DB_PUBLIC ShapeCollection * delivered by "properties_repository". */ void apply_property_translator (const db::PropertiesTranslator &pt); + +protected: + template + Delegate *copy_data_id (Delegate *dlg) + { + dlg->set_data_id (get_delegate ()->data_id ()); + return dlg; + } }; } diff --git a/src/db/db/dbTexts.cc b/src/db/db/dbTexts.cc index 47420fd39..1e15801ed 100644 --- a/src/db/db/dbTexts.cc +++ b/src/db/db/dbTexts.cc @@ -103,7 +103,7 @@ void Texts::convert_to_deep (const db::DeepLayer &layer) { tl_assert (mp_delegate->deep () == 0); - set_delegate (new db::DeepTexts (layer)); + set_delegate (copy_data_id (new db::DeepTexts (layer))); } void diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index 0ea5564f0..5a865399a 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -630,9 +630,9 @@ static bool is_deep (const db::EdgePairs *ep) return dynamic_cast (ep->delegate ()) != 0; } -static size_t id (const db::EdgePairs *ep) +static size_t data_id (const db::EdgePairs *ep) { - return tl::id_of (ep->delegate ()); + return ep->delegate ()->data_id (); } static db::EdgePairs filtered (const db::EdgePairs *r, const gsi::EdgePairFilterBase *f) @@ -1114,7 +1114,7 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs", "\n" "This method has been added in version 0.26." ) + - method_ext ("data_id", &id, + method_ext ("data_id", &data_id, "@brief Returns the data ID (a unique identifier for the underlying data storage)\n" "\n" "This method has been added in version 0.26." diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index a434a7d60..667878d62 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -892,9 +892,9 @@ static db::Edges *new_texts_as_dots2 (const db::RecursiveShapeIterator &si, db:: return new db::Edges (db::Region (si).texts_as_dots (pat, pattern, dss)); } -static size_t id (const db::Edges *e) +static size_t data_id (const db::Edges *e) { - return tl::id_of (e->delegate ()); + return e->delegate ()->data_id (); } static std::vector andnot_with_edges (const db::Edges *r, const db::Edges &other) @@ -2572,7 +2572,7 @@ Class decl_Edges (decl_dbShapeCollection, "db", "Edges", "\n" "This method has been added in version 0.26." ) + - method_ext ("data_id", &id, + method_ext ("data_id", &data_id, "@brief Returns the data ID (a unique identifier for the underlying data storage)\n" "\n" "This method has been added in version 0.26." diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 528342e4a..de29f6ba7 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -1288,9 +1288,9 @@ static bool is_deep (const db::Region *region) return dynamic_cast (region->delegate ()) != 0; } -static size_t id (const db::Region *r) +static size_t data_id (const db::Region *r) { - return tl::id_of (r->delegate ()); + return r->delegate ()->data_id (); } @@ -4214,7 +4214,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "This method has been added in version 0.26." ) + - method_ext ("data_id", &id, + method_ext ("data_id", &data_id, "@brief Returns the data ID (a unique identifier for the underlying data storage)\n" "\n" "This method has been added in version 0.26." diff --git a/src/db/db/gsiDeclDbTexts.cc b/src/db/db/gsiDeclDbTexts.cc index 22209b412..21f04d888 100644 --- a/src/db/db/gsiDeclDbTexts.cc +++ b/src/db/db/gsiDeclDbTexts.cc @@ -477,9 +477,9 @@ static bool is_deep (const db::Texts *t) return dynamic_cast (t->delegate ()) != 0; } -static size_t id (const db::Texts *t) +static size_t data_id (const db::Texts *t) { - return tl::id_of (t->delegate ()); + return t->delegate ()->data_id (); } static db::Texts filtered (const db::Texts *r, const gsi::TextFilterBase *f) @@ -686,7 +686,7 @@ Class decl_Texts (decl_dbShapeCollection, "db", "Texts", method_ext ("is_deep?", &is_deep, "@brief Returns true if the edge pair collection is a deep (hierarchical) one\n" ) + - method_ext ("data_id", &id, + method_ext ("data_id", &data_id, "@brief Returns the data ID (a unique identifier for the underlying data storage)\n" ) + method ("+|join", &db::Texts::operator+, gsi::arg ("other"), diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index e5ec8f0a2..75506aae2 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -323,7 +323,9 @@ def extract_devices(devex, layer_selection) # # If layers are not named, they will be given a name made from the # \name_prefix and an incremental number when the layer is used for the - # first time. + # first time. As the default name prefix is "l", you may can name conflicts + # with auto-named layers, if you register explicit layer names like "l5". + # Consider changing the name prefix in that case to some prefix you are not using. # # \name can only be used once on a layer and the layer names must be # unique (not taken by another layer). From 964083ba12acbbee6267a0dc927b4958a8923f36 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 7 May 2026 00:21:39 +0200 Subject: [PATCH 3/4] Updating test data --- testdata/lvs/split_substrate.l2n | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/testdata/lvs/split_substrate.l2n b/testdata/lvs/split_substrate.l2n index 4e9853fcb..95cb99951 100644 --- a/testdata/lvs/split_substrate.l2n +++ b/testdata/lvs/split_substrate.l2n @@ -11,16 +11,16 @@ L(l16 '6/1') L(l13 '7/0') L(l14 '8/0') L(l17) -L(l23 '10/0') -L(l18) +L(l22 '10/0') +L(l7) L(l10) L(l2) L(l9) L(l6) -L(l22) -L(l19) L(l21) +L(l18) L(l20) +L(l19) C(l3 l3 l10) C(l4 l4 l15 l11) C(l15 l4 l15) @@ -33,22 +33,22 @@ C(l16 l12 l16) C(l13 l12 l13 l14) C(l14 l13 l14 l17) C(l17 l14 l17) -C(l23 l23 l22 l21) -C(l18 l18 l19 l21) +C(l22 l22 l21 l20) +C(l7 l7 l18 l20) C(l10 l3 l8 l10) CS(l10 l3) C(l2 l8 l2) -C(l9 l8 l9 l22 l20) +C(l9 l8 l9 l21 l19) C(l6 l8 l6) -C(l22 l23 l9 l22) -CS(l22 l23) -C(l19 l18 l19) -C(l21 l23 l18 l21) -C(l20 l9 l20) -G(l23 IOSUB) +C(l21 l22 l9 l21) +CS(l21 l22) +C(l18 l7 l18) +C(l20 l22 l7 l20) +C(l19 l9 l19) +G(l22 IOSUB) +G(l18 SUBSTRATE) G(l19 SUBSTRATE) -G(l20 SUBSTRATE) -GS(l20 SUBSTRATE) +GS(l19 SUBSTRATE) H(W B('Net with incomplete wiring (soft-connected partial nets)') C(TOP) X('soft-connection-check')) H(B('\tPartial net #1: TOP/INV[r0 3,1.6]:$1 - $2') C(TOP) Q('(1.5,3.95;1.5,4.85;5.3,4.85;5.3,3.95)')) H(B('\tPartial net #2: TOP/INV[r0 7.7,1.6]:$2 - $2') C(TOP) Q('(6.2,3.95;6.2,4.85;10,4.85;10,3.95)')) @@ -79,7 +79,7 @@ D(D$NMOS NMOS R(l6 (125 -475) (775 950)) ) T(B - R(l18 (-125 -475) (250 950)) + R(l7 (-125 -475) (250 950)) ) ) X(INV @@ -183,16 +183,16 @@ X(TOP R(l16 (-400 -200) (0 0)) ) N(4 I(IOSUB) - R(l23 (1334 621) (4230 5073)) - R(l22 (-964 -4594) (400 1000)) - R(l21 (-2125 -975) (250 950)) + R(l22 (1334 621) (4230 5073)) + R(l21 (-964 -4594) (400 1000)) + R(l20 (-2125 -975) (250 950)) ) N(5 I($7) R(l3 (4000 3400) (2700 2000)) ) N(6 I(SUBSTRATE) - R(l19 (7575 1125) (250 950)) - R(l20 (1475 -975) (400 1000)) + R(l18 (7575 1125) (250 950)) + R(l19 (1475 -975) (400 1000)) ) P(2 I(A)) P(3 I(Q)) From 8f1e432146d97a8e866d21ea9d54a403304a5be0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 9 May 2026 19:04:19 +0200 Subject: [PATCH 4/4] Updating test data --- testdata/drc/drcSimpleTests_au121.gds | Bin 2944 -> 3476 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/testdata/drc/drcSimpleTests_au121.gds b/testdata/drc/drcSimpleTests_au121.gds index 5476d67136c05263e051eeabf2c75316b9fc1179..e873870f5935d3b06619399db50d893c97710a8a 100644 GIT binary patch delta 658 zcmZn=pCVn)z{bGD6u}_F$i)7Nft7)iL70JwK@yqGz`?}k3AI!kO!ok46#>>RO#lXhL#K6FyBf$Ls|JNJ;|Np2r z05KRC*e?J%KVUSF4HgH{3@n0J4FIa;0LueukUj=2P%eP>Mz8M83=ERf;NIN)m#KwuWA-$r&5bPo*#Jq_wFdwI delta 120 zcmbOt-5{RGz{bGD6u}_F$i)5v$Yx^@VX$J*LS{2?FtPb~Ix#SaFtge@cA9%1TmHe) pWrzNP*-;@3GOT#?v9X2t2W