diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 2171c4f37..0c1c4245d 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1377,6 +1377,23 @@ 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 +{ + return sized_inside (inside, d, d, steps, mode, stop_at); +} + +RegionDelegate * +AsIfFlatRegion::sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const +{ + if (steps <= 0) { + return clone (); + } + + return 0; // @@@ + +} + RegionDelegate * AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_constraint) const { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index bc59155a1..dffcb3af0 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -121,6 +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 *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 d52df7f9c..132d47e4d 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1781,6 +1781,36 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const return res.release (); } +RegionDelegate * +DeepRegion::sized_inside (const Region *inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const +{ + if (steps <= 0) { + return clone (); + } + + + return 0; // @@@ + +} + +RegionDelegate * +DeepRegion::sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const +{ + if (steps <= 0 || empty ()) { + // Nothing to do - NOTE: don't return EmptyRegion because we want to + // maintain "deepness" + return clone (); + } + + if (dx == dy) { + return sized_inside (inside, dx, steps, mode, stop_at); + } + + + return 0; // @@@ + +} + template static Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &node) diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 1d5537554..a7e2e78f6 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -136,6 +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 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 086ea9837..62e405543 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -97,6 +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 *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 2d04a2758..37c668350 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -309,6 +309,32 @@ Region::sized (coord_type dx, coord_type dy, unsigned int mode) const return Region (mp_delegate->sized (dx, dy, mode)); } +Region & +Region::size_inside (const db::Region *inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) +{ + set_delegate (mp_delegate->sized_inside (inside, d, steps, mode, stop_at)); + 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) +{ + set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at)); + return *this; +} + +Region +Region::sized_inside (const db::Region *inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) const +{ + return Region (mp_delegate->sized_inside (inside, d, steps, mode, stop_at)); +} + +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 +{ + return Region (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at)); +} + void Region::round_corners (double rinner, double router, unsigned int n) { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 145018ef0..b4f0f3524 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -1027,6 +1027,65 @@ public: */ Region sized (coord_type dx, coord_type dy, unsigned int mode = 2) const; + /** + * @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. + * + * @param inside The confinement region or 0 for "no confinement" + * @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); + + /** + * @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. + * + * @param inside The confinement region or 0 for "no confinement" + * @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); + + /** + * @brief Returns the sized region + * + * This is an out-of-place version of the size method with isotropic sizing + * "merged polygon" semantics applies if merged_polygon_semantics is true (see set_auto_merge). + * + * 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; + + /** + * @brief Returns the sized region + * + * This is an out-of-place version of the size method with anisotropic sizing + * "merged polygon" semantics applies if merged_polygon_semantics is true (see set_auto_merge). + * + * 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; + /** * @brief Boolean AND operator */ diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index cfc627cf7..d8c4a1330 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -226,6 +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 *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/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index cfd5205e2..7526b1ded 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -1008,6 +1008,19 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode) return *region; } +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) +{ + return region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at); +} + +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) +{ + region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at); + return *region; +} + static db::Edges edges (const db::Region *region, db::PolygonToEdgeProcessor::EdgeMode mode) { @@ -1929,6 +1942,86 @@ 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"), + "@brief Incremental, anisotropic sizing inside of another region\n" + "\n" + "@param inside The region the incremental sizing will stay inside. Can be nil to skip the inside condition.\n" + "@param dx The x sizing value\n" + "@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. " + "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 will. 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 region " + "touches a shape from the stop region. In case of the latch-up rule application this will be the well tap layer.\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"), + "@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" + "\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"), + "@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" + "\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"), + "@brief Returns the incrementally and anisotropically sized region\n" + "\n" + "@return The sized region\n" + "\n" + "This method returns the incrementally sized region (see \\size_inside), but does not modify self.\n" + "\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"), + "@brief Returns the incrementally and anisotropically sized region\n" + "\n" + "@return The sized region\n" + "\n" + "This method returns the incrementally sized region (see \\size_inside), but does not modify self.\n" + "\n" + "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" + "\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"), + "@brief Returns the incrementally sized region\n" + "\n" + "@return The sized region\n" + "\n" + "This method returns the incrementally sized region (see \\size_inside), but does not modify self.\n" + "\n" + "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" + ) + method_ext ("andnot", &andnot, gsi::arg ("other"), gsi::arg ("property_constraint", db::IgnoreProperties, "IgnoreProperties"), "@brief Returns the boolean AND and NOT between self and the other region\n" "\n"