Hierarchical implementation DRC functions (measurements)

This commit is contained in:
Matthias Koefferlein 2019-02-16 22:34:36 +01:00
parent 5a994fef6d
commit 5dc833970b
6 changed files with 181 additions and 44 deletions

View File

@ -716,14 +716,14 @@ DeepRegion::to_string (size_t nmax) const
EdgePairs
DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
{
// NOTE: snap be optimized by forming grid variants etc.
// TODO: snap be optimized by forming grid variants etc.
return db::AsIfFlatRegion::grid_check (gx, gy);
}
EdgePairs
DeepRegion::angle_check (double min, double max, bool inverse) const
{
// NOTE: snap be optimized by forming rotation variants etc.
// TODO: snap be optimized by forming rotation variants etc.
return db::AsIfFlatRegion::angle_check (min, max, inverse);
}
@ -1241,41 +1241,63 @@ class CheckLocalOperation
: public local_operation<db::PolygonRef, db::PolygonRef, db::EdgePair>
{
public:
CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons)
: m_check (check), m_different_polygons (different_polygons)
CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons, bool has_other)
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other)
{
// .. nothing yet ..
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::EdgePair> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (m_check, result, false, false);
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_different_polygons, m_has_other);
poly2poly_check<std::unordered_set<db::EdgePair> > poly_check (edge_check);
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
}
}
size_t n = 0;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i, ++n) {
const db::PolygonRef &subject = interactions.subject_shape (i->first);
db::Polygon poly = subject.obj ().transformed (subject.trans ());
poly_check.enter (poly, n);
n += 2;
}
n = 1;
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
db::Polygon poly = o->obj ().transformed (o->trans ());
poly_check.enter (poly, n);
n += 2;
}
std::list<db::Polygon> heap;
db::box_scanner<db::Polygon, size_t> scanner;
if (m_has_other) {
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
}
}
size_t n = 0;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::PolygonRef &subject = interactions.subject_shape (i->first);
heap.push_back (subject.obj ().transformed (subject.trans ()));
scanner.insert (& heap.back (), n);
n += 2;
}
n = 1;
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
heap.push_back (o->obj ().transformed (o->trans ()));
scanner.insert (& heap.back (), n);
n += 2;
}
} else {
std::set<db::PolygonRef> polygons;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
polygons.insert (interactions.subject_shape (i->first));
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
polygons.insert (interactions.intruder_shape (*j));
}
}
size_t n = 0;
for (std::set<db::PolygonRef>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
heap.push_back (o->obj ().transformed (o->trans ()));
scanner.insert (& heap.back (), n);
n += 2;
}
}
do {
scanner.process (poly_check, m_check.distance (), db::box_convert<db::Polygon> ());
} while (edge_check.prepare_next_pass ());
@ -1283,7 +1305,7 @@ public:
virtual db::Coord dist () const
{
// TODO: will the distance be sufficient? Or should be take somewhat more?
// TODO: will the distance be sufficient? Or should we take somewhat more?
return m_check.distance ();
}
@ -1300,6 +1322,7 @@ public:
private:
EdgeRelationFilter m_check;
bool m_different_polygons;
bool m_has_other;
};
}
@ -1307,9 +1330,12 @@ private:
EdgePairs
DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const
{
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
if (! other_deep) {
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection);
const db::DeepRegion *other_deep = 0;
if (other) {
other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
if (! other_deep) {
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection);
}
}
ensure_merged_polygons_valid ();
@ -1320,16 +1346,19 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
check.set_min_projection (min_projection);
check.set_max_projection (max_projection);
DeepLayer dl_out (m_deep_layer.derived ());
std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (m_merged_polygons.derived ()));
db::CheckLocalOperation op (check, different_polygons);
db::CheckLocalOperation op (check, different_polygons, other_deep != 0);
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()),
const_cast<db::Cell *> (&m_deep_layer.initial_cell ()),
other_deep ? &other_deep->deep_layer ().layout () : const_cast<db::Layout *> (&m_deep_layer.layout ()),
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&m_deep_layer.initial_cell ()));
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
proc.set_base_verbosity (base_verbosity ());
proc.set_threads (m_deep_layer.store ()->threads ());
proc.run (&op, m_merged_polygons.layer (), other_deep->deep_layer ().layer (), dl_out.layer ());
proc.run (&op, m_merged_polygons.layer (), other_deep ? other_deep->deep_layer ().layer () : m_merged_polygons.layer (), res->deep_layer ().layer ());
return db::EdgePairs (res.release ());
}

View File

@ -274,8 +274,18 @@ public:
*
* Creates an edge pair set representing a single instance of that object
*/
template <class Sh>
explicit EdgePairs (const Sh &s)
explicit EdgePairs (const db::EdgePair &s)
: mp_delegate (0)
{
insert (s);
}
/**
* @brief Constructor from an object
*
* Creates an edge pair set representing a single instance of that object
*/
explicit EdgePairs (const db::Shape &s)
: mp_delegate (0)
{
insert (s);

View File

@ -315,10 +315,10 @@ local_processor_cell_context<TS, TI, TR>::propagate (const std::unordered_set<TR
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::EdgePair>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::EdgePair>;
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Polygon, db::Edge>;
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Polygon, db::EdgePair>;
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Edge, db::EdgePair>;
// ---------------------------------------------------------------------------------------------
// LocalProcessorCellContexts implementation
@ -1033,7 +1033,7 @@ template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef,
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::PolygonRef, db::Edge>;
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::PolygonRef, db::EdgePair>;
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::Edge, db::EdgePair>;
// ---------------------------------------------------------------------------------------------
// LocalProcessor implementation
@ -1610,10 +1610,10 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::EdgePair>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair>;
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::Edge>;
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::EdgePair>;
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::EdgePair>;
}

View File

@ -927,6 +927,92 @@ TEST(16_MergeWithMinWC)
}
}
TEST(17_SinglePolygonChecks)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
unsigned int l6 = ly.get_layer (db::LayerProperties (6, 0));
unsigned int l4 = ly.get_layer (db::LayerProperties (4, 0));
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss);
db::Region r4 (db::RecursiveShapeIterator (ly, top_cell, l4), dss);
{
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (3, 0)), r3);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (4, 0)), r4);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (6, 0)), r6);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r3.width_check (260, false, db::Euclidian, 90, 0));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r3.width_check (260, true, db::Projection, 90, 2000));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r6.notch_check (1300, false, db::Euclidian, 90, 0));
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au17.gds");
}
}
TEST(18_Checks)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
unsigned int l6 = ly.get_layer (db::LayerProperties (6, 0));
unsigned int l4 = ly.get_layer (db::LayerProperties (4, 0));
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss);
db::Region r4 (db::RecursiveShapeIterator (ly, top_cell, l4), dss);
{
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (3, 0)), r3);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (4, 0)), r4);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (6, 0)), r6);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r3.space_check (500, false, db::Projection, 90, 0));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r3.space_check (500, true, db::Projection, 90, 300));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r3.separation_check (r4, 200, false, db::Projection, 90, 0));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r6.enclosing_check (r4, 100, true, db::Projection, 90, 0));
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au18.gds");
}
}
TEST(100_Integration)
{
db::Layout ly;

View File

@ -296,7 +296,7 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
int layer = l->second.layer;
int datatype = l->second.datatype;
db::ShapeIterator shape (cref.shapes (l->first).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Texts));
db::ShapeIterator shape (cref.shapes (l->first).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::EdgePairs | db::ShapeIterator::Paths | db::ShapeIterator::Texts));
while (! shape.at_end ()) {
progress_checkpoint ();
@ -307,6 +307,9 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
write_polygon (layer, datatype, sf, *shape, multi_xy, max_vertex_count, layout, shape->prop_id ());
} else if (shape->is_edge ()) {
write_edge (layer, datatype, sf, *shape, layout, shape->prop_id ());
} else if (shape->is_edge_pair ()) {
write_edge (layer, datatype, sf, shape->edge_pair ().first (), layout, shape->prop_id ());
write_edge (layer, datatype, sf, shape->edge_pair ().second (), layout, shape->prop_id ());
} else if (shape->is_path ()) {
if (no_zero_length_paths && (shape->path_length () - shape->path_extensions ().first - shape->path_extensions ().second) == 0) {
// eliminate the zero-width path
@ -580,8 +583,12 @@ GDS2WriterBase::write_path (int layer, int datatype, double sf, const db::Shape
void
GDS2WriterBase::write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id)
{
db::Edge e (shape.edge ());
write_edge (layer, datatype, sf, shape.edge (), layout, prop_id);
}
void
GDS2WriterBase::write_edge (int layer, int datatype, double sf, const db::Edge &e, const db::Layout &layout, db::properties_id_type prop_id)
{
write_record_size (4);
write_record (sPATH);

View File

@ -134,6 +134,11 @@ protected:
*/
void write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id);
/**
* @brief Writes an edge
*/
void write_edge (int layer, int datatype, double sf, const db::Edge &edge, const db::Layout &layout, db::properties_id_type prop_id);
/**
* @brief Write a shape as path
*/