mirror of https://github.com/KLayout/klayout.git
WIP: DRC properties constraints now need explicit generation of output properties.
This commit is contained in:
parent
9b64224cb4
commit
38808fccf7
|
|
@ -1017,7 +1017,7 @@ EdgePairsDelegate *
|
|||
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||
{
|
||||
std::unique_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
|
||||
} else {
|
||||
region_cop_with_properties_impl<db::EdgePair> (this, &output->raw_edge_pairs (), output->properties_repository (), node, prop_constraint);
|
||||
|
|
@ -1029,7 +1029,7 @@ RegionDelegate *
|
|||
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||
{
|
||||
std::unique_ptr<FlatRegion> output (new FlatRegion ());
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
|
||||
} else {
|
||||
region_cop_with_properties_impl<db::Polygon> (this, &output->raw_polygons (), output->properties_repository (), node, prop_constraint);
|
||||
|
|
@ -1041,7 +1041,7 @@ EdgesDelegate *
|
|||
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint)
|
||||
{
|
||||
std::unique_ptr<FlatEdges> output (new FlatEdges ());
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
|
||||
} else {
|
||||
region_cop_with_properties_impl<db::Edge> (this, &output->raw_edges (), output->properties_repository (), node, prop_constraint);
|
||||
|
|
@ -1113,7 +1113,7 @@ EdgePairsDelegate *
|
|||
AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const
|
||||
{
|
||||
// force different polygons in the different properties case to skip intra-polygon checks
|
||||
if (options.prop_constraint == DifferentPropertiesConstraint) {
|
||||
if (pc_always_different (options.prop_constraint)) {
|
||||
different_polygons = true;
|
||||
}
|
||||
|
||||
|
|
@ -1159,7 +1159,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
|||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_edge_pairs ());
|
||||
|
||||
if (options.prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (options.prop_constraint)) {
|
||||
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options);
|
||||
|
||||
|
|
@ -1209,7 +1209,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord
|
|||
|
||||
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : pm (p.prop_id ()));
|
||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : pm (p.prop_id ()));
|
||||
poly2poly_check<db::Polygon> poly_check (edge_check);
|
||||
|
||||
do {
|
||||
|
|
@ -1364,7 +1364,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
|||
// Nothing to do
|
||||
return new EmptyRegion ();
|
||||
|
||||
} else if (property_constraint == db::IgnoreProperties && is_box () && other.is_box ()) {
|
||||
} else if (pc_skip (property_constraint) && is_box () && other.is_box ()) {
|
||||
|
||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||
|
||||
|
|
@ -1373,7 +1373,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
|||
b &= other.bbox ();
|
||||
return region_from_box (b);
|
||||
|
||||
} else if (property_constraint == db::IgnoreProperties && is_box () && ! other.strict_handling ()) {
|
||||
} else if (pc_skip (property_constraint) && is_box () && ! other.strict_handling ()) {
|
||||
|
||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||
|
||||
|
|
@ -1390,7 +1390,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
|||
|
||||
return new_region.release ();
|
||||
|
||||
} else if (property_constraint == db::IgnoreProperties && other.is_box () && ! strict_handling ()) {
|
||||
} else if (pc_skip (property_constraint) && other.is_box () && ! strict_handling ()) {
|
||||
|
||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||
|
||||
|
|
@ -1443,7 +1443,7 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const
|
|||
RegionDelegate *
|
||||
AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const
|
||||
{
|
||||
if (property_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (property_constraint)) {
|
||||
|
||||
// Generic case
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
|
|
@ -1520,7 +1520,7 @@ AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_co
|
|||
// Nothing to do
|
||||
return std::make_pair (new EmptyRegion (), clone ());
|
||||
|
||||
} else if (property_constraint == db::IgnoreProperties) {
|
||||
} else if (pc_skip (property_constraint)) {
|
||||
|
||||
// Generic case
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
|
|
|
|||
|
|
@ -1549,7 +1549,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
|
|||
set_description ("check");
|
||||
|
||||
// force different polygons in the different properties case to skip intra-polygon checks
|
||||
if (m_options.prop_constraint == DifferentPropertiesConstraint) {
|
||||
if (pc_always_different (m_options.prop_constraint)) {
|
||||
m_different_polygons = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1658,7 +1658,7 @@ protected:
|
|||
|
||||
for (size_t n = 0; n < results.size (); ++n) {
|
||||
for (auto i = results_wo_props [n].begin (); i != results_wo_props [n].end (); ++i) {
|
||||
results [n].insert (db::object_with_properties<TR> (*i, s2p->first));
|
||||
results [n].insert (db::object_with_properties<TR> (*i, pc_norm (m_prop_constraint, s2p->first)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -858,7 +858,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op, db::PropertyC
|
|||
{
|
||||
DeepLayer dl_out (deep_layer ().derived ());
|
||||
|
||||
if (property_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (property_constraint)) {
|
||||
|
||||
db::BoolAndOrNotLocalOperation op (and_op);
|
||||
|
||||
|
|
@ -893,7 +893,7 @@ DeepRegion::and_and_not_with (const DeepRegion *other, PropertyConstraint proper
|
|||
DeepLayer dl_out1 (deep_layer ().derived ());
|
||||
DeepLayer dl_out2 (deep_layer ().derived ());
|
||||
|
||||
if (property_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (property_constraint)) {
|
||||
|
||||
db::TwoBoolAndNotLocalOperation op;
|
||||
|
||||
|
|
@ -1840,7 +1840,7 @@ EdgePairsDelegate *
|
|||
DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||
{
|
||||
DeepEdgePairs *output = 0;
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
output = region_cop_impl<db::EdgePair, DeepEdgePairs> (this, node);
|
||||
} else {
|
||||
output = region_cop_with_properties_impl<db::EdgePair, DeepEdgePairs> (this, node, prop_constraint);
|
||||
|
|
@ -1856,7 +1856,7 @@ RegionDelegate *
|
|||
DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||
{
|
||||
DeepRegion *output = 0;
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
output = region_cop_impl<db::PolygonRef, db::DeepRegion> (this, node);
|
||||
} else {
|
||||
output = region_cop_with_properties_impl<db::PolygonRef, DeepRegion> (this, node, prop_constraint);
|
||||
|
|
@ -1872,7 +1872,7 @@ EdgesDelegate *
|
|||
DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||
{
|
||||
DeepEdges *output = 0;
|
||||
if (prop_constraint == db::IgnoreProperties) {
|
||||
if (pc_skip (prop_constraint)) {
|
||||
output = region_cop_impl<db::Edge, DeepEdges> (this, node);
|
||||
} else {
|
||||
output = region_cop_with_properties_impl<db::Edge, DeepEdges> (this, node, prop_constraint);
|
||||
|
|
@ -1894,7 +1894,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
|||
}
|
||||
|
||||
// force different polygons in the different properties case to skip intra-polygon checks
|
||||
if (options.prop_constraint == DifferentPropertiesConstraint) {
|
||||
if (pc_always_different (options.prop_constraint)) {
|
||||
different_polygons = true;
|
||||
}
|
||||
|
||||
|
|
@ -2004,7 +2004,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c
|
|||
|
||||
for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::Polygons); ! s.at_end (); ++s) {
|
||||
|
||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : s->prop_id ());
|
||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : s->prop_id ());
|
||||
poly2poly_check<db::Polygon> poly_check (edge_check);
|
||||
|
||||
db::Polygon poly;
|
||||
|
|
|
|||
|
|
@ -341,9 +341,8 @@ separate_interactions_by_properties (const shape_interactions<db::object_with_pr
|
|||
for (auto ii = i->second.begin (); ii != i->second.end (); ++ii) {
|
||||
|
||||
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
|
||||
db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmi (intruder.second.properties_id ()));
|
||||
|
||||
if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) {
|
||||
if (pc_match (property_constraint, prop_id, pmi (intruder.second.properties_id ()))) {
|
||||
s2p.second.insert (&intruder.second);
|
||||
}
|
||||
|
||||
|
|
@ -382,9 +381,8 @@ separate_interactions_to_interactions_by_properties (const shape_interactions<db
|
|||
|
||||
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
|
||||
tl_assert (intruder.first < (unsigned int) pmis.size ());
|
||||
db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmis[intruder.first] (intruder.second.properties_id ()));
|
||||
|
||||
if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) {
|
||||
if (pc_match (property_constraint, prop_id, pmis[intruder.first] (intruder.second.properties_id ()))) {
|
||||
s2p.add_interaction (i->first, *ii);
|
||||
intruder_ids.insert (*ii);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define HDR_dbPropertyConstraint
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbTypes.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -56,14 +57,74 @@ enum PropertyConstraint
|
|||
*/
|
||||
SamePropertiesConstraint = 2,
|
||||
|
||||
/**
|
||||
* @brief Shapes are processed if their properties are the same
|
||||
*
|
||||
* No properties are attached to the output.
|
||||
*/
|
||||
SamePropertiesConstraintDrop = 3,
|
||||
|
||||
/**
|
||||
* @brief Shapes are processed if their properties are different
|
||||
*
|
||||
* Properties are attached to the outputs where applicable.
|
||||
*/
|
||||
DifferentPropertiesConstraint = 3
|
||||
DifferentPropertiesConstraint = 4,
|
||||
|
||||
/**
|
||||
* @brief Shapes are processed if their properties are different
|
||||
*
|
||||
* No properties are attached to the output.
|
||||
*/
|
||||
DifferentPropertiesConstraintDrop = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns a predicate indicating whether properties need to be considered
|
||||
*/
|
||||
bool inline pc_skip (PropertyConstraint pc)
|
||||
{
|
||||
return pc == IgnoreProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a predicate indicating whether properties are always different
|
||||
*/
|
||||
bool inline pc_always_different (PropertyConstraint pc)
|
||||
{
|
||||
return pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether two properties satisfy the condition
|
||||
*/
|
||||
bool inline pc_match (PropertyConstraint pc, db::properties_id_type a, db::properties_id_type b)
|
||||
{
|
||||
if (pc == SamePropertiesConstraint || pc == SamePropertiesConstraintDrop) {
|
||||
return a == b;
|
||||
} else if (pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop) {
|
||||
return a != b;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the property can be removed on output
|
||||
*/
|
||||
bool inline pc_remove (PropertyConstraint pc)
|
||||
{
|
||||
return pc == IgnoreProperties || pc == SamePropertiesConstraintDrop || pc == DifferentPropertiesConstraintDrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a normalized property for output
|
||||
*/
|
||||
db::properties_id_type inline pc_norm (PropertyConstraint pc, db::properties_id_type prop_id)
|
||||
{
|
||||
return pc_remove (pc) ? 0 : prop_id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ check_local_operation_with_properties<TS, TI>::do_compute_local (db::Layout *lay
|
|||
}
|
||||
|
||||
for (auto r = result.begin (); r != result.end (); ++r) {
|
||||
results.front ().insert (db::EdgePairWithProperties (*r, s2p->first));
|
||||
results.front ().insert (db::EdgePairWithProperties (*r, pc_norm (check_local_operation_base<TS, TI>::m_options.prop_constraint, s2p->first)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1668,8 +1668,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
|
|||
|
||||
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
||||
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
|
||||
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
|
||||
if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) {
|
||||
shapes_by_prop.second.insert (intruder);
|
||||
}
|
||||
}
|
||||
|
|
@ -1684,7 +1683,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
|
|||
size_t p1 = 0, p2 = 1;
|
||||
|
||||
const std::set<TI> &others = p2s->second.second;
|
||||
db::properties_id_type prop_id = p2s->first;
|
||||
db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first);
|
||||
|
||||
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
||||
|
||||
|
|
@ -1857,8 +1856,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
|
|||
|
||||
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
||||
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
|
||||
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
|
||||
if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) {
|
||||
shapes_by_prop.second.insert (intruder);
|
||||
}
|
||||
}
|
||||
|
|
@ -1873,7 +1871,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
|
|||
size_t p1 = 0, p2 = 1;
|
||||
|
||||
const std::set<TR> &others = p2s->second.second;
|
||||
db::properties_id_type prop_id = p2s->first;
|
||||
db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first);
|
||||
|
||||
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
||||
|
||||
|
|
|
|||
|
|
@ -3172,10 +3172,20 @@ gsi::EnumIn<db::Region, db::PropertyConstraint> decl_Region_PropertyConstraint (
|
|||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||
"only if their user properties are the same. Properties are generated on the output shapes where applicable."
|
||||
) +
|
||||
gsi::enum_const ("SamePropertiesConstraintDrop", db::SamePropertiesConstraintDrop,
|
||||
"@brief Specifies to consider shapes only if their user properties are the same\n"
|
||||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||
"only if their user properties are the same. No properties are generated on the output shapes."
|
||||
) +
|
||||
gsi::enum_const ("DifferentPropertiesConstraint", db::DifferentPropertiesConstraint,
|
||||
"@brief Specifies to consider shapes only if their user properties are different\n"
|
||||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||
"only if their user properties are different. Properties are generated on the output shapes where applicable."
|
||||
) +
|
||||
gsi::enum_const ("DifferentPropertiesConstraintDrop", db::DifferentPropertiesConstraintDrop,
|
||||
"@brief Specifies to consider shapes only if their user properties are different\n"
|
||||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||
"only if their user properties are the same. No properties are generated on the output shapes."
|
||||
),
|
||||
"@brief This class represents the property constraint for boolean and check functions.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -267,6 +267,13 @@ module DRC
|
|||
#
|
||||
# m1m2_overlap_connected = metal1.nets.and(metal2, props_eq)
|
||||
# @/code
|
||||
#
|
||||
# "props_eq" can be combined with \props_copy. In this case, properties
|
||||
# are transferred to the output shapes and can be used in further processing:
|
||||
#
|
||||
# @code
|
||||
# m1m2_overlap_connected = metal1.nets.and(metal2, props_eq + props_copy)
|
||||
# @/code
|
||||
#
|
||||
# See also \props_ne.
|
||||
|
||||
|
|
@ -291,6 +298,13 @@ module DRC
|
|||
# m1m2_overlap_not_connected = metal1.nets.and(metal2, props_ne)
|
||||
# @/code
|
||||
#
|
||||
# "props_ne" can be combined with \props_copy. In this case, properties
|
||||
# are transferred to the output shapes and can be used in further processing:
|
||||
#
|
||||
# @code
|
||||
# m1m2_overlap_connected = metal1.nets.and(metal2, props_ne + props_copy)
|
||||
# @/code
|
||||
#
|
||||
# See also \props_eq.
|
||||
|
||||
# %DRC%
|
||||
|
|
|
|||
|
|
@ -3781,10 +3781,17 @@ CODE
|
|||
# @code
|
||||
#
|
||||
# \props_copy is a special properties constraint that does not alter the behaviour of
|
||||
# the checks, but copies the primary shape's properties to the output markers
|
||||
# (a behaviour that is implied by \props_eq and \props_ne, but not there by default).
|
||||
# the checks, but copies the primary shape's properties to the output markers.
|
||||
# This constraint is applicable to \width and \notch checks too. The effect is that
|
||||
# the original polygon's properties are copied to the error markers.
|
||||
# \props_copy can be combined with \props_eq and \props_ne to copy the original
|
||||
# shape's properties to the output too:
|
||||
#
|
||||
# @code
|
||||
# space_not_connected = metal1_nets.space(0.4.um, props_ne + props_copy)
|
||||
# space_connected = metal1_nets.space(0.4.um, props_eq + props_copy)
|
||||
# @code
|
||||
#
|
||||
|
||||
# %DRC%
|
||||
# @name space
|
||||
|
|
|
|||
|
|
@ -151,6 +151,30 @@ module DRC
|
|||
def initialize(v)
|
||||
self.value = v
|
||||
end
|
||||
def is_eq?
|
||||
self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::SamePropertiesConstraintDrop
|
||||
end
|
||||
def is_ne?
|
||||
self.value == RBA::Region::DifferentPropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraintDrop
|
||||
end
|
||||
def is_copy?
|
||||
self.value == RBA::Region::NoPropertyConstraint || self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraint
|
||||
end
|
||||
def +(other)
|
||||
other.is_a?(DRCPropertiesConstraint) || raise("'+' needs to be applied to two properties constraints (got #{other.inspect} for the second one)")
|
||||
is_eq = self.is_eq? || other.is_eq?
|
||||
is_ne = self.is_ne? || other.is_ne?
|
||||
is_copy = self.is_copy? || other.is_copy?
|
||||
if is_eq == is_ne
|
||||
DRCPropertiesConstraint::new(is_copy ? RBA::Region::NoPropertyConstraint : RBA::Region::IgnoreProperties)
|
||||
elsif is_eq
|
||||
DRCPropertiesConstraint::new(is_copy ? RBA::Region::SamePropertiesConstraint : RBA::Region::SamePropertiesConstraintDrop)
|
||||
elsif is_ne
|
||||
DRCPropertiesConstraint::new(is_copy ? RBA::Region::DifferentPropertiesConstraint : RBA::Region::DifferentPropertiesConstraintDrop)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Negative output on checks
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ l4_wp.output(16, 0)
|
|||
|
||||
# booleans with properties constraints
|
||||
|
||||
l3_wp.and(l4_wp, props_eq).output(20, 0)
|
||||
l3_wp1.and(l4_wp, props_eq).output(21, 0)
|
||||
l3_wp2as1.and(l4_wp, props_eq).output(22, 0)
|
||||
l3_nowp.and(l4_wp, props_eq).output(23, 0)
|
||||
l3_wp.and(l4_wp, props_eq + props_copy).output(20, 0)
|
||||
l3_wp1.and(l4_wp, props_eq + props_copy).output(21, 0)
|
||||
l3_wp2as1.and(l4_wp, props_eq + props_copy).output(22, 0)
|
||||
l3_nowp.and(l4_wp, props_eq + props_copy).output(23, 0)
|
||||
|
||||
l3_wp.and(l4_wp, props_ne).output(30, 0)
|
||||
l3_wp1.and(l4_wp, props_ne).output(31, 0)
|
||||
l3_wp2as1.and(l4_wp, props_ne).output(32, 0)
|
||||
l3_nowp.and(l4_wp, props_ne).output(33, 0)
|
||||
l3_wp.and(l4_wp, props_ne + props_copy).output(30, 0)
|
||||
l3_wp1.and(l4_wp, props_ne + props_copy).output(31, 0)
|
||||
l3_wp2as1.and(l4_wp, props_ne + props_copy).output(32, 0)
|
||||
l3_nowp.and(l4_wp, props_ne + props_copy).output(33, 0)
|
||||
|
||||
l3_wp.and(l4_wp, props_copy).output(40, 0)
|
||||
l3_wp1.and(l4_wp, props_copy).output(41, 0)
|
||||
|
|
@ -79,15 +79,15 @@ l1.nets("NOTEXIST", "NOTEXIST").output(113, 0)
|
|||
l1_nets = l1.nets
|
||||
|
||||
l1_nets.space(1.0.um, projection).polygons.output(200, 0)
|
||||
l1_nets.space(1.0.um, projection, props_eq).polygons.output(201, 0)
|
||||
l1_nets.space(1.0.um, projection, props_ne).polygons.output(202, 0)
|
||||
l1_nets.space(1.0.um, projection, props_eq + props_copy).polygons.output(201, 0)
|
||||
l1_nets.space(1.0.um, projection, props_ne + props_copy).polygons.output(202, 0)
|
||||
l1_nets.space(1.0.um, projection, props_copy).polygons.output(203, 0)
|
||||
l1_nets.width(1.0.um, projection).polygons.output(204, 0)
|
||||
l1_nets.width(1.0.um, projection, props_copy).polygons.output(205, 0)
|
||||
|
||||
l1_nets.drc(space(projection) < 1.0.um).polygons.output(210, 0)
|
||||
l1_nets.drc(space(projection) < 1.0.um, props_eq).polygons.output(211, 0)
|
||||
l1_nets.drc(space(projection) < 1.0.um, props_ne).polygons.output(212, 0)
|
||||
l1_nets.drc(space(projection) < 1.0.um, props_eq + props_copy).polygons.output(211, 0)
|
||||
l1_nets.drc(space(projection) < 1.0.um, props_ne + props_copy).polygons.output(212, 0)
|
||||
l1_nets.drc(space(projection) < 1.0.um, props_copy).polygons.output(213, 0)
|
||||
l1_nets.drc(width(projection) < 1.0.um).polygons.output(214, 0)
|
||||
l1_nets.drc(width(projection) < 1.0.um, props_copy).polygons.output(215, 0)
|
||||
|
|
@ -103,10 +103,10 @@ l1_nets.space(1.0.um, projection, props_copy).edges.extended_in(10.nm).output(22
|
|||
# sizing with properties
|
||||
|
||||
l1_nets_sized = l1_nets.sized(0.2.um)
|
||||
l1_nets_sized.and(l1_nets_sized, props_ne).output(300, 0) # overlap of different nets, same layer
|
||||
l1_nets_sized.and(l1_nets_sized, props_ne + props_copy).output(300, 0) # overlap of different nets, same layer
|
||||
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um)).output(310, 0)
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne).output(311, 0)
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq).output(312, 0)
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne + props_copy).output(311, 0)
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq + props_copy).output(312, 0)
|
||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_copy).output(313, 0)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue