diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 235f8e02c..d731f059d 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1378,13 +1378,13 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const } RegionDelegate * -AsIfFlatRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const +AsIfFlatRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const { - return sized_inside (inside, d, d, steps, mode, stop_at); + return sized_inside (inside, d, d, steps, mode); } RegionDelegate * -AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const +AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const { if (steps <= 0 || empty ()) { // Nothing to do - NOTE: don't return EmptyRegion because we want to @@ -1409,9 +1409,6 @@ AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy std::vector > others; others.push_back (inside.begin_merged ()); - if (stop_at) { - others.push_back (stop_at->begin ()); - } proc.run_flat (begin_merged (), others, std::vector (), &op, results); diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index dedbec91a..b517ddc90 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -121,8 +121,8 @@ public: virtual RegionDelegate *sized (coord_type d, unsigned int mode) const; virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const; virtual RegionDelegate *and_with (const Region &other, PropertyConstraint property_constraint) const; virtual RegionDelegate *not_with (const Region &other, PropertyConstraint property_constraint) const; diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 5dbca4150..52578aba8 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1782,13 +1782,13 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const } RegionDelegate * -DeepRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const +DeepRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const { - return sized_inside (inside, d, d, steps, mode, stop_at); + return sized_inside (inside, d, d, steps, mode); } RegionDelegate * -DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const +DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const { if (steps <= 0 || empty ()) { // Nothing to do - NOTE: don't return EmptyRegion because we want to @@ -1802,23 +1802,7 @@ DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, in const db::DeepRegion *inside_deep = dynamic_cast (inside.delegate ()); if (! inside_deep) { - return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode, stop_at); - } - - const db::DeepRegion *stop_at_deep = 0; - if (stop_at) { - - stop_at_deep = dynamic_cast (stop_at->delegate ()); - if (! stop_at_deep) { - return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode, stop_at); - } - - if (&inside_deep->deep_layer ().layout () != &stop_at_deep->deep_layer ().layout () - || &inside_deep->deep_layer ().initial_cell () != &stop_at_deep->deep_layer ().initial_cell ()) { - throw tl::Exception (tl::to_string (tr ("'sized_inside' operation needs to use the same layout and top cell " - "for 'inside' and 'stop_at' arguments"))); - } - + return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode); } const db::DeepLayer &polygons = merged_deep_layer (); @@ -1834,13 +1818,7 @@ DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, in std::unique_ptr res (new db::DeepRegion (polygons.derived ())); - std::vector other_layers; - other_layers.push_back (inside_polygons.layer ()); - if (stop_at_deep) { - other_layers.push_back (stop_at_deep->deep_layer ().layer ()); - } - - proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); + proc.run (&op, polygons.layer (), inside_polygons.layer (), res->deep_layer ().layer ()); return res.release (); } diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index b4868a29f..1102c194a 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -136,8 +136,8 @@ public: virtual RegionDelegate *sized (coord_type d, unsigned int mode) const; virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const; virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const; diff --git a/src/db/db/dbEmptyRegion.h b/src/db/db/dbEmptyRegion.h index d9e6a850c..2170b5546 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -97,8 +97,8 @@ public: virtual RegionDelegate *sized (coord_type, unsigned int) const { return new EmptyRegion (); } virtual RegionDelegate *sized (coord_type, coord_type, unsigned int) const { return new EmptyRegion (); } - virtual RegionDelegate *sized_inside (const Region &, coord_type, int, unsigned int, const Region *) const { return new EmptyRegion (); } - virtual RegionDelegate *sized_inside (const Region &, coord_type, coord_type, int, unsigned int, const Region *) const { return new EmptyRegion (); } + virtual RegionDelegate *sized_inside (const Region &, coord_type, int, unsigned int) const { return new EmptyRegion (); } + virtual RegionDelegate *sized_inside (const Region &, coord_type, coord_type, int, unsigned int) const { return new EmptyRegion (); } virtual RegionDelegate *and_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); } virtual RegionDelegate *not_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); } diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index f7bc80213..f68f5ca89 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -310,29 +310,29 @@ Region::sized (coord_type dx, coord_type dy, unsigned int mode) const } Region & -Region::size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) +Region::size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode) { - set_delegate (mp_delegate->sized_inside (inside, d, steps, mode, stop_at)); + set_delegate (mp_delegate->sized_inside (inside, d, steps, mode)); return *this; } Region & -Region::size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at) +Region::size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) { - set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at)); + set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode)); return *this; } Region -Region::sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) const +Region::sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode) const { - return Region (mp_delegate->sized_inside (inside, d, steps, mode, stop_at)); + return Region (mp_delegate->sized_inside (inside, d, steps, mode)); } Region -Region::sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at) const +Region::sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const { - return Region (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at)); + return Region (mp_delegate->sized_inside (inside, dx, dy, steps, mode)); } void diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index a1a485b43..8e7ad5678 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -1031,40 +1031,32 @@ public: * @brief Size the region incrementally * * This method applies an incremental sizing to the region. Before the sizing is done, the - * region is merged if this is not the case already. - * - * Incremental sizing can be confined to be inside a certain region and a stop condition - * can be supplied. With a stop condition, sizing will stop when the sized region touches - * a shape on the "stop_at" region. + * region is merged if this is not the case already. Incremental sizing is confined to be inside a certain region. + * Only positive or zero sizing values are supported. * * @param inside The confinement region * @param d The (isotropic) sizing value * @param steps The number of steps to take * @param mode The sizing mode (see EdgeProcessor) for a description of the sizing mode which controls the miter distance. - * @param stop_at The stop condition or 0 for "not stopping" * @return A reference to self */ - Region &size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0); + Region &size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2); /** * @brief Size the region incrementally and anisotropically * * This method applies an incremental sizing to the region. Before the sizing is done, the - * region is merged if this is not the case already. - * - * Incremental sizing can be confined to be inside a certain region and a stop condition - * can be supplied. With a stop condition, sizing will stop when the sized region touches - * a shape on the "stop_at" region. + * region is merged if this is not the case already. Incremental sizing is confined to be inside a certain region. + * Only positive or zero sizing values are supported. * * @param inside The confinement region * @param dx The x sizing value * @param dy The y sizing value * @param steps The number of steps to take * @param mode The sizing mode (see EdgeProcessor) for a description of the sizing mode which controls the miter distance. - * @param stop_at The stop condition or 0 for "not stopping" * @return A reference to self */ - Region &size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2, const db::Region *stop_at = 0); + Region &size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2); /** * @brief Returns the sized region @@ -1074,7 +1066,7 @@ public: * * Merged semantics applies. */ - Region sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0) const; + Region sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2) const; /** * @brief Returns the sized region @@ -1084,7 +1076,7 @@ public: * * Merged semantics applies. */ - Region sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2, const db::Region *stop_at = 0) const; + Region sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2) const; /** * @brief Boolean AND operator diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index 5928b1f5a..137aa7ac4 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -226,8 +226,8 @@ public: virtual RegionDelegate *sized (coord_type d, unsigned int mode) const = 0; virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const = 0; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const = 0; - virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const = 0; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const = 0; + virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const = 0; virtual RegionDelegate *and_with (const Region &other, PropertyConstraint prop_constraint) const = 0; virtual RegionDelegate *not_with (const Region &other, PropertyConstraint prop_constraint) const = 0; diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index e0799dbe0..a7142ad9c 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -2004,16 +2004,10 @@ sized_inside_local_operation::do_compute_local (db::Layout *layout, std::vector subjects; std::set inside; - std::set stop_at; for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (typename shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - const std::pair &is = interactions.intruder_shape (*j); - if (is.first == 0) { - inside.insert (&is.second); - } else if (is.first == 1) { - stop_at.insert (&is.second); - } + inside.insert (&interactions.intruder_shape (*j).second); } } @@ -2062,50 +2056,6 @@ sized_inside_local_operation::do_compute_local (db::Layout *layout, db::BooleanOp op (db::BooleanOp::And); ep_and.process (pg, op); - if (! subjects.empty () && ! stop_at.empty ()) { - - // compute interations with "stop_at" - - ep_interact.clear (); - - db::EdgeProcessor::property_type p = 0; - for (auto i = subjects.begin (); i != subjects.end (); ++i, ++p) { - ep_interact.insert (*i, p); - } - - db::EdgeProcessor::property_type nstart = p; - for (auto i = stop_at.begin (); i != stop_at.end (); ++i, ++p) { - ep_interact.insert (**i, p); - } - - db::InteractionDetector id (0 /*interacting*/, nstart - 1); - id.set_include_touching (true); - db::EdgeSink es; - ep_interact.process (es, id); - id.finish (); - - std::set interacting; - for (db::InteractionDetector::iterator i = id.begin (); i != id.end (); ++i) { - interacting.insert (i->first); - } - - // drop interacting subjects - - if (! interacting.empty ()) { - std::vector::iterator iw = subjects.begin (); - for (auto i = subjects.begin (); i != subjects.end (); ++i) { - if (interacting.find (i - subjects.begin ()) == interacting.end ()) { - if (iw != i) { - iw->swap (*i); - } - ++iw; - } - } - subjects.erase (iw, subjects.end ()); - } - - } - } db::polygon_ref_generator gen (layout, result); diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 25c4ef3f4..dab1e9ed8 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -1009,15 +1009,15 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode) } static db::Region -sized_inside_dvm (const db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at) +sized_inside_dvm (const db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode) { - return region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at); + return region->sized_inside (inside, dv.x (), dv.y (), steps, mode); } static db::Region & -size_inside_dvm (db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at) +size_inside_dvm (db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode) { - region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at); + region->sized_inside (inside, dv.x (), dv.y (), steps, mode); return *region; } @@ -1942,7 +1942,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" ) + - method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), "@brief Incremental, anisotropic sizing inside of another region\n" "\n" "@param inside The region the incremental sizing will stay inside.\n" @@ -1950,51 +1950,46 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "@param dy The y sizing value\n" "@param steps The number of steps to take\n" "@param mode The sizing mode (see \\size)\n" - "@param stop_at The optional stop layer\n" "\n" "@return The region after the sizing has been applied (self)\n" "\n" "Sizes the region, keeping inside another region and performing the size in discrete steps.\n" "\n" - "Using this method is equivalent to applying a single-step size and consecutively doing a boolean AND with the 'inside' regiuon. " + "Using this method is equivalent to applying a single-step size and consecutively doing a boolean AND with the 'inside' region. " "This is repeated until the full sizing value is applied.\n" "\n" - "This operaton is employed to implement latch-up rules where a device needs to be close to a well tap within the " - "same well. For this, the incremental size of the device active region with the well as the 'inside' region is applied. The step is chosen as " - "somewhat less than the minimum well space, so sizing the active region results in a growing footprint that " - "follows the well contours.\n" - "\n" - "A stop region can be specified, meaning that the sizing propagation will stop if the sized shape " - "touches a shape from the stop region. If that happens, the sized shape is discarded. " - "In case of the latch-up rule application, the stop region will be the well tap layer.\n" + "This operation is employed to implement latch-up rules, where a device needs to be close to a well tap within the " + "same well. For this, the tap footprint is incrementally sized, with the well as the 'inside' region. The steps is chosen so " + "the per-step sizing is somewhat less than the minimum well space. Sizing the tap shape results in a growing footprint that " + "follows the well contours and a small enough per-step sizing value ensures the sized contour does not cross well gaps.\n" "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" "\n" "This method has been introduced in version 0.29.3." ) + - method_ext ("size_inside", &size_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method_ext ("size_inside", &size_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), "@brief Incremental, anisotropic sizing inside of another region\n" "\n" "@return The region after the sizing has applied (self)\n" "\n" - "This method is equivalent to \"size_inside(dv.x, dv.y, steps, mode, stop_at)\".\n" + "This method is equivalent to \"size_inside(dv.x, dv.y, steps, mode)\".\n" "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" "\n" "This method has been introduced in version 0.29.3." ) + - method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, int, unsigned int, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, int, unsigned int)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), "@brief Incremental, isotropic sizing inside of another region\n" "\n" "@return The region after the sizing has applied (self)\n" "\n" - "This method is equivalent to \"size_inside(d, d, steps, mode, stop_at)\".\n" + "This method is equivalent to \"size_inside(d, d, steps, mode)\".\n" "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" "\n" "This method has been introduced in version 0.29.3." ) + - method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int, const db::Region *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), "@brief Returns the incrementally and anisotropically sized region\n" "\n" "@return The sized region\n" @@ -2003,7 +1998,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" ) + - method_ext ("sized_inside", &sized_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method_ext ("sized_inside", &sized_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), "@brief Returns the incrementally and anisotropically sized region\n" "\n" "@return The sized region\n" @@ -2014,7 +2009,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "This variant has been introduced in version 0.28." ) + - method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, int, unsigned int, const db::Region *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"), + method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, int, unsigned int) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), "@brief Returns the incrementally sized region\n" "\n" "@return The sized region\n" diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 073956432..0ec05992a 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -313,6 +313,14 @@ module DRC DRCEdgeMode::new(RBA::EdgeMode::NotStep) end + def steps(arg) + DRCSizingSteps::new(arg) + end + + def inside(arg) + DRCSizingInside::new(arg) + end + def padding_zero DRCDensityPadding::new(:zero) end diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 1fe0b10e9..faa10e974 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -4678,8 +4678,8 @@ TP_SCRIPT # %DRC% # @name sized # @brief Polygon sizing (per-edge biasing) - # @synopsis layer.sized(d [, mode]) - # @synopsis layer.sized(dx, dy [, mode])) + # @synopsis layer.sized(d [, mode] [, inside(l) [, steps(n)]]) + # @synopsis layer.sized(dx, dy [, mode] [, inside(l) [, steps(n)]])) # # This method requires a polygon layer. It will apply a bias per edge of the polygons # and return the biased layer. The layer that this method is called on is not modified. @@ -4711,6 +4711,26 @@ TP_SCRIPT # Bias values can be given as floating-point values (in micron) or integer values (in # database units). To explicitly specify the unit, use the unit denominators. # + # The "inside" option and the "steps" option implement incremental size. Incremental + # size means that the sizing value is applied in n steps. Between the steps, the sized + # shape is confined to the "inside" layer by means of a boolean "AND" operation. + # + # This scheme is used to implement latch-up rules where a device active region has to + # be close to a well tap. By using the well layer as the "inside" layer, the size function + # follows the well contours. The steps have to selected such that the per-step size value + # is smaller than the minimum space of the well shapes. With that, the sized shapes will + # not cross over to neighbor well regions. Specifically, the per-step size has to be less + # than about 70% of the minimum space to account for the minimum corner-to-corner case + # with Euclidian space measurements. + # + # "inside" and "steps" can be used with positive sizing values only. + # + # An example for the "inside" option is this: + # + # @code + # ntap.sized(30.um, inside(nwell), steps(100)) + # @/code + # # \size is working like \sized but modifies the layer it is called on. # # The following images show the effect of various forms of the "sized" method: @@ -4733,10 +4753,11 @@ TP_SCRIPT # %DRC% # @name size # @brief Polygon sizing (per-edge biasing, modifies the layer) - # @synopsis layer.size(d [, mode]) - # @synopsis layer.size(dx, dy [, mode])) + # @synopsis layer.size(d [, mode] [, inside(l) [, steps(n)]]) + # @synopsis layer.size(dx, dy [, mode] [, inside(l) [, steps(n)]])) # - # See \sized. The size method basically does the same but modifies the layer + # See \sized for a description of the options. + # The size method basically does the same but modifies the layer # it is called on. The input layer is returned and available for further processing. %w(size sized).each do |f| @@ -4749,6 +4770,8 @@ TP_SCRIPT dist = 0 + steps = nil + inside = nil mode = 2 values = [] args.each do |a| @@ -4758,10 +4781,40 @@ TP_SCRIPT values.push(v) elsif a.is_a?(DRCSizingMode) mode = a.value + elsif a.is_a?(DRCSizingSteps) + steps = a.value + elsif a.is_a?(DRCSizingInside) + inside = a.value end end aa = [] + + f_size = :size + f_sized = :sized + + if steps + if !inside + raise "'steps' is only allowed with 'inside'" + end + if !steps.is_a?(1.class) + raise "'steps' must be an integer value" + end + end + + if inside + + inside.is_a?(DRCLayer) || raise("'inside' argument needs to be a DRC layer") + inside.data.is_a?(RBA::Region) || raise("'inside' requires a polygon layer") + aa.push(inside.data) + + steps ||= 1 + + f_size = :size_inside + f_sized = :sized_inside + + end + if values.size < 1 raise "Method requires one or two sizing values" elsif values.size > 2 @@ -4771,17 +4824,21 @@ TP_SCRIPT aa.push(values[-1]) end + if inside + aa.push(steps) + end + aa.push(mode) - + if :#{f} == :size && @engine.is_tiled? # in tiled mode, no modifying versions are available - self.data = @engine._tcmd(self.data, dist, RBA::Region, :sized, *aa) + self.data = @engine._tcmd(self.data, dist, RBA::Region, f_sized, *aa) self elsif :#{f} == :size - @engine._tcmd(self.data, dist, RBA::Region, :#{f}, *aa) + @engine._tcmd(self.data, dist, RBA::Region, f_size, *aa) self else - DRCLayer::new(@engine, @engine._tcmd(self.data, dist, RBA::Region, :#{f}, *aa)) + DRCLayer::new(@engine, @engine._tcmd(self.data, dist, RBA::Region, f_sized, *aa)) end end diff --git a/src/drc/drc/built-in-macros/_drc_tags.rb b/src/drc/drc/built-in-macros/_drc_tags.rb index 11d826943..e2a32f3f1 100644 --- a/src/drc/drc/built-in-macros/_drc_tags.rb +++ b/src/drc/drc/built-in-macros/_drc_tags.rb @@ -57,6 +57,22 @@ module DRC end end + # A wrapper for the sizing steps value + class DRCSizingSteps + attr_accessor :value + def initialize(v) + self.value = v + end + end + + # A wrapper for the sizing "inside" value + class DRCSizingInside + attr_accessor :value + def initialize(v) + self.value = v + end + end + # A wrapper for the edge mode value for Region#edges class DRCEdgeMode attr_accessor :value