mirror of https://github.com/KLayout/klayout.git
WIP: DRC integration
This commit is contained in:
parent
e63a7b5940
commit
a54365a9a7
|
|
@ -1378,13 +1378,13 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDelegate *
|
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 *
|
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 ()) {
|
if (steps <= 0 || empty ()) {
|
||||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
// 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<db::generic_shape_iterator<db::Polygon> > others;
|
std::vector<db::generic_shape_iterator<db::Polygon> > others;
|
||||||
others.push_back (inside.begin_merged ());
|
others.push_back (inside.begin_merged ());
|
||||||
if (stop_at) {
|
|
||||||
others.push_back (stop_at->begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
proc.run_flat (begin_merged (), others, std::vector<bool> (), &op, results);
|
proc.run_flat (begin_merged (), others, std::vector<bool> (), &op, results);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const;
|
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 (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 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 Region *stop_at) 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 *and_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||||
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint property_constraint) const;
|
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||||
|
|
|
||||||
|
|
@ -1782,13 +1782,13 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDelegate *
|
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 *
|
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 ()) {
|
if (steps <= 0 || empty ()) {
|
||||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
// 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<const db::DeepRegion *> (inside.delegate ());
|
const db::DeepRegion *inside_deep = dynamic_cast<const db::DeepRegion *> (inside.delegate ());
|
||||||
if (! inside_deep) {
|
if (! inside_deep) {
|
||||||
return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode, stop_at);
|
return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode);
|
||||||
}
|
|
||||||
|
|
||||||
const db::DeepRegion *stop_at_deep = 0;
|
|
||||||
if (stop_at) {
|
|
||||||
|
|
||||||
stop_at_deep = dynamic_cast<const db::DeepRegion *> (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")));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
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<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
|
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
|
||||||
|
|
||||||
std::vector<unsigned int> other_layers;
|
proc.run (&op, polygons.layer (), inside_polygons.layer (), res->deep_layer ().layer ());
|
||||||
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 ());
|
|
||||||
|
|
||||||
return res.release ();
|
return res.release ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const;
|
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 (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 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 Region *stop_at) 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;
|
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type, unsigned int) const { return new EmptyRegion (); }
|
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 (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, int, unsigned int) 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, coord_type, int, unsigned int) const { return new EmptyRegion (); }
|
||||||
|
|
||||||
virtual RegionDelegate *and_with (const Region &, db::PropertyConstraint) 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 (); }
|
virtual RegionDelegate *not_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); }
|
||||||
|
|
|
||||||
|
|
@ -310,29 +310,29 @@ Region::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
Region &
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Region &
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Region
|
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
|
||||||
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
|
void
|
||||||
|
|
|
||||||
|
|
@ -1031,40 +1031,32 @@ public:
|
||||||
* @brief Size the region incrementally
|
* @brief Size the region incrementally
|
||||||
*
|
*
|
||||||
* This method applies an incremental sizing to the region. Before the sizing is done, the
|
* 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.
|
* 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.
|
||||||
* 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
|
* @param inside The confinement region
|
||||||
* @param d The (isotropic) sizing value
|
* @param d The (isotropic) sizing value
|
||||||
* @param steps The number of steps to take
|
* @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 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
|
* @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
|
* @brief Size the region incrementally and anisotropically
|
||||||
*
|
*
|
||||||
* This method applies an incremental sizing to the region. Before the sizing is done, the
|
* 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.
|
* 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.
|
||||||
* 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
|
* @param inside The confinement region
|
||||||
* @param dx The x sizing value
|
* @param dx The x sizing value
|
||||||
* @param dy The y sizing value
|
* @param dy The y sizing value
|
||||||
* @param steps The number of steps to take
|
* @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 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
|
* @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
|
* @brief Returns the sized region
|
||||||
|
|
@ -1074,7 +1066,7 @@ public:
|
||||||
*
|
*
|
||||||
* Merged semantics applies.
|
* 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
|
* @brief Returns the sized region
|
||||||
|
|
@ -1084,7 +1076,7 @@ public:
|
||||||
*
|
*
|
||||||
* Merged semantics applies.
|
* 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
|
* @brief Boolean AND operator
|
||||||
|
|
|
||||||
|
|
@ -226,8 +226,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const = 0;
|
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 (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 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 Region *stop_at) 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 *and_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
||||||
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
||||||
|
|
|
||||||
|
|
@ -2004,16 +2004,10 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
||||||
|
|
||||||
std::vector<db::Polygon> subjects;
|
std::vector<db::Polygon> subjects;
|
||||||
std::set<const TI *> inside;
|
std::set<const TI *> inside;
|
||||||
std::set<const TI *> stop_at;
|
|
||||||
|
|
||||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
for (typename shape_interactions<TS, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
for (typename shape_interactions<TS, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||||
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*j);
|
inside.insert (&interactions.intruder_shape (*j).second);
|
||||||
if (is.first == 0) {
|
|
||||||
inside.insert (&is.second);
|
|
||||||
} else if (is.first == 1) {
|
|
||||||
stop_at.insert (&is.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2062,50 +2056,6 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
||||||
db::BooleanOp op (db::BooleanOp::And);
|
db::BooleanOp op (db::BooleanOp::And);
|
||||||
ep_and.process (pg, op);
|
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<size_t> interacting;
|
|
||||||
for (db::InteractionDetector::iterator i = id.begin (); i != id.end (); ++i) {
|
|
||||||
interacting.insert (i->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
// drop interacting subjects
|
|
||||||
|
|
||||||
if (! interacting.empty ()) {
|
|
||||||
std::vector<db::Polygon>::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<TR> gen (layout, result);
|
db::polygon_ref_generator<TR> gen (layout, result);
|
||||||
|
|
|
||||||
|
|
@ -1009,15 +1009,15 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static db::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)
|
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 &
|
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;
|
return *region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1942,7 +1942,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\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"
|
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@param inside The region the incremental sizing will stay inside.\n"
|
"@param inside The region the incremental sizing will stay inside.\n"
|
||||||
|
|
@ -1950,51 +1950,46 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"@param dy The y sizing value\n"
|
"@param dy The y sizing value\n"
|
||||||
"@param steps The number of steps to take\n"
|
"@param steps The number of steps to take\n"
|
||||||
"@param mode The sizing mode (see \\size)\n"
|
"@param mode The sizing mode (see \\size)\n"
|
||||||
"@param stop_at The optional stop layer\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"@return The region after the sizing has been applied (self)\n"
|
"@return The region after the sizing has been applied (self)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Sizes the region, keeping inside another region and performing the size in discrete steps.\n"
|
"Sizes the region, keeping inside another region and performing the size in discrete steps.\n"
|
||||||
"\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"
|
"This is repeated until the full sizing value is applied.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This operaton is employed to implement latch-up rules where a device needs to be close to a well tap within the "
|
"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 incremental size of the device active region with the well as the 'inside' region is applied. The step is chosen as "
|
"same well. For this, the tap footprint is incrementally sized, with the well as the 'inside' region. The steps is chosen so "
|
||||||
"somewhat less than the minimum well space, so sizing the active region results in a growing footprint that "
|
"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.\n"
|
"follows the well contours and a small enough per-step sizing value ensures the sized contour does not cross well gaps.\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"
|
|
||||||
"\n"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.29.3."
|
"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"
|
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The region after the sizing has applied (self)\n"
|
"@return The region after the sizing has applied (self)\n"
|
||||||
"\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"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.29.3."
|
"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"
|
"@brief Incremental, isotropic sizing inside of another region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The region after the sizing has applied (self)\n"
|
"@return The region after the sizing has applied (self)\n"
|
||||||
"\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"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.29.3."
|
"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"
|
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The sized region\n"
|
"@return The sized region\n"
|
||||||
|
|
@ -2003,7 +1998,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\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"
|
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The sized region\n"
|
"@return The sized region\n"
|
||||||
|
|
@ -2014,7 +2009,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"This variant has been introduced in version 0.28."
|
"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"
|
"@brief Returns the incrementally sized region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The sized region\n"
|
"@return The sized region\n"
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,14 @@ module DRC
|
||||||
DRCEdgeMode::new(RBA::EdgeMode::NotStep)
|
DRCEdgeMode::new(RBA::EdgeMode::NotStep)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def steps(arg)
|
||||||
|
DRCSizingSteps::new(arg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def inside(arg)
|
||||||
|
DRCSizingInside::new(arg)
|
||||||
|
end
|
||||||
|
|
||||||
def padding_zero
|
def padding_zero
|
||||||
DRCDensityPadding::new(:zero)
|
DRCDensityPadding::new(:zero)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4678,8 +4678,8 @@ TP_SCRIPT
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name sized
|
# @name sized
|
||||||
# @brief Polygon sizing (per-edge biasing)
|
# @brief Polygon sizing (per-edge biasing)
|
||||||
# @synopsis layer.sized(d [, mode])
|
# @synopsis layer.sized(d [, mode] [, inside(l) [, steps(n)]])
|
||||||
# @synopsis layer.sized(dx, dy [, mode]))
|
# @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
|
# 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.
|
# 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
|
# 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.
|
# 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.
|
# \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:
|
# The following images show the effect of various forms of the "sized" method:
|
||||||
|
|
@ -4733,10 +4753,11 @@ TP_SCRIPT
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name size
|
# @name size
|
||||||
# @brief Polygon sizing (per-edge biasing, modifies the layer)
|
# @brief Polygon sizing (per-edge biasing, modifies the layer)
|
||||||
# @synopsis layer.size(d [, mode])
|
# @synopsis layer.size(d [, mode] [, inside(l) [, steps(n)]])
|
||||||
# @synopsis layer.size(dx, dy [, mode]))
|
# @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.
|
# it is called on. The input layer is returned and available for further processing.
|
||||||
|
|
||||||
%w(size sized).each do |f|
|
%w(size sized).each do |f|
|
||||||
|
|
@ -4749,6 +4770,8 @@ TP_SCRIPT
|
||||||
|
|
||||||
dist = 0
|
dist = 0
|
||||||
|
|
||||||
|
steps = nil
|
||||||
|
inside = nil
|
||||||
mode = 2
|
mode = 2
|
||||||
values = []
|
values = []
|
||||||
args.each do |a|
|
args.each do |a|
|
||||||
|
|
@ -4758,10 +4781,40 @@ TP_SCRIPT
|
||||||
values.push(v)
|
values.push(v)
|
||||||
elsif a.is_a?(DRCSizingMode)
|
elsif a.is_a?(DRCSizingMode)
|
||||||
mode = a.value
|
mode = a.value
|
||||||
|
elsif a.is_a?(DRCSizingSteps)
|
||||||
|
steps = a.value
|
||||||
|
elsif a.is_a?(DRCSizingInside)
|
||||||
|
inside = a.value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
aa = []
|
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
|
if values.size < 1
|
||||||
raise "Method requires one or two sizing values"
|
raise "Method requires one or two sizing values"
|
||||||
elsif values.size > 2
|
elsif values.size > 2
|
||||||
|
|
@ -4771,17 +4824,21 @@ TP_SCRIPT
|
||||||
aa.push(values[-1])
|
aa.push(values[-1])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if inside
|
||||||
|
aa.push(steps)
|
||||||
|
end
|
||||||
|
|
||||||
aa.push(mode)
|
aa.push(mode)
|
||||||
|
|
||||||
if :#{f} == :size && @engine.is_tiled?
|
if :#{f} == :size && @engine.is_tiled?
|
||||||
# in tiled mode, no modifying versions are available
|
# 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
|
self
|
||||||
elsif :#{f} == :size
|
elsif :#{f} == :size
|
||||||
@engine._tcmd(self.data, dist, RBA::Region, :#{f}, *aa)
|
@engine._tcmd(self.data, dist, RBA::Region, f_size, *aa)
|
||||||
self
|
self
|
||||||
else
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,22 @@ module DRC
|
||||||
end
|
end
|
||||||
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
|
# A wrapper for the edge mode value for Region#edges
|
||||||
class DRCEdgeMode
|
class DRCEdgeMode
|
||||||
attr_accessor :value
|
attr_accessor :value
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue