diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 390301734..1b8eb3dec 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -171,15 +171,15 @@ DeepRegion::begin_merged () const std::pair DeepRegion::begin_iter () const { - const db::Layout *layout = m_deep_layer.layout (); - if (layout->cells () == 0) { + const db::Layout &layout = m_deep_layer.layout (); + if (layout.cells () == 0) { return std::make_pair (db::RecursiveShapeIterator (), db::ICplxTrans ()); } else { - const db::Cell &top_cell = layout->cell (*layout->begin_top_down ()); - db::RecursiveShapeIterator iter (*m_deep_layer.layout (), top_cell, m_deep_layer.layer ()); + const db::Cell &top_cell = layout.cell (*layout.begin_top_down ()); + db::RecursiveShapeIterator iter (m_deep_layer.layout (), top_cell, m_deep_layer.layer ()); return std::make_pair (iter, db::ICplxTrans ()); } @@ -236,7 +236,7 @@ bool DeepRegion::equals (const Region &other) const { const DeepRegion *other_delegate = dynamic_cast (other.delegate ()); - if (other_delegate && other_delegate->m_deep_layer.layout () == m_deep_layer.layout () + if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout () && other_delegate->m_deep_layer.layer () == m_deep_layer.layer ()) { return true; } else { @@ -248,7 +248,7 @@ bool DeepRegion::less (const Region &other) const { const DeepRegion *other_delegate = dynamic_cast (other.delegate ()); - if (other_delegate && other_delegate->m_deep_layer.layout () == m_deep_layer.layout ()) { + if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout ()) { return other_delegate->m_deep_layer.layer () < m_deep_layer.layer (); } else { return AsIfFlatRegion::less (other); @@ -348,7 +348,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const db::BoolAndOrNotLocalOperation op (and_op, m_deep_layer.store ()->max_area_ratio (), m_deep_layer.store ()->max_vertex_count ()); - db::LocalProcessor proc (const_cast (m_deep_layer.layout ()), const_cast (m_deep_layer.initial_cell ()), other->deep_layer ().layout (), other->deep_layer ().initial_cell ()); + db::LocalProcessor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); proc.set_threads (m_deep_layer.store ()->threads ()); proc.run (&op, m_deep_layer.layer (), other->deep_layer ().layer (), dl_out.layer ()); @@ -392,20 +392,20 @@ DeepRegion::xor_with (const Region &other) const void DeepRegion::add_from (const DeepLayer &dl) { - if (dl.layout () == deep_layer ().layout ()) { + if (&dl.layout () == &deep_layer ().layout ()) { // intra-layout merge - deep_layer ().layout ()->copy_layer (dl.layer (), deep_layer ().layer ()); + deep_layer ().layout ().copy_layer (dl.layer (), deep_layer ().layer ()); } else { // inter-layout merge - db::cell_index_type into_cell = deep_layer ().initial_cell ()->cell_index (); - db::Layout *into_layout = deep_layer ().layout (); - db::cell_index_type source_cell = dl.initial_cell ()->cell_index (); - const db::Layout *source_layout = dl.layout (); + db::cell_index_type into_cell = deep_layer ().initial_cell ().cell_index (); + db::Layout *into_layout = &deep_layer ().layout (); + db::cell_index_type source_cell = dl.initial_cell ().cell_index (); + const db::Layout *source_layout = &dl.layout (); db::CellMapping cm; cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell); @@ -439,7 +439,7 @@ DeepRegion::add_in_place (const Region &other) // non-deep to deep merge (flat) - db::Shapes &shapes = deep_layer ().initial_cell ()->shapes (deep_layer ().layer ()); + db::Shapes &shapes = deep_layer ().initial_cell ().shapes (deep_layer ().layer ()); for (db::Region::const_iterator p = other.begin (); ! p.at_end (); ++p) { shapes.insert (*p); } diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index eea29866c..c0e900a17 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -24,6 +24,8 @@ #include "dbDeepShapeStore.h" #include "dbCellMapping.h" #include "dbLayoutUtils.h" +#include "dbRegion.h" +#include "dbDeepRegion.h" #include "tlTimer.h" @@ -38,6 +40,14 @@ DeepLayer::DeepLayer () // .. nothing yet .. } +DeepLayer::DeepLayer (const Region ®ion) + : mp_store (), m_layout (0), m_layer (0) +{ + const db::DeepRegion *dr = dynamic_cast (region.delegate ()); + tl_assert (dr != 0); + *this = dr->deep_layer (); +} + DeepLayer::DeepLayer (const DeepLayer &x) : mp_store (x.mp_store), m_layout (x.m_layout), m_layer (x.m_layer) { @@ -82,7 +92,7 @@ DeepLayer::~DeepLayer () DeepLayer DeepLayer::derived () const { - return DeepLayer (const_cast (mp_store.get ()), m_layout, const_cast (layout ())->insert_layer ()); + return DeepLayer (const_cast (mp_store.get ()), m_layout, const_cast (layout ()).insert_layer ()); } DeepLayer @@ -91,9 +101,7 @@ DeepLayer::copy () const DeepLayer new_layer (derived ()); db::DeepShapeStore *non_const_store = const_cast (mp_store.get ()); - if (non_const_store->layout (m_layout)) { - non_const_store->layout (m_layout)->copy_layer (m_layer, new_layer.layer ()); - } + non_const_store->layout (m_layout).copy_layer (m_layer, new_layer.layer ()); return new_layer; } @@ -105,34 +113,32 @@ DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, const_cast (mp_store.get ())->insert (*this, into_layout, into_cell, into_layer); } -db::Layout * +db::Layout & DeepLayer::layout () { check_dss (); return mp_store->layout (m_layout); } -const db::Layout * +const db::Layout & DeepLayer::layout () const { check_dss (); return const_cast (mp_store.get ())->layout (m_layout); } -db::Cell * +db::Cell & DeepLayer::initial_cell () { - db::Layout *ly = layout (); - tl_assert (ly->begin_top_down () != ly->end_top_down ()); - return &ly->cell (*ly->begin_top_down ()); + check_dss (); + return mp_store->initial_cell (m_layout); } -const db::Cell * +const db::Cell & DeepLayer::initial_cell () const { - const db::Layout *ly = layout (); - tl_assert (ly->begin_top_down () != ly->end_top_down ()); - return &ly->cell (*ly->begin_top_down ()); + check_dss (); + return mp_store->const_initial_cell (m_layout); } void @@ -192,6 +198,32 @@ DeepShapeStore::~DeepShapeStore () m_layouts.clear (); } +bool DeepShapeStore::is_singular () const +{ + return m_layouts.size () == 1; +} + +void DeepShapeStore::require_singular () const +{ + if (! is_singular ()) { + throw tl::Exception (tl::to_string (tr ("Internal error: deep shape store isn't singular. This may happen if you try to mix hierarchical layers from different sources our you use clipping."))); + } +} + +Cell &DeepShapeStore::initial_cell(unsigned int n) +{ + db::Layout &ly = layout (n); + tl_assert (ly.cells () > 0); + return ly.cell (*ly.begin_top_down ()); +} + +const db::Cell &DeepShapeStore::const_initial_cell (unsigned int n) const +{ + const db::Layout &ly = const_layout (n); + tl_assert (ly.cells () > 0); + return ly.cell (*ly.begin_top_down ()); +} + void DeepShapeStore::set_text_enlargement (int enl) { m_text_enlargement = enl; @@ -207,16 +239,16 @@ bool DeepShapeStore::is_valid_layout_index (unsigned int n) const return (n < (unsigned int) m_layouts.size () && m_layouts[n] != 0); } -const db::Layout *DeepShapeStore::const_layout (unsigned int n) const +const db::Layout &DeepShapeStore::const_layout (unsigned int n) const { tl_assert (is_valid_layout_index (n)); - return &(m_layouts [n]->layout); + return m_layouts [n]->layout; } -db::Layout *DeepShapeStore::layout (unsigned int n) +db::Layout &DeepShapeStore::layout (unsigned int n) { tl_assert (is_valid_layout_index (n)); - return &(m_layouts [n]->layout); + return m_layouts [n]->layout; } size_t DeepShapeStore::instance_count () @@ -395,14 +427,14 @@ DeepShapeStore::cell_mapping_to_original (size_t layout_index, db::Layout *into_ void DeepShapeStore::insert (const DeepLayer &deep_layer, db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) { - const db::Layout *source_layout = deep_layer.layout (); - if (source_layout->begin_top_down () == source_layout->end_top_cells ()) { + const db::Layout &source_layout = deep_layer.layout (); + if (source_layout.begin_top_down () == source_layout.end_top_cells ()) { // empty source - nothing to do. return; } // prepare the transformation - db::ICplxTrans trans (source_layout->dbu () / into_layout->dbu ()); + db::ICplxTrans trans (source_layout.dbu () / into_layout->dbu ()); // prepare a layer map std::map lm; @@ -413,10 +445,10 @@ DeepShapeStore::insert (const DeepLayer &deep_layer, db::Layout *into_layout, db // prepare a vector with the source cells std::vector source_cells; - source_cells.push_back (*source_layout->begin_top_down()); + source_cells.push_back (*source_layout.begin_top_down()); // actually copy the shapes - db::copy_shapes (*into_layout, *source_layout, trans, source_cells, cm.table (), lm); + db::copy_shapes (*into_layout, source_layout, trans, source_cells, cm.table (), lm); } } diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index d944260a9..7fcc7ec07 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -40,6 +40,7 @@ namespace db { class DeepShapeStore; +class Region; /** * @brief Represents a shape collection from the deep shape store @@ -60,6 +61,12 @@ public: */ ~DeepLayer (); + /** + * @brief Conversion operator from Region to DeepLayer + * This requires the Region to be a DeepRegion. Otherwise, this constructor will assert + */ + DeepLayer (const Region ®ion); + /** * @brief Copy constructor */ @@ -74,23 +81,23 @@ public: * @brief Gets the layout object * The return value is guaranteed to be non-null. */ - db::Layout *layout (); + Layout &layout(); /** * @brief Gets the layout object (const version) */ - const db::Layout *layout () const; + const db::Layout &layout () const; /** * @brief Gets the layout object * The return value is guaranteed to be non-null. */ - db::Cell *initial_cell (); + Cell &initial_cell(); /** * @brief Gets the initial cell object (const version) */ - const db::Cell *initial_cell () const; + const db::Cell &initial_cell () const; /** * @brief Gets the layer @@ -185,6 +192,20 @@ public: */ ~DeepShapeStore (); + /** + * @brief Returns true, if the DeepShapeStore is singular + * + * A "singular" shape store needs a single layout to keep the information. + * This is the case, if all Regions derived from it share the same origin + * and do not use clipping or region selection. Singular shape stores are + * required for netlist extraction for example. + * + * For a singular shape store, "layout()" will return the layout + * object and "initial_cell()" will return the initial cell of the + * only layout. + */ + bool is_singular () const; + /** * @brief Inserts a polygon layer into the deep shape store * @@ -219,7 +240,72 @@ public: /** * @brief Gets the nth layout (const version) */ - const db::Layout *const_layout (unsigned int n) const; + const db::Layout &const_layout (unsigned int n) const; + + /** + * @brief Gets the nth layout (non-const version) + * + * Don't try to mess too much with the layout object, you'll screw up the internals. + */ + db::Layout &layout (unsigned int n); + + /** + * @brief Gets the initial cell of the nth layout (const version) + */ + const db::Cell &const_initial_cell (unsigned int n) const; + + /** + * @brief Gets the initial cell of the nth layout (non-const version) + * + * Don't try to mess too much with the cell object, you'll screw up the internals. + */ + db::Cell &initial_cell (unsigned int n); + + /** + * @brief Gets the singular layout (const version) + * + * This method will throw an exception if the deep shape store is not singular. + */ + const db::Layout &const_layout () const + { + require_singular (); + return const_layout (0); + } + + /** + * @brief Gets the singular layout (non-const version) + * + * This method will throw an exception if the deep shape store is not singular. + * Don't try to mess too much with the layout object, you'll screw up the internals. + */ + db::Layout &layout () + { + require_singular (); + return layout (0); + } + + /** + * @brief Gets the initial cell of the singular layout (const version) + * + * This method will throw an exception if the deep shape store is not singular. + */ + const db::Cell &const_initial_cell () const + { + require_singular (); + return const_initial_cell (0); + } + + /** + * @brief Gets the initial cell of the singular layout (non-const version) + * + * This method will throw an exception if the deep shape store is not singular. + * Don't try to mess too much with the cell object, you'll screw up the internals. + */ + db::Cell &initial_cell () + { + require_singular (); + return initial_cell (0); + } /** * @brief Gets the number of layouts @@ -324,11 +410,11 @@ private: struct LayoutHolder; - db::Layout *layout (unsigned int n); - void add_ref (unsigned int layout, unsigned int layer); void remove_ref (unsigned int layout, unsigned int layer); + void require_singular () const; + typedef std::map layout_map_type; // no copying diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 6020ba4be..eadc2b973 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -28,6 +28,7 @@ #include "dbPolygon.h" #include "dbPolygonTools.h" #include "dbBoxScanner.h" +#include "dbDeepRegion.h" #include "tlProgress.h" #include "tlLog.h" #include "tlTimer.h" @@ -64,6 +65,18 @@ Connectivity::connect (unsigned int l) m_all_layers.insert (l); } +void +Connectivity::connect (const db::DeepLayer &l) +{ + connect (l.layer ()); +} + +void +Connectivity::connect (const db::DeepLayer &la, const db::DeepLayer &lb) +{ + connect (la.layer (), lb.layer ()); +} + Connectivity::layer_iterator Connectivity::begin_layers () const { diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index d27a39174..87b957f23 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -36,6 +36,8 @@ namespace db { +class DeepLayer; + /** * @brief Defines the connectivity * @@ -61,6 +63,20 @@ public: */ void connect (unsigned int la, unsigned int lb); + /** + * @brief Adds intra-layer connectivity for layer l + * This is a convenience method that takes a db::DeepLayer object. + * It is assumed that all those layers originate from the same deep shape store. + */ + void connect (const db::DeepLayer &l); + + /** + * @brief Adds inter-layer connectivity + * This is a convenience method that takes a db::DeepLayer object. + * It is assumed that all those layers originate from the same deep shape store. + */ + void connect (const db::DeepLayer &la, const db::DeepLayer &lb); + /** * @brief Adds intra-layer connectivity for layer l */ diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index 60b00f006..09787dd46 100644 --- a/src/db/db/dbNetlistDeviceExtractor.cc +++ b/src/db/db/dbNetlistDeviceExtractor.cc @@ -62,49 +62,26 @@ static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &t region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ()))); } -void NetlistDeviceExtractor::extract (const std::vector regions) +void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const std::vector &deep_layers, db::Netlist *nl) { - tl_assert (! regions.empty ()); + db::Layout &layout = dss.layout (); + db::Cell &cell = dss.initial_cell (); - const db::Layout *layout = 0; - const db::Cell *cell = 0; std::vector layers; - layers.reserve (regions.size ()); - - for (std::vector::const_iterator r = regions.begin (); r != regions.end (); ++r) { - - // TODO: this is clumsy ... - db::DeepRegion *dr = dynamic_cast ((*r)->delegate ()); - tl_assert (dr != 0); - - db::DeepLayer dl = dr->deep_layer (); - tl_assert (dl.layout () != 0); - tl_assert (dl.initial_cell () != 0); - - if (! layout) { - layout = dl.layout (); - } else { - tl_assert (layout == dl.layout ()); - } - - if (! cell) { - cell = dl.initial_cell (); - } else { - tl_assert (cell == dl.initial_cell ()); - } - - layers.push_back (dl.layer ()); + layers.reserve (deep_layers.size ()); + for (std::vector::const_iterator dl = deep_layers.begin (); dl != deep_layers.end (); ++dl) { + tl_assert (&dl->layout () == &layout); + layers.push_back (dl->layer ()); } - // NOTE: the const_cast's are there because the extraction will annotate the layout with port - // shapes. That's not part of the initial design, where the underlying deep shape store is - // immutable from the outside. But we know what we're doing. - extract (const_cast (*layout), const_cast (*cell), layers); + extract (layout, cell, layers, nl); } -void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers) +void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl) { + initialize (nl); + typedef db::PolygonRef shape_type; db::ShapeIterator::flags_type shape_iter_flags = db::ShapeIterator::Polygons; diff --git a/src/db/db/dbNetlistDeviceExtractor.h b/src/db/db/dbNetlistDeviceExtractor.h index ca5d8563b..4f99cc1ba 100644 --- a/src/db/db/dbNetlistDeviceExtractor.h +++ b/src/db/db/dbNetlistDeviceExtractor.h @@ -27,6 +27,7 @@ #include "dbNetlist.h" #include "dbLayout.h" #include "dbHierNetworkProcessor.h" +#include "dbDeepShapeStore.h" #include "gsiObject.h" @@ -63,12 +64,6 @@ public: */ static const tl::Variant &terminal_property_name (); - /** - * @brief Initializes the extractor - * This method will produce the device classes required for the device extraction. - */ - void initialize (db::Netlist *nl); - /** * @brief Performs the extraction * @@ -87,21 +82,17 @@ public: * * NOTE: The extractor expects "PolygonRef" type layers. */ - void extract (Layout &layout, Cell &cell, const std::vector &layers); + void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist); /** * @brief Extracts the devices from a list of regions * * This method behaves identical to the other "extract" method, but accepts - * regions for input. - * - * As a requirement, the layout and initial cell of all of the regions - * has to be identical. - * - * Currently, the regions have to be deep regions. + * DeepShape layers for input. By definition, these already have the "PolygonRef" type. */ - void extract (const std::vector regions); + void extract (DeepShapeStore &dss, const std::vector &layers, Netlist *netlist); +protected: /** * @brief Creates the device classes * At least one device class needs to be defined. Use "register_device_class" to register @@ -131,7 +122,6 @@ public: */ virtual void extract_devices (const std::vector &layer_geometry); -protected: /** * @brief Registers a device class * The device class object will become owned by the netlist and must not be deleted by @@ -205,6 +195,12 @@ private: std::vector m_device_classes; std::vector m_layers; unsigned int m_device_name_index; + + /** + * @brief Initializes the extractor + * This method will produce the device classes required for the device extraction. + */ + void initialize (db::Netlist *nl); }; } diff --git a/src/db/unit_tests/dbDeepShapeStoreTests.cc b/src/db/unit_tests/dbDeepShapeStoreTests.cc index cc3ee008d..1eb8371d5 100644 --- a/src/db/unit_tests/dbDeepShapeStoreTests.cc +++ b/src/db/unit_tests/dbDeepShapeStoreTests.cc @@ -42,12 +42,12 @@ TEST(1) EXPECT_EQ (dl1.layer (), l1); EXPECT_EQ (dl2.layer (), l2); - EXPECT_EQ (dl1.layout (), dl2.layout ()); + EXPECT_EQ (&dl1.layout (), &dl2.layout ()); EXPECT_EQ (store.layouts (), (unsigned int) 1); db::DeepLayer dl3 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c2), l1)); EXPECT_EQ (dl3.layer (), l1); - EXPECT_NE (dl1.layout (), dl3.layout ()); + EXPECT_NE (&dl1.layout (), &dl3.layout ()); EXPECT_EQ (store.layouts (), (unsigned int) 2); db::DeepLayer dl4 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c1), l1, db::Box (0, 1, 2, 3))); @@ -58,13 +58,13 @@ TEST(1) db::DeepLayer dl6 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c1), l1, db::Box (0, 1, 2, 3))); EXPECT_EQ (dl6.layer (), l2); // a new layer (a copy) - EXPECT_EQ (dl6.layout (), dl4.layout ()); + EXPECT_EQ (&dl6.layout (), &dl4.layout ()); EXPECT_EQ (store.layouts (), (unsigned int) 4); } -static size_t shapes_in_top (const db::Layout *layout, unsigned int layer) +static size_t shapes_in_top (const db::Layout &layout, unsigned int layer) { - const db::Cell &top = layout->cell (*layout->begin_top_down ()); + const db::Cell &top = layout.cell (*layout.begin_top_down ()); return top.shapes (layer).size (); } @@ -162,23 +162,23 @@ TEST(3_TextTreatment) db::DeepLayer dl1 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c1), l1)); EXPECT_EQ (store.layouts (), (unsigned int) 1); - EXPECT_EQ (dl1.initial_cell ()->shapes (dl1.layer ()).empty (), true); + EXPECT_EQ (dl1.initial_cell ().shapes (dl1.layer ()).empty (), true); store.set_text_enlargement (1); dl1 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c1), l1)); EXPECT_EQ (store.layouts (), (unsigned int) 1); - EXPECT_EQ (dl1.initial_cell ()->shapes (dl1.layer ()).size (), size_t (1)); - EXPECT_EQ (dl1.initial_cell ()->shapes (dl1.layer ()).begin (db::ShapeIterator::All)->to_string (), "polygon (999,1999;999,2001;1001,2001;1001,1999)"); + EXPECT_EQ (dl1.initial_cell ().shapes (dl1.layer ()).size (), size_t (1)); + EXPECT_EQ (dl1.initial_cell ().shapes (dl1.layer ()).begin (db::ShapeIterator::All)->to_string (), "polygon (999,1999;999,2001;1001,2001;1001,1999)"); store.set_text_property_name (tl::Variant ("text")); dl1 = store.create_polygon_layer (db::RecursiveShapeIterator (layout, layout.cell (c1), l1)); EXPECT_EQ (store.layouts (), (unsigned int) 1); - EXPECT_EQ (dl1.initial_cell ()->shapes (dl1.layer ()).size (), size_t (1)); - EXPECT_EQ (dl1.initial_cell ()->shapes (dl1.layer ()).begin (db::ShapeIterator::All)->to_string (), "polygon (999,1999;999,2001;1001,2001;1001,1999) prop_id=1"); + EXPECT_EQ (dl1.initial_cell ().shapes (dl1.layer ()).size (), size_t (1)); + EXPECT_EQ (dl1.initial_cell ().shapes (dl1.layer ()).begin (db::ShapeIterator::All)->to_string (), "polygon (999,1999;999,2001;1001,2001;1001,1999) prop_id=1"); - const db::Layout *dss_layout = store.const_layout (0); + const db::Layout *dss_layout = &store.const_layout (0); db::PropertiesRepository::properties_set ps = dss_layout->properties_repository ().properties (1); EXPECT_EQ (ps.size (), size_t (1)); EXPECT_EQ (dss_layout->properties_repository ().prop_name (ps.begin ()->first).to_string (), "text"); diff --git a/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc b/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc index 30d0e53d6..97c648649 100644 --- a/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc @@ -48,10 +48,9 @@ class MOSFETExtractor : public db::NetlistDeviceExtractor { public: - MOSFETExtractor (db::Netlist &nl, db::Layout *debug_out) + MOSFETExtractor (db::Layout *debug_out) : db::NetlistDeviceExtractor (), mp_debug_out (debug_out), m_ldiff (0), m_lgate (0) { - initialize (&nl); if (mp_debug_out) { m_ldiff = mp_debug_out->insert_layer (db::LayerProperties (100, 0)); m_lgate = mp_debug_out->insert_layer (db::LayerProperties (101, 0)); @@ -230,14 +229,9 @@ static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_la return lid; } -// @@@ TODO: move somewhere else static unsigned int layer_of (const db::Region ®ion) { - // TODO: this is clumsy ... - db::DeepRegion *dr = dynamic_cast (region.delegate ()); - tl_assert (dr != 0); - - return dr->deep_layer ().layer (); + return db::DeepLayer (region).layer (); } // @@@ TODO: move somewhere else @@ -255,42 +249,37 @@ public: void extract_nets (const db::DeepShapeStore &dss, const db::Connectivity &conn, db::Netlist *nl) { - // only works for singular-layout stores currently. This rules out layers from different sources - // and clipping. - tl_assert (dss.layouts () == 1); - const db::Layout *layout = dss.const_layout (0); - - tl_assert (layout->cells () != 0); - const db::Cell &cell = layout->cell (*layout->begin_top_down ()); + const db::Layout &layout = dss.const_layout (); + const db::Cell &cell = dss.const_initial_cell (); // gets the text annotation property ID - // this is how the texts are passed for annotating the net names std::pair text_annot_name_id (false, 0); if (! dss.text_property_name ().is_nil ()) { - text_annot_name_id = layout->properties_repository ().get_id_of_name (dss.text_property_name ()); + text_annot_name_id = layout.properties_repository ().get_id_of_name (dss.text_property_name ()); } // gets the device terminal annotation property ID - // this is how the device extractor conveys terminal shape annotations. std::pair terminal_annot_name_id; - terminal_annot_name_id = layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::terminal_property_name ()); + terminal_annot_name_id = layout.properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::terminal_property_name ()); // the big part: actually extract the nets - m_net_clusters.build (*layout, cell, db::ShapeIterator::Polygons, conn); + m_net_clusters.build (layout, cell, db::ShapeIterator::Polygons, conn); // reverse lookup for Circuit vs. cell index std::map circuits; // some circuits may be there because of device extraction for (db::Netlist::circuit_iterator c = nl->begin_circuits (); c != nl->end_circuits (); ++c) { - tl_assert (layout->is_valid_cell_index (c->cell_index ())); + tl_assert (layout.is_valid_cell_index (c->cell_index ())); circuits.insert (std::make_pair (c->cell_index (), c.operator-> ())); } std::map > pins_per_cluster; - for (db::Layout::bottom_up_const_iterator cid = layout->begin_bottom_up (); cid != layout->end_bottom_up (); ++cid) { + for (db::Layout::bottom_up_const_iterator cid = layout.begin_bottom_up (); cid != layout.end_bottom_up (); ++cid) { const connected_clusters_type &clusters = m_net_clusters.clusters_per_cell (*cid); if (clusters.empty ()) { @@ -305,7 +294,7 @@ public: if (k == circuits.end ()) { circuit = new db::Circuit (); nl->add_circuit (circuit); - circuit->set_name (layout->cell_name (*cid)); + circuit->set_name (layout.cell_name (*cid)); circuit->set_cell_index (*cid); circuits.insert (std::make_pair (*cid, circuit)); } else { @@ -348,7 +337,7 @@ public: tl_assert (k != circuits.end ()); // because we walk bottom-up subcircuit = new db::SubCircuit (k->second); - db::CplxTrans dbu_trans (layout->dbu ()); + db::CplxTrans dbu_trans (layout.dbu ()); subcircuit->set_trans (dbu_trans * i->inst ().complex_trans () * dbu_trans.inverted ()); circuit->add_subcircuit (subcircuit); subcircuits.insert (std::make_pair (i->inst (), subcircuit)); @@ -371,7 +360,7 @@ public: const local_cluster_type &lc = clusters.cluster_by_id (*c); for (local_cluster_type::attr_iterator a = lc.begin_attr (); a != lc.end_attr (); ++a) { - const db::PropertiesRepository::properties_set &ps = layout->properties_repository ().properties (*a); + const db::PropertiesRepository::properties_set &ps = layout.properties_repository ().properties (*a); for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) { if (terminal_annot_name_id.first && j->first == terminal_annot_name_id.second) { @@ -624,15 +613,15 @@ TEST(1_DeviceNetExtraction) // NOTE: the device extractor will add more debug layers for the transistors: // 20/0 -> Diffusion // 21/0 -> Gate - MOSFETExtractor ex (nl, &ly); + MOSFETExtractor ex (&ly); - std::vector region_ptrs; - region_ptrs.push_back (&rpdiff); - region_ptrs.push_back (&rndiff); - region_ptrs.push_back (&rgate); - region_ptrs.push_back (&rpoly); + std::vector dl; + dl.push_back (rpdiff); + dl.push_back (rndiff); + dl.push_back (rgate); + dl.push_back (rpoly); - ex.extract (region_ptrs); + ex.extract (dss, dl, &nl); // perform the net extraction @@ -640,25 +629,25 @@ TEST(1_DeviceNetExtraction) db::Connectivity conn; // Intra-layer - conn.connect (layer_of (rpdiff)); - conn.connect (layer_of (rndiff)); - conn.connect (layer_of (rpoly)); - conn.connect (layer_of (rdiff_cont)); - conn.connect (layer_of (rpoly_cont)); - conn.connect (layer_of (rmetal1)); - conn.connect (layer_of (rvia1)); - conn.connect (layer_of (rmetal2)); + conn.connect (rpdiff); + conn.connect (rndiff); + conn.connect (rpoly); + conn.connect (rdiff_cont); + conn.connect (rpoly_cont); + conn.connect (rmetal1); + conn.connect (rvia1); + conn.connect (rmetal2); // Inter-layer - conn.connect (layer_of (rpdiff), layer_of (rdiff_cont)); - conn.connect (layer_of (rndiff), layer_of (rdiff_cont)); - conn.connect (layer_of (rpoly), layer_of (rpoly_cont)); - conn.connect (layer_of (rpoly_cont), layer_of (rmetal1)); - conn.connect (layer_of (rdiff_cont), layer_of (rmetal1)); - conn.connect (layer_of (rmetal1), layer_of (rvia1)); - conn.connect (layer_of (rvia1), layer_of (rmetal2)); - conn.connect (layer_of (rpoly), layer_of (rpoly_lbl)); // attaches labels - conn.connect (layer_of (rmetal1), layer_of (rmetal1_lbl)); // attaches labels - conn.connect (layer_of (rmetal2), layer_of (rmetal2_lbl)); // attaches labels + conn.connect (rpdiff, rdiff_cont); + conn.connect (rndiff, rdiff_cont); + conn.connect (rpoly, rpoly_cont); + conn.connect (rpoly_cont, rmetal1); + conn.connect (rdiff_cont, rmetal1); + conn.connect (rmetal1, rvia1); + conn.connect (rvia1, rmetal2); + conn.connect (rpoly, rpoly_lbl); // attaches labels + conn.connect (rmetal1, rmetal1_lbl); // attaches labels + conn.connect (rmetal2, rmetal2_lbl); // attaches labels // extract the nets