Skip to content

Commit

Permalink
DRC switch to exclude the kissing corner configuration (and more) (#1600
Browse files Browse the repository at this point in the history
)

* Some refactoring, introducing new configuration option for edge pair check core algorithm for zero distance handling.

* Bugfix

* Renaming for clarification of collinear edges vs. distance which is defined otherwise.

* Implemented low-level option for collinear edge handling in Edges and Region

* DRC integration of new features

* Simple test for collinear mode feature

* Updating documentation

* Experiment: extending collinear mode towards 'zero distance'

* DRC 'collinear mode' becomes 'zero distance mode'

With this change, the default implementation for kissing corners
is changed from collinear edges only to touching edges in general.

The original mode can be restored by using:

l1.space(600.nm, DRCZeroDistanceMode::new(RBA::ZeroDistanceMode::IncludeZeroDistanceWhenCollinearAndTouching)).output(103, 0)

* Adding test data

* Fixed unit tests

* Fixed unit test

* Renamed new DRC options to: without_touching_corners and without_touching_edges as this is more consistent

* Fixed GSI binding, so no internal error is thrown when generating the doc

---------

Co-authored-by: Matthias Koefferlein <[email protected]>
  • Loading branch information
klayoutmatthias and Matthias Koefferlein committed Feb 12, 2024
1 parent a170fd2 commit 0c02976
Show file tree
Hide file tree
Showing 37 changed files with 1,114 additions and 411 deletions.
70 changes: 70 additions & 0 deletions scripts/drc_lvs_doc/create_drc_samples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,37 @@ def produce(s1, s2)
run_demo gen, "input.width(1.2, square)", "drc_width3.png"
run_demo gen, "input.width(1.2, whole_edges)", "drc_width4.png"

class Gen
def produce(s1, s2)
pts = [
RBA::Point::new(0, 0),
RBA::Point::new(2000, 0),
RBA::Point::new(2000, 2000),
RBA::Point::new(0, 2000)
];
s1.insert(RBA::Polygon::new(pts))
pts = [
RBA::Point::new(2000, 2000),
RBA::Point::new(4000, 2000),
RBA::Point::new(4000, 4000),
RBA::Point::new(2000, 4000)
];
s1.insert(RBA::Polygon::new(pts))
pts = [
RBA::Point::new( 500, 4000),
RBA::Point::new(2500, 4000),
RBA::Point::new(2500, 6000),
RBA::Point::new( 500, 6000)
];
s1.insert(RBA::Polygon::new(pts))
end
end

gen = Gen::new

run_demo gen, "input.width(1.0)", "drc_width5.png"
run_demo gen, "input.width(1.0, without_touching_corners)", "drc_width6.png"

class Gen
def produce(s1, s2)
pts = [
Expand Down Expand Up @@ -381,6 +412,45 @@ def produce(s1, s2)
" one_side_allowed,\n" +
" two_opposite_sides_allowed)", "drc_separation11.png"

class Gen
def produce(s1, s2)
pts = [
RBA::Point::new(0, 0),
RBA::Point::new(2000, 0),
RBA::Point::new(2000, 1500),
RBA::Point::new(0, 1500)
];
s2.insert(RBA::Polygon::new(pts))
pts = [
RBA::Point::new(2000, 1500),
RBA::Point::new(3500, 1500),
RBA::Point::new(3500, 3500),
RBA::Point::new(2000, 3500)
];
s1.insert(RBA::Polygon::new(pts))
pts = [
RBA::Point::new(1000, 3500),
RBA::Point::new(3000, 3500),
RBA::Point::new(3000, 5000),
RBA::Point::new(1000, 5000)
];
s2.insert(RBA::Polygon::new(pts))
pts = [
RBA::Point::new(1000, 5500),
RBA::Point::new(3000, 5500),
RBA::Point::new(3000, 7000),
RBA::Point::new(1000, 7000)
];
s1.insert(RBA::Polygon::new(pts))
end
end

gen = Gen::new

run_demo gen, "input1.sep(input2, 1.0)", "drc_separation12.png"
run_demo gen, "input1.sep(input2, 1.0, without_touching_corners)", "drc_separation13.png"
run_demo gen, "input1.sep(input2, 1.0, without_touching_edges)", "drc_separation14.png"

# ...

class Gen
Expand Down
7 changes: 1 addition & 6 deletions src/db/db/dbAsIfFlatEdges.cc
Original file line number Diff line number Diff line change
Expand Up @@ -761,12 +761,7 @@ AsIfFlatEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Co
}
}

EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d, options);

edge2edge_check_for_edges<db::FlatEdgePairs> edge_check (check, *result, other != 0);
scanner.process (edge_check, d, db::box_convert<db::Edge> ());
Expand Down
14 changes: 2 additions & 12 deletions src/db/db/dbAsIfFlatRegion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1139,12 +1139,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
db::RegionIterator polygons (needs_merged_primary ? begin_merged () : begin ());
bool primary_is_merged = ! merged_semantics () || needs_merged_primary || is_merged ();

EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d, options);

std::vector<db::RegionIterator> others;
std::vector<bool> foreign;
Expand Down Expand Up @@ -1217,12 +1212,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord
std::unique_ptr<FlatEdgePairs> result (new FlatEdgePairs ());
db::PropertyMapper pm (result->properties_repository (), properties_repository ());

EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d, options);

for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {

Expand Down
24 changes: 3 additions & 21 deletions src/db/db/dbCompoundOperation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1625,36 +1625,24 @@ CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundR
// ---------------------------------------------------------------------------------------------

CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
: CompoundRegionMultiInputOperationNode (), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
{
set_description ("check");

m_check.set_include_zero (false);
m_check.set_whole_edges (options.whole_edges);
m_check.set_ignore_angle (options.ignore_angle);
m_check.set_min_projection (options.min_projection);
m_check.set_max_projection (options.max_projection);
}

CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
: CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
{
set_description ("check");

// force different polygons in the different properties case to skip intra-polygon checks
if (pc_always_different (m_options.prop_constraint)) {
m_different_polygons = true;
}

m_check.set_include_zero (false);
m_check.set_whole_edges (options.whole_edges);
m_check.set_ignore_angle (options.ignore_angle);
m_check.set_min_projection (options.min_projection);
m_check.set_max_projection (options.max_projection);
}

CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options)
: CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options)
{
tl_assert (input == 0); // input is a dummy parameter

Expand All @@ -1663,12 +1651,6 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
m_is_other_merged = other->is_merged ();

set_description ("check");

m_check.set_include_zero (false);
m_check.set_whole_edges (options.whole_edges);
m_check.set_ignore_angle (options.ignore_angle);
m_check.set_min_projection (options.min_projection);
m_check.set_max_projection (options.max_projection);
}

db::OnEmptyIntruderHint
Expand Down
7 changes: 1 addition & 6 deletions src/db/db/dbDeepEdges.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2046,12 +2046,7 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord

const db::DeepLayer &edges = merged_deep_layer ();

EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d, options);

std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (edges.derived ()));

Expand Down
14 changes: 2 additions & 12 deletions src/db/db/dbDeepRegion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1940,12 +1940,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons

const db::DeepLayer &polygons = needs_merged_primary ? merged_deep_layer () : deep_layer ();

EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d, options);

std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));

Expand Down Expand Up @@ -2008,12 +2003,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c
double mag = tr.mag ();
db::Coord d_with_mag = db::coord_traits<db::Coord>::rounded (d / mag);

EdgeRelationFilter check (rel, d_with_mag, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
EdgeRelationFilter check (rel, d_with_mag, options);

const db::Shapes &shapes = c->shapes (polygons.layer ());
db::Shapes &result = c->shapes (res->deep_layer ().layer ());
Expand Down
Loading

0 comments on commit 0c02976

Please sign in to comment.