WIP: refactoring - texts for net extractor.

This commit is contained in:
Matthias Koefferlein 2020-05-20 00:21:06 +02:00
parent 371009ba80
commit 4c13bb96a0
39 changed files with 1217 additions and 302 deletions

View File

@ -193,7 +193,8 @@ SOURCES = \
dbEmptyTexts.cc \
dbFlatTexts.cc \
dbTextsUtils.cc \
dbOriginalLayerTexts.cc
dbOriginalLayerTexts.cc \
dbNetShape.cc
HEADERS = \
dbArray.h \
@ -348,7 +349,8 @@ HEADERS = \
dbEmptyTexts.h \
dbFlatTexts.h \
dbTextsUtils.h \
dbOriginalLayerTexts.h
dbOriginalLayerTexts.h \
dbNetShape.h
!equals(HAVE_QT, "0") {

View File

@ -394,7 +394,7 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse)
scanner.reserve2 (other.size ());
std::auto_ptr<FlatRegion> output (new FlatRegion (false));
region_to_text_interaction_filter<Shapes, db::Polygon> filter (output->raw_polygons (), inverse);
region_to_text_interaction_filter<Shapes, db::Text, db::Polygon> filter (output->raw_polygons (), inverse);
AddressablePolygonDelivery p (begin_merged (), has_valid_merged_polygons ());
@ -527,7 +527,7 @@ AsIfFlatRegion::pull_generic (const Texts &other) const
scanner.reserve2 (other.size ());
std::auto_ptr<FlatTexts> output (new FlatTexts (false));
region_to_text_interaction_filter<Shapes, db::Text> filter (output->raw_texts (), false);
region_to_text_interaction_filter<Shapes, db::Text, db::Text> filter (output->raw_texts (), false);
AddressablePolygonDelivery p (begin (), has_valid_merged_polygons ());

View File

@ -312,13 +312,13 @@ AsIfFlatTexts::selected_interacting_generic (const Region &other, bool inverse)
if (! inverse) {
text_to_region_interaction_filter<FlatTexts> filter (*output);
text_to_region_interaction_filter<FlatTexts, db::Text> filter (*output);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
} else {
std::set<db::Text> interacting;
text_to_region_interaction_filter<std::set<db::Text> > filter (interacting);
text_to_region_interaction_filter<std::set<db::Text>, db::Text> filter (interacting);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
for (TextsIterator o (begin ()); ! o.at_end (); ++o) {
@ -356,7 +356,7 @@ AsIfFlatTexts::pull_generic (const Region &other) const
std::auto_ptr<FlatRegion> output (new FlatRegion (true));
text_to_region_interaction_filter<FlatRegion> filter (*output);
text_to_region_interaction_filter<FlatRegion, db::Text> filter (*output);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
return output.release ();

View File

@ -417,7 +417,7 @@ DeepEdges::ensure_merged_edges_valid () const
db::Connectivity conn;
conn.connect (m_deep_layer);
hc.set_base_verbosity (base_verbosity() + 10);
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Edges, conn);
hc.build (layout, m_deep_layer.initial_cell (), conn);
// collect the clusters and merge them into big polygons
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
@ -1077,7 +1077,7 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
db::Connectivity conn (db::Connectivity::EdgesConnectByPoints);
conn.connect (edges);
hc.set_base_verbosity (base_verbosity () + 10);
hc.build (layout, edges.initial_cell (), db::ShapeIterator::Edges, conn);
hc.build (layout, edges.initial_cell (), conn);
// TODO: iterate only over the called cells?
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {

View File

@ -455,7 +455,7 @@ DeepRegion::ensure_merged_polygons_valid () const
db::Connectivity conn;
conn.connect (m_deep_layer);
hc.set_base_verbosity (base_verbosity () + 10);
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Polygons, conn);
hc.build (layout, m_deep_layer.initial_cell (), conn);
// collect the clusters and merge them into big polygons
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
@ -1238,7 +1238,7 @@ DeepRegion::merged (bool min_coherence, unsigned int min_wc) const
db::Connectivity conn;
conn.connect (m_deep_layer);
hc.set_base_verbosity (base_verbosity () + 10);
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Polygons, conn);
hc.build (layout, m_deep_layer.initial_cell (), conn);
// collect the clusters and merge them into big polygons
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
@ -1899,25 +1899,25 @@ public:
struct TextResultInserter
{
typedef db::Text value_type;
typedef db::TextRef value_type;
TextResultInserter (std::unordered_set<db::Text> &result)
TextResultInserter (std::unordered_set<db::TextRef> &result)
: mp_result (&result)
{
// .. nothing yet ..
}
void insert (const db::Text &e)
void insert (const db::TextRef &e)
{
(*mp_result).insert (e);
}
private:
std::unordered_set<db::Text> *mp_result;
std::unordered_set<db::TextRef> *mp_result;
};
class PullWithTextLocalOperation
: public local_operation<db::PolygonRef, db::Text, db::Text>
: public local_operation<db::PolygonRef, db::TextRef, db::TextRef>
{
public:
PullWithTextLocalOperation ()
@ -1931,15 +1931,15 @@ public:
return 1;
}
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::Text> &interactions, std::unordered_set<db::Text> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner;
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
TextResultInserter inserter (result);
region_to_text_interaction_filter<TextResultInserter> filter (inserter, false);
region_to_text_interaction_filter<TextResultInserter, db::TextRef> filter (inserter, false);
for (shape_interactions<db::PolygonRef, db::Text>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::Text>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
scanner.insert2 (& interactions.intruder_shape (*j), 0);
}
}
@ -1954,7 +1954,7 @@ public:
}
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::Text> ());
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::TextRef> ());
}
virtual on_empty_intruder_mode on_empty_intruder_hint () const
@ -1969,7 +1969,7 @@ public:
};
class InteractingWithTextLocalOperation
: public local_operation<db::PolygonRef, db::Text, db::PolygonRef>
: public local_operation<db::PolygonRef, db::TextRef, db::PolygonRef>
{
public:
InteractingWithTextLocalOperation (bool inverse)
@ -1984,12 +1984,12 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::Text> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner;
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
ResultInserter inserter (layout, result);
region_to_text_interaction_filter<ResultInserter> filter (inserter, m_inverse);
region_to_text_interaction_filter<ResultInserter, db::TextRef> filter (inserter, m_inverse);
for (shape_interactions<db::PolygonRef, db::Text>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::Text>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
@ -2010,7 +2010,7 @@ public:
}
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::Text> ());
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::TextRef> ());
if (m_inverse) {
filter.fill_output ();
}
@ -2199,7 +2199,7 @@ DeepRegion::pull_generic (const Texts &other) const
db::PullWithTextLocalOperation op;
db::local_processor<db::PolygonRef, db::Text, db::Text> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_texts.layout (), &other_texts.initial_cell (), polygons.breakout_cells (), other_texts.breakout_cells ());
db::local_processor<db::PolygonRef, db::TextRef, db::TextRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_texts.layout (), &other_texts.initial_cell (), polygons.breakout_cells (), other_texts.breakout_cells ());
proc.set_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ());
proc.run (&op, polygons.layer (), other_texts.layer (), dl_out.layer ());
@ -2229,7 +2229,7 @@ DeepRegion::selected_interacting_generic (const Texts &other, bool inverse) cons
db::InteractingWithTextLocalOperation op (inverse);
db::local_processor<db::PolygonRef, db::Text, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
db::local_processor<db::PolygonRef, db::TextRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
proc.set_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ());
if (split_after) {

View File

@ -474,7 +474,7 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Texts &texts, const db::IC
db::Shapes *shapes = &initial_cell ().shapes (layer);
db::Box world = db::Box::world ();
db::TextBuildingHierarchyBuilderShapeReceiver tb;
db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout ());
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = texts.begin_iter ();
db::ICplxTrans ttop = trans * ii.second;
@ -849,7 +849,10 @@ DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterat
DeepLayer DeepShapeStore::create_text_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{
db::TextBuildingHierarchyBuilderShapeReceiver refs;
unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout;
db::TextBuildingHierarchyBuilderShapeReceiver refs (&layout);
return create_custom_layer (si, &refs, trans);
}

View File

@ -408,7 +408,7 @@ void DeepTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type int
namespace {
class Text2PolygonInteractingLocalOperation
: public local_operation<db::Text, db::PolygonRef, db::Text>
: public local_operation<db::TextRef, db::PolygonRef, db::TextRef>
{
public:
Text2PolygonInteractingLocalOperation (bool inverse)
@ -423,19 +423,19 @@ public:
return 1;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Text, db::PolygonRef> &interactions, std::unordered_set<db::Text> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner;
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Text, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
}
}
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::Text &subject = interactions.subject_shape (i->first);
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::TextRef &subject = interactions.subject_shape (i->first);
scanner.insert1 (&subject, 0);
}
@ -447,12 +447,12 @@ public:
if (m_inverse) {
std::unordered_set<db::Text> interacting;
text_to_region_interaction_filter<std::unordered_set<db::Text> > filter (interacting);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
std::unordered_set<db::TextRef> interacting;
text_to_region_interaction_filter<std::unordered_set<db::TextRef>, db::TextRef> filter (interacting);
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::Text &subject = interactions.subject_shape (i->first);
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::TextRef &subject = interactions.subject_shape (i->first);
if (interacting.find (subject) == interacting.end ()) {
result.insert (subject);
}
@ -460,8 +460,8 @@ public:
} else {
text_to_region_interaction_filter<std::unordered_set<db::Text> > filter (result);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
text_to_region_interaction_filter<std::unordered_set<db::TextRef>, db::TextRef> filter (result);
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
}
}
@ -505,7 +505,7 @@ private:
};
class Text2PolygonPullLocalOperation
: public local_operation<db::Text, db::PolygonRef, db::PolygonRef>
: public local_operation<db::TextRef, db::PolygonRef, db::PolygonRef>
{
public:
Text2PolygonPullLocalOperation ()
@ -519,19 +519,19 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Text, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner;
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Text, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
}
}
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::Text &subject = interactions.subject_shape (i->first);
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::TextRef &subject = interactions.subject_shape (i->first);
scanner.insert1 (&subject, 1);
}
@ -542,8 +542,8 @@ public:
}
ResultInserter inserter (layout, result);
text_to_region_interaction_filter<ResultInserter> filter (inserter);
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
text_to_region_interaction_filter<ResultInserter, db::TextRef> filter (inserter);
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
}
virtual on_empty_intruder_mode on_empty_intruder_hint () const
@ -576,7 +576,7 @@ DeepTexts::selected_interacting_generic (const Region &other, bool inverse) cons
db::Text2PolygonInteractingLocalOperation op (inverse);
db::local_processor<db::Text, db::PolygonRef, db::Text> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::TextRef, db::PolygonRef, db::TextRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
proc.set_base_verbosity (other.base_verbosity ());
proc.set_threads (texts.store ()->threads ());
@ -602,7 +602,7 @@ RegionDelegate *DeepTexts::pull_generic (const Region &other) const
db::Text2PolygonPullLocalOperation op;
db::local_processor<db::Text, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
db::local_processor<db::TextRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
proc.set_base_verbosity (other.base_verbosity ());
proc.set_threads (texts.store ()->threads ());

View File

@ -29,6 +29,7 @@
#include "dbPolygonTools.h"
#include "dbBoxScanner.h"
#include "dbDeepRegion.h"
#include "dbNetShape.h"
#include "tlProgress.h"
#include "tlLog.h"
#include "tlTimer.h"
@ -43,9 +44,9 @@ namespace db
// ------------------------------------------------------------------------------
template <class Container, class Shape, class Trans> void insert_transformed (db::Layout &layout, Container &shapes, const Shape &s, const Trans &t);
template <class Shape, class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const Shape &s, const Trans &t);
template <class Container, class Trans> void insert_transformed (db::Layout &layout, Container &shapes, const db::PolygonRef &s, const Trans &t)
template <class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const db::PolygonRef &s, const Trans &t)
{
db::Polygon poly = s.obj ();
poly.transform (s.trans ());
@ -55,7 +56,32 @@ template <class Container, class Trans> void insert_transformed (db::Layout &lay
shapes.insert (db::PolygonRef (poly, layout.shape_repository ()));
}
template <class Container, class Trans> void insert_transformed (db::Layout & /*layout*/, Container &shapes, const db::Edge &s, const Trans &t)
template <class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const db::NetShape &s, const Trans &t)
{
if (s.type () == db::NetShape::Polygon) {
db::PolygonRef pr = s.polygon_ref ();
db::Polygon poly = pr.obj ();
poly.transform (pr.trans ());
if (! t.is_unity ()) {
poly.transform (t);
}
shapes.insert (db::PolygonRef (poly, layout.shape_repository ()));
} else if (s.type () == db::NetShape::Text) {
db::TextRef tr = s.text_ref ();
db::Text text = tr.obj ();
text.transform (tr.trans ());
if (! t.is_unity ()) {
text.transform (t);
}
shapes.insert (db::TextRef (text, layout.shape_repository ()));
}
}
template <class Trans> void insert_transformed (db::Layout & /*layout*/, db::Shapes &shapes, const db::Edge &s, const Trans &t)
{
shapes.insert (s.transformed (t));
}
@ -237,6 +263,20 @@ interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const db::un
}
}
template <class Trans>
static bool
interaction_test (const db::NetShape &a, const db::NetShape &b, const Trans &trans, db::Connectivity::edge_connectivity_type)
{
return a.interacts_with_transformed (b, trans);
}
template <class C>
static bool
interaction_test (const db::NetShape &a, const db::NetShape &b, const db::unit_trans<C> &, db::Connectivity::edge_connectivity_type)
{
return a.interacts_with (b);
}
template <class Trans>
static bool
interaction_test (const db::Edge &a, const db::Edge &b, const Trans &trans, db::Connectivity::edge_connectivity_type ec)
@ -272,6 +312,8 @@ bool Connectivity::interacts (const T &a, unsigned int la, const T &b, unsigned
}
// explicit instantiations
template DB_PUBLIC bool Connectivity::interacts<db::NetShape> (const db::NetShape &a, unsigned int la, const db::NetShape &b, unsigned int lb, const db::UnitTrans &trans) const;
template DB_PUBLIC bool Connectivity::interacts<db::NetShape> (const db::NetShape &a, unsigned int la, const db::NetShape &b, unsigned int lb, const db::ICplxTrans &trans) const;
template DB_PUBLIC bool Connectivity::interacts<db::PolygonRef> (const db::PolygonRef &a, unsigned int la, const db::PolygonRef &b, unsigned int lb, const db::UnitTrans &trans) const;
template DB_PUBLIC bool Connectivity::interacts<db::PolygonRef> (const db::PolygonRef &a, unsigned int la, const db::PolygonRef &b, unsigned int lb, const db::ICplxTrans &trans) const;
template DB_PUBLIC bool Connectivity::interacts<db::Edge> (const db::Edge &a, unsigned int la, const db::Edge &b, unsigned int lb, const db::UnitTrans &trans) const;
@ -630,8 +672,10 @@ size_t local_cluster<T>::split (double max_area_ratio, Iter &output) const
}
// explicit instantiations
template class DB_PUBLIC local_cluster<db::NetShape>;
template class DB_PUBLIC local_cluster<db::PolygonRef>;
template class DB_PUBLIC local_cluster<db::Edge>;
template DB_PUBLIC size_t local_cluster<db::NetShape>::split<std::back_insert_iterator<std::list<local_cluster<db::NetShape> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::NetShape> > > &) const;
template DB_PUBLIC size_t local_cluster<db::PolygonRef>::split<std::back_insert_iterator<std::list<local_cluster<db::PolygonRef> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::PolygonRef> > > &) const;
template DB_PUBLIC size_t local_cluster<db::Edge>::split<std::back_insert_iterator<std::list<local_cluster<db::Edge> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::Edge> > > &) const;
@ -886,22 +930,112 @@ private:
}
};
template <class T>
struct addressable_shape_delivery
{
const T *operator () (const db::Shape &shape)
{
typename T::tag object_tag;
return shape.basic_ptr (object_tag);
}
};
template <>
struct addressable_shape_delivery<db::NetShape>
{
const NetShape *operator () (const db::Shape &shape)
{
if (shape.type () == db::Shape::TextRef) {
m_heap.push_back (db::NetShape (shape.text_ref ()));
return &m_heap.back ();
} else if (shape.type () == db::Shape::PolygonRef) {
m_heap.push_back (db::NetShape (shape.polygon_ref ()));
return &m_heap.back ();
} else {
tl_assert (false);
}
}
private:
std::list<NetShape> m_heap;
};
template <class T>
struct attr_accessor
{
size_t operator() (const db::Shape &shape) const
{
return shape.prop_id ();
}
};
template <>
struct attr_accessor<db::NetShape>
{
size_t operator() (const db::Shape &shape) const
{
// NOTE: the attribute is
// * odd: a StringRef pointer's value
// * even: a Property ID times 2
if (shape.type () == db::Shape::TextRef) {
return db::text_ref_to_attr (&shape.text_ref ().obj ());
} else {
return db::prop_id_to_attr (shape.prop_id ());
}
}
};
template <class T> struct get_shape_flags { };
template <>
struct get_shape_flags<db::Edge>
{
db::ShapeIterator::flags_type operator() (bool /*with_attr*/) const
{
return db::ShapeIterator::Edges;
}
};
template <>
struct get_shape_flags<db::PolygonRef>
{
db::ShapeIterator::flags_type operator() (bool /*with_attr*/) const
{
return db::ShapeIterator::Polygons;
}
};
template <>
struct get_shape_flags<db::NetShape>
{
db::ShapeIterator::flags_type operator() (bool with_attr) const
{
if (with_attr) {
return db::ShapeIterator::flags_type (db::ShapeIterator::Polygons | db::ShapeIterator::Texts);
} else {
return db::ShapeIterator::flags_type (db::ShapeIterator::Polygons);
}
}
};
}
template <class T>
void
local_clusters<T>::build_clusters (const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, bool report_progress)
local_clusters<T>::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool report_progress)
{
static std::string desc = tl::to_string (tr ("Building local clusters"));
db::box_scanner<T, std::pair<unsigned int, unsigned int> > bs (report_progress, desc);
typename T::tag object_tag;
db::box_scanner<T, std::pair<unsigned int, size_t> > bs (report_progress, desc);
db::box_convert<T> bc;
addressable_shape_delivery<T> heap;
attr_accessor<T> attr;
db::ShapeIterator::flags_type shape_flags = get_shape_flags<T> () (attr_equivalence != 0 /*with attributes*/);
for (db::Connectivity::layer_iterator l = conn.begin_layers (); l != conn.end_layers (); ++l) {
const db::Shapes &shapes = cell.shapes (*l);
for (db::Shapes::shape_iterator s = shapes.begin (shape_flags); ! s.at_end (); ++s) {
bs.insert (s->basic_ptr (object_tag), std::make_pair (*l, (unsigned int) s->prop_id ()));
bs.insert (heap (*s), std::make_pair (*l, attr (*s)));
}
}
@ -916,9 +1050,9 @@ local_clusters<T>::build_clusters (const db::Cell &cell, db::ShapeIterator::flag
template <class T>
void
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsigned int> &attr_equivalence)
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence)
{
tl::equivalence_clusters<unsigned int> eq;
tl::equivalence_clusters<size_t> eq;
// collect all local attributes (the ones which are present in attr_equivalence) into "eq"
// and form equivalences for multi-attribute clusters.
@ -939,18 +1073,18 @@ local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsig
// identify the layout clusters joined into one attribute cluster and join them
std::map<tl::equivalence_clusters<unsigned int>::cluster_id_type, std::set<size_t> > c2c;
std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> > c2c;
for (const_iterator c = begin (); c != end (); ++c) {
for (typename local_cluster<T>::attr_iterator a = c->begin_attr (); a != c->end_attr (); ++a) {
tl::equivalence_clusters<unsigned int>::cluster_id_type cl = attr_equivalence.cluster_id (*a);
tl::equivalence_clusters<size_t>::cluster_id_type cl = attr_equivalence.cluster_id (*a);
if (cl > 0) {
c2c [cl].insert (c->id ());
}
}
}
for (std::map<tl::equivalence_clusters<unsigned int>::cluster_id_type, std::set<size_t> >::const_iterator c = c2c.begin (); c != c2c.end (); ++c) {
for (std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> >::const_iterator c = c2c.begin (); c != c2c.end (); ++c) {
if (c->second.size () > 1) {
std::set<size_t>::const_iterator cl0 = c->second.begin ();
std::set<size_t>::const_iterator cl = cl0;
@ -962,6 +1096,7 @@ local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsig
}
// explicit instantiations
template class DB_PUBLIC local_clusters<db::NetShape>;
template class DB_PUBLIC local_clusters<db::PolygonRef>;
template class DB_PUBLIC local_clusters<db::Edge>;
@ -984,6 +1119,7 @@ connected_clusters_iterator<T>::connected_clusters_iterator (const connected_clu
}
// explicit instantiations
template class DB_PUBLIC connected_clusters_iterator<db::NetShape>;
template class DB_PUBLIC connected_clusters_iterator<db::PolygonRef>;
template class DB_PUBLIC connected_clusters_iterator<db::Edge>;
@ -1053,6 +1189,7 @@ connected_clusters<T>::find_cluster_with_connection (const ClusterInstance &inst
}
// explicit instantiations
template class DB_PUBLIC connected_clusters<db::NetShape>;
template class DB_PUBLIC connected_clusters<db::PolygonRef>;
template class DB_PUBLIC connected_clusters<db::Edge>;
@ -1133,11 +1270,11 @@ void hier_clusters<T>::clear ()
template <class T>
void
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
{
clear ();
cell_clusters_box_converter<T> cbc (layout, *this);
do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence, breakout_cells);
do_build (cbc, layout, cell, conn, attr_equivalence, breakout_cells);
}
namespace
@ -1939,7 +2076,7 @@ hier_clusters<T>::propagate_cluster_inst (const db::Layout &layout, const db::Ce
template <class T>
void
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
{
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters")));
@ -1957,8 +2094,8 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
// look for the net label joining spec - for the top cell the "top_cell_index" entry is looked for.
// If there is no such entry or the cell is not the top cell, look for the entry by cell index.
std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> >::const_iterator ae;
const tl::equivalence_clusters<unsigned int> *ec = 0;
std::map<db::cell_index_type, tl::equivalence_clusters<size_t> >::const_iterator ae;
const tl::equivalence_clusters<size_t> *ec = 0;
if (attr_equivalence) {
if (*c == cell.cell_index ()) {
ae = attr_equivalence->find (top_cell_index);
@ -1974,7 +2111,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
}
}
build_local_cluster (layout, layout.cell (*c), shape_flags, conn, ec);
build_local_cluster (layout, layout.cell (*c), conn, ec);
++progress;
@ -2021,7 +2158,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
template <class T>
void
hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence)
hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence)
{
std::string msg = tl::to_string (tr ("Computing local clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ()));
if (tl::verbosity () >= m_base_verbosity + 20) {
@ -2030,7 +2167,7 @@ hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 20, msg);
connected_clusters<T> &local = m_per_cell_clusters [cell.cell_index ()];
local.build_clusters (cell, shape_flags, conn, attr_equivalence, true);
local.build_clusters (cell, conn, attr_equivalence, true);
}
template <class T>
@ -2336,6 +2473,7 @@ hier_clusters<T>::return_to_hierarchy (db::Layout &layout, const std::map<unsign
}
// explicit instantiations
template class DB_PUBLIC hier_clusters<db::NetShape>;
template class DB_PUBLIC hier_clusters<db::PolygonRef>;
template class DB_PUBLIC hier_clusters<db::Edge>;
@ -2460,6 +2598,7 @@ void recursive_cluster_shape_iterator<T>::down (db::cell_index_type ci, typename
}
// explicit instantiations
template class DB_PUBLIC recursive_cluster_shape_iterator<db::NetShape>;
template class DB_PUBLIC recursive_cluster_shape_iterator<db::PolygonRef>;
template class DB_PUBLIC recursive_cluster_shape_iterator<db::Edge>;
@ -2533,6 +2672,7 @@ void recursive_cluster_iterator<T>::down (db::cell_index_type ci, typename db::l
}
// explicit instantiations
template class DB_PUBLIC recursive_cluster_iterator<db::NetShape>;
template class DB_PUBLIC recursive_cluster_iterator<db::PolygonRef>;
template class DB_PUBLIC recursive_cluster_iterator<db::Edge>;
@ -2614,6 +2754,7 @@ incoming_cluster_connections<T>::ensure_computed_parent (db::cell_index_type ci)
}
// explicit instantiations
template class DB_PUBLIC incoming_cluster_connections<db::NetShape>;
template class DB_PUBLIC incoming_cluster_connections<db::PolygonRef>;
template class DB_PUBLIC incoming_cluster_connections<db::Edge>;

View File

@ -505,7 +505,7 @@ public:
* cluster joining may happen in this case, because multi-attribute
* assignment might create connections too.
*/
void build_clusters (const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence = 0, bool report_progress = false);
void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence = 0, bool report_progress = false);
/**
* @brief Creates and inserts a new clusters
@ -540,7 +540,7 @@ private:
tree_type m_clusters;
size_t m_next_dummy_id;
void apply_attr_equivalences (const tl::equivalence_clusters<unsigned int> &attr_equivalence);
void apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence);
};
/**
@ -998,7 +998,7 @@ public:
/**
* @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity
*/
void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0);
void build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0);
/**
* @brief Gets the connected clusters for a given cell
@ -1036,10 +1036,10 @@ public:
size_t propagate_cluster_inst (const db::Layout &layout, const Cell &cell, const ClusterInstance &ci, db::cell_index_type parent_ci, bool with_self);
private:
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence);
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence);
void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, instance_interaction_cache_type &instance_interaction_cache);
void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache);
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells);
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells);
std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
int m_base_verbosity;
@ -1335,6 +1335,39 @@ private:
void ensure_computed_parent (db::cell_index_type ci) const;
};
/**
* @brief A helper function generating an attribute ID from a property ID
* This function is used to provide a generic attribute wrapping a property ID and a text ID.
*/
inline size_t prop_id_to_attr (db::properties_id_type id)
{
return size_t (id) * 2;
}
/**
* @brief Gets a value indicating whether the attribute is a property ID
*/
inline bool is_prop_id_attr (size_t attr)
{
return (attr & 1) == 0;
}
/**
* @brief Gets the property ID from an attribute
*/
inline db::properties_id_type prop_id_from_attr (size_t attr)
{
return attr / 2;
}
/**
* @brief A helper function generating an attribute from a StringRef
*/
inline size_t text_ref_to_attr (const db::Text *tr)
{
return size_t (tr) * 2 + 1;
}
}
#endif

View File

@ -157,29 +157,6 @@ public:
}
};
template <>
class shape_reference_translator<db::Text>
{
public:
typedef db::Text shape_type;
shape_reference_translator (db::Layout * /*target_layout*/)
{
// .. nothing yet ..
}
const shape_type &operator() (const shape_type &s) const
{
return s;
}
template <class Trans>
shape_type operator() (const shape_type &s, const Trans &tr) const
{
return s.transformed (tr);
}
};
template <class Ref, class Trans>
class shape_reference_translator_with_trans_from_shape_ref
{
@ -656,11 +633,11 @@ shape_interactions<TS, TI>::intruder_shape (unsigned int id) const
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::Edge>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::Text>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::TextRef>;
template class DB_PUBLIC shape_interactions<db::Edge, db::Edge>;
template class DB_PUBLIC shape_interactions<db::Edge, db::PolygonRef>;
template class DB_PUBLIC shape_interactions<db::Text, db::Text>;
template class DB_PUBLIC shape_interactions<db::Text, db::PolygonRef>;
template class DB_PUBLIC shape_interactions<db::TextRef, db::TextRef>;
template class DB_PUBLIC shape_interactions<db::TextRef, db::PolygonRef>;
// ---------------------------------------------------------------------------------------------
// Helper classes for the LocalProcessor
@ -683,7 +660,7 @@ inline unsigned int shape_flags<db::Edge> ()
}
template <>
inline unsigned int shape_flags<db::Text> ()
inline unsigned int shape_flags<db::TextRef> ()
{
return db::ShapeIterator::Texts;
}
@ -1780,15 +1757,15 @@ 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::Edge>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Text, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Text, db::Text>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::TextRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::TextRef, db::TextRef>;
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::PolygonRef>;
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::EdgePair>;
template class DB_PUBLIC local_processor<db::Text, db::PolygonRef, db::Text>;
template class DB_PUBLIC local_processor<db::Text, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::TextRef, db::PolygonRef, db::TextRef>;
template class DB_PUBLIC local_processor<db::TextRef, db::PolygonRef, db::PolygonRef>;
}

View File

@ -706,7 +706,8 @@ void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape
// ---------------------------------------------------------------------------------------------
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver ()
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout)
: mp_layout (layout)
{
// .. nothing yet ..
}
@ -714,10 +715,10 @@ TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeRece
void TextBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
{
if (shape.is_text ()) {
db::Text t;
shape.text (t);
t.transform (trans);
target->insert (t);
// NOTE: we intentionally skip all the text attributes (font etc.) here because in the context
// of a text collections we're only interested in the locations.
db::Text t (shape.text_string (), shape.text_trans ());
target->insert (db::TextRef (t.transformed (trans), mp_layout->shape_repository ()));
}
}

View File

@ -196,11 +196,14 @@ class DB_PUBLIC TextBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
TextBuildingHierarchyBuilderShapeReceiver ();
TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout);
virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
virtual void push (const db::Polygon &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
private:
db::Layout *mp_layout;
};
/**

View File

@ -558,6 +558,14 @@ public:
return m_string_repository;
}
/**
* @brief Accessor to the string repository (const version)
*/
const StringRepository &string_repository () const
{
return m_string_repository;
}
/**
* @brief Accessor to the shape repository
*/
@ -566,6 +574,14 @@ public:
return m_shape_repository;
}
/**
* @brief Accessor to the shape repository (const version)
*/
const GenericRepository &shape_repository () const
{
return m_shape_repository;
}
/**
* @brief Accessor to the properties repository
*/

View File

@ -206,7 +206,7 @@ void LayoutToNetlist::link_nets (const db::Net *net, const db::Net *with)
return;
}
connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (net->circuit ()->cell_index ());
connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (net->circuit ()->cell_index ());
clusters.join_cluster_with (net->cluster_id (), with->cluster_id ());
}
@ -221,7 +221,7 @@ size_t LayoutToNetlist::link_net_to_parent_circuit (const Net *subcircuit_net, C
db::CplxTrans dbu_trans (internal_layout ()->dbu ());
db::ICplxTrans trans = dbu_trans.inverted () * dtrans * dbu_trans;
connected_clusters<db::PolygonRef> &parent_net_clusters = m_net_clusters.clusters_per_cell (parent_circuit->cell_index ());
connected_clusters<db::NetShape> &parent_net_clusters = m_net_clusters.clusters_per_cell (parent_circuit->cell_index ());
size_t id = parent_net_clusters.insert_dummy ();
@ -613,49 +613,84 @@ namespace
}
template <class Tr>
static bool deliver_shape (const db::PolygonRef &, StopOnFirst, const Tr &, db::properties_id_type)
static bool deliver_shape (const db::NetShape &, StopOnFirst, const Tr &, db::properties_id_type)
{
return false;
}
template <class Tr>
static bool deliver_shape (const db::PolygonRef &pr, db::Region &region, const Tr &tr, db::properties_id_type /*propid*/)
static bool deliver_shape (const db::NetShape &s, db::Region &region, const Tr &tr, db::properties_id_type /*propid*/)
{
if (pr.obj ().is_box ()) {
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
} else {
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
if (s.type () == db::NetShape::Polygon) {
db::PolygonRef pr = s.polygon_ref ();
if (pr.obj ().is_box ()) {
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
} else {
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
}
}
return true;
}
template <class Tr>
static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr, db::properties_id_type propid)
static bool deliver_shape (const db::NetShape &s, db::Shapes &shapes, const Tr &tr, db::properties_id_type propid)
{
if (pr.obj ().is_box ()) {
if (propid) {
shapes.insert (db::BoxWithProperties (pr.obj ().box ().transformed (pr.trans ()).transformed (tr), propid));
if (s.type () == db::NetShape::Polygon) {
db::PolygonRef pr = s.polygon_ref ();
if (pr.obj ().is_box ()) {
if (propid) {
shapes.insert (db::BoxWithProperties (pr.obj ().box ().transformed (pr.trans ()).transformed (tr), propid));
} else {
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
}
} else {
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
db::Layout *layout = shapes.layout ();
if (layout) {
db::PolygonRef polygon_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
if (propid) {
shapes.insert (db::PolygonRefWithProperties (polygon_ref, propid));
} else {
shapes.insert (polygon_ref);
}
} else {
db::Polygon polygon (pr.obj ().transformed (pr.trans ()).transformed (tr));
if (propid) {
shapes.insert (db::PolygonWithProperties (polygon, propid));
} else {
shapes.insert (polygon);
}
}
}
} else {
} else if (s.type () == db::NetShape::Text) {
db::TextRef pr = s.text_ref ();
db::Layout *layout = shapes.layout ();
if (layout) {
db::PolygonRef polygon_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
db::TextRef text_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
if (propid) {
shapes.insert (db::PolygonRefWithProperties (polygon_ref, propid));
shapes.insert (db::TextRefWithProperties (text_ref, propid));
} else {
shapes.insert (polygon_ref);
shapes.insert (text_ref);
}
} else {
db::Polygon polygon (pr.obj ().transformed (pr.trans ()).transformed (tr));
db::Text text (pr.obj ().transformed (pr.trans ()).transformed (tr));
if (propid) {
shapes.insert (db::PolygonWithProperties (polygon, propid));
shapes.insert (db::TextWithProperties (text, propid));
} else {
shapes.insert (polygon);
shapes.insert (text);
}
}
}
return true;
}
@ -759,7 +794,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
if (net_cell_name_prefix) {
const db::connected_clusters<db::PolygonRef> &ccl = m_net_clusters.clusters_per_cell (ci);
const db::connected_clusters<db::NetShape> &ccl = m_net_clusters.clusters_per_cell (ci);
bool any_connections = circuit_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty ();
if (! any_connections) {
@ -805,8 +840,8 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
db::ICplxTrans tr_wo_mag = tr * db::ICplxTrans (1.0 / tr.mag ());
db::ICplxTrans tr_mag (tr.mag ());
const db::connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (ci);
typedef db::connected_clusters<db::PolygonRef>::connections_type connections_type;
const db::connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (ci);
typedef db::connected_clusters<db::NetShape>::connections_type connections_type;
const connections_type &connections = clusters.connections_for_cluster (cid);
for (connections_type::const_iterator c = connections.begin (); c != connections.end (); ++c) {
@ -1007,13 +1042,13 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::DPoi
return probe_net (of_region, db::CplxTrans (internal_layout ()->dbu ()).inverted () * point);
}
size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path)
size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::NetShape> &test_cluster, std::vector<db::InstElement> &rev_inst_path)
{
db::Box local_box = trans * test_cluster.bbox ();
const db::local_clusters<db::PolygonRef> &lcc = net_clusters ().clusters_per_cell (cell->cell_index ());
for (db::local_clusters<db::PolygonRef>::touching_iterator i = lcc.begin_touching (local_box); ! i.at_end (); ++i) {
const db::local_cluster<db::PolygonRef> &lc = *i;
const db::local_clusters<db::NetShape> &lcc = net_clusters ().clusters_per_cell (cell->cell_index ());
for (db::local_clusters<db::NetShape>::touching_iterator i = lcc.begin_touching (local_box); ! i.at_end (); ++i) {
const db::local_cluster<db::NetShape> &lc = *i;
if (lc.interacts (test_cluster, trans, m_conn)) {
return lc.id ();
}
@ -1053,7 +1088,7 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
// Prepare a test cluster
db::Box box (point - db::Vector (1, 1), point + db::Vector (1, 1));
db::GenericRepository sr;
db::local_cluster<db::PolygonRef> test_cluster;
db::local_cluster<db::NetShape> test_cluster;
test_cluster.add (db::PolygonRef (db::Polygon (box), sr), layer);
std::vector<db::InstElement> inst_path;
@ -1155,12 +1190,12 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg
for (db::Layout::bottom_up_const_iterator cid = ly.begin_bottom_up (); cid != ly.end_bottom_up (); ++cid) {
const connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (*cid);
const connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (*cid);
if (clusters.empty ()) {
continue;
}
for (connected_clusters<db::PolygonRef>::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
for (connected_clusters<db::NetShape>::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
if (! clusters.is_root (*c)) {
continue;

View File

@ -522,7 +522,7 @@ public:
* NOTE: the layer and cell indexes used inside this structure refer to the
* internal layout.
*/
const db::hier_clusters<db::PolygonRef> &net_clusters () const
const db::hier_clusters<db::NetShape> &net_clusters () const
{
return m_net_clusters;
}
@ -530,7 +530,7 @@ public:
/**
* @brief Gets the hierarchical shape clusters derived in the net extraction (non-conver version)
*/
db::hier_clusters<db::PolygonRef> &net_clusters ()
db::hier_clusters<db::NetShape> &net_clusters ()
{
return m_net_clusters;
}
@ -744,7 +744,7 @@ private:
tl::weak_ptr<db::DeepShapeStore> mp_dss;
unsigned int m_layout_index;
db::Connectivity m_conn;
db::hier_clusters<db::PolygonRef> m_net_clusters;
db::hier_clusters<db::NetShape> m_net_clusters;
std::auto_ptr<db::Netlist> mp_netlist;
std::set<db::DeepLayer> m_dlrefs;
std::map<std::string, db::DeepLayer> m_named_regions;
@ -786,7 +786,7 @@ private:
void init ();
void ensure_netlist ();
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<NetShape> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
void build_net_rec (const db::Net &net, db::Layout &target, cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;

View File

@ -524,7 +524,7 @@ LayoutToNetlistStandardReader::read_polygon ()
}
void
LayoutToNetlistStandardReader::read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::PolygonRef> &lc, db::Cell &cell)
LayoutToNetlistStandardReader::read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::NetShape> &lc, db::Cell &cell)
{
m_ref = db::Point ();
@ -561,8 +561,8 @@ LayoutToNetlistStandardReader::read_net (db::Netlist * /*netlist*/, db::LayoutTo
if (l2n) {
db::connected_clusters<db::PolygonRef> &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ());
db::local_cluster<db::PolygonRef> &lc = *cc.insert ();
db::connected_clusters<db::NetShape> &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ());
db::local_cluster<db::NetShape> &lc = *cc.insert ();
net->set_cluster_id (lc.id ());
db::Cell &cell = l2n->internal_layout ()->cell (circuit->cell_index ());
@ -1025,8 +1025,8 @@ LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n,
if (l2n) {
db::connected_clusters<db::PolygonRef> &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ());
db::local_cluster<db::PolygonRef> &lc = *cc.insert ();
db::connected_clusters<db::NetShape> &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ());
db::local_cluster<db::NetShape> &lc = *cc.insert ();
dm->set_cluster_id_for_terminal (tid, lc.id ());
db::Cell &cell = l2n->internal_layout ()->cell (dm->cell_index ());

View File

@ -143,7 +143,7 @@ protected:
void read_property (db::NetlistObject *obj);
db::Polygon read_polygon ();
db::Box read_rect ();
void read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::PolygonRef> &lc, db::Cell &cell);
void read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<NetShape> &lc, db::Cell &cell);
db::Point read_point ();
private:

View File

@ -397,11 +397,16 @@ void std_writer_impl<Keys>::reset_geometry_ref ()
}
template <class Keys>
void std_writer_impl<Keys>::write (const db::PolygonRef *s, const db::ICplxTrans &tr, const std::string &lname, bool relative)
void std_writer_impl<Keys>::write (const db::NetShape *s, const db::ICplxTrans &tr, const std::string &lname, bool relative)
{
db::ICplxTrans t = tr * db::ICplxTrans (s->trans ());
if (s->type () != db::NetShape::Polygon) {
return;
}
const db::Polygon &poly = s->obj ();
db::PolygonRef pr = s->polygon_ref ();
db::ICplxTrans t = tr * db::ICplxTrans (pr.trans ());
const db::Polygon &poly = pr.obj ();
if (poly.is_box ()) {
db::Box box = t * poly.box ();
@ -435,7 +440,7 @@ bool std_writer_impl<Keys>::new_cell (cell_index_type ci) const
template <class Keys>
void std_writer_impl<Keys>::write (const db::Net &net, unsigned int id, const std::string &indent)
{
const db::hier_clusters<db::PolygonRef> &clusters = mp_l2n->net_clusters ();
const db::hier_clusters<db::NetShape> &clusters = mp_l2n->net_clusters ();
const db::Circuit *circuit = net.circuit ();
const db::Connectivity &conn = mp_l2n->connectivity ();
@ -450,7 +455,7 @@ void std_writer_impl<Keys>::write (const db::Net &net, unsigned int id, const st
db::cell_index_type cci = circuit->cell_index ();
db::cell_index_type prev_ci = cci;
for (db::recursive_cluster_shape_iterator<db::PolygonRef> si (clusters, *l, cci, net.cluster_id (), this); ! si.at_end (); ) {
for (db::recursive_cluster_shape_iterator<db::NetShape> si (clusters, *l, cci, net.cluster_id (), this); ! si.at_end (); ) {
// NOTE: we don't recursive into circuits which will later be output. However, as circuits may
// vanish in "purge" but the clusters will still be there we need to recursive into clusters from
@ -570,7 +575,7 @@ void std_writer_impl<Keys>::write (const db::DeviceAbstract &device_abstract, co
{
const std::vector<db::DeviceTerminalDefinition> &td = device_abstract.device_class ()->terminal_definitions ();
const db::hier_clusters<db::PolygonRef> &clusters = mp_l2n->net_clusters ();
const db::hier_clusters<db::NetShape> &clusters = mp_l2n->net_clusters ();
const db::Connectivity &conn = mp_l2n->connectivity ();
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
@ -587,8 +592,8 @@ void std_writer_impl<Keys>::write (const db::DeviceAbstract &device_abstract, co
continue;
}
const db::local_cluster<db::PolygonRef> &lc = clusters.clusters_per_cell (device_abstract.cell_index ()).cluster_by_id (cid);
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (*l); ! s.at_end (); ++s) {
const db::local_cluster<db::NetShape> &lc = clusters.clusters_per_cell (device_abstract.cell_index ()).cluster_by_id (cid);
for (db::local_cluster<db::NetShape>::shape_iterator s = lc.begin (*l); ! s.at_end (); ++s) {
*mp_stream << indent << indent2;
write (s.operator-> (), db::ICplxTrans (), name_for_layer (mp_l2n, *l), true);

View File

@ -41,6 +41,7 @@ class DeviceAbstract;
class Net;
class Netlist;
class LayoutToNetlist;
class NetShape;
namespace l2n_std_format
{
@ -75,7 +76,7 @@ private:
void write (const db::SubCircuit &subcircuit, std::map<const Net *, unsigned int> &net2id, const std::string &indent);
void write (const db::Device &device, std::map<const Net *, unsigned int> &net2id, const std::string &indent);
void write (const db::DeviceAbstract &device_abstract, const std::string &indent);
void write (const db::PolygonRef *s, const db::ICplxTrans &tr, const std::string &lname, bool relative);
void write (const db::NetShape *s, const db::ICplxTrans &tr, const std::string &lname, bool relative);
void write (const db::DCplxTrans &trans);
void reset_geometry_ref ();

218
src/db/db/dbNetShape.cc Normal file
View File

@ -0,0 +1,218 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbNetShape.h"
#include "dbShapes.h"
#include "dbPolygonTools.h"
namespace db {
NetShape::NetShape ()
: m_ptr (0), m_dx (0), m_dy (0)
{ }
NetShape::NetShape (const db::PolygonRef &pr)
{
m_ptr = size_t (&pr.obj ()) + 1;
m_dx = pr.trans ().disp ().x ();
m_dy = pr.trans ().disp ().y ();
}
NetShape::NetShape (const db::Polygon &poly, db::GenericRepository &repo)
{
db::PolygonRef pr (poly, repo);
m_ptr = size_t (&pr.obj ()) + 1;
m_dx = pr.trans ().disp ().x ();
m_dy = pr.trans ().disp ().y ();
}
NetShape::NetShape (const db::TextRef &tr)
{
m_ptr = size_t (&tr.obj ());
m_dx = tr.trans ().disp ().x ();
m_dy = tr.trans ().disp ().y ();
}
NetShape::NetShape (const db::Text &text, db::GenericRepository &repo)
{
db::TextRef tr (text, repo);
m_ptr = size_t (&tr.obj ());
m_dx = tr.trans ().disp ().x ();
m_dy = tr.trans ().disp ().y ();
}
NetShape::shape_type NetShape::type () const
{
if (m_ptr == 0) {
return None;
} else if ((m_ptr & 1) != 0) {
return Polygon;
} else {
return Text;
}
}
db::PolygonRef NetShape::polygon_ref () const
{
if ((size_t (m_ptr) & 1) != 0) {
return db::PolygonRef (reinterpret_cast<db::Polygon *> (m_ptr - 1), db::Disp (db::Vector (m_dx, m_dy)));
}
tl_assert (false);
}
db::TextRef NetShape::text_ref () const
{
if ((size_t (m_ptr) & 1) == 0) {
return db::TextRef (reinterpret_cast<db::Text *> (m_ptr), db::Disp (db::Vector (m_dx, m_dy)));
}
tl_assert (false);
}
void NetShape::transform (const db::Disp &tr)
{
m_dx += tr.disp ().x ();
m_dy += tr.disp ().y ();
}
NetShape::box_type NetShape::bbox () const
{
if ((m_ptr & 1) != 0) {
return polygon_ref ().box ();
} else if (m_ptr != 0) {
return text_ref ().box ();
} else {
return box_type ();
}
}
void NetShape::insert_into (db::Shapes &shapes) const
{
if ((m_ptr & 1) != 0) {
shapes.insert (polygon_ref ());
} else if (m_ptr != 0) {
shapes.insert (text_ref ());
}
}
void NetShape::insert_into (db::Shapes &shapes, db::properties_id_type pi) const
{
if ((m_ptr & 1) != 0) {
shapes.insert (db::PolygonRefWithProperties (polygon_ref (), pi));
} else if (m_ptr != 0) {
shapes.insert (db::TextRefWithProperties (text_ref (), pi));
}
}
bool NetShape::interacts_with (const db::NetShape &other) const
{
if (m_ptr == 0 || other.m_ptr == 0 || ! bbox ().touches (other.bbox ())) {
return false;
}
if ((m_ptr & 1) != 0) {
if ((other.m_ptr & 1) != 0) {
// Polygon vs. polygon
db::PolygonRef pr_other = other.polygon_ref ();
db::PolygonRef pr = polygon_ref ();
db::Polygon p = pr_other.obj ().transformed (pr.trans ().inverted () * pr_other.trans ());
return db::interact_pp (pr.obj (), p);
} else {
// NOTE: we assume that the text ref's target is at 0,0
db::PolygonRef pr = polygon_ref ();
db::Point pt = db::Point (other.m_dx, other.m_dy) - pr.trans ().disp ();
return db::inside_poly (pr.obj ().begin_edge (), pt) >= 0;
}
} else {
if ((other.m_ptr & 1) == 0) {
// Text vs. text
return m_dx == other.m_dx && m_dy == other.m_dy;
} else {
// NOTE: we assume that the text ref's target is at 0,0
db::PolygonRef pr_other = other.polygon_ref ();
db::Point pt = db::Point (m_dx, m_dy) - pr_other.trans ().disp ();
return db::inside_poly (pr_other.obj ().begin_edge (), pt) >= 0;
}
}
}
template <class Tr>
bool NetShape::interacts_with_transformed (const db::NetShape &other, const Tr &trans) const
{
if (m_ptr == 0 || other.m_ptr == 0 || ! bbox ().touches (other.bbox ().transformed (trans))) {
return false;
}
if ((m_ptr & 1) != 0) {
if ((other.m_ptr & 1) != 0) {
// Polygon vs. polygon
db::PolygonRef pr_other = other.polygon_ref ();
db::PolygonRef pr = polygon_ref ();
db::Polygon p = pr_other.obj ().transformed (Tr (pr.trans ().inverted ()) * trans * Tr (pr_other.trans ()));
return db::interact_pp (pr.obj (), p);
} else {
// NOTE: we assume that the text ref's target is at 0,0
db::PolygonRef pr = polygon_ref ();
db::Point pt = trans * db::Point (other.m_dx, other.m_dy) - pr.trans ().disp ();
return db::inside_poly (pr.obj ().begin_edge (), pt) >= 0;
}
} else {
if ((other.m_ptr & 1) == 0) {
// Text vs. text
db::Point pt = trans * db::Point (other.m_dx, other.m_dy);
return db::Point (m_dx, m_dy) == pt;
} else {
// NOTE: we assume that the text ref's target is at 0,0
db::PolygonRef pr_other = other.polygon_ref ();
db::Point pt = trans.inverted () * db::Point (m_dx, m_dy) - pr_other.trans ().disp ();
return db::inside_poly (pr_other.obj ().begin_edge (), pt) >= 0;
}
}
}
// explicit instantiations
template bool NetShape::interacts_with_transformed<db::ICplxTrans> (const db::NetShape &other, const db::ICplxTrans &trans) const;
template bool NetShape::interacts_with_transformed<db::Trans> (const db::NetShape &other, const db::Trans &trans) const;
}

178
src/db/db/dbNetShape.h Normal file
View File

@ -0,0 +1,178 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_dbNetShape
#define HDR_dbNetShape
#include "dbPolygon.h"
#include "dbText.h"
#include "dbShapeRepository.h"
#include "dbBoxConvert.h"
namespace db {
class Shapes;
/**
* @brief Provides a union of a PolygonRef and a TextRef
*
* This object is used in the netlist extractor and represents either a polygon or a text.
* The TextRef shall utilize a StringRef to represent the string.
*/
class DB_PUBLIC NetShape
{
public:
enum shape_type { None, Text, Polygon };
typedef db::Point point_type;
typedef db::Box box_type;
typedef db::Coord coord_type;
typedef db::Disp trans_type;
/**
* @brief Default constructor
*/
NetShape ();
/**
* @brief A NetShape object representing a PolygonRef
*/
NetShape (const db::PolygonRef &pr);
/**
* @brief A NetShape object representing a Polygon from the given shape repository
*/
NetShape (const db::Polygon &poly, db::GenericRepository &repo);
/**
* @brief A NetShape object representing a TextRef
*/
NetShape (const db::TextRef &tr);
/**
* @brief A NetShape object representing a Text from the given shape repository
*/
NetShape (const db::Text &text, db::GenericRepository &repo);
/**
* @brief Gets a code indicating the type of object stored herein
*/
shape_type type () const;
/**
* @brief Gets the PolygonRef object
* Asserts if the object stored is not a polygon.
*/
db::PolygonRef polygon_ref () const;
/**
* @brief Gets the TextRef object
* Asserts if the object stored is not a text.
*/
db::TextRef text_ref () const;
/**
* @brief In-place transformation
*/
void transform (const db::Disp &tr);
/**
* @brief Equality
*/
bool operator== (const NetShape &net_shape) const
{
return m_ptr == net_shape.m_ptr && m_dx == net_shape.m_dx && m_dy == net_shape.m_dy;
}
/**
* @brief Inequality
*/
bool operator!= (const NetShape &net_shape) const
{
return ! operator== (net_shape);
}
/**
* @brief Less operator
*/
bool operator< (const NetShape &net_shape) const
{
if (m_ptr != net_shape.m_ptr) {
return m_ptr < net_shape.m_ptr;
}
if (m_dx != net_shape.m_dx) {
return m_dx < net_shape.m_dx;
}
return m_dy < net_shape.m_dy;
}
/**
* @brief Gets the bounding box of the object
*/
box_type bbox () const;
/**
* @brief Inserts the object into a Shapes collection
*/
void insert_into (db::Shapes &shapes) const;
/**
* @brief Inserts the object into a Shapes collection with the given properties ID
*/
void insert_into (db::Shapes &shapes, db::properties_id_type pi) const;
/**
* @brief Returns true if the object interacts with another NetShape object
*/
bool interacts_with (const db::NetShape &other) const;
/**
* @brief Returns true if the object interacts with another NetShape object after transforming it
*/
template <class Tr>
bool interacts_with_transformed (const db::NetShape &other, const Tr &trans) const;
public:
size_t m_ptr;
coord_type m_dx, m_dy;
};
/**
* @brief A box converter implementation for NetShape
*/
template <>
struct box_convert<db::NetShape>
{
typedef db::NetShape::box_type box_type;
typedef db::NetShape::coord_type coord_type;
typedef db::complex_bbox_tag complexity;
box_type operator() (const db::NetShape &net_shape) const
{
return net_shape.bbox ();
}
};
}
#endif

View File

@ -119,9 +119,12 @@ void NetlistDeviceExtractor::initialize (db::Netlist *nl)
setup ();
}
static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &tr, db::Region &region)
static void insert_into_region (const db::NetShape &s, const db::ICplxTrans &tr, db::Region &region)
{
region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ())));
if (s.type () == db::NetShape::Polygon) {
db::PolygonRef pr = s.polygon_ref ();
region.insert (pr.obj ().transformed (tr * db::ICplxTrans (pr.trans ())));
}
}
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters, double device_scaling)
@ -207,8 +210,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
{
tl_assert (layers.size () == m_layer_definitions.size ());
typedef db::PolygonRef shape_type;
db::ShapeIterator::flags_type shape_iter_flags = db::ShapeIterator::Polygons;
typedef db::NetShape shape_type;
mp_layout = &layout;
m_layers = layers;
@ -247,7 +249,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
db::Connectivity device_conn = get_connectivity (layout, layers);
db::hier_clusters<shape_type> device_clusters;
device_clusters.build (layout, cell, shape_iter_flags, device_conn, 0, breakout_cells);
device_clusters.build (layout, cell, device_conn, 0, breakout_cells);
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices")));
@ -365,12 +367,12 @@ void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
DeviceCellKey key;
for (geometry_per_terminal_type::const_iterator t = d->second.second.begin (); t != d->second.second.end (); ++t) {
std::map<unsigned int, std::set<db::PolygonRef> > &gt = key.geometry [t->first];
std::map<unsigned int, std::set<db::NetShape> > &gt = key.geometry [t->first];
for (geometry_per_layer_type::const_iterator l = t->second.begin (); l != t->second.end (); ++l) {
std::set<db::PolygonRef> &gl = gt [l->first];
for (std::vector<db::PolygonRef>::const_iterator p = l->second.begin (); p != l->second.end (); ++p) {
db::PolygonRef pr = *p;
pr.transform (db::PolygonRef::trans_type (-disp));
std::set<db::NetShape> &gl = gt [l->first];
for (std::vector<db::NetShape>::const_iterator p = l->second.begin (); p != l->second.end (); ++p) {
db::NetShape pr = *p;
pr.transform (db::NetShape::trans_type (-disp));
gl.insert (pr);
}
}
@ -411,10 +413,10 @@ void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
for (geometry_per_layer_type::const_iterator l = t->second.begin (); l != t->second.end (); ++l) {
db::Shapes &shapes = device_cell.shapes (l->first);
for (std::vector<db::PolygonRef>::const_iterator s = l->second.begin (); s != l->second.end (); ++s) {
db::PolygonRef pr = *s;
pr.transform (db::PolygonRef::trans_type (-disp));
shapes.insert (db::PolygonRefWithProperties (pr, pi));
for (std::vector<db::NetShape>::const_iterator s = l->second.begin (); s != l->second.end (); ++s) {
db::NetShape pr = *s;
pr.transform (db::NetShape::trans_type (-disp));
pr.insert_into (shapes, pi);
}
}
@ -542,10 +544,10 @@ void NetlistDeviceExtractor::define_terminal (Device *device, size_t terminal_id
std::pair<db::Device *, geometry_per_terminal_type> &dd = m_new_devices[device->id ()];
dd.first = device;
std::vector<db::PolygonRef> &geo = dd.second[terminal_id][layer_index];
std::vector<db::NetShape> &geo = dd.second[terminal_id][layer_index];
for (db::Region::const_iterator p = region.begin_merged (); !p.at_end (); ++p) {
geo.push_back (db::PolygonRef (*p, mp_layout->shape_repository ()));
geo.push_back (db::NetShape (*p, mp_layout->shape_repository ()));
}
}
@ -555,7 +557,7 @@ void NetlistDeviceExtractor::define_terminal (Device *device, size_t terminal_id
tl_assert (geometry_index < m_layers.size ());
unsigned int layer_index = m_layers [geometry_index];
db::PolygonRef pr (polygon, mp_layout->shape_repository ());
db::NetShape pr (polygon, mp_layout->shape_repository ());
std::pair<db::Device *, geometry_per_terminal_type> &dd = m_new_devices[device->id ()];
dd.first = device;
dd.second[terminal_id][layer_index].push_back (pr);

View File

@ -29,6 +29,7 @@
#include "dbHierNetworkProcessor.h"
#include "dbDeepShapeStore.h"
#include "dbRegion.h"
#include "dbNetShape.h"
#include "gsiObject.h"
@ -205,7 +206,7 @@ public:
typedef std::vector<db::NetlistDeviceExtractorLayerDefinition> layer_definitions;
typedef layer_definitions::const_iterator layer_definitions_iterator;
typedef std::map<std::string, db::Region *> input_layers;
typedef db::hier_clusters<db::PolygonRef> hier_clusters_type;
typedef db::hier_clusters<db::NetShape> hier_clusters_type;
/**
* @brief Constructor
@ -260,8 +261,6 @@ public:
* the nets later to associate nets with device terminals.
*
* The definition of the input layers is device class specific.
*
* NOTE: The extractor expects "PolygonRef" type layers.
*/
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set<cell_index_type> *breakout_cells = 0);
@ -521,11 +520,11 @@ private:
return false;
}
std::map<size_t, std::map<unsigned int, std::set<db::PolygonRef> > > geometry;
std::map<size_t, std::map<unsigned int, std::set<db::NetShape> > > geometry;
std::map<size_t, double> parameters;
};
typedef std::map<unsigned int, std::vector<db::PolygonRef> > geometry_per_layer_type;
typedef std::map<unsigned int, std::vector<db::NetShape> > geometry_per_layer_type;
typedef std::map<size_t, geometry_per_layer_type> geometry_per_terminal_type;
tl::weak_ptr<db::Netlist> m_netlist;

View File

@ -23,6 +23,7 @@
#include "dbNetlistExtractor.h"
#include "dbDeepShapeStore.h"
#include "dbNetlistDeviceExtractor.h"
#include "dbShapeRepository.h"
#include "tlGlobPattern.h"
namespace db
@ -50,9 +51,9 @@ void NetlistExtractor::set_include_floating_subcircuits (bool f)
}
static void
build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type net_name_id, const std::string &joined_net_names, tl::equivalence_clusters<unsigned int> &eq)
build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type net_name_id, const std::string &joined_net_names, tl::equivalence_clusters<size_t> &eq)
{
std::map<std::string, std::set<unsigned int> > prop_by_name;
std::map<std::string, std::set<size_t> > prop_by_name;
tl::GlobPattern jn_pattern (joined_net_names);
for (db::PropertiesRepository::iterator i = layout->properties_repository ().begin (); i != layout->properties_repository ().end (); ++i) {
@ -60,15 +61,23 @@ build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type
if (p->first == net_name_id) {
std::string nn = p->second.to_string ();
if (jn_pattern.match (nn)) {
prop_by_name [nn].insert (i->first);
prop_by_name [nn].insert (db::prop_id_to_attr (i->first));
}
}
}
}
for (std::map<std::string, std::set<unsigned int> >::const_iterator pn = prop_by_name.begin (); pn != prop_by_name.end (); ++pn) {
std::set<unsigned int>::const_iterator p = pn->second.begin ();
std::set<unsigned int>::const_iterator p0 = p;
const db::repository<db::Text> &text_repository = layout->shape_repository ().repository (db::object_tag<db::Text> ());
for (db::repository<db::Text>::iterator t = text_repository.begin (); t != text_repository.end (); ++t) {
std::string nn = t->string ();
if (jn_pattern.match (nn)) {
prop_by_name [nn].insert (db::text_ref_to_attr (t.operator-> ()));
}
}
for (std::map<std::string, std::set<size_t> >::const_iterator pn = prop_by_name.begin (); pn != prop_by_name.end (); ++pn) {
std::set<size_t>::const_iterator p = pn->second.begin ();
std::set<size_t>::const_iterator p0 = p;
while (p != pn->second.end ()) {
eq.same (*p0, *p);
++p;
@ -93,9 +102,9 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
m_terminal_annot_name_id = mp_layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::terminal_id_property_name ());
m_device_annot_name_id = mp_layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::device_id_property_name ());
// the big part: actually extract the nets
// build an attribute equivalence map which lists the "attribute IDs" which are identical in terms of net names
std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > net_name_equivalence;
std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > net_name_equivalence;
if (m_text_annot_name_id.first) {
if (! m_joined_net_names.empty ()) {
build_net_name_equivalence (mp_layout, m_text_annot_name_id.second, m_joined_net_names, net_name_equivalence [hier_clusters_type::top_cell_index]);
@ -107,7 +116,10 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
}
}
}
mp_clusters->build (*mp_layout, *mp_cell, db::ShapeIterator::Polygons, conn, &net_name_equivalence);
// the big part: actually extract the nets
mp_clusters->build (*mp_layout, *mp_cell, conn, &net_name_equivalence);
// reverse lookup for Circuit vs. cell index
std::map<db::cell_index_type, db::Circuit *> circuits;
@ -181,7 +193,7 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
for (connected_clusters_type::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
const db::local_cluster<db::PolygonRef> &lc = clusters.cluster_by_id (*c);
const db::local_cluster<db::NetShape> &lc = clusters.cluster_by_id (*c);
if (clusters.connections_for_cluster (*c).empty () && lc.empty ()) {
// this is an entirely empty cluster so we skip it.
// Such clusters are left over when joining clusters.
@ -204,8 +216,8 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
// add the global names as second priority
if (net_names.empty ()) {
const db::local_cluster<db::PolygonRef>::global_nets &gn = lc.get_global_nets ();
for (db::local_cluster<db::PolygonRef>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
const db::local_cluster<db::NetShape>::global_nets &gn = lc.get_global_nets ();
for (db::local_cluster<db::NetShape>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
net_names.insert (conn.global_net_name (*g));
}
}
@ -250,7 +262,13 @@ NetlistExtractor::make_device_abstract_connections (db::DeviceAbstract *dm, cons
for (local_cluster_type::attr_iterator a = dc->begin_attr (); a != dc->end_attr (); ++a) {
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
if (! db::is_prop_id_attr (*a)) {
continue;
}
db::properties_id_type pi = db::prop_id_from_attr (*a);
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
if (j->first == m_terminal_annot_name_id.second) {
dm->set_cluster_id_for_terminal (j->second.to<size_t> (), dc->id ());
@ -282,7 +300,13 @@ void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,
const local_cluster_type &lc = clusters.cluster_by_id (cid);
for (local_cluster_type::attr_iterator a = lc.begin_attr (); a != lc.end_attr (); ++a) {
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
if (! db::is_prop_id_attr (*a)) {
continue;
}
db::properties_id_type pi = db::prop_id_from_attr (*a);
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
if (m_text_annot_name_id.first && j->first == m_text_annot_name_id.second) {
@ -343,13 +367,19 @@ void NetlistExtractor::connect_devices (db::Circuit *circuit,
continue;
}
const db::local_cluster<db::PolygonRef> &dc = mp_clusters->clusters_per_cell (inst_cell_index).cluster_by_id (i->id ());
const db::local_cluster<db::NetShape> &dc = mp_clusters->clusters_per_cell (inst_cell_index).cluster_by_id (i->id ());
// connect the net to the terminal of the device: take the terminal ID from the properties on the
// device cluster
for (local_cluster_type::attr_iterator a = dc.begin_attr (); a != dc.end_attr (); ++a) {
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
if (! db::is_prop_id_attr (*a)) {
continue;
}
db::properties_id_type pi = db::prop_id_from_attr (*a);
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
if (m_terminal_annot_name_id.first && j->first == m_terminal_annot_name_id.second) {

View File

@ -25,6 +25,7 @@
#include "dbCommon.h"
#include "dbHierNetworkProcessor.h"
#include "dbNetShape.h"
#include <map>
#include <set>
@ -71,9 +72,9 @@ class DeviceAbstract;
class DB_PUBLIC NetlistExtractor
{
public:
typedef db::hier_clusters<db::PolygonRef> hier_clusters_type;
typedef db::connected_clusters<db::PolygonRef> connected_clusters_type;
typedef db::local_cluster<db::PolygonRef> local_cluster_type;
typedef db::hier_clusters<db::NetShape> hier_clusters_type;
typedef db::connected_clusters<db::NetShape> connected_clusters_type;
typedef db::local_cluster<db::NetShape> local_cluster_type;
/**
* @brief NetExtractor constructor

View File

@ -353,23 +353,23 @@ template class region_to_edge_interaction_filter_base<db::Edge>;
// -------------------------------------------------------------------------------------
// RegionToTextInteractionFilterBase implementation
template <class OutputType>
region_to_text_interaction_filter_base<OutputType>::region_to_text_interaction_filter_base (bool inverse)
template <class OutputType, class TextType>
region_to_text_interaction_filter_base<OutputType, TextType>::region_to_text_interaction_filter_base (bool inverse)
: m_inverse (inverse)
{
// .. nothing yet ..
}
template <class OutputType>
template <class OutputType, class TextType>
void
region_to_text_interaction_filter_base<OutputType>::preset (const OutputType *s)
region_to_text_interaction_filter_base<OutputType, TextType>::preset (const OutputType *s)
{
m_seen.insert (s);
}
template <class OutputType>
template <class OutputType, class TextType>
void
region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, size_t, const db::Text *t, size_t)
region_to_text_interaction_filter_base<OutputType, TextType>::add (const db::Polygon *p, size_t, const TextType *t, size_t)
{
const OutputType *o = 0;
tl::select (o, p, t);
@ -378,8 +378,7 @@ region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, s
// A polygon and an text interact if the text is either inside completely
// of at least one text of the polygon intersects with the text
db::Point pt;
pt += t->trans ().disp ();
db::Point pt = db::box_convert<TextType> () (*t).p1 ();
if (p->box ().contains (pt) && db::inside_poly (p->begin_edge (), pt) >= 0) {
if (m_inverse) {
m_seen.erase (o);
@ -392,9 +391,9 @@ region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, s
}
}
template <class OutputType>
template <class OutputType, class TextType>
void
region_to_text_interaction_filter_base<OutputType>::fill_output ()
region_to_text_interaction_filter_base<OutputType, TextType>::fill_output ()
{
for (typename std::set<const OutputType *>::const_iterator s = m_seen.begin (); s != m_seen.end (); ++s) {
put (**s);
@ -402,8 +401,9 @@ region_to_text_interaction_filter_base<OutputType>::fill_output ()
}
// explicit instantiations
template class region_to_text_interaction_filter_base<db::Polygon>;
template class region_to_text_interaction_filter_base<db::Text>;
template class region_to_text_interaction_filter_base<db::Polygon, db::TextRef>;
template class region_to_text_interaction_filter_base<db::Text, db::Text>;
template class region_to_text_interaction_filter_base<db::TextRef, db::TextRef>;
// -------------------------------------------------------------------------------------
// Polygon snapping

View File

@ -527,15 +527,15 @@ private:
/**
* @brief A helper class for the region to text interaction functionality
*/
template <class OutputType>
template <class OutputType, class TextType>
class DB_PUBLIC region_to_text_interaction_filter_base
: public db::box_scanner_receiver2<db::Polygon, size_t, db::Text, size_t>
: public db::box_scanner_receiver2<db::Polygon, size_t, TextType, size_t>
{
public:
region_to_text_interaction_filter_base (bool inverse);
void preset (const OutputType *s);
void add (const db::Polygon *p, size_t, const db::Text *e, size_t);
void add (const db::Polygon *p, size_t, const TextType *e, size_t);
void fill_output ();
protected:
@ -549,13 +549,13 @@ private:
/**
* @brief A helper class for the region to text interaction functionality
*/
template <class OutputContainer, class OutputType = typename OutputContainer::value_type>
template <class OutputContainer, class TextType, class OutputType = typename OutputContainer::value_type>
class DB_PUBLIC_TEMPLATE region_to_text_interaction_filter
: public region_to_text_interaction_filter_base<OutputType>
: public region_to_text_interaction_filter_base<OutputType, TextType>
{
public:
region_to_text_interaction_filter (OutputContainer &output, bool inverse)
: region_to_text_interaction_filter_base<OutputType> (inverse), mp_output (&output)
: region_to_text_interaction_filter_base<OutputType, TextType> (inverse), mp_output (&output)
{
// .. nothing yet ..
}

View File

@ -176,6 +176,15 @@ public:
return m_text_repository;
}
/**
* @brief Return the repository by tag
*/
template <class Sh>
const db::repository<Sh> &repository (db::object_tag<Sh> tag) const
{
return const_cast<generic_repository<C> *> (this)->repository (tag);
}
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const
{
db::mem_stat (stat, purpose, cat, m_polygon_repository, no_self, parent);

View File

@ -234,6 +234,20 @@ Shapes::swap (Shapes &d)
m_layers.swap (d.m_layers);
}
static
Shapes::shape_type safe_insert_text (Shapes &shapes, const Shapes::shape_type &shape, tl::func_delegate_base <db::properties_id_type> &pm)
{
// for texts referring to a string repository we go the safe way and
// simply instantiate and re-insert the text:
Shapes::shape_type::text_type p;
shape.text (p);
if (! shape.has_prop_id ()) {
return shapes.insert (p);
} else {
return shapes.insert (db::object_with_properties<Shapes::shape_type::text_type> (p, pm (shape.prop_id ())));
}
}
Shapes::shape_type
Shapes::do_insert (const Shapes::shape_type &shape, const Shapes::unit_trans_type & /*t*/, tl::func_delegate_base <db::properties_id_type> &pm)
{
@ -352,19 +366,23 @@ Shapes::do_insert (const Shapes::shape_type &shape, const Shapes::unit_trans_typ
case shape_type::ShortBoxArray:
return (insert_by_tag (shape_type::short_box_array_type::tag (), shape, pm));
case shape_type::Text:
case shape_type::TextRef:
case shape_type::TextPtrArrayMember:
{
// because texts can refer to a string repository we go the safe way and
// simply instantiate and re-insert the text:
shape_type::text_type p;
shape.text (p);
if (! shape.has_prop_id ()) {
return insert (p);
if (shape.text ().string_ref () != 0) {
return safe_insert_text (*this, shape, pm);
} else {
return insert (db::object_with_properties<shape_type::text_type> (p, pm (shape.prop_id ())));
return (insert_by_tag (shape_type::text_type::tag (), shape, pm));
}
}
case shape_type::TextRef:
{
if (shape.text_ref ().obj ().string_ref () != 0) {
return safe_insert_text (*this, shape, pm);
} else {
return (insert_by_tag (shape_type::text_ref_type::tag (), shape, pm));
}
}
case shape_type::TextPtrArrayMember:
return safe_insert_text (*this, shape, pm);
case shape_type::TextPtrArray:
tl_assert (layout () != 0); // cannot translate the array members
return insert_array_by_tag (shape_type::text_ptr_array_type::tag (), shape, shape_repository (), pm);

View File

@ -159,6 +159,9 @@ inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int
class DB_PUBLIC StringRepository
{
public:
typedef std::set<StringRef *> string_refs_type;
typedef string_refs_type::const_iterator iterator;
/**
* @brief Constructor
*/
@ -216,6 +219,22 @@ public:
return m_string_refs.size ();
}
/**
* @brief Iterates over the string refs (begin)
*/
iterator begin () const
{
return m_string_refs.begin ();
}
/**
* @brief Iterates over the string refs (end)
*/
iterator end () const
{
return m_string_refs.end ();
}
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const
{
if (! no_self) {
@ -559,6 +578,21 @@ public:
}
}
/**
* @brief Gets the StringRef object is there is one
*
* If the string is a plain text kept internally, this method returns 0.
*/
const StringRef *string_ref () const
{
size_t p = (size_t) mp_ptr;
if (p & 1) {
return reinterpret_cast<const StringRef *> (p - 1);
} else {
return 0;
}
}
/**
* @brief The transformation write accessor
*/

View File

@ -153,7 +153,7 @@ private:
};
/**
* @brief A helper class for the text to region interaction functionality which acts as an text receiver
* @brief A helper class for the text ref to region interaction functionality which acts as an text receiver
*
* Note: This special scanner uses pointers to two different objects: texts and polygons.
* It uses odd value pointers to indicate pointers to polygons and even value pointers to indicate
@ -161,9 +161,9 @@ private:
*
* There is a special box converter which is able to sort that out as well.
*/
template <class OutputContainer, class OutputType = typename OutputContainer::value_type>
template <class OutputContainer, class TextType, class OutputType = typename OutputContainer::value_type>
class text_to_region_interaction_filter
: public db::box_scanner_receiver2<db::Text, size_t, db::Polygon, size_t>
: public db::box_scanner_receiver2<TextType, size_t, db::Polygon, size_t>
{
public:
text_to_region_interaction_filter (OutputContainer &output)
@ -172,6 +172,19 @@ public:
// .. nothing yet ..
}
void add (const db::TextRef *t, size_t, const db::Polygon *p, size_t)
{
const OutputType *tt = 0;
tl::select (tt, t, p);
if (m_seen.find (tt) == m_seen.end ()) {
if (db::interact (*p, t->obj ().transformed (t->trans ()))) {
m_seen.insert (tt);
mp_output->insert (*tt);
}
}
}
void add (const db::Text *t, size_t, const db::Polygon *p, size_t)
{
const OutputType *tt = 0;

View File

@ -369,21 +369,21 @@ TEST(20_LocalClustersBasic)
db::local_clusters<db::PolygonRef> clusters;
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
// one more shape
cell.shapes (0).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)");
// one more shape creating a new cluster
cell.shapes (2).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)\n"
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)"
@ -393,7 +393,7 @@ TEST(20_LocalClustersBasic)
cell.shapes (2).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1000))), repo));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)"
);
@ -402,7 +402,7 @@ TEST(20_LocalClustersBasic)
cell.shapes (1).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)\n"
"#2:[1](0,1100;0,2100;1000,2100;1000,1100)"
@ -430,21 +430,21 @@ TEST(21_LocalClustersBasicWithAttributes)
db::local_clusters<db::PolygonRef> clusters;
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
// one more shape
cell.shapes (0).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo), 1));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1");
// one more shape creating a new cluster
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 2));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1\n"
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
@ -454,7 +454,7 @@ TEST(21_LocalClustersBasicWithAttributes)
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1000))), repo), 3));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2%3"
);
@ -463,7 +463,7 @@ TEST(21_LocalClustersBasicWithAttributes)
cell.shapes (1).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 4));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2%3\n"
"#2:[1](0,1100;0,2100;1000,2100;1000,1100)%4"
@ -491,21 +491,21 @@ TEST(22_LocalClustersWithGlobal)
db::local_clusters<db::PolygonRef> clusters;
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
// one more shape
cell.shapes (0).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo), 1));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1");
// one more shape creating a new cluster
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 2));
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1\n"
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
@ -514,7 +514,7 @@ TEST(22_LocalClustersWithGlobal)
conn.connect_global (0, "GLOBAL");
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1+GLOBAL\n"
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
@ -523,7 +523,7 @@ TEST(22_LocalClustersWithGlobal)
conn.connect_global (2, "GLOBAL2");
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1+GLOBAL\n"
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2+GLOBAL2"
@ -533,7 +533,7 @@ TEST(22_LocalClustersWithGlobal)
// now, GLOBAL2 will connect these clusters
clusters.clear ();
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2+GLOBAL+GLOBAL2"
);
@ -570,7 +570,7 @@ TEST(23_LocalClustersWithEdges)
conn.connect (0);
db::local_clusters<db::Edge> clusters;
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,500);[0](0,500;0,1000)\n"
"#2:[0](2000,500;1000,250);[0](1500,375;0,0)\n"
@ -585,7 +585,7 @@ TEST(23_LocalClustersWithEdges)
conn.connect (0);
db::local_clusters<db::Edge> clusters;
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
clusters.build_clusters (cell, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,500);[0](0,500;0,1000);[0](1500,375;0,0);[0](0,1000;2000,1000);[0](2000,1000;2000,500);[0](2000,500;1000,250)");
}
}
@ -700,7 +700,7 @@ TEST(40_HierClustersBasic)
db::Connectivity conn;
conn.connect (l1, l1);
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
hc.build (ly, top, conn);
int n, nc;
const db::connected_clusters<db::PolygonRef> *cluster;
@ -815,7 +815,7 @@ TEST(41_HierClustersRecursiveClusterShapeIterator)
db::Connectivity conn;
conn.connect (l1, l1);
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
hc.build (ly, top, conn);
std::string res;
int n = 0;
@ -860,7 +860,7 @@ TEST(41_HierClustersRecursiveClusterIterator)
db::Connectivity conn;
conn.connect (l1, l1);
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
hc.build (ly, top, conn);
std::string res;
int n = 0;
@ -1020,7 +1020,7 @@ static void run_hc_test (tl::TestBase *_this, const std::string &file, const std
conn.connect_global (l6, "BULK2");
db::hier_clusters<db::PolygonRef> hc;
hc.build (ly, ly.cell (*ly.begin_top_down ()), db::ShapeIterator::Polygons, conn);
hc.build (ly, ly.cell (*ly.begin_top_down ()), conn);
std::vector<std::pair<db::Polygon::area_type, unsigned int> > net_layers;
@ -1153,7 +1153,7 @@ static void run_hc_test_with_backannotation (tl::TestBase *_this, const std::str
conn.connect_global (l6, "BULK2");
db::hier_clusters<db::PolygonRef> hc;
hc.build (ly, ly.cell (*ly.begin_top_down ()), db::ShapeIterator::Polygons, conn);
hc.build (ly, ly.cell (*ly.begin_top_down ()), conn);
std::map<unsigned int, unsigned int> lm;
lm[l1] = ly.insert_layer (db::LayerProperties (101, 0));

View File

@ -91,7 +91,7 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L
bool any = false;
for (std::map<const db::Region *, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end () && !any; ++m) {
any = !db::recursive_cluster_shape_iterator<db::PolygonRef> (l2n.net_clusters (), l2n.layer_of (*m->first), c->cell_index (), n->cluster_id ()).at_end ();
any = !db::recursive_cluster_shape_iterator<db::NetShape> (l2n.net_clusters (), l2n.layer_of (*m->first), c->cell_index (), n->cluster_id ()).at_end ();
}
if (!any) {

View File

@ -0,0 +1,187 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbNetShape.h"
#include "dbShapes.h"
#include "tlUnitTest.h"
TEST(1)
{
db::GenericRepository repo;
db::NetShape s;
EXPECT_EQ (s.type () == db::NetShape::None, true);
EXPECT_EQ (s.bbox ().to_string (), "()");
db::Polygon p (db::Box (0, 0, 100, 200));
s = db::NetShape (p, repo);
EXPECT_EQ (s.type () == db::NetShape::Polygon, true);
EXPECT_EQ (s.bbox ().to_string (), "(0,0;100,200)");
EXPECT_EQ (s.polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
EXPECT_EQ (db::NetShape (s.polygon_ref ()).type () == db::NetShape::Polygon, true);
EXPECT_EQ (db::NetShape (s.polygon_ref ()).polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
s = db::NetShape (t, repo);
EXPECT_EQ (s.type () == db::NetShape::Text, true);
EXPECT_EQ (s.bbox ().to_string (), "(100,200;100,200)");
EXPECT_EQ (s.text_ref ().obj ().to_string (), "('abc',r0 0,0)");
EXPECT_EQ (db::NetShape (s.text_ref ()).type () == db::NetShape::Text, true);
EXPECT_EQ (db::NetShape (s.text_ref ()).text_ref ().obj ().to_string (), "('abc',r0 0,0)");
}
TEST(2)
{
db::GenericRepository repo;
db::NetShape s;
EXPECT_EQ (s.type () == db::NetShape::None, true);
EXPECT_EQ (s.bbox ().to_string (), "()");
db::Polygon p (db::Box (0, 0, 100, 200));
s = db::NetShape (p, repo);
EXPECT_EQ (s.polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
s.transform (db::Disp (db::Vector (10, 20)));
EXPECT_EQ (s.bbox ().to_string (), "(10,20;110,220)");
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
s = db::NetShape (t, repo);
EXPECT_EQ (s.text_ref ().obj ().to_string (), "('abc',r0 0,0)");
s.transform (db::Disp (db::Vector (10, 20)));
EXPECT_EQ (s.text_ref ().obj ().transformed (s.text_ref ().trans ()).to_string (), "('abc',r0 110,220)");
}
TEST(3)
{
db::GenericRepository repo;
db::NetShape s, s2;
EXPECT_EQ (s == db::NetShape (), true);
EXPECT_EQ (s != db::NetShape (), false);
EXPECT_EQ (s < db::NetShape (), false);
db::Polygon p (db::Box (0, 0, 100, 200));
s = db::NetShape (p, repo);
s2 = s;
EXPECT_EQ (s == db::NetShape (), false);
EXPECT_EQ (s != db::NetShape (), true);
EXPECT_EQ (s < db::NetShape (), false);
EXPECT_EQ (s == s2, true);
EXPECT_EQ (s != s2, false);
EXPECT_EQ (s < s2, false);
EXPECT_EQ (s2 < s, false);
s.transform (db::Disp (db::Vector (10, 20)));
EXPECT_EQ (s == s2, false);
EXPECT_EQ (s != s2, true);
EXPECT_EQ (s < s2, false);
EXPECT_EQ (s2 < s, true);
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
s = db::NetShape (t, repo);
EXPECT_EQ (s == s2, false);
EXPECT_EQ (s != s2, true);
EXPECT_EQ (s < s2, true);
EXPECT_EQ (s2 < s, false);
s2 = s;
EXPECT_EQ (s == db::NetShape (), false);
EXPECT_EQ (s != db::NetShape (), true);
EXPECT_EQ (s < db::NetShape (), false);
EXPECT_EQ (s == s2, true);
EXPECT_EQ (s != s2, false);
EXPECT_EQ (s < s2, false);
EXPECT_EQ (s2 < s, false);
s.transform (db::Disp (db::Vector (10, 20)));
EXPECT_EQ (s == s2, false);
EXPECT_EQ (s != s2, true);
EXPECT_EQ (s < s2, false);
EXPECT_EQ (s2 < s, true);
}
TEST(4)
{
db::GenericRepository repo;
db::NetShape s;
EXPECT_EQ (s.type () == db::NetShape::None, true);
EXPECT_EQ (s.bbox ().to_string (), "()");
db::Polygon p (db::Box (0, 0, 100, 200));
s = db::NetShape (p, repo);
db::Shapes shapes;
s.insert_into (shapes);
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
s = db::NetShape (t, repo);
s.insert_into (shapes);
db::ShapeIterator si = shapes.begin (db::ShapeIterator::All);
EXPECT_EQ (si->to_string (), "polygon (0,0;0,200;100,200;100,0)");
++si;
EXPECT_NE (si.at_end (), true);
EXPECT_EQ (si->to_string (), "text ('abc',r0 100,200)");
++si;
EXPECT_EQ (si.at_end (), true);
}
TEST(5)
{
db::GenericRepository repo;
db::NetShape sp1 (db::Polygon (db::Box (10, 20, 100, 200)), repo);
db::NetShape sp2 (db::Polygon (db::Box (80, 20, 180, 200)), repo);
db::NetShape sp3 (db::Polygon (db::Box (10, 320, 100, 500)), repo);
db::NetShape st1 (db::Text ("abc", db::Trans (db::Vector (0, 0))), repo);
db::NetShape st2 (db::Text ("xyz", db::Trans (db::Vector (50, 60))), repo);
EXPECT_EQ (sp1.interacts_with (db::NetShape ()), false);
EXPECT_EQ (sp1.interacts_with_transformed (db::NetShape (), db::Trans (db::Vector (1000, 0))), false);
EXPECT_EQ (sp1.interacts_with (sp1), true);
EXPECT_EQ (sp1.interacts_with_transformed (sp1, db::Trans (db::Vector (1000, 0))), false);
EXPECT_EQ (sp1.interacts_with (sp2), true);
EXPECT_EQ (sp2.interacts_with (sp1), true);
EXPECT_EQ (sp1.interacts_with (sp3), false);
EXPECT_EQ (sp1.interacts_with_transformed (sp3, db::Trans (db::Vector (50, -200))), true);
EXPECT_EQ (sp3.interacts_with (sp1), false);
EXPECT_EQ (sp3.interacts_with_transformed (sp1, db::Trans (db::Vector (50, 200))), true);
EXPECT_EQ (sp1.interacts_with (st1), false);
EXPECT_EQ (sp1.interacts_with_transformed (st1, db::Trans (db::Vector (10, 20))), true);
EXPECT_EQ (sp1.interacts_with_transformed (st1, db::Trans (db::Vector (5, 20))), false);
EXPECT_EQ (sp1.interacts_with (st2), true);
EXPECT_EQ (st1.interacts_with (sp1), false);
EXPECT_EQ (st1.interacts_with_transformed (sp1, db::Trans (db::Vector (-10, -20))), true);
EXPECT_EQ (st1.interacts_with_transformed (sp1, db::Trans (db::Vector (-5, -20))), false);
EXPECT_EQ (st2.interacts_with (sp1), true);
EXPECT_EQ (st1.interacts_with (st1), true);
EXPECT_EQ (st1.interacts_with_transformed (st1, db::Trans (db::Vector (-5, -20))), false);
EXPECT_EQ (st2.interacts_with (st1), false);
EXPECT_EQ (st2.interacts_with_transformed (st1, db::Trans (db::Vector (50, 60))), true);
}

View File

@ -123,7 +123,7 @@ TEST(10_MOS3DeviceExtractorTest)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
@ -179,7 +179,7 @@ TEST(11_MOS3DeviceExtractorTestNotRectangularGate)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
@ -235,7 +235,7 @@ TEST(12_MOS3DeviceExtractorTestCircular)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
@ -293,7 +293,7 @@ TEST(20_MOS4DeviceExtractorTest)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
@ -354,7 +354,7 @@ TEST(21_MOS4DeviceExtractorTestNotRectangularGate)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
@ -415,7 +415,7 @@ TEST(22_MOS4DeviceExtractorTestCircular)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
@ -475,7 +475,7 @@ TEST(30_DMOS3DeviceExtractorTest)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
@ -533,7 +533,7 @@ TEST(31_DMOS3DeviceExtractorTestNotRectangularGate)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
@ -591,7 +591,7 @@ TEST(32_DMOS3DeviceExtractorTestCircular)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
@ -651,7 +651,7 @@ TEST(40_DMOS4DeviceExtractorTest)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);
@ -714,7 +714,7 @@ TEST(41_DMOS4DeviceExtractorTestNotRectangularGate)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);
@ -777,7 +777,7 @@ TEST(42_DMOS4DeviceExtractorTestCircular)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);

View File

@ -59,7 +59,7 @@ static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_la
return lid;
}
static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<db::PolygonRef> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap, bool with_device_cells = false)
static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<db::NetShape> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap, bool with_device_cells = false)
{
std::set<db::cell_index_type> device_cells_seen;
@ -69,7 +69,7 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
const db::local_cluster<db::PolygonRef> &lc = clusters.clusters_per_cell (c->cell_index ()).cluster_by_id (n->cluster_id ());
const db::local_cluster<db::NetShape> &lc = clusters.clusters_per_cell (c->cell_index ()).cluster_by_id (n->cluster_id ());
bool any_shapes = false;
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) {
@ -84,8 +84,8 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
db::Shapes &target = net_cell.shapes (m->second);
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (m->first); !s.at_end (); ++s) {
target.insert (*s);
for (db::local_cluster<db::NetShape>::shape_iterator s = lc.begin (m->first); !s.at_end (); ++s) {
s->insert_into (target);
}
}
@ -137,12 +137,12 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
const std::vector<db::DeviceTerminalDefinition> &td = d->device_class ()->terminal_definitions ();
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
const db::local_cluster<db::PolygonRef> &dc = clusters.clusters_per_cell (dci).cluster_by_id (d->device_abstract ()->cluster_id_for_terminal (t->id ()));
const db::local_cluster<db::NetShape> &dc = clusters.clusters_per_cell (dci).cluster_by_id (d->device_abstract ()->cluster_id_for_terminal (t->id ()));
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
db::Shapes &target = device_cell.shapes (m->second);
for (db::local_cluster<db::PolygonRef>::shape_iterator s = dc.begin (m->first); !s.at_end (); ++s) {
target.insert (*s);
for (db::local_cluster<db::NetShape>::shape_iterator s = dc.begin (m->first); !s.at_end (); ++s) {
s->insert_into (target);
}
}
@ -233,7 +233,7 @@ TEST(1_DeviceAndNetExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -452,7 +452,7 @@ TEST(2_DeviceAndNetExtractionFlat)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -686,7 +686,7 @@ TEST(3_DeviceAndNetExtractionWithImplicitConnections)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -935,7 +935,7 @@ TEST(4_ResAndCapExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -1182,7 +1182,7 @@ TEST(5_ResAndCapWithBulkExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS");
@ -1449,7 +1449,7 @@ TEST(6_BJT3TransistorExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS");
@ -1656,7 +1656,7 @@ TEST(7_DiodeExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorDiode diode_ex ("DIODE");
@ -1790,7 +1790,7 @@ TEST(8_DiodeExtractionScaled)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorDiode diode_ex ("DIODE");
@ -1951,7 +1951,7 @@ TEST(9_StrictDeviceExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS", true /*strict*/);
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS", true /*strict*/);
@ -2184,7 +2184,7 @@ TEST(10_DeviceExtractionWithBreakoutCells)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -2352,7 +2352,7 @@ TEST(11_DeviceExtractionWithSameClass)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorResistor polyres_ex ("RES", 50.0);
db::NetlistDeviceExtractorResistor diffres_ex ("RES", 150.0);
@ -2474,7 +2474,7 @@ TEST(12_FloatingSubcircuitExtraction)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
@ -2628,7 +2628,7 @@ TEST(13_RemoveDummyPins)
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::hier_clusters<db::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");

View File

@ -75,7 +75,8 @@ SOURCES = \
dbBoxScannerTests.cc \
dbBoxTests.cc \
dbArrayTests.cc \
dbDeepTextsTests.cc
dbDeepTextsTests.cc \
dbNetShapeTests.cc
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC

View File

@ -87,7 +87,7 @@ size_t count_shapes (db::LayoutToNetlist *l2ndb, db::Net *net, unsigned int laye
size_t cluster_id = net->cluster_id ();
size_t n = 0;
for (db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (l2ndb->net_clusters (), layer, cell_index, cluster_id); ! shapes.at_end (); ++shapes) {
for (db::recursive_cluster_shape_iterator<db::NetShape> shapes (l2ndb->net_clusters (), layer, cell_index, cluster_id); ! shapes.at_end (); ++shapes) {
++n;
}
return n;
@ -278,7 +278,11 @@ void NetInfoDialog::update_info_text ()
std::string l = layer_string (mp_l2ndb.get (), *layer);
for (db::recursive_cluster_shape_iterator<db::PolygonRef> si (mp_l2ndb->net_clusters (), *layer, cell_index, cluster_id); ! si.at_end (); ++si) {
for (db::recursive_cluster_shape_iterator<db::NetShape> si (mp_l2ndb->net_clusters (), *layer, cell_index, cluster_id); ! si.at_end (); ++si) {
if (si->type () != db::NetShape::Polygon) {
continue;
}
if (tot_shapes++ >= max_shapes) {
incomplete = true;
@ -295,7 +299,7 @@ void NetInfoDialog::update_info_text ()
statinfo_area.insert (std::make_pair (*layer, db::coord_traits<db::Coord>::area_type (0)));
}
s->second.push_back (si->instantiate ());
s->second.push_back (si->polygon_ref ().instantiate ());
std::string c (ly->cell_name (si.cell_index ()));
c += " (with ";

View File

@ -987,9 +987,9 @@ NetlistBrowserPage::adjust_view ()
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
db::Box layer_bbox;
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
while (! shapes.at_end ()) {
layer_bbox += shapes.trans () * shapes->box ();
layer_bbox += shapes->bbox ();
++shapes;
}
@ -1187,15 +1187,19 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma
db::LayerProperties lp = layout->get_properties (*layer);
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator>::const_iterator display = display_by_lp.find (lp);
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
while (! shapes.at_end ()) {
if (shapes->type () != db::NetShape::Polygon) {
continue;
}
if (n_markers == m_max_shape_count) {
return true;
}
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
mp_markers.back ()->set (*shapes, net_trans * shapes.trans (), tv);
mp_markers.back ()->set (shapes->polygon_ref (), net_trans * shapes.trans (), tv);
if (net_color.isValid ()) {