diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 78ca0ac83..7134c59d1 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -527,7 +527,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const db::BoolAndOrNotLocalOperation op (and_op); - db::local_processor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), m_deep_layer.breakout_cells (), other->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (m_deep_layer.store ()->threads ()); proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ()); @@ -1501,7 +1501,9 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), other_deep ? &other_deep->deep_layer ().layout () : const_cast (&polygons.layout ()), - other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&polygons.initial_cell ())); + other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&polygons.initial_cell ()), + m_deep_layer.breakout_cells (), + other_deep ? other_deep->deep_layer ().breakout_cells () : 0); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); @@ -1892,7 +1894,7 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to db::InteractingLocalOperation op (mode, touching, inverse); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); if (split_after) { @@ -1929,7 +1931,7 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse) cons db::InteractingWithEdgeLocalOperation op (inverse); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&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) { @@ -1968,7 +1970,7 @@ DeepRegion::pull_generic (const Region &other, int mode, bool touching) const db::PullLocalOperation op (mode, touching); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); if (split_after) { @@ -2004,7 +2006,7 @@ DeepRegion::pull_generic (const Edges &other) const db::PullWithEdgeLocalOperation op; - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell (), polygons.breakout_cells (), other_edges.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); proc.run (&op, polygons.layer (), other_edges.layer (), dl_out.layer ()); diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index db8ce5d01..726ba86eb 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -81,7 +81,6 @@ DeepLayer &DeepLayer::operator= (const DeepLayer &other) return *this; } - DeepLayer::~DeepLayer () { if (mp_store.get ()) { @@ -139,6 +138,12 @@ DeepLayer::add_from (const DeepLayer &dl) } } +const std::set * +DeepLayer::breakout_cells () const +{ + return store ()->breakout_cells (layout_index ()); +} + void DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const { @@ -251,16 +256,114 @@ struct DeepShapeStore::LayoutHolder // ---------------------------------------------------------------------------------- +DeepShapeStoreState::DeepShapeStoreState () + : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) +{ + // .. nothing yet .. +} + +void DeepShapeStoreState::set_text_enlargement (int enl) +{ + m_text_enlargement = enl; +} + +int DeepShapeStoreState::text_enlargement () const +{ + return m_text_enlargement; +} + +void DeepShapeStoreState::set_text_property_name (const tl::Variant &pn) +{ + m_text_property_name = pn; +} + +const tl::Variant & +DeepShapeStoreState::text_property_name () const +{ + return m_text_property_name; +} + +const std::set * +DeepShapeStoreState::breakout_cells (unsigned int layout_index) const +{ + const std::set &boc = (const_cast (this))->ensure_breakout_cells (layout_index); + if (boc.empty ()) { + return 0; + } else { + return &boc; + } +} + +void +DeepShapeStoreState::clear_breakout_cells (unsigned int layout_index) +{ + ensure_breakout_cells (layout_index).clear (); +} + +void +DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set &boc) +{ + ensure_breakout_cells (layout_index) = boc; +} + +void +DeepShapeStoreState::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci) +{ + ensure_breakout_cells (layout_index).insert (ci); +} + +void +DeepShapeStoreState::add_breakout_cells (unsigned int layout_index, const std::set &cc) +{ + ensure_breakout_cells (layout_index).insert (cc.begin (), cc.end ()); +} + +void +DeepShapeStoreState::set_threads (int n) +{ + m_threads = n; +} + +int +DeepShapeStoreState::threads () const +{ + return m_threads; +} + +void +DeepShapeStoreState::set_max_area_ratio (double ar) +{ + m_max_area_ratio = ar; +} + +double +DeepShapeStoreState::max_area_ratio () const +{ + return m_max_area_ratio; +} + +void +DeepShapeStoreState::set_max_vertex_count (size_t n) +{ + m_max_vertex_count = n; +} + +size_t +DeepShapeStoreState::max_vertex_count () const +{ + return m_max_vertex_count; +} + +// ---------------------------------------------------------------------------------- + static size_t s_instance_count = 0; DeepShapeStore::DeepShapeStore () - : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) { ++s_instance_count; } DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu) - : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) { ++s_instance_count; @@ -292,17 +395,17 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n unsigned int layer = layout ().insert_layer (); if (max_area_ratio == 0.0) { - max_area_ratio = m_max_area_ratio; + max_area_ratio = m_state.max_area_ratio (); } if (max_vertex_count == 0) { - max_vertex_count = m_max_vertex_count; + max_vertex_count = m_state.max_vertex_count (); } db::Shapes *shapes = &initial_cell ().shapes (layer); db::Box world = db::Box::world (); // The chain of operators for producing clipped and reduced polygon references - db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), m_text_enlargement, m_text_property_name); + db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), text_enlargement (), text_property_name ()); db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count); // try to maintain the texts on top level - go through shape iterator @@ -399,12 +502,95 @@ const db::Cell &DeepShapeStore::const_initial_cell (unsigned int n) const void DeepShapeStore::set_text_enlargement (int enl) { - m_text_enlargement = enl; + m_state.set_text_enlargement (enl); +} + +int DeepShapeStore::text_enlargement () const +{ + return m_state.text_enlargement (); } void DeepShapeStore::set_text_property_name (const tl::Variant &pn) { - m_text_property_name = pn; + m_state.set_text_property_name (pn); +} + +const tl::Variant &DeepShapeStore::text_property_name () const +{ + return m_state.text_property_name (); +} + +const std::set * +DeepShapeStore::breakout_cells (unsigned int layout_index) const +{ + return m_state.breakout_cells (layout_index); +} + +void +DeepShapeStore::clear_breakout_cells (unsigned int layout_index) +{ + m_state.clear_breakout_cells (layout_index); +} + +void +DeepShapeStore::set_breakout_cells (unsigned int layout_index, const std::set &boc) +{ + m_state.set_breakout_cells (layout_index, boc); +} + +void +DeepShapeStore::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci) +{ + m_state.add_breakout_cell (layout_index, ci); +} + +void +DeepShapeStore::add_breakout_cells (unsigned int layout_index, const std::set &cc) +{ + m_state.add_breakout_cells (layout_index, cc); +} + +void DeepShapeStore::set_threads (int n) +{ + m_state.set_threads (n); +} + +int DeepShapeStore::threads () const +{ + return m_state.threads (); +} + +void DeepShapeStore::set_max_area_ratio (double ar) +{ + m_state.set_max_area_ratio (ar); +} + +double DeepShapeStore::max_area_ratio () const +{ + return m_state.max_area_ratio (); +} + +void DeepShapeStore::set_max_vertex_count (size_t n) +{ + m_state.set_max_vertex_count (n); +} + +size_t DeepShapeStore::max_vertex_count () const +{ + return m_state.max_vertex_count (); +} + +void DeepShapeStore::push_state () +{ + m_state_stack.push_back (m_state); +} + +void DeepShapeStore::pop_state () +{ + if (! m_state_stack.empty ()) { + m_state = m_state_stack.back (); + m_state_stack.pop_back (); + } } bool DeepShapeStore::is_valid_layout_index (unsigned int n) const @@ -429,21 +615,6 @@ size_t DeepShapeStore::instance_count () return s_instance_count; } -void DeepShapeStore::set_threads (int n) -{ - m_threads = n; -} - -void DeepShapeStore::set_max_area_ratio (double ar) -{ - m_max_area_ratio = ar; -} - -void DeepShapeStore::set_max_vertex_count (size_t n) -{ - m_max_vertex_count = n; -} - void DeepShapeStore::add_ref (unsigned int layout, unsigned int layer) { tl::MutexLocker locker (&m_lock); @@ -474,6 +645,7 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer) if ((m_layouts[layout]->refs -= 1) <= 0) { delete m_layouts[layout]; m_layouts[layout] = 0; + clear_breakout_cells (layout); } } @@ -542,10 +714,10 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans) { if (max_area_ratio == 0.0) { - max_area_ratio = m_max_area_ratio; + max_area_ratio = m_state.max_area_ratio (); } if (max_vertex_count == 0) { - max_vertex_count = m_max_vertex_count; + max_vertex_count = m_state.max_vertex_count (); } unsigned int layout_index = layout_for_iter (si, trans); @@ -557,7 +729,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator builder.set_target_layer (layer_index); // The chain of operators for producing clipped and reduced polygon references - db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, m_text_enlargement, m_text_property_name); + db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, text_enlargement (), text_property_name ()); db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count); db::ClippingHierarchyBuilderShapeReceiver clip (&red); diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 0a5404f35..2219e4d46 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -40,6 +40,7 @@ namespace db { class DeepShapeStore; +class DeepShapeStoreState; class Region; class Edges; @@ -132,6 +133,13 @@ public: return m_layout; } + /** + * @brief Gets the list of breakout cells if there are some + * "breakout cells" are cells which are not considered to participate in hierarchical operations, + * neither as sibling nor in parent-child relationships. + */ + const std::set *breakout_cells () const; + /** * @brief Inserts the layer into the given layout, starting from the given cell and into the given layer */ @@ -200,6 +208,52 @@ private: unsigned int m_layer; }; +/** + * @brief An object holding the state of a DeepShapeStore + */ +class DB_PUBLIC DeepShapeStoreState +{ +public: + DeepShapeStoreState (); + + void set_threads (int n); + int threads () const; + + void set_max_vertex_count (size_t n); + size_t max_vertex_count () const; + + void set_max_area_ratio (double ar); + double max_area_ratio () const; + + void set_text_property_name (const tl::Variant &pn); + const tl::Variant &text_property_name () const; + + void set_text_enlargement (int enl); + int text_enlargement () const; + + const std::set *breakout_cells (unsigned int layout_index) const; + void clear_breakout_cells (unsigned int layout_index); + void set_breakout_cells (unsigned int layout_index, const std::set &boc); + void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci); + void add_breakout_cells (unsigned int layout_index, const std::set &cc); + +private: + int m_threads; + double m_max_area_ratio; + size_t m_max_vertex_count; + tl::Variant m_text_property_name; + std::vector > m_breakout_cells; + int m_text_enlargement; + + std::set &ensure_breakout_cells (unsigned int layout_index) + { + if (m_breakout_cells.size () <= size_t (layout_index)) { + m_breakout_cells.resize (layout_index + 1, std::set ()); + } + return m_breakout_cells [layout_index]; + } +}; + struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy { bool operator () (const std::pair &a, const std::pair &b) const @@ -514,10 +568,7 @@ public: /** * @brief Gets the number of threads */ - int threads () const - { - return m_threads; - } + int threads () const; /** * @brief Sets the maximum vertex count default value @@ -531,10 +582,7 @@ public: /** * @brief Gets the maximum vertex count */ - size_t max_vertex_count () const - { - return m_max_vertex_count; - } + size_t max_vertex_count () const; /** * @brief Sets the max. area ratio for bounding box vs. polygon area @@ -548,10 +596,7 @@ public: /** * @brief Gets the max. area ratio */ - double max_area_ratio () const - { - return m_max_area_ratio; - } + double max_area_ratio () const; /** * @brief Sets the text property name @@ -566,10 +611,7 @@ public: /** * @brief Gets the text property name */ - const tl::Variant &text_property_name () const - { - return m_text_property_name; - } + const tl::Variant &text_property_name () const; /** * @brief Sets the text enlargement value @@ -584,10 +626,45 @@ public: /** * @brief Gets the text enlargement value */ - int text_enlargement () const - { - return m_text_enlargement; - } + int text_enlargement () const; + + /** + * @brief Gets the breakout cells for a given layout + * Returns 0 if there are no breakout cells for this layout. + */ + const std::set *breakout_cells (unsigned int layout_index) const; + + /** + * @brief Clears the breakout cell list for a given layout + */ + void clear_breakout_cells (unsigned int layout_index); + + /** + * @brief Sets the breakout cell list for a given layout + */ + void set_breakout_cells (unsigned int layout_index, const std::set &boc); + + /** + * @brief Adds a breakout cell for a given layout + */ + void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci); + + /** + * @brief Adds breakout cells for a given layout + */ + void add_breakout_cells (unsigned int layout_index, const std::set &cc); + + /** + * @brief Pushes the state on the state stack + * The state involves threads, max_area_ratio, max_vertex_count, the breakout cells and + * the text representation properties (enlargement, property name). + */ + void push_state (); + + /** + * @brief Pops the state (see @ref push_state) + */ + void pop_state (); private: friend class DeepLayer; @@ -614,11 +691,8 @@ private: std::map > m_layers_for_flat; std::map, size_t> m_flat_region_id; layout_map_type m_layout_map; - int m_threads; - double m_max_area_ratio; - size_t m_max_vertex_count; - tl::Variant m_text_property_name; - int m_text_enlargement; + DeepShapeStoreState m_state; + std::list m_state_stack; tl::Mutex m_lock; struct DeliveryMappingCacheKey diff --git a/src/db/db/dbDeviceClass.cc b/src/db/db/dbDeviceClass.cc index d16daf212..7ae697472 100644 --- a/src/db/db/dbDeviceClass.cc +++ b/src/db/db/dbDeviceClass.cc @@ -136,13 +136,13 @@ bool AllDeviceParametersAreEqual::equal (const db::Device &a, const db::Device & // DeviceClass class implementation DeviceClass::DeviceClass () - : mp_netlist (0), m_strict (false) + : m_strict (false), mp_netlist (0) { // .. nothing yet .. } DeviceClass::DeviceClass (const DeviceClass &other) - : gsi::ObjectBase (other), tl::Object (other), tl::UniqueId (other), mp_netlist (0), m_strict (false) + : gsi::ObjectBase (other), tl::Object (other), tl::UniqueId (other), m_strict (false), mp_netlist (0) { operator= (other); } diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index f2e88a520..3c85dc9be 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -60,6 +60,13 @@ template void insert_transformed (db::Layout & /* shapes.insert (s.transformed (t)); } +// ------------------------------------------------------------------------------ + +static bool is_breakout_cell (const std::set *breakout_cells, db::cell_index_type ci) +{ + return breakout_cells && breakout_cells->find (ci) != breakout_cells->end (); +} + // ------------------------------------------------------------------------------ // Connectivity implementation @@ -1117,11 +1124,11 @@ void hier_clusters::clear () template void -hier_clusters::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) +hier_clusters::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells) { clear (); cell_clusters_box_converter cbc (layout, *this); - do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence); + do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence, breakout_cells); } namespace @@ -1159,8 +1166,8 @@ public: /** * @brief Constructor */ - hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn) - : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn) + hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells, typename hier_clusters::instance_interaction_cache_type *instance_interaction_cache) + : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn), mp_breakout_cells (breakout_cells), mp_instance_interaction_cache (instance_interaction_cache) { mp_cell_clusters = &cell_clusters; } @@ -1170,9 +1177,37 @@ public: */ void add (const db::Instance *i1, unsigned int /*p1*/, const db::Instance *i2, unsigned int /*p2*/) { - std::vector p; - db::ICplxTrans t; - add_pair (box_type::world (), *i1, p, t, *i2, p, t); + db::ICplxTrans t1 = i1->complex_trans (); + db::ICplxTrans t2 = i2->complex_trans (); + db::ICplxTrans t21 = t1.inverted () * t2; + + InstanceToInstanceInteraction ii_key (i1->cell_index (), i2->cell_index (), t21); + + instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key); + if (ii != mp_instance_interaction_cache->end ()) { + + db::ICplxTrans ic_trans = t1 * ii->second.first.inverted (); + connect_clusters (ii->second.second, &ic_trans, i1->prop_id (), i2->prop_id ()); + + } else { + + std::list > &ic = mp_instance_interaction_cache->insert (std::make_pair (ii_key, std::make_pair (t1, cluster_instance_pair_list_type ()))).first->second.second; + + std::vector p; + db::ICplxTrans t; + add_pair (box_type::world (), *i1, p, t, *i2, p, t, ic); + +#if 1 + // For debugging: ensures the instance properties are configured properly (important for cache consistency) + for (cluster_instance_pair_list_type::const_iterator i = ic.begin (); i != ic.end (); ++i) { + tl_assert (i->first.inst_prop_id () == i1->prop_id ()); + tl_assert (i->second.inst_prop_id () == i2->prop_id ()); + } +#endif + + connect_clusters (ic); + + } } /** @@ -1180,9 +1215,7 @@ public: */ void finish (const db::Instance *i, unsigned int /*p1*/) { - if (i->size () > 1) { - add_single_inst (*i); - } + add_single_inst (*i); } /** @@ -1243,16 +1276,45 @@ public: } private: + struct InteractionKeyForClustersType + : public InstanceToInstanceInteraction + { + InteractionKeyForClustersType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21, const box_type &_box) + : InstanceToInstanceInteraction (_ci1, _ci2, _t21), box (_box) + { } + + bool operator== (const InteractionKeyForClustersType &other) const + { + return InstanceToInstanceInteraction::operator== (other) && box == other.box; + } + + bool operator< (const InteractionKeyForClustersType &other) const + { + if (! InstanceToInstanceInteraction::operator== (other)) { + return InstanceToInstanceInteraction::operator< (other); + } + if (box != other.box) { + return box < other.box; + } + return false; + } + + box_type box; + }; + const db::Layout *mp_layout; const db::Cell *mp_cell; db::connected_clusters *mp_cell_clusters; hier_clusters *mp_tree; const cell_clusters_box_converter *mp_cbc; const db::Connectivity *mp_conn; + const std::set *mp_breakout_cells; typedef std::list > join_set_list; std::map m_cm2join_map; join_set_list m_cm2join_sets; std::list m_ci_interactions; + std::map > > m_interaction_cache_for_clusters; + instance_interaction_cache_type *mp_instance_interaction_cache; /** * @brief Handles the cluster interactions between two instances or instance arrays @@ -1264,8 +1326,12 @@ private: * @param p2 The instantiation path to the child cell (not including i2) * @param t2 The accumulated transformation of the path, not including i2 */ - void add_pair (const box_type &common, const db::Instance &i1, const std::vector &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2) + void add_pair (const box_type &common, const db::Instance &i1, const std::vector &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2, std::list > &interacting_clusters) { + if (is_breakout_cell (mp_breakout_cells, i1.cell_index ()) || is_breakout_cell (mp_breakout_cells, i2.cell_index ())) { + return; + } + box_type bb1 = (*mp_cbc) (i1.cell_index ()); box_type b1 = i1.cell_inst ().bbox (*mp_cbc).transformed (t1); @@ -1310,12 +1376,12 @@ private: pp2.insert (pp2.end (), p2.begin (), p2.end ()); pp2.push_back (ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ())); - add_single_pair (common12, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2); + add_single_pair (common12, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2, interacting_clusters); // dive into cell of ii2 const db::Cell &cell2 = mp_layout->cell (i2.cell_index ()); for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common12.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) { - add_pair (common12, i1, p1, t1, *jj2, pp2, tt2); + add_pair (common12, i1, p1, t1, *jj2, pp2, tt2, interacting_clusters); } } @@ -1329,7 +1395,7 @@ private: // dive into cell of ii1 const db::Cell &cell1 = mp_layout->cell (i1.cell_index ()); for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common1.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) { - add_pair (common1, *jj1, pp1, tt1, i2, p2, t2); + add_pair (common1, *jj1, pp1, tt1, i2, p2, t2, interacting_clusters); } } @@ -1349,75 +1415,70 @@ private: */ void add_single_pair (const box_type &common, db::cell_index_type ci1, const std::vector &p1, const db::ICplxTrans &t1, - db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) + db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2, + cluster_instance_pair_list_type &interacting_clusters) { - const db::Cell &cell2 = mp_layout->cell (ci2); - - const db::local_clusters &cl1 = mp_tree->clusters_per_cell (ci1); - const db::local_clusters &cl2 = mp_tree->clusters_per_cell (ci2); + if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) { + return; + } db::ICplxTrans t1i = t1.inverted (); db::ICplxTrans t2i = t2.inverted (); db::ICplxTrans t21 = t1i * t2; + box_type common2 = common.transformed (t2i); + // NOTE: make_path may disturb the iteration (because of modification), hence // we first collect and then process the interactions. - std::vector > interactions; + const std::vector > *interactions; - for (typename db::local_clusters::touching_iterator i = cl1.begin_touching (common.transformed (t1i)); ! i.at_end (); ++i) { + InteractionKeyForClustersType ikey (ci1, ci2, t21, common2); - // skip the test, if this cluster doesn't interact with the whole cell2 - if (! i->interacts (cell2, t21, *mp_conn)) { - continue; - } + typename std::map > >::const_iterator ici = m_interaction_cache_for_clusters.find (ikey); + if (ici != m_interaction_cache_for_clusters.end ()) { - box_type bc1 = common & i->bbox ().transformed (t1); - for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc1.transformed (t2i)); ! j.at_end (); ++j) { + interactions = &ici->second; + + } else { + + const db::Cell &cell2 = mp_layout->cell (ci2); + + const db::local_clusters &cl1 = mp_tree->clusters_per_cell (ci1); + const db::local_clusters &cl2 = mp_tree->clusters_per_cell (ci2); + + std::vector > new_interactions; + db::ICplxTrans t12 = t2i * t1; + + for (typename db::local_clusters::touching_iterator i = cl1.begin_touching (common2.transformed (t21)); ! i.at_end (); ++i) { + + // skip the test, if this cluster doesn't interact with the whole cell2 + if (! i->interacts (cell2, t21, *mp_conn)) { + continue; + } + + box_type bc2 = (common2 & i->bbox ().transformed (t12)); + for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) { + + if (i->interacts (*j, t21, *mp_conn)) { + new_interactions.push_back (std::make_pair (i->id (), j->id ())); + } - if (i->interacts (*j, t21, *mp_conn)) { - interactions.push_back (std::make_pair (i->id (), j->id ())); } } + std::vector > &out = m_interaction_cache_for_clusters [ikey]; + out = new_interactions; + interactions = &out; + } - for (std::vector >::const_iterator ii = interactions.begin (); ii != interactions.end (); ++ii) { + for (std::vector >::const_iterator ii = interactions->begin (); ii != interactions->end (); ++ii) { ClusterInstance k1 = make_path (ii->first, p1); ClusterInstance k2 = make_path (ii->second, p2); - id_type x1 = mp_cell_clusters->find_cluster_with_connection (k1); - id_type x2 = mp_cell_clusters->find_cluster_with_connection (k2); - - if (x1 == 0) { - - if (x2 == 0) { - - id_type connector = mp_cell_clusters->insert_dummy (); - mp_cell_clusters->add_connection (connector, k1); - mp_cell_clusters->add_connection (connector, k2); - - } else { - mp_cell_clusters->add_connection (x2, k1); - } - - } else if (x2 == 0) { - - mp_cell_clusters->add_connection (x1, k2); - - } else if (x1 != x2) { - - // for instance-to-instance interactions the number of connections is more important for the - // cost of the join operation: make the one with more connections the target - if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) { - std::swap (x1, x2); - } - - mp_cell_clusters->join_cluster_with (x1, x2); - mp_cell_clusters->remove_cluster (x2); - - } + interacting_clusters.push_back (std::make_pair (k1, k2)); } } @@ -1427,6 +1488,10 @@ private: */ void add_single_inst (const db::Instance &i) { + if (is_breakout_cell (mp_breakout_cells, i.cell_index ())) { + return; + } + box_type bb = (*mp_cbc) (i.cell_index ()); const db::Cell &cell = mp_layout->cell (i.cell_index ()); @@ -1456,8 +1521,10 @@ private: std::vector pp2; pp2.push_back (ClusterInstElement (i.cell_index (), i.complex_trans (*ii2), i.prop_id ())); + cluster_instance_pair_list_type interacting_clusters; + box_type common = (ib & ib2); - add_single_pair (common, i.cell_index (), pp, tt, i.cell_index (), pp2, tt2); + add_single_pair (common, i.cell_index (), pp, tt, i.cell_index (), pp2, tt2, interacting_clusters); // dive into cell of ii2 - this is a self-interaction of a cell with parts of itself // as these self-interactions are expected to be the same always (regular array), we can skip this test the next times. @@ -1465,10 +1532,12 @@ private: for (db::Cell::touching_iterator jj2 = cell.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) { std::vector p; db::ICplxTrans t; - add_pair (common, i, p, t, *jj2, pp2, tt2); + add_pair (common, i, p, t, *jj2, pp2, tt2, interacting_clusters); } } + connect_clusters (interacting_clusters); + any = true; } @@ -1494,6 +1563,10 @@ private: */ void add_pair (const local_cluster &c1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2) { + if (is_breakout_cell (mp_breakout_cells, i2.cell_index ())) { + return; + } + box_type b1 = c1.bbox (); box_type bb2 = (*mp_cbc) (i2.cell_index ()); @@ -1519,6 +1592,7 @@ private: if (b1.touches (ib2) && c1.interacts (cell2, tt2, *mp_conn)) { pp2.back () = ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ()); + add_single_pair (c1, i2.cell_index (), pp2, tt2); // dive into cell of ii2 @@ -1541,6 +1615,10 @@ private: void add_single_pair (const local_cluster &c1, db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) { + if (is_breakout_cell (mp_breakout_cells, ci2)) { + return; + } + // NOTE: make_path may disturb the iteration (because of modification), hence // we first collect and then process the interactions. @@ -1638,6 +1716,58 @@ private: { return mp_tree->make_path (*mp_layout, *mp_cell, id, path); } + + /** + * @brief Establishes connections between the cluster instances listed in the argument + */ + void connect_clusters (const cluster_instance_pair_list_type &interacting_clusters, const db::ICplxTrans *ic_trans = 0, db::properties_id_type prop_id1 = 0, db::properties_id_type prop_id2 = 0) + { + for (cluster_instance_pair_list_type::const_iterator ic = interacting_clusters.begin (); ic != interacting_clusters.end (); ++ic) { + + ClusterInstance k1 = ic->first; + ClusterInstance k2 = ic->second; + + if (ic_trans) { + k1.transform (*ic_trans); + k1.set_inst_prop_id (prop_id1); + k2.transform (*ic_trans); + k2.set_inst_prop_id (prop_id2); + } + + id_type x1 = mp_cell_clusters->find_cluster_with_connection (k1); + id_type x2 = mp_cell_clusters->find_cluster_with_connection (k2); + + if (x1 == 0) { + + if (x2 == 0) { + + id_type connector = mp_cell_clusters->insert_dummy (); + mp_cell_clusters->add_connection (connector, k1); + mp_cell_clusters->add_connection (connector, k2); + + } else { + mp_cell_clusters->add_connection (x2, k1); + } + + } else if (x2 == 0) { + + mp_cell_clusters->add_connection (x1, k2); + + } else if (x1 != x2) { + + // for instance-to-instance interactions the number of connections is more important for the + // cost of the join operation: make the one with more connections the target + if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) { + std::swap (x1, x2); + } + + mp_cell_clusters->join_cluster_with (x1, x2); + mp_cell_clusters->remove_cluster (x2); + + } + + } + } }; template @@ -1793,7 +1923,7 @@ hier_clusters::make_path (const db::Layout &layout, const db::Cell &cell, siz template void -hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) +hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells) { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters"))); @@ -1815,6 +1945,8 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou // build the hierarchical connections bottom-up and for all cells whose children are computed already + instance_interaction_cache_type instance_interaction_cache; + { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing hierarchical shape clusters"))); tl::RelativeProgress progress (tl::to_string (tr ("Computing hierarchical clusters")), called.size (), 1); @@ -1835,7 +1967,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou todo.push_back (*c); } else { tl_assert (! todo.empty ()); - build_hier_connections_for_cells (cbc, layout, todo, conn, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); done.insert (todo.begin (), todo.end ()); todo.clear (); todo.push_back (*c); @@ -1845,7 +1977,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou } - build_hier_connections_for_cells (cbc, layout, todo, conn, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); } } @@ -1865,10 +1997,10 @@ hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell template void -hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, tl::RelativeProgress &progress) +hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache) { for (std::vector::const_iterator c = cells.begin (); c != cells.end (); ++c) { - build_hier_connections (cbc, layout, layout.cell (*c), conn); + build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells, instance_interaction_cache); ++progress; } } @@ -1952,7 +2084,7 @@ private: template void -hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn) +hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache) { std::string msg = tl::to_string (tr ("Computing hierarchical clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ())); if (tl::verbosity () >= m_base_verbosity + 20) { @@ -1964,7 +2096,7 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c // NOTE: this is a receiver for both the child-to-child and // local to child interactions. - std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn)); + std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache)); cell_inst_clusters_box_converter cibc (cbc); // The box scanner needs pointers so we have to first store the instances @@ -1992,7 +2124,9 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c db::box_scanner bs (true, desc); for (std::vector::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) { - bs.insert (inst.operator-> (), 0); + if (! is_breakout_cell (breakout_cells, inst->cell_index ())) { + bs.insert (inst.operator-> (), 0); + } } bs.process (*rec, 1 /*touching*/, cibc); @@ -2026,7 +2160,9 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c } for (std::vector::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) { - bs2.insert2 (inst.operator-> (), 0); + if (! is_breakout_cell (breakout_cells, inst->cell_index ())) { + bs2.insert2 (inst.operator-> (), 0); + } } bs2.process (*rec, 1 /*touching*/, local_cluster_box_convert (), cibc); diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 03d2df07c..a47e93bd8 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -33,6 +33,8 @@ #include "tlEquivalenceClusters.h" #include +#include +#include #include #include @@ -608,6 +610,14 @@ public: return m_inst_prop_id; } + /** + * @brief Sets the instance properties id + */ + void set_inst_prop_id (db::properties_id_type pid) + { + m_inst_prop_id = pid; + } + /** * @brief Transform with the given transformation */ @@ -722,6 +732,42 @@ private: size_t m_id; }; +typedef std::list > cluster_instance_pair_list_type; + +/** + * @brief A helper struct to describe a pair of cell instances with a specific relative transformation + */ +struct InstanceToInstanceInteraction +{ + InstanceToInstanceInteraction (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21) + : ci1 (_ci1), ci2 (_ci2), t21 (_t21) + { } + + bool operator== (const InstanceToInstanceInteraction &other) const + { + return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21); + } + + bool operator< (const InstanceToInstanceInteraction &other) const + { + if (ci1 != other.ci1) { + return ci1 < other.ci1; + } + if (ci2 != other.ci2) { + return ci2 < other.ci2; + } + if (! t21.equal (other.t21)) { + return t21.less (other.t21); + } + return false; + } + + db::cell_index_type ci1, ci2; + db::ICplxTrans t21; +}; + +typedef std::map > instance_interaction_cache_type; + template class hier_clusters; template class connected_clusters; @@ -895,6 +941,7 @@ class DB_PUBLIC hier_clusters { public: typedef typename local_cluster::box_type box_type; + typedef std::map > instance_interaction_cache_type; /** * @brief Creates an empty set of clusters @@ -912,7 +959,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 tl::equivalence_clusters *attr_equivalence = 0); + void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0, const std::set *breakout_cells = 0); /** * @brief Gets the connected clusters for a given cell @@ -951,9 +998,9 @@ public: 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 *attr_equivalence); - void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn); - void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, tl::RelativeProgress &progress); - void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0); + void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache); + void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache); + void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells); std::map > m_per_cell_clusters; int m_base_verbosity; diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 1385deea2..30374c11d 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1046,15 +1046,21 @@ template class DB_PUBLIC local_processor_result_computation_task -local_processor::local_processor (db::Layout *layout, db::Cell *top) - : mp_subject_layout (layout), mp_intruder_layout (layout), mp_subject_top (top), mp_intruder_top (top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) +local_processor::local_processor (db::Layout *layout, db::Cell *top, const std::set *breakout_cells) + : mp_subject_layout (layout), mp_intruder_layout (layout), + mp_subject_top (top), mp_intruder_top (top), + mp_subject_breakout_cells (breakout_cells), mp_intruder_breakout_cells (breakout_cells), + m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) { // .. nothing yet .. } template -local_processor::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top) - : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), mp_subject_top (subject_top), mp_intruder_top (intruder_top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) +local_processor::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top, const std::set *subject_breakout_cells, const std::set *intruder_breakout_cells) + : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), + mp_subject_top (subject_top), mp_intruder_top (intruder_top), + mp_subject_breakout_cells (subject_breakout_cells), mp_intruder_breakout_cells (intruder_breakout_cells), + m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) { // .. nothing yet .. } @@ -1265,10 +1271,10 @@ void local_processor::compute_contexts (local_processor_contextsbegin (); !i.at_end (); ++i) { unsigned int iid = ++id; - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), iid); } - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), iid); } } @@ -1276,14 +1282,14 @@ void local_processor::compute_contexts (local_processor_contextsbegin (); !i.at_end (); ++i) { - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), ++id); } } if (intruder_cell) { for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) { - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), ++id); } } @@ -1306,7 +1312,7 @@ void local_processor::compute_contexts (local_processor_contexts rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions); for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) { - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), 0); } } @@ -1701,7 +1707,7 @@ local_processor::compute_local_cell (const db::local_processor_conte } else if (intruder_cell) { // TODO: can we confine this search to the subject's (sized) bounding box? for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) { - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), ++inst_id); } } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 6444c8753..fcef32df4 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -368,8 +368,8 @@ template class DB_PUBLIC local_processor { public: - local_processor (db::Layout *layout, db::Cell *top); - local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell); + local_processor (db::Layout *layout, db::Cell *top, const std::set *breakout_cells = 0); + local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set *subject_breakout_cells = 0, const std::set *intruder_breakout_cells = 0); void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer); void compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, unsigned int intruder_layer) const; void compute_results (local_processor_contexts &contexts, const local_operation *op, unsigned int output_layer) const; @@ -427,6 +427,8 @@ private: const db::Layout *mp_intruder_layout; db::Cell *mp_subject_top; const db::Cell *mp_intruder_top; + const std::set *mp_subject_breakout_cells; + const std::set *mp_intruder_breakout_cells; std::string m_description; unsigned int m_nthreads; size_t m_max_vertex_count; @@ -445,6 +447,16 @@ private: void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const; void compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::unordered_set &result) const; std::pair effective_instance (local_processor_contexts &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const; + + bool subject_cell_is_breakout (db::cell_index_type ci) const + { + return mp_subject_breakout_cells && mp_subject_breakout_cells->find (ci) != mp_subject_breakout_cells->end (); + } + + bool intruder_cell_is_breakout (db::cell_index_type ci) const + { + return mp_intruder_breakout_cells && mp_intruder_breakout_cells->find (ci) != mp_intruder_breakout_cells->end (); + } }; } diff --git a/src/db/db/dbLibrary.cc b/src/db/db/dbLibrary.cc index 71989274e..008af5085 100644 --- a/src/db/db/dbLibrary.cc +++ b/src/db/db/dbLibrary.cc @@ -36,7 +36,7 @@ Library::Library() } Library::Library(const Library &d) - : gsi::ObjectBase (), m_name (d.m_name), m_description (d.m_description), m_id (0), m_layout (d.m_layout) + : gsi::ObjectBase (), tl::Object (), m_name (d.m_name), m_description (d.m_description), m_id (0), m_layout (d.m_layout) { // .. nothing yet .. } diff --git a/src/db/db/dbNet.h b/src/db/db/dbNet.h index dd476652a..25e19324f 100644 --- a/src/db/db/dbNet.h +++ b/src/db/db/dbNet.h @@ -603,9 +603,17 @@ public: } /** - * @brief Returns true, if the net is floating (there is no active element on the net) + * @brief Returns true, if the net is floating (there is no device, no subcircuit and no pin) */ bool is_floating () const + { + return (m_subcircuit_pins.size () + m_terminals.size () + m_pins.size ()) < 1; + } + + /** + * @brief Returns true, if the net is passive (there is no active element on the net) + */ + bool is_passive () const { return (m_subcircuit_pins.size () + m_terminals.size ()) < 1; } diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 429ea8b7d..62056542c 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -380,6 +380,30 @@ void Netlist::purge_circuit (Circuit *circuit) remove_circuit (circuit); } +void Netlist::flatten_circuits (const std::vector &circuits) +{ + if (circuits.empty ()) { + return; + } + + std::set circuits_set (circuits.begin (), circuits.end ()); + + std::vector to_flatten; + to_flatten.reserve (circuits.size ()); + + // Before flatten, we sort top-down. This optimizes for the case of flattening away + // some hierarchy above a certain circuit. + for (top_down_circuit_iterator c = begin_top_down (); c != end_top_down (); ++c) { + if (circuits_set.find (c.operator-> ()) != circuits_set.end ()) { + to_flatten.push_back (c.operator-> ()); + } + } + + for (std::vector::const_iterator c = to_flatten.begin (); c != to_flatten.end (); ++c) { + flatten_circuit (*c); + } +} + void Netlist::flatten_circuit (Circuit *circuit) { tl_assert (circuit != 0); @@ -485,8 +509,16 @@ void Netlist::purge () Circuit *circuit = c.operator-> (); + // purge floating, disconnected nets circuit->purge_nets (); - if (circuit->begin_nets () == circuit->end_nets () && ! circuit->dont_purge ()) { + + // if only passive nets are left, consider this circuit for purging + bool purge_candidate = ! circuit->dont_purge (); + for (db::Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets () && purge_candidate; ++n) { + purge_candidate = n->is_passive (); + } + + if (purge_candidate) { // No nets left: delete the subcircuits that refer to us and finally delete the circuit while (circuit->begin_refs () != circuit->end_refs ()) { diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index 760fa381f..ff961036b 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -174,6 +174,12 @@ public: */ void flatten_circuit (Circuit *circuit); + /** + * @brief Flattens the given circuits + * This is basically equivalent to calling flatten on all given circuits, but more efficient. + */ + void flatten_circuits (const std::vector &circuits); + /** * @brief Flattens the netlist */ diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 1124dae2d..7ca7590b2 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -42,6 +42,18 @@ // (applies to circuits, device classes) #define COMPARE_CASE_INSENSITIVE +// A constant indicating a failed match +const size_t failed_match = std::numeric_limits::max (); + +// A constant indicating an unknown match +// const size_t unknown_match = std::numeric_limits::max () - 1; + +// A constant indicating an invalid ID +const size_t invalid_id = std::numeric_limits::max (); + +// A constant indicating an unknown ID +const size_t unknown_id = std::numeric_limits::max () - 1; + namespace db { @@ -320,7 +332,7 @@ public: } else if (! ca) { same (cb, ca); } else if (! cb) { - // makeing a object same as null will make this device being ignored + // making a object same as null will make this device being ignored m_cat_by_ptr [ca] = 0; return; } @@ -489,13 +501,10 @@ public: void same_circuit (const db::Circuit *ca, const db::Circuit *cb) { // no arbitrary cross-pairing + // NOTE: many layout circuits are allowed for one schematic to account for layout alternatives. if (ca && has_cat_for (ca)) { throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + ca->name ()); } - if (cb && has_cat_for (cb)) { - throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + cb->name ()); - } - generic_categorizer::same (ca, cb); } @@ -663,12 +672,9 @@ public: std::string to_string () const { if (is_for_subcircuit ()) { - size_t pin_id1 = std::numeric_limits::max () - m_id1; - size_t pin_id2 = m_id2; const db::SubCircuit *sc = subcircuit_pair ().first; const db::Circuit *c = sc->circuit_ref (); - return std::string ("X") + sc->expanded_name () + " " + c->name () + " " - + "(" + c->pin_by_id (pin_id1)->expanded_name () + ")->(" + c->pin_by_id (pin_id2)->expanded_name () + ")"; + return std::string ("X") + sc->expanded_name () + " " + c->name (); } else { size_t term_id1 = m_id1; size_t term_id2 = m_id2; @@ -754,7 +760,17 @@ public: bool has_other () const { - return m_other_net_index != std::numeric_limits::max (); + return m_other_net_index != invalid_id && m_other_net_index != unknown_id; + } + + bool has_any_other () const + { + return m_other_net_index != invalid_id; + } + + bool has_unknown_other () const + { + return m_other_net_index == unknown_id; } size_t other_net_index () const @@ -769,7 +785,7 @@ public: void unset_other_net () { - m_other_net_index = std::numeric_limits::max (); + m_other_net_index = invalid_id; } bool empty () const @@ -857,7 +873,7 @@ std::string indent (size_t depth) { std::string s; for (size_t d = 0; d < depth; ++d) { - s += " "; + s += "| "; } return s; } @@ -1024,7 +1040,7 @@ private: // -------------------------------------------------------------------------------------------------------------------- NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map *circuit_map, const CircuitPinMapper *pin_map) - : mp_net (net), m_other_net_index (std::numeric_limits::max ()) + : mp_net (net), m_other_net_index (invalid_id) { if (! net) { return; @@ -1130,7 +1146,7 @@ NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_catego } NetGraphNode::NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map *circuit_map, const CircuitPinMapper *pin_map) - : mp_net (0), m_other_net_index (std::numeric_limits::max ()) + : mp_net (0), m_other_net_index (invalid_id) { std::map n2entry; @@ -1256,7 +1272,7 @@ NetGraphNode::to_string () const res += "(null)"; } res += "]"; - if (m_other_net_index != std::numeric_limits::max ()) { + if (m_other_net_index != invalid_id) { res += " (other: #" + tl::to_string (m_other_net_index) + ")"; } res += "\n"; @@ -1406,15 +1422,16 @@ struct NodeRange class TentativeNodeMapping { public: - TentativeNodeMapping (NetGraph *g1, NetGraph *g2) - : mp_g1 (g1), mp_g2 (g2) + TentativeNodeMapping () { } ~TentativeNodeMapping () { - for (std::vector >::const_iterator i = m_to_undo.begin (); i != m_to_undo.end (); ++i) { - mp_g1->unidentify (i->first); - mp_g2->unidentify (i->second); + for (std::vector >::const_iterator i = m_to_undo.begin (); i != m_to_undo.end (); ++i) { + i->first->unidentify (i->second); + } + for (std::vector >::const_iterator i = m_to_undo_to_unknown.begin (); i != m_to_undo_to_unknown.end (); ++i) { + i->first->identify (i->second, unknown_id); } } @@ -1423,17 +1440,40 @@ public: g1->identify (n1, n2); g2->identify (n2, n1); if (nm) { - nm->keep (n1, n2); + nm->keep (g1, n1); + nm->keep (g2, n2); + } + } + + static void map_pair_from_unknown (TentativeNodeMapping *nm, NetGraph *g1, size_t n1, NetGraph *g2, size_t n2) + { + g1->identify (n1, n2); + g2->identify (n2, n1); + if (nm) { + nm->keep_for_unknown (g1, n1); + nm->keep_for_unknown (g2, n2); + } + } + + static void map_to_unknown (TentativeNodeMapping *nm, NetGraph *g1, size_t n1) + { + g1->identify (n1, unknown_id); + if (nm) { + nm->keep (g1, n1); } } private: - std::vector > m_to_undo; - NetGraph *mp_g1, *mp_g2; + std::vector > m_to_undo, m_to_undo_to_unknown; - void keep (size_t n1, size_t n2) + void keep (NetGraph *g1, size_t n1) { - m_to_undo.push_back (std::make_pair (n1, n2)); + m_to_undo.push_back (std::make_pair (g1, n1)); + } + + void keep_for_unknown (NetGraph *g1, size_t n1) + { + m_to_undo_to_unknown.push_back (std::make_pair (g1, n1)); } }; @@ -1564,14 +1604,20 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr if (tentative) { if (nodes.size () != other_nodes.size ()) { - return std::numeric_limits::max (); +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif + return failed_match; } // 1:1 pairing is less strict if (nodes.size () > 1 || other_nodes.size () > 1) { for (size_t i = 0; i < nodes.size (); ++i) { if (! (*nodes[i] == *other_nodes[i])) { - return std::numeric_limits::max (); +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif + return failed_match; } } } @@ -1583,8 +1629,11 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr size_t bt_count = derive_node_identities_from_node_set (nodes, other_nodes, depth, n_branch, tentative, with_ambiguous, data); - if (bt_count == std::numeric_limits::max ()) { + if (bt_count == failed_match) { if (tentative) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif return bt_count; } } else { @@ -1593,6 +1642,11 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr } +#if defined(PRINT_DEBUG_NETCOMPARE) + if (! new_nodes) { + tl::info << indent(depth) << "! no updates."; + } +#endif return new_nodes; } @@ -1620,6 +1674,8 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc #if defined(PRINT_DEBUG_NETCOMPARE) if (! tentative) { tl::info << indent(depth) << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); + } else { + tl::info << indent(depth) << "tentatively deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); } #endif @@ -1664,14 +1720,56 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc ++ee_other; } - new_nodes += derive_node_identities_for_edges (e, ee, e_other, ee_other, net_index, other_net_index, depth, n_branch, tentative, with_ambiguous, data); + size_t bt_count = derive_node_identities_for_edges (e, ee, e_other, ee_other, net_index, other_net_index, depth, n_branch, tentative, with_ambiguous, data); + if (bt_count == failed_match) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair."; +#endif + return bt_count; + } else { + new_nodes += bt_count; + } + } else if (tentative) { + // in tentative mode an exact match is required: no having the same edges for a node disqualifies the node + // as matching. +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair for missing edge."; +#endif + return failed_match; } e = ee; } + if (tentative) { + + // in tentative mode, again an exact match is required + + for (NetGraphNode::edge_iterator e_other = n_other->begin (); e_other != n_other->end (); ) { + + NetGraphNode::edge_iterator ee_other = e_other; + ++ee_other; + + while (ee_other != n_other->end () && ee_other->first == e_other->first) { + ++ee_other; + } + + NetGraphNode::edge_iterator e = n->find_edge (e_other->first); + if (e == n->end ()) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair for missing edge."; +#endif + return failed_match; + } + + e_other = ee_other; + + } + + } + #if defined(PRINT_DEBUG_NETCOMPARE) if (! tentative && new_nodes > 0) { tl::info << indent(depth) << "finished pair deduction: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name () << " with " << new_nodes << " new pairs"; @@ -1689,7 +1787,7 @@ namespace { bool operator() (const NetGraphNode *a, const NetGraphNode *b) const { tl_assert (a->net () && b->net ()); - return a->net ()->name () < b->net ()->name (); + return name_compare (a->net ()->name (), b->net ()->name ()) < 0; } }; @@ -1750,7 +1848,7 @@ static bool net_names_are_different (const db::Net *a, const db::Net *b) if (! a || ! b || a->name ().empty () || b->name ().empty ()) { return false; } else { - return (a->name () != b->name ()); + return name_compare (a->name (), b->name ()) != 0; } } @@ -1758,25 +1856,22 @@ size_t NetGraph::derive_node_identities_from_node_set (std::vector &nodes, std::vector &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data) { #if defined(PRINT_DEBUG_NETCOMPARE) - std::string indent; - for (size_t d = 0; d < depth; ++d) { - indent += " "; - } - indent += "*" + tl::to_string (n_branch) + " "; + std::string indent_s = indent (depth); + indent_s += "*" + tl::to_string (n_branch) + " "; #endif size_t new_nodes = 0; if (depth > data->max_depth) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "max. depth exhausted (" << depth + 1 << ">" << data->max_depth << ")"; + tl::info << indent_s << "max. depth exhausted (" << depth + 1 << ">" << data->max_depth << ")"; #endif - return std::numeric_limits::max (); + return failed_match; } if (nodes.size () == 1 && other_nodes.size () == 1) { - if (! nodes.front ()->has_other () && ! other_nodes.front ()->has_other ()) { + if (! nodes.front ()->has_any_other () && ! other_nodes.front ()->has_any_other ()) { // a single candiate: just take this one -> this may render // inexact matches, but further propagates net pairing @@ -1787,7 +1882,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorother, other_ni); #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name (); + tl::info << indent_s << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name (); #endif if (data->logger && ! tentative) { if (! (node (ni) == data->other->node (other_ni))) { @@ -1801,7 +1896,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector::max ()) { + if (bt_count != failed_match) { new_nodes += bt_count; } else if (tentative) { return bt_count; @@ -1809,17 +1904,21 @@ NetGraph::derive_node_identities_from_node_set (std::vectorhas_unknown_other ()) { + + // accept this solution as the pairing is possible + } else if (nodes.front ()->has_other ()) { // this decision leads to a contradiction if (data->other->node_index_for_net (other_nodes.front ()->net ()) != nodes.front ()->other_net_index ()) { - return std::numeric_limits::max (); + return failed_match; } } else { // mismatch of assignment state - return std::numeric_limits::max (); + return failed_match; } @@ -1836,10 +1935,10 @@ NetGraph::derive_node_identities_from_node_set (std::vectorhas_other ()) { + if ((*n1)->has_any_other ()) { ++n1; continue; - } else if ((*n2)->has_other ()) { + } else if ((*n2)->has_any_other ()) { ++n2; continue; } @@ -1858,9 +1957,9 @@ NetGraph::derive_node_identities_from_node_set (std::vectorhas_other ()) { + if ((*nn1)->has_any_other ()) { ++nn1; - } else if ((*nn2)->has_other ()) { + } else if ((*nn2)->has_any_other ()) { ++nn2; } else if (! (**nn1 == **n1) || ! (**nn2 == **n2)) { break; @@ -1878,7 +1977,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector 1 && tentative && ! with_ambiguous) { - return std::numeric_limits::max (); + return failed_match; } n1 = nn1; @@ -1895,9 +1994,9 @@ NetGraph::derive_node_identities_from_node_set (std::vectorn1 != nr->nn1 && nr->n2 != nr->nn2) { - if ((*nr->n1)->has_other ()) { + if ((*nr->n1)->has_any_other ()) { ++nr->n1; - } else if ((*nr->n2)->has_other ()) { + } else if ((*nr->n2)->has_any_other ()) { ++nr->n2; } else { break; @@ -1908,9 +2007,9 @@ NetGraph::derive_node_identities_from_node_set (std::vector::const_iterator i1 = nr->n1, i2 = nr->n2; while (i1 != nr->nn1 && i2 != nr->nn2) { - if ((*i1)->has_other ()) { + if ((*i1)->has_any_other ()) { ++i1; - } else if ((*i2)->has_other ()) { + } else if ((*i2)->has_any_other ()) { ++i2; } else { ++nr->num; @@ -1925,16 +2024,16 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum == 1) { - if (! (*nr->n1)->has_other () && ! (*nr->n2)->has_other ()) { + if (! (*nr->n1)->has_any_other () && ! (*nr->n2)->has_any_other ()) { // in tentative mode, reject this choice if both nets are named and // their names differ -> this favors net matching by name if (tentative && ! data->dont_consider_net_names && net_names_are_different ((*nr->n1)->net (), (*nr->n2)->net ())) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "rejecting pair as names are not identical: " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); + tl::info << indent_s << "rejecting pair as names are not identical: " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); #endif - return std::numeric_limits::max (); + return failed_match; } // A single candiate: just take this one -> this may render @@ -1946,7 +2045,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorother, other_ni); #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); + tl::info << indent_s << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); #endif if (data->logger && ! tentative) { if (! (node (ni) == data->other->node (other_ni))) { @@ -1960,41 +2059,45 @@ NetGraph::derive_node_identities_from_node_set (std::vector::max ()) { + if (bt_count != failed_match) { new_nodes += bt_count; new_nodes += 1; } else if (tentative) { new_nodes = bt_count; } + } else if ((*nr->n1)->has_unknown_other ()) { + + // accept any other net + } else if ((*nr->n1)->has_other ()) { // this decision leads to a contradiction if (data->other->node_index_for_net ((*nr->n2)->net ()) != (*nr->n1)->other_net_index ()) { - return std::numeric_limits::max (); + return failed_match; } } else { // mismatch of assignment state - return std::numeric_limits::max (); + return failed_match; } } else if (nr->num * n_branch > data->max_n_branch) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch."; + tl::info << indent_s << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch."; #endif - return std::numeric_limits::max (); + return failed_match; } else { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "analyzing ambiguity group with " << nr->num << " members"; + tl::info << indent_s << "analyzing ambiguity group with " << nr->num << " members"; #endif - // sort the ambiguity group such that net names + // sort the ambiguity group such that net names match best std::vector > pairs; tl::equivalence_clusters equivalent_other_nodes; @@ -2004,70 +2107,91 @@ NetGraph::derive_node_identities_from_node_set (std::vector::const_iterator i1 = nr->n1; i1 != nr->nn1; ++i1) { + { - if ((*i1)->has_other ()) { - continue; + // marks the nodes from the ambiguity group as unknown so we don't revisit them (causing deep recursion) + TentativeNodeMapping tn2unknown; + + // collect and mark the ambiguity combinations to consider + std::vector::const_iterator> iters1, iters2; + + for (std::vector::const_iterator i1 = nr->n1; i1 != nr->nn1; ++i1) { + if (! (*i1)->has_any_other ()) { + iters1.push_back (i1); + size_t ni = node_index_for_net ((*i1)->net ()); + TentativeNodeMapping::map_to_unknown (&tn2unknown, this, ni); + } } - bool any = false; - - std::vector::const_iterator i2; - for (i2 = nr->n2; i2 != nr->nn2; ++i2) { - - if ((*i2)->has_other ()) { - continue; + for (std::vector::const_iterator i2 = nr->n2; i2 != nr->nn2; ++i2) { + if (! (*i2)->has_any_other ()) { + iters2.push_back (i2); + size_t other_ni = data->other->node_index_for_net ((*i2)->net ()); + TentativeNodeMapping::map_to_unknown (&tn2unknown, data->other, other_ni); } + } - if (seen.find (*i2) != seen.end ()) { - continue; - } + for (std::vector::const_iterator>::const_iterator ii1 = iters1.begin (); ii1 != iters1.end (); ++ii1) { - size_t ni = node_index_for_net ((*i1)->net ()); - size_t other_ni = data->other->node_index_for_net ((*i2)->net ()); + std::vector::const_iterator i1 = *ii1; - TentativeNodeMapping tn (this, data->other); - TentativeNodeMapping::map_pair (&tn, this, ni, data->other, other_ni); + bool any = false; - // try this candidate in tentative mode + for (std::vector::const_iterator>::const_iterator ii2 = iters2.begin (); ii2 != iters2.end (); ++ii2) { + + std::vector::const_iterator i2 = *ii2; + + if (seen.find (*i2) != seen.end ()) { + continue; + } + + size_t ni = node_index_for_net ((*i1)->net ()); + size_t other_ni = data->other->node_index_for_net ((*i2)->net ()); + + TentativeNodeMapping tn; + TentativeNodeMapping::map_pair_from_unknown (&tn, this, ni, data->other, other_ni); + + // try this candidate in tentative mode #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name (); + tl::info << indent_s << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name (); #endif - size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, &tn, with_ambiguous, data); + size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, &tn, with_ambiguous, data); - if (bt_count != std::numeric_limits::max ()) { + if (bt_count != failed_match) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "match found"; + tl::info << indent_s << "match found"; #endif - // we have a match ... + // we have a match ... - if (any) { + if (any) { - // there is already a known pair, so we can mark *i2 and the previous *i2 as equivalent - // (makes them ambiguous) - equivalent_other_nodes.same (*i2, pairs.back ().second); + // there is already a known pair, so we can mark *i2 and the previous *i2 as equivalent + // (makes them ambiguous) + equivalent_other_nodes.same (*i2, pairs.back ().second); - } else { + } else { - // identified a new pair - new_nodes += bt_count + 1; - pairs.push_back (std::make_pair (*i1, *i2)); - seen.insert (*i2); - any = true; + // identified a new pair + new_nodes += bt_count + 1; + pairs.push_back (std::make_pair (*i1, *i2)); + seen.insert (*i2); + any = true; + + } } } - } - - if (! any && tentative) { + if (! any && tentative) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "mismatch."; + tl::info << indent_s << "mismatch."; #endif - // a mismatch - stop here. - return std::numeric_limits::max (); + // a mismatch - stop here. + return failed_match; + } + } } @@ -2085,9 +2209,9 @@ NetGraph::derive_node_identities_from_node_set (std::vectorsecond)) { - tl::info << indent << "deduced ambiguous match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); + tl::info << indent_s << "deduced ambiguous match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); } else { - tl::info << indent << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); + tl::info << indent_s << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); } #endif if (data->logger) { @@ -2108,7 +2232,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorfirst->net ()); size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, tentative, with_ambiguous, data); - tl_assert (bt_count != std::numeric_limits::max ()); + tl_assert (bt_count != failed_match); } @@ -2126,7 +2250,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum << " members"; + tl::info << indent_s << "finished analysis of ambiguity group with " << nr->num << " members"; #endif } @@ -2150,8 +2274,8 @@ NetlistComparer::NetlistComparer (NetlistCompareLogger *logger) m_cap_threshold = -1.0; // not set m_res_threshold = -1.0; // not set - m_max_depth = 8; - m_max_n_branch = 100; + m_max_depth = 50; + m_max_n_branch = 500; m_dont_consider_net_names = false; } @@ -2227,39 +2351,39 @@ NetlistComparer::unmatched_circuits (db::Netlist *a, db::Netlist *b, std::vector // we need to create a copy because this method is supposed to be const. db::CircuitCategorizer circuit_categorizer = *mp_circuit_categorizer; - std::map > cat2circuits; + std::map, std::vector > > cat2circuits; for (db::Netlist::circuit_iterator i = a->begin_circuits (); i != a->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].first = i.operator-> (); + cat2circuits[cat].first.push_back (i.operator-> ()); } } for (db::Netlist::circuit_iterator i = b->begin_circuits (); i != b->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].second = i.operator-> (); + cat2circuits[cat].second.push_back (i.operator-> ()); } } size_t na = 0, nb = 0; - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first) { - ++nb; - } else if (! i->second.second) { - ++na; + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { + nb += i->second.second.size (); + } else if (i->second.second.empty ()) { + na += i->second.first.size (); } } in_a.reserve (na); in_b.reserve (nb); - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first) { - in_b.push_back (i->second.second); - } else if (! i->second.second) { - in_a.push_back (i->second.first); + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { + in_b.insert (in_b.end (), i->second.second.begin (), i->second.second.end ()); + } else if (i->second.second.empty ()) { + in_a.insert (in_a.end (), i->second.first.begin (), i->second.first.end ()); } } } @@ -2274,13 +2398,13 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const bool good = true; - std::map > cat2circuits; + std::map, std::vector > > cat2circuits; std::set verified_circuits_a, verified_circuits_b; for (db::Netlist::const_circuit_iterator i = a->begin_circuits (); i != a->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].first = i.operator-> (); + cat2circuits[cat].first.push_back (i.operator-> ()); } else { // skip circuit (but count it as verified) verified_circuits_a.insert (i.operator-> ()); @@ -2290,7 +2414,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const for (db::Netlist::const_circuit_iterator i = b->begin_circuits (); i != b->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].second = i.operator-> (); + cat2circuits[cat].second.push_back (i.operator-> ()); } else { // skip circuit (but count it as verified) verified_circuits_b.insert (i.operator-> ()); @@ -2342,11 +2466,21 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const // check for circuits that don't match - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first || ! i->second.second) { + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { good = false; if (mp_logger) { - mp_logger->circuit_mismatch (i->second.first, i->second.second); + for (std::vector::const_iterator j = i->second.second.begin (); j != i->second.second.end (); ++j) { + mp_logger->circuit_mismatch (0, *j); + } + } + } + if (i->second.second.empty ()) { + good = false; + if (mp_logger) { + for (std::vector::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) { + mp_logger->circuit_mismatch (*j, 0); + } } } } @@ -2355,59 +2489,62 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const for (db::Netlist::const_bottom_up_circuit_iterator c = a->begin_bottom_up (); c != a->end_bottom_up (); ++c) { - size_t ccat = circuit_categorizer.cat_for_circuit (c.operator-> ()); + const db::Circuit *ca = c.operator-> (); + + size_t ccat = circuit_categorizer.cat_for_circuit (ca); if (! ccat) { continue; } - std::map >::const_iterator i = cat2circuits.find (ccat); + std::map, std::vector > >::const_iterator i = cat2circuits.find (ccat); tl_assert (i != cat2circuits.end ()); + tl_assert (! i->second.first.empty ()); + if (i->second.second.empty ()) { + continue; + } - if (i->second.first && i->second.second) { + // NOTE: there can only be one schematic circuit + tl_assert (i->second.second.size () == size_t (1)); + const db::Circuit *cb = i->second.second.front (); - const db::Circuit *ca = i->second.first; - const db::Circuit *cb = i->second.second; + std::vector > empty; + const std::vector > *net_identity = ∅ + std::map, std::vector > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); + if (sn != m_same_nets.end ()) { + net_identity = &sn->second; + } - std::vector > empty; - const std::vector > *net_identity = ∅ - std::map, std::vector > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); - if (sn != m_same_nets.end ()) { - net_identity = &sn->second; - } - - if (all_subcircuits_verified (ca, verified_circuits_a) && all_subcircuits_verified (cb, verified_circuits_b)) { + if (all_subcircuits_verified (ca, verified_circuits_a) && all_subcircuits_verified (cb, verified_circuits_b)) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << "treating circuit: " << ca->name () << " vs. " << cb->name (); + tl::info << "treating circuit: " << ca->name () << " vs. " << cb->name (); #endif - if (mp_logger) { - mp_logger->begin_circuit (ca, cb); - } + if (mp_logger) { + mp_logger->begin_circuit (ca, cb); + } - bool pin_mismatch = false; - bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping); - if (! g) { - good = false; - } + bool pin_mismatch = false; + bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping); + if (! g) { + good = false; + } - if (! pin_mismatch) { - verified_circuits_a.insert (ca); - verified_circuits_b.insert (cb); - } + if (! pin_mismatch) { + verified_circuits_a.insert (ca); + verified_circuits_b.insert (cb); + } - derive_pin_equivalence (ca, cb, &circuit_pin_mapper); + derive_pin_equivalence (ca, cb, &circuit_pin_mapper); - if (mp_logger) { - mp_logger->end_circuit (ca, cb, g); - } + if (mp_logger) { + mp_logger->end_circuit (ca, cb, g); + } - } else { - - if (mp_logger) { - mp_logger->circuit_skipped (ca, cb); - good = false; - } + } else { + if (mp_logger) { + mp_logger->circuit_skipped (ca, cb); + good = false; } } @@ -2428,7 +2565,7 @@ std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitP for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) { const db::Net *net = c->net_for_pin (p->id ()); - if ((! net || net->is_floating ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { + if ((! net || net->is_passive ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { pins.push_back (p->id ()); } } @@ -2567,7 +2704,7 @@ struct DeviceConnectionDistance { int d = 0.0; for (std::vector >::const_iterator i = a.first.begin (), j = b.first.begin (); i != a.first.end () && j != b.first.end (); ++i, ++j) { - if (i->second != j->second || i->second == std::numeric_limits::max () || j->second == std::numeric_limits::max ()) { + if (i->second != j->second || i->second == invalid_id || j->second == invalid_id) { ++d; } } @@ -2645,6 +2782,32 @@ void align (Iter i1, Iter i2, Iter j1, Iter j2, Distance distance) } +/** + * @brief Returns true, if the given net is passive + * A passive net does not have devices nor pins except those which are ignored (not mapped). + */ +static bool is_passive_net (const db::Net *net, const std::map &circuit_and_pin_mapping) +{ + if (net->terminal_count () != 0) { + return false; + } + + if (net->subcircuit_pin_count () == 0) { + return true; + } + + for (db::Net::const_subcircuit_pin_iterator p = net->begin_subcircuit_pins (); p != net->end_subcircuit_pins (); ++p) { + const db::Circuit *c = p->subcircuit ()->circuit_ref (); + std::map::const_iterator ic; + ic = circuit_and_pin_mapping.find (c); + if (ic != circuit_and_pin_mapping.end () && ic->second.has_other_pin_for_this_pin (p->pin_id ())) { + return false; + } + } + + return true; +} + bool NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, @@ -2715,7 +2878,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, data.logger = mp_logger; size_t ni = g1.derive_node_identities (i1 - g1.begin (), 0, 1, 0 /*not tentative*/, pass > 0 /*with ambiguities*/, &data); - if (ni > 0 && ni != std::numeric_limits::max ()) { + if (ni > 0 && ni != failed_match) { new_identities += ni; #if defined(PRINT_DEBUG_NETCOMPARE) tl::info << ni << " new identities."; @@ -2749,8 +2912,12 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, } if (nodes.empty () || other_nodes.empty ()) { - if (! nodes.empty () || ! other_nodes.empty ()) { - good = false; + // active mismatched nodes give an error + for (std::vector::const_iterator n = nodes.begin (); n != nodes.end () && good; ++n) { + good = is_passive_net ((*n)->net (), c12_circuit_and_pin_mapping); + } + for (std::vector::const_iterator n = other_nodes.begin (); n != other_nodes.end () && good; ++n) { + good = is_passive_net ((*n)->net (), c22_circuit_and_pin_mapping); } // this assumes that we don't gain anything here. Stop now. break; @@ -2768,7 +2935,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, data.logger = mp_logger; size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, 0, 1, 0 /*not tentative*/, pass > 0 /*with ambiguities*/, &data); - if (ni > 0 && ni != std::numeric_limits::max ()) { + if (ni > 0 && ni != failed_match) { new_identities += ni; #if defined(PRINT_DEBUG_NETCOMPARE) tl::info << ni << " new identities."; @@ -2808,12 +2975,20 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, void NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *pin2, bool &good, bool &pin_mismatch) const { - // Determine whether the pin in question is used - only in this case we will report an error. - // Otherwise, the report will be "match" against 0. - const db::Circuit *c = pin1 ? c1 : c2; const db::Pin *pin = pin1 ? pin1 : pin2; + // If the pin isn't connected internally inside the circuit we can ignore it + if (c->net_for_pin (pin->id ()) && c->net_for_pin (pin->id ())->is_passive ()) { + if (mp_logger) { + mp_logger->match_pins (pin1, pin2); + } + return; + } + + // Determine whether the pin in question is used - only in this case we will report an error. + // Otherwise, the report will be "match" against 0. + bool is_not_connected = true; for (db::Circuit::const_refs_iterator r = c->begin_refs (); r != c->end_refs () && is_not_connected; ++r) { const db::SubCircuit *sc = r.operator-> (); @@ -2842,43 +3017,46 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g // Report pin assignment // This step also does the pin identity mapping. - // try to assign floating pins by name with higher prio - std::map > floating_pins_by_name; + // try to assign abstract pins by name with higher prio + // NOTE: An "abstract" pin is a concept that is used in the context of circuit abstracts where the circuits is + // intentionally emptied. An "abstract pin" is not just a floating pin. An abstract does not have a net while + // a floating pin has a net, but this net is passive - i.e. not attached to any device. + std::map > abstract_pins_by_name; for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) { const db::Net *net = c2->net_for_pin (p->id ()); if (!net && !p->name ().empty ()) { - floating_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> (); + abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> (); } } for (db::Circuit::const_pin_iterator p = c1->begin_pins (); p != c1->end_pins (); ++p) { const db::Net *net = c1->net_for_pin (p->id ()); if (!net && !p->name ().empty ()) { - floating_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> (); + abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> (); } } - std::map floating_pin_name_mapping; - for (std::map >::const_iterator i = floating_pins_by_name.begin (); i != floating_pins_by_name.end (); ++i) { + std::map abstract_pin_name_mapping; + for (std::map >::const_iterator i = abstract_pins_by_name.begin (); i != abstract_pins_by_name.end (); ++i) { if (i->second.first && i->second.second) { - floating_pin_name_mapping [i->second.first] = i->second.second; - floating_pin_name_mapping [i->second.second] = i->second.first; + abstract_pin_name_mapping [i->second.first] = i->second.second; + abstract_pin_name_mapping [i->second.second] = i->second.first; } } - std::vector floating_pins; + std::vector abstract_pins; std::multimap net2pin; for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) { const db::Net *net = c2->net_for_pin (p->id ()); if (net) { net2pin.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ())); - } else if (floating_pin_name_mapping.find (p.operator-> ()) == floating_pin_name_mapping.end ()) { - floating_pins.push_back (p.operator-> ()); + } else if (abstract_pin_name_mapping.find (p.operator-> ()) == abstract_pin_name_mapping.end ()) { + abstract_pins.push_back (p.operator-> ()); } } - std::vector::iterator next_float = floating_pins.begin (); + std::vector::iterator next_abstract = abstract_pins.begin (); CircuitMapper &c12_pin_mapping = c12_circuit_and_pin_mapping [c1]; c12_pin_mapping.set_other (c2); @@ -2892,10 +3070,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g const db::Net *net = c1->net_for_pin (p->id ()); if (! net) { - std::map::const_iterator fp = floating_pin_name_mapping.find (p.operator-> ()); - if (fp != floating_pin_name_mapping.end ()) { + std::map::const_iterator fp = abstract_pin_name_mapping.find (p.operator-> ()); + if (fp != abstract_pin_name_mapping.end ()) { - // assign a floating pin - this is a dummy assignment which is mitigated + // assign an abstract pin - this is a dummy assignment which is mitigated // by declaring the pins equivalent in derive_pin_equivalence if (mp_logger) { mp_logger->match_pins (p.operator-> (), fp->second); @@ -2903,17 +3081,17 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g c12_pin_mapping.map_pin (p->id (), fp->second->id ()); c22_pin_mapping.map_pin (fp->second->id (), p->id ()); - } else if (next_float != floating_pins.end ()) { + } else if (next_abstract != abstract_pins.end ()) { - // assign a floating pin - this is a dummy assignment which is mitigated + // assign an abstract pin - this is a dummy assignment which is mitigated // by declaring the pins equivalent in derive_pin_equivalence if (mp_logger) { - mp_logger->match_pins (p.operator-> (), *next_float); + mp_logger->match_pins (p.operator-> (), *next_abstract); } - c12_pin_mapping.map_pin (p->id (), (*next_float)->id ()); - c22_pin_mapping.map_pin ((*next_float)->id (), p->id ()); + c12_pin_mapping.map_pin (p->id (), (*next_abstract)->id ()); + c22_pin_mapping.map_pin ((*next_abstract)->id (), p->id ()); - ++next_float; + ++next_abstract; } else { @@ -2929,11 +3107,8 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g const db::NetGraphNode &n = *(g1.begin () + g1.node_index_for_net (net)); if (! n.has_other ()) { - handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch); - continue; - } std::multimap::iterator np = net2pin.find (n.other_net_index ()); @@ -2966,9 +3141,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g handle_pin_mismatch (c1, 0, c2, np->second, good, pin_mismatch); } - while (next_float != floating_pins.end ()) { - handle_pin_mismatch (c1, 0, c2, *next_float, good, pin_mismatch); - ++next_float; + // abstract pins must match. + while (next_abstract != abstract_pins.end ()) { + handle_pin_mismatch (c1, 0, c2, *next_abstract, good, pin_mismatch); + ++next_abstract; } } @@ -3000,7 +3176,7 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph bool mapped = true; for (std::vector >::iterator i = k.begin (); i != k.end (); ++i) { if (! g1.begin () [i->second].has_other ()) { - i->second = std::numeric_limits::max (); // normalization + i->second = invalid_id; // normalization mapped = false; } } @@ -3034,7 +3210,7 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph bool mapped = true; for (std::vector >::iterator i = k.begin (); i != k.end (); ++i) { if (! g2.begin () [i->second].has_other ()) { - i->second = std::numeric_limits::max (); // normalization + i->second = invalid_id; // normalization mapped = false; } else { i->second = g2.begin () [i->second].other_net_index (); diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index 5f1bc66c0..aa5b9f84a 100644 --- a/src/db/db/dbNetlistDeviceExtractor.cc +++ b/src/db/db/dbNetlistDeviceExtractor.cc @@ -75,7 +75,7 @@ std::string NetlistDeviceExtractorError::to_string () const // NetlistDeviceExtractor implementation NetlistDeviceExtractor::NetlistDeviceExtractor (const std::string &name) - : mp_layout (0), m_cell_index (0), m_device_scaling (1.0), mp_circuit (0) + : mp_layout (0), m_cell_index (0), mp_breakout_cells (0), m_device_scaling (1.0), mp_circuit (0) { m_name = name; m_terminal_id_propname_id = 0; @@ -184,13 +184,13 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo } - extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling); + extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling, dss.breakout_cells (layout_index)); } -void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling) +void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling, const std::set *breakout_cells) { initialize (nl); - extract_without_initialize (layout, cell, clusters, layers, device_scaling); + extract_without_initialize (layout, cell, clusters, layers, device_scaling, breakout_cells); } namespace { @@ -203,7 +203,7 @@ struct ExtractorCacheValueType { } -void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling) +void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling, const std::set *breakout_cells) { tl_assert (layers.size () == m_layer_definitions.size ()); @@ -214,6 +214,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db: m_layers = layers; mp_clusters = &clusters; m_device_scaling = device_scaling; + mp_breakout_cells = breakout_cells; // terminal properties are kept in a property with the terminal_property_name name m_terminal_id_propname_id = mp_layout->properties_repository ().prop_name_id (terminal_id_property_name ()); @@ -246,7 +247,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db: db::Connectivity device_conn = get_connectivity (layout, layers); db::hier_clusters device_clusters; - device_clusters.build (layout, cell, shape_iter_flags, device_conn); + device_clusters.build (layout, cell, shape_iter_flags, device_conn, 0, breakout_cells); tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices"))); diff --git a/src/db/db/dbNetlistDeviceExtractor.h b/src/db/db/dbNetlistDeviceExtractor.h index 5143b9c7f..e91961377 100644 --- a/src/db/db/dbNetlistDeviceExtractor.h +++ b/src/db/db/dbNetlistDeviceExtractor.h @@ -263,7 +263,7 @@ public: * * NOTE: The extractor expects "PolygonRef" type layers. */ - void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0); + void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set *breakout_cells = 0); /** * @brief Extracts the devices from a list of regions @@ -533,6 +533,7 @@ private: db::properties_id_type m_terminal_id_propname_id, m_device_id_propname_id, m_device_class_propname_id; hier_clusters_type *mp_clusters; db::cell_index_type m_cell_index; + const std::set *mp_breakout_cells; double m_device_scaling; db::Circuit *mp_circuit; db::DeviceClass *mp_device_class; @@ -553,7 +554,7 @@ private: */ void initialize (db::Netlist *nl); - void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling); + void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling, const std::set *breakout_cells); void push_new_devices (const Vector &disp_cache); void push_cached_devices (const tl::vector &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp); }; diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index 01406124e..20215b670 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -92,7 +92,6 @@ db::Connectivity NetlistDeviceExtractorMOS3Transistor::get_connectivity (const d } else { - tl_assert (layers.size () >= 4); unsigned int sdiff = layers [0]; diff --git a/src/db/db/gsiDeclDbDeepShapeStore.cc b/src/db/db/gsiDeclDbDeepShapeStore.cc index 471c6fe67..085f5366e 100644 --- a/src/db/db/gsiDeclDbDeepShapeStore.cc +++ b/src/db/db/gsiDeclDbDeepShapeStore.cc @@ -22,10 +22,78 @@ #include "gsiDecl.h" #include "dbDeepShapeStore.h" +#include "tlGlobPattern.h" namespace gsi { +static void set_or_add_breakout_cells (db::DeepShapeStore *dss, const std::string &pattern, bool add, unsigned int layout_index = std::numeric_limits::max ()) +{ + // set or add for all + if (layout_index == std::numeric_limits::max ()) { + for (unsigned int l = 0; l < dss->layouts (); ++l) { + set_or_add_breakout_cells (dss, pattern, add, l); + } + return; + } + + std::set cc; + + if (! pattern.empty ()) { + tl::GlobPattern p (pattern); + const db::Layout &ly = dss->layout (layout_index); + for (db::Layout::const_iterator ci = ly.begin (); ci != ly.end (); ++ci) { + if (p.match (ly.cell_name (ci->cell_index ()))) { + cc.insert (ci->cell_index ()); + } + } + } + + if (! add) { + dss->clear_breakout_cells (layout_index); + } + if (! cc.empty ()) { + dss->add_breakout_cells (layout_index, cc); + } +} + +static void clear_breakout_cells (db::DeepShapeStore *dss) +{ + set_or_add_breakout_cells (dss, std::string (), false); +} + +static void set_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector &cc) +{ + std::set cs (cc.begin (), cc.end ()); + dss->set_breakout_cells (layout_index, cs); +} + +static void set_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, false, layout_index); +} + +static void set_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, false); +} + +static void add_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector &cc) +{ + std::set cs (cc.begin (), cc.end ()); + dss->add_breakout_cells (layout_index, cs); +} + +static void add_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, true, layout_index); +} + +static void add_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, true); +} + Class decl_dbDeepShapeStore ("db", "DeepShapeStore", gsi::method ("instance_count", &db::DeepShapeStore::instance_count, "@hide\n" @@ -84,6 +152,82 @@ Class decl_dbDeepShapeStore ("db", "DeepShapeStore", ) + gsi::method ("text_enlargement", &db::DeepShapeStore::text_enlargement, "@brief Gets the text enlargement value.\n" + ) + + gsi::method ("clear_breakout_cells", &db::DeepShapeStore::clear_breakout_cells, gsi::arg ("layout_index"), + "@brief Clears the breakout cells\n" + "Breakout cells are a feature by which hierarchy handling can be disabled for specific cells. " + "If cells are specified as breakout cells, they don't interact with neighbor or parent cells, hence " + "are virtually isolated. Breakout cells are useful to shortcut hierarchy evaluation for cells which " + "are otherwise difficult to handle. An example are memory array cells with overlaps to their neighbors: " + "a precise handling of such cells would generate variants and the boundary of the array. Although precise, " + "this behavior leads to partial flattening and propagation of shapes. In consequence, this will also " + "result in wrong device detection in LVS applications. In such cases, these array cells can be declared " + "'breakout cells' which makes them isolated entities and variant generation does not happen.\n" + "\n" + "See also \\set_breakout_cells and \\add_breakout_cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("clear_breakout_cells", &clear_breakout_cells, + "@brief Clears the breakout cells\n" + "See the other variant of \\clear_breakout_cells for details.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"), + "@brief Sets the breakout cell list (as cell indexes) for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"), + "@brief Sets the breakout cell list (as cell name pattern) for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells3, gsi::arg ("pattern"), + "@brief Sets the breakout cell list (as cell name pattern) for the all layouts inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"), + "@brief Adds cell indexes to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cell", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cell_index"), + "@brief Adds a cell indexe to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"), + "@brief Adds cells (given by a cell name pattern) to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells3, gsi::arg ("pattern"), + "@brief Adds cells (given by a cell name pattern) to the breakout cell list to all layouts inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method ("push_state", &db::DeepShapeStore::push_state, + "@brief Pushes the store's state on the state state\n" + "This will save the stores state (\\threads, \\max_vertex_count, \\max_area_ratio, breakout cells ...) on " + "the state stack. \\pop_state can be used to restore the state.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method ("pop_state", &db::DeepShapeStore::pop_state, + "@brief Restores the store's state on the state state\n" + "This will restore the state pushed by \\push_state.\n" + "\n" + "This method has been added in version 0.26.1\n" ), "@brief An opaque layout heap for the deep region processor\n" "\n" diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 9e59ea3c2..85f985571 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -567,7 +567,14 @@ Class decl_dbNet ("db", "Net", ) + gsi::method ("is_floating?", &db::Net::is_floating, "@brief Returns true, if the net is floating.\n" - "Floating nets are those who don't have any or only a single connection (pin_count + terminal_count < 2)." + "Floating nets are those which don't have any device or subcircuit on it and are not connected through a pin." + ) + + gsi::method ("is_passive?", &db::Net::is_passive, + "@brief Returns true, if the net is passive.\n" + "Passive nets don't have devices or subcircuits on it. They can be exposed through a pin.\n" + "\\is_floating? implies \\is_passive?.\n" + "\n" + "This method has been introduced in version 0.26.1.\n" ) + gsi::method ("is_internal?", &db::Net::is_internal, "@brief Returns true, if the net is an internal net.\n" @@ -1338,7 +1345,7 @@ static void read_netlist (db::Netlist *nl, const std::string &file, db::NetlistR static void flatten_circuit_by_name (db::Netlist *nl, const std::string &name_pattern) { - std::list > circuits_to_flatten; + std::vector circuits_to_flatten; tl::GlobPattern pat (name_pattern); for (db::Netlist::circuit_iterator c = nl->begin_circuits (); c != nl->end_circuits (); ++c) { if (pat.match (c->name ())) { @@ -1346,11 +1353,7 @@ static void flatten_circuit_by_name (db::Netlist *nl, const std::string &name_pa } } - for (std::list >::iterator c = circuits_to_flatten.begin (); c != circuits_to_flatten.end (); ++c) { - if (c->get ()) { - nl->flatten_circuit (c->get ()); - } - } + nl->flatten_circuits (circuits_to_flatten); } static void blank_circuit_by_name (db::Netlist *nl, const std::string &name_pattern) @@ -1392,6 +1395,12 @@ Class decl_dbNetlist ("db", "Netlist", "@brief Flattens all circuits of the netlist\n" "After calling this method, only the top circuits will remain." ) + + gsi::method ("flatten_circuits", &db::Netlist::flatten_circuits, + "@brief Flattens all given circuits of the netlist\n" + "This method is equivalent to calling \\flatten_circuit for all given circuits, but more efficient.\n" + "\n" + "This method has been introduced in version 0.26.1" + ) + gsi::method ("flatten_circuit", &db::Netlist::flatten_circuit, gsi::arg ("circuit"), "@brief Flattens a subcircuit\n" "This method will substitute all instances (subcircuits) of the given circuit by it's " diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 7e60ba869..3fcc353da 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -35,6 +35,8 @@ #include "tlGlobPattern.h" #include +#include +#include namespace gsi { @@ -801,7 +803,7 @@ Class decl_Region ("db", "Region", "See \\strict_handling= for a description of this attribute.\n" "\n" "This method has been introduced in version 0.23.2." - ) + + ) + method ("min_coherence=", &db::Region::set_min_coherence, gsi::arg ("f"), "@brief Enable or disable minimum coherence\n" "If minimum coherence is set, the merge operations (explicit merge with \\merge or\n" diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index e6d3b7dc3..a9f2c84dd 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -1452,6 +1452,44 @@ TEST(25_Pull) } } +TEST(26_BreakoutCells) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_l26.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + + dss.add_breakout_cell (0, ly.cell_by_name ("CHILD").second); + + db::Region r12 = r1 & r2; + db::Region r1m2 = r1 - r2; + db::Region r21 = r2 & r1; + db::Region r2m1 = r2 - r1; + + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (100, 0)), r12); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (101, 0)), r1m2); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (102, 0)), r21); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (103, 0)), r2m1); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au26.gds"); +} + TEST(100_Integration) { db::Layout ly; diff --git a/src/db/unit_tests/dbDeepShapeStoreTests.cc b/src/db/unit_tests/dbDeepShapeStoreTests.cc index 9ef242efe..9aadfa660 100644 --- a/src/db/unit_tests/dbDeepShapeStoreTests.cc +++ b/src/db/unit_tests/dbDeepShapeStoreTests.cc @@ -208,3 +208,60 @@ TEST(4_FlatAndEmptyInput) EXPECT_EQ ((dr1 - dr3).to_string (), "(0,0;0,1000;1000,1000;1000,0)"); } +TEST(5_State) +{ + db::DeepShapeStore store ("TOP", 0.01); + EXPECT_EQ (store.layout ().dbu (), 0.01); + + store.set_threads (4); + EXPECT_EQ (store.threads (), 4); + store.set_max_area_ratio (2.5); + EXPECT_EQ (store.max_area_ratio (), 2.5); + store.set_max_vertex_count (100); + EXPECT_EQ (store.max_vertex_count (), size_t (100)); + store.set_text_enlargement (5); + EXPECT_EQ (store.text_enlargement (), 5); + store.set_text_property_name (tl::Variant ("x")); + EXPECT_EQ (store.text_property_name ().to_string (), "x"); + EXPECT_EQ (store.breakout_cells (0) == 0, true); + + { + std::set boc; + boc.insert (5); + store.set_breakout_cells (0, boc); + EXPECT_EQ (store.breakout_cells (0) == 0, false); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), false); + store.add_breakout_cell (0, 3); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), true); + } + + store.push_state (); + + store.set_threads (2); + store.set_max_area_ratio (1); + store.set_max_vertex_count (10); + store.set_text_enlargement (1); + store.set_text_property_name (tl::Variant ("y")); + EXPECT_EQ (store.threads (), 2); + EXPECT_EQ (store.max_area_ratio (), 1.0); + EXPECT_EQ (store.max_vertex_count (), size_t (10)); + EXPECT_EQ (store.text_enlargement (), 1); + EXPECT_EQ (store.text_property_name ().to_string (), "y"); + + store.clear_breakout_cells (0); + EXPECT_EQ (store.breakout_cells (0) == 0, true); + + store.pop_state (); + + EXPECT_EQ (store.threads (), 4); + EXPECT_EQ (store.max_area_ratio (), 2.5); + EXPECT_EQ (store.max_vertex_count (), size_t (100)); + EXPECT_EQ (store.text_enlargement (), 5); + EXPECT_EQ (store.text_property_name ().to_string (), "x"); + + EXPECT_EQ (store.breakout_cells (0) == 0, false); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), true); +} diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index c4b7ca373..53947ec0c 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -792,7 +792,7 @@ TEST(2_Probing) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I18"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I3"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I5"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -835,7 +835,7 @@ TEST(2_Probing) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I18"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I3"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I5"); } TEST(3_GlobalNetConnections) @@ -1073,7 +1073,7 @@ TEST(3_GlobalNetConnections) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -1096,7 +1096,7 @@ TEST(3_GlobalNetConnections) " subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n" " subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n" "end;\n" - "circuit INV2 ($1=(null),IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=(null));\n" + "circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n" " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" @@ -1116,7 +1116,7 @@ TEST(3_GlobalNetConnections) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); } TEST(4_GlobalNetDeviceExtraction) @@ -1360,7 +1360,7 @@ TEST(4_GlobalNetDeviceExtraction) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -1403,7 +1403,7 @@ TEST(4_GlobalNetDeviceExtraction) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); } TEST(5_DeviceExtractionWithDeviceCombination) diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 7d2443e95..820b61b1f 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -2605,8 +2605,8 @@ TEST(17_InherentlyAmbiguousDecoder) "match_nets NQ1 NQ1\n" "match_nets NQ2 NQ2\n" "match_nets NQ3 NQ3\n" - "match_ambiguous_nets NA NA\n" - "match_ambiguous_nets NB NB\n" + "match_nets NA NA\n" + "match_nets NB NB\n" "match_nets B B\n" "match_nets A A\n" "match_pins $0 $1\n" @@ -2796,3 +2796,573 @@ TEST(18_ClockTree) EXPECT_EQ (good, true); } +TEST(19_SymmetricCircuit) +{ + // Test test requires a certain depth, name sensitivity to resolve ambiguities and + // tests the backtracking paths. + + const char *nls1 = + "circuit DECODE (VDD=VDD,nn1_=nn1_,nn1=nn1,q0=q0,q0_=q0_,q1_=q1_,q1=q1,nn2=nn2,nn2_=nn2_,a0=a0,a0_=a0_,g1=g1,g0=g0,gtp=gtp,VSS=VSS,WELL=$14);" + " device PMOS4 $1 (S=VDD,G=$44,D=q1_,B=VDD) (L=1.2,W=7);" + " device PMOS4 $2 (S=q1_,G=$44,D=q1,B=VDD) (L=1.2,W=7);" + " device PMOS4 $3 (S=q1,G=$44,D=VDD,B=VDD) (L=1.2,W=7);" + " device PMOS4 $4 (S=VDD,G=$44,D=q0,B=VDD) (L=1.2,W=7);" + " device PMOS4 $5 (S=q0,G=$44,D=q0_,B=VDD) (L=1.2,W=7);" + " device PMOS4 $6 (S=q0_,G=$44,D=VDD,B=VDD) (L=1.2,W=7);" + " device PMOS4 $7 (S=q0_,G=$11,D=nn2_,B=VDD) (L=1.2,W=5);" + " device PMOS4 $8 (S=nn2_,G=$13,D=q1_,B=VDD) (L=1.2,W=5);" + " device PMOS4 $9 (S=VDD,G=g0,D=$39,B=VDD) (L=1.2,W=3);" + " device PMOS4 $10 (S=$39,G=g1,D=VDD,B=VDD) (L=1.2,W=3);" + " device PMOS4 $11 (S=VDD,G=a0_,D=$11,B=VDD) (L=1.2,W=10);" + " device PMOS4 $12 (S=$11,G=$44,D=VDD,B=VDD) (L=1.2,W=10);" + " device PMOS4 $13 (S=q0,G=$11,D=nn2,B=VDD) (L=1.2,W=5);" + " device PMOS4 $14 (S=nn1_,G=$13,D=$9,B=$14) (L=1.2,W=11);" + " device PMOS4 $15 (S=$4,G=$11,D=nn1_,B=$14) (L=1.2,W=11);" + " device PMOS4 $16 (S=VDD,G=$44,D=$13,B=VDD) (L=1.2,W=10);" + " device PMOS4 $17 (S=$13,G=a0,D=VDD,B=VDD) (L=1.2,W=10);" + " device PMOS4 $18 (S=$6,G=$11,D=nn1,B=$14) (L=1.2,W=11);" + " device PMOS4 $19 (S=nn1,G=$13,D=$8,B=$14) (L=1.2,W=11);" + " device PMOS4 $20 (S=VDD,G=$41,D=$44,B=VDD) (L=1.2,W=15);" + " device PMOS4 $21 (S=nn2,G=$13,D=q1,B=VDD) (L=1.2,W=5);" + " device PMOS4 $22 (S=VDD,G=$39,D=$37,B=VDD) (L=1.2,W=6);" + " device PMOS4 $23 (S=VDD,G=$42,D=$41,B=VDD) (L=1.2,W=3);" + " device PMOS4 $24 (S=gtp,G=$39,D=$42,B=VDD) (L=1.2,W=16);" + " device NMOS4 $25 (S=$44,G=$41,D=VSS,B=VSS) (L=1.2,W=22);" + " device NMOS4 $26 (S=VSS,G=$39,D=$37,B=VSS) (L=1.2,W=9);" + " device NMOS4 $27 (S=q0_,G=$6,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 $28 (S=VSS,G=$8,D=q1_,B=VSS) (L=1.2,W=1);" + " device NMOS4 $29 (S=$13,G=$44,D=$35,B=VSS) (L=1.2,W=19);" + " device NMOS4 $30 (S=$35,G=a0,D=VSS,B=VSS) (L=1.2,W=19);" + " device NMOS4 $31 (S=gtp,G=$37,D=$42,B=VSS) (L=1.2,W=16);" + " device NMOS4 $32 (S=VSS,G=$39,D=$42,B=VSS) (L=1.2,W=20);" + " device NMOS4 $33 (S=VSS,G=$4,D=q0,B=VSS) (L=1.2,W=1);" + " device NMOS4 $34 (S=VSS,G=$11,D=$6,B=VSS) (L=1.2,W=18);" + " device NMOS4 $35 (S=$9,G=$13,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 $36 (S=VSS,G=$11,D=$4,B=VSS) (L=1.2,W=18);" + " device NMOS4 $37 (S=q1,G=$9,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 $38 (S=$8,G=$13,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 $39 (S=VSS,G=a0_,D=$34,B=VSS) (L=1.2,W=19);" + " device NMOS4 $40 (S=$34,G=$44,D=$11,B=VSS) (L=1.2,W=19);" + " device NMOS4 $41 (S=VSS,G=g0,D=$40,B=VSS) (L=1.2,W=17);" + " device NMOS4 $42 (S=$40,G=g1,D=$39,B=VSS) (L=1.2,W=17);" + " device NMOS4 $43 (S=VSS,G=$42,D=$41,B=VSS) (L=1.2,W=2);" + "end;" + ; + + const char *nls2 = + "circuit DECODE (A0=A0,A0_=A0_,Q0=Q0,Q0_=Q0_,Q1=Q1,Q1_=Q1_,NN2=NN2,NN2_=NN2_,NN1=NN1,NN1_=NN1_,G0=G0,G1=G1,NN3=NN3,VDD=VDD,VSS=VSS,WELL=WELL);" + " device NMOS4 '0' (S=HNET44,G=A0,D=VSS,B=VSS) (L=1.2,W=19);" + " device NMOS4 '1' (S=CS1,G=YI,D=HNET44,B=VSS) (L=1.2,W=19);" + " device PMOS4 '10' (S=VDD,G=G0,D=NET194,B=VDD) (L=1.2,W=3);" + " device PMOS4 '11' (S=VDD,G=G1,D=NET194,B=VDD) (L=1.2,W=3);" + " device NMOS4 '12' (S=NET200,G=CS0,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 '13' (S=VSS,G=CS1,D=NET175,B=VSS) (L=1.2,W=18);" + " device NMOS4 '14' (S=VSS,G=CS0,D=NET181,B=VSS) (L=1.2,W=18);" + " device NMOS4 '15' (S=NET215,G=CS1,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 '16' (S=Q1,G=NET175,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 '17' (S=VSS,G=NET200,D=Q0,B=VSS) (L=1.2,W=1);" + " device NMOS4 '18' (S=Q0_,G=NET181,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 '19' (S=VSS,G=NET215,D=Q1_,B=VSS) (L=1.2,W=1);" + " device PMOS4 '2' (S=VDD,G=A0,D=CS1,B=VDD) (L=1.2,W=10);" + " device NMOS4 '20' (S=NET189,G=NET193,D=NN3,B=VSS) (L=1.2,W=16);" + " device NMOS4 '21' (S=VSS,G=NET194,D=NET189,B=VSS) (L=1.2,W=20);" + " device PMOS4 '22' (S=VDD,G=NET194,D=NET193,B=VDD) (L=1.2,W=6);" + " device NMOS4 '23' (S=NET193,G=NET194,D=VSS,B=VSS) (L=1.2,W=9);" + " device PMOS4 '24' (S=VDD,G=NET189,D=WL1_EN_,B=VDD) (L=1.2,W=3);" + " device NMOS4 '25' (S=WL1_EN_,G=NET189,D=VSS,B=VSS) (L=1.2,W=2);" + " device PMOS4 '26' (S=VDD,G=WL1_EN_,D=YI,B=VDD) (L=1.2,W=15);" + " device NMOS4 '27' (S=YI,G=WL1_EN_,D=VSS,B=VSS) (L=1.2,W=22);" + " device PMOS4 '28' (S=NN1_,G=CS0,D=NET200,B=WELL) (L=1.2,W=11);" + " device PMOS4 '29' (S=NET175,G=CS1,D=NN1_,B=WELL) (L=1.2,W=11);" + " device PMOS4 '3' (S=VDD,G=YI,D=CS1,B=VDD) (L=1.2,W=10);" + " device PMOS4 '30' (S=NET181,G=CS0,D=NN1,B=WELL) (L=1.2,W=11);" + " device PMOS4 '31' (S=Q1,G=CS1,D=NN2,B=VDD) (L=1.2,W=5);" + " device PMOS4 '32' (S=NN2,G=CS0,D=Q0,B=VDD) (L=1.2,W=5);" + " device PMOS4 '33' (S=NN1,G=CS1,D=NET215,B=WELL) (L=1.2,W=11);" + " device PMOS4 '34' (S=Q0_,G=CS0,D=NN2_,B=VDD) (L=1.2,W=5);" + " device PMOS4 '35' (S=NN2_,G=CS1,D=Q1_,B=VDD) (L=1.2,W=5);" + " device PMOS4 '36' (S=NN3,G=NET194,D=NET189,B=VDD) (L=1.2,W=16);" + " device PMOS4 '37' (S=VDD,G=YI,D=Q1,B=VDD) (L=1.2,W=7);" + " device PMOS4 '38' (S=VDD,G=YI,D=Q0_,B=VDD) (L=1.2,W=7);" + " device PMOS4 '39' (S=VDD,G=YI,D=Q0,B=VDD) (L=1.2,W=7);" + " device NMOS4 '4' (S=HNET48,G=A0_,D=VSS,B=VSS) (L=1.2,W=19);" + " device PMOS4 '40' (S=Q0_,G=YI,D=Q0,B=VDD) (L=1.2,W=7);" + " device PMOS4 '41' (S=Q1,G=YI,D=Q1_,B=VDD) (L=1.2,W=7);" + " device PMOS4 '42' (S=VDD,G=YI,D=Q1_,B=VDD) (L=1.2,W=7);" + " device NMOS4 '5' (S=CS0,G=YI,D=HNET48,B=VSS) (L=1.2,W=19);" + " device PMOS4 '6' (S=VDD,G=A0_,D=CS0,B=VDD) (L=1.2,W=10);" + " device PMOS4 '7' (S=VDD,G=YI,D=CS0,B=VDD) (L=1.2,W=10);" + " device NMOS4 '8' (S=HNET52,G=G0,D=VSS,B=VSS) (L=1.2,W=17);" + " device NMOS4 '9' (S=NET194,G=G1,D=HNET52,B=VSS) (L=1.2,W=17);" + "end;" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "begin_circuit DECODE DECODE\n" + "match_nets $41 WL1_EN_\n" + "match_nets VDD VDD\n" + "match_nets $39 NET194\n" + "match_nets g0 G0\n" + "match_nets $40 HNET52\n" + "match_nets VSS VSS\n" + "match_nets $42 NET189\n" + "match_nets gtp NN3\n" + "match_nets $37 NET193\n" + "match_nets g1 G1\n" + "match_nets $44 YI\n" + "match_nets $14 WELL\n" + "match_nets $8 NET215\n" + "match_nets $9 NET175\n" + "match_nets $6 NET181\n" + "match_nets $4 NET200\n" + "match_nets nn1 NN1\n" + "match_nets $11 CS0\n" + "match_nets $13 CS1\n" + "match_nets nn2 NN2\n" + "match_nets nn2_ NN2_\n" + "match_nets q0 Q0\n" + "match_nets q1 Q1\n" + "match_nets q0_ Q0_\n" + "match_nets q1_ Q1_\n" + "match_nets a0_ A0_\n" + "match_nets $34 HNET48\n" + "match_nets nn1_ NN1_\n" + "match_nets a0 A0\n" + "match_nets $35 HNET44\n" + "match_pins VDD VDD\n" + "match_pins nn1_ NN1_\n" + "match_pins nn1 NN1\n" + "match_pins q0 Q0\n" + "match_pins q0_ Q0_\n" + "match_pins q1_ Q1_\n" + "match_pins q1 Q1\n" + "match_pins nn2 NN2\n" + "match_pins nn2_ NN2_\n" + "match_pins a0 A0\n" + "match_pins a0_ A0_\n" + "match_pins g1 G1\n" + "match_pins g0 G0\n" + "match_pins gtp NN3\n" + "match_pins VSS VSS\n" + "match_pins WELL WELL\n" + "match_devices $30 0\n" + "match_devices $29 1\n" + "match_devices $9 10\n" + "match_devices $10 11\n" + "match_devices $36 12\n" + "match_devices $35 13\n" + "match_devices $34 14\n" + "match_devices $38 15\n" + "match_devices $37 16\n" + "match_devices $33 17\n" + "match_devices $27 18\n" + "match_devices $28 19\n" + "match_devices $17 2\n" + "match_devices $31 20\n" + "match_devices $32 21\n" + "match_devices $22 22\n" + "match_devices $26 23\n" + "match_devices $23 24\n" + "match_devices $43 25\n" + "match_devices $20 26\n" + "match_devices $25 27\n" + "match_devices $15 28\n" + "match_devices $14 29\n" + "match_devices $16 3\n" + "match_devices $18 30\n" + "match_devices $21 31\n" + "match_devices $13 32\n" + "match_devices $19 33\n" + "match_devices $7 34\n" + "match_devices $8 35\n" + "match_devices $24 36\n" + "match_devices $3 37\n" + "match_devices $6 38\n" + "match_devices $4 39\n" + "match_devices $39 4\n" + "match_devices $5 40\n" + "match_devices $2 41\n" + "match_devices $1 42\n" + "match_devices $40 5\n" + "match_devices $11 6\n" + "match_devices $12 7\n" + "match_devices $41 8\n" + "match_devices $42 9\n" + "end_circuit DECODE DECODE MATCH" + ); + EXPECT_EQ (good, true); +} + +TEST(20_BusLikeConnections) +{ + // Test test requires a certain depth and tests the backtracking paths. + + const char *nls1 = + "circuit INV (IN=IN,OUT=OUT,VDD=VDD,VSS=VSS);\n" + " device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + "end;\n" + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I1 (IN=IN1,OUT=OUT1,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I2 (IN=IN2,OUT=OUT2,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I3 (IN=IN3,OUT=OUT3,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I4 (IN=IN4,OUT=OUT4,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I5 (IN=IN5,OUT=OUT5,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I6 (IN=IN6,OUT=OUT6,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I7 (IN=IN7,OUT=OUT7,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I8 (IN=IN8,OUT=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit INV8_WRAP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + const char *nls2 = + "circuit INV (OUT=OUT,IN=IN,VDD=VDD,VSS=VSS);\n" + " device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + "end;\n" + "circuit INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I1 (OUT=Q1,IN=A1,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I8 (OUT=Q8,IN=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I3 (OUT=Q3,IN=A3,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I7 (OUT=Q7,IN=A7,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I4 (OUT=Q4,IN=A4,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I2 (OUT=Q2,IN=A2,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I6 (OUT=Q6,IN=A6,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I5 (OUT=Q5,IN=A5,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit INV8_WRAP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "begin_circuit INV INV\n" + "match_nets VDD VDD\n" + "match_nets OUT OUT\n" + "match_nets IN IN\n" + "match_nets VSS VSS\n" + "match_pins IN IN\n" + "match_pins OUT OUT\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_devices $1 $1\n" + "match_devices $2 $2\n" + "end_circuit INV INV MATCH\n" + "begin_circuit INV8 INV8\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_ambiguous_nets IN1 A1\n" + "match_ambiguous_nets IN2 A2\n" + "match_ambiguous_nets IN3 A3\n" + "match_ambiguous_nets IN4 A4\n" + "match_ambiguous_nets IN5 A5\n" + "match_ambiguous_nets IN6 A6\n" + "match_ambiguous_nets IN7 A7\n" + "match_ambiguous_nets IN8 A8\n" + "match_nets OUT1 Q1\n" + "match_nets OUT2 Q2\n" + "match_nets OUT3 Q3\n" + "match_nets OUT4 Q4\n" + "match_nets OUT5 Q5\n" + "match_nets OUT6 Q6\n" + "match_nets OUT7 Q7\n" + "match_nets OUT8 Q8\n" + "match_pins IN1 A1\n" + "match_pins OUT1 Q1\n" + "match_pins IN2 A2\n" + "match_pins OUT2 Q2\n" + "match_pins IN3 A3\n" + "match_pins OUT3 Q3\n" + "match_pins IN4 A4\n" + "match_pins OUT4 Q4\n" + "match_pins IN5 A5\n" + "match_pins OUT5 Q5\n" + "match_pins IN6 A6\n" + "match_pins OUT6 Q6\n" + "match_pins IN7 A7\n" + "match_pins OUT7 Q7\n" + "match_pins IN8 A8\n" + "match_pins OUT8 Q8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits I1 I1\n" + "match_subcircuits I8 I8\n" + "match_subcircuits I3 I3\n" + "match_subcircuits I7 I7\n" + "match_subcircuits I4 I4\n" + "match_subcircuits I2 I2\n" + "match_subcircuits I6 I6\n" + "match_subcircuits I5 I5\n" + "end_circuit INV8 INV8 MATCH\n" + "begin_circuit INV8_WRAP INV8_WRAP\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets IN8 A8\n" + "match_nets OUT8 Q8\n" + "match_nets IN7 A7\n" + "match_nets OUT7 Q7\n" + "match_nets IN6 A6\n" + "match_nets OUT6 Q6\n" + "match_nets IN5 A5\n" + "match_nets OUT5 Q5\n" + "match_nets IN4 A4\n" + "match_nets OUT4 Q4\n" + "match_nets IN3 A3\n" + "match_nets OUT3 Q3\n" + "match_nets IN2 A2\n" + "match_nets OUT2 Q2\n" + "match_nets IN1 A1\n" + "match_nets OUT1 Q1\n" + "match_pins IN1 A1\n" + "match_pins OUT1 Q1\n" + "match_pins IN2 A2\n" + "match_pins OUT2 Q2\n" + "match_pins IN3 A3\n" + "match_pins OUT3 Q3\n" + "match_pins IN4 A4\n" + "match_pins OUT4 Q4\n" + "match_pins IN5 A5\n" + "match_pins OUT5 Q5\n" + "match_pins IN6 A6\n" + "match_pins OUT6 Q6\n" + "match_pins IN7 A7\n" + "match_pins OUT7 Q7\n" + "match_pins IN8 A8\n" + "match_pins OUT8 Q8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits INV8 INV8\n" + "end_circuit INV8_WRAP INV8_WRAP MATCH\n" + "begin_circuit TOP TOP\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets IN8 A8\n" + "match_nets OUT8 Q8\n" + "match_nets IN7 A7\n" + "match_nets OUT7 Q7\n" + "match_nets IN6 A6\n" + "match_nets OUT6 Q6\n" + "match_nets IN5 A5\n" + "match_nets OUT5 Q5\n" + "match_nets IN4 A4\n" + "match_nets OUT4 Q4\n" + "match_nets IN3 A3\n" + "match_nets OUT3 Q3\n" + "match_nets IN2 A2\n" + "match_nets OUT2 Q2\n" + "match_nets IN1 A1\n" + "match_nets OUT1 Q1\n" + "match_pins IN1 A1\n" + "match_pins OUT1 Q1\n" + "match_pins IN2 A2\n" + "match_pins OUT2 Q2\n" + "match_pins IN3 A3\n" + "match_pins OUT3 Q3\n" + "match_pins IN4 A4\n" + "match_pins OUT4 Q4\n" + "match_pins IN5 A5\n" + "match_pins OUT5 Q5\n" + "match_pins IN6 A6\n" + "match_pins OUT6 Q6\n" + "match_pins IN7 A7\n" + "match_pins OUT7 Q7\n" + "match_pins IN8 A8\n" + "match_pins OUT8 Q8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits INV8 INV8\n" + "end_circuit TOP TOP MATCH" + ); + EXPECT_EQ (good, true); +} + +TEST(21_BusLikeAmbiguousConnections) +{ + // Test test requires a certain depth and tests the backtracking paths. + + const char *nls1 = + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + // NOTE: passive nets make the pins ambiguous + "end;\n" + "circuit INV8_WRAP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + const char *nls2 = + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + // NOTE: passive nets make the pins ambiguous + "end;\n" + "circuit INV8_WRAP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=A1,OUT1=Q1,IN2=A2,OUT2=Q2,IN3=A3,OUT3=Q3,IN4=A4,OUT4=Q4,IN5=A5,OUT5=Q5,IN6=A6,OUT6=Q6,IN7=A7,OUT7=Q7,IN8=A8,OUT8=Q8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "begin_circuit INV8 INV8\n" + "match_nets IN1 IN1\n" + "match_nets IN2 IN2\n" + "match_nets IN3 IN3\n" + "match_nets IN4 IN4\n" + "match_nets IN5 IN5\n" + "match_nets IN6 IN6\n" + "match_nets IN7 IN7\n" + "match_nets IN8 IN8\n" + "match_nets OUT1 OUT1\n" + "match_nets OUT2 OUT2\n" + "match_nets OUT3 OUT3\n" + "match_nets OUT4 OUT4\n" + "match_nets OUT5 OUT5\n" + "match_nets OUT6 OUT6\n" + "match_nets OUT7 OUT7\n" + "match_nets OUT8 OUT8\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" + "match_pins IN1 IN1\n" + "match_pins OUT1 OUT1\n" + "match_pins IN2 IN2\n" + "match_pins OUT2 OUT2\n" + "match_pins IN3 IN3\n" + "match_pins OUT3 OUT3\n" + "match_pins IN4 IN4\n" + "match_pins OUT4 OUT4\n" + "match_pins IN5 IN5\n" + "match_pins OUT5 OUT5\n" + "match_pins IN6 IN6\n" + "match_pins OUT6 OUT6\n" + "match_pins IN7 IN7\n" + "match_pins OUT7 OUT7\n" + "match_pins IN8 IN8\n" + "match_pins OUT8 OUT8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "end_circuit INV8 INV8 MATCH\n" + "begin_circuit INV8_WRAP INV8_WRAP\n" + "match_ambiguous_nets VDD VDD\n" + "match_ambiguous_nets VSS VSS\n" + "match_ambiguous_nets IN1 A1\n" + "match_ambiguous_nets IN2 A2\n" + "match_ambiguous_nets IN3 A3\n" + "match_ambiguous_nets IN4 A4\n" + "match_ambiguous_nets IN5 A5\n" + "match_ambiguous_nets IN6 A6\n" + "match_ambiguous_nets IN7 A7\n" + "match_ambiguous_nets IN8 A8\n" + "match_ambiguous_nets OUT1 Q1\n" + "match_ambiguous_nets OUT2 Q2\n" + "match_ambiguous_nets OUT3 Q3\n" + "match_ambiguous_nets OUT4 Q4\n" + "match_ambiguous_nets OUT5 Q5\n" + "match_ambiguous_nets OUT6 Q6\n" + "match_ambiguous_nets OUT7 Q7\n" + "match_ambiguous_nets OUT8 Q8\n" + "match_pins IN1 A1\n" + "match_pins OUT1 Q1\n" + "match_pins IN2 A2\n" + "match_pins OUT2 Q2\n" + "match_pins IN3 A3\n" + "match_pins OUT3 Q3\n" + "match_pins IN4 A4\n" + "match_pins OUT4 Q4\n" + "match_pins IN5 A5\n" + "match_pins OUT5 Q5\n" + "match_pins IN6 A6\n" + "match_pins OUT6 Q6\n" + "match_pins IN7 A7\n" + "match_pins OUT7 Q7\n" + "match_pins IN8 A8\n" + "match_pins OUT8 Q8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits INV8 INV8\n" + "end_circuit INV8_WRAP INV8_WRAP MATCH\n" + "begin_circuit TOP TOP\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets IN8 A8\n" + "match_nets OUT8 Q8\n" + "match_nets IN7 A7\n" + "match_nets OUT7 Q7\n" + "match_nets IN6 A6\n" + "match_nets OUT6 Q6\n" + "match_nets IN5 A5\n" + "match_nets OUT5 Q5\n" + "match_nets IN4 A4\n" + "match_nets OUT4 Q4\n" + "match_nets IN3 A3\n" + "match_nets OUT3 Q3\n" + "match_nets IN2 A2\n" + "match_nets OUT2 Q2\n" + "match_nets IN1 A1\n" + "match_nets OUT1 Q1\n" + "match_pins IN1 A1\n" + "match_pins OUT1 Q1\n" + "match_pins IN2 A2\n" + "match_pins OUT2 Q2\n" + "match_pins IN3 A3\n" + "match_pins OUT3 Q3\n" + "match_pins IN4 A4\n" + "match_pins OUT4 Q4\n" + "match_pins IN5 A5\n" + "match_pins OUT5 Q5\n" + "match_pins IN6 A6\n" + "match_pins OUT6 Q6\n" + "match_pins IN7 A7\n" + "match_pins OUT7 Q7\n" + "match_pins IN8 A8\n" + "match_pins OUT8 Q8\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_subcircuits INV8 INV8\n" + "end_circuit TOP TOP MATCH" + ); + EXPECT_EQ (good, true); +} + diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index 932334032..e04637320 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -2108,3 +2108,198 @@ TEST(9_StrictDeviceExtraction) db::compare_layouts (_this, ly, au); } + +TEST(10_DeviceExtractionWithBreakoutCells) +{ + db::Layout ly; + db::LayerMap lmap; + + unsigned int nwell = define_layer (ly, lmap, 1); + unsigned int active = define_layer (ly, lmap, 2); + unsigned int poly = define_layer (ly, lmap, 3); + unsigned int poly_lbl = define_layer (ly, lmap, 3, 1); + unsigned int diff_cont = define_layer (ly, lmap, 4); + unsigned int poly_cont = define_layer (ly, lmap, 5); + unsigned int metal1 = define_layer (ly, lmap, 6); + unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1); + unsigned int via1 = define_layer (ly, lmap, 7); + unsigned int metal2 = define_layer (ly, lmap, 8); + unsigned int metal2_lbl = define_layer (ly, lmap, 8, 1); + + { + db::LoadLayoutOptions options; + options.get_options ().layer_map = lmap; + options.get_options ().create_other_layers = false; + + std::string fn (tl::testsrc ()); + fn = tl::combine_path (fn, "testdata"); + fn = tl::combine_path (fn, "algo"); + fn = tl::combine_path (fn, "device_extract_l10.gds"); + + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly, options); + } + + db::Cell &tc = ly.cell (*ly.begin_top_down ()); + + db::DeepShapeStore dss; + dss.set_text_enlargement (1); + dss.set_text_property_name (tl::Variant ("LABEL")); + + // original layers + db::Region rnwell (db::RecursiveShapeIterator (ly, tc, nwell), dss); + db::Region ractive (db::RecursiveShapeIterator (ly, tc, active), dss); + db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss); + db::Region rpoly_lbl (db::RecursiveShapeIterator (ly, tc, poly_lbl), dss); + db::Region rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss); + db::Region rpoly_cont (db::RecursiveShapeIterator (ly, tc, poly_cont), dss); + db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss); + db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss); + db::Region rvia1 (db::RecursiveShapeIterator (ly, tc, via1), dss); + db::Region rmetal2 (db::RecursiveShapeIterator (ly, tc, metal2), dss); + db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss); + + // derived regions + + db::Region rpactive = ractive & rnwell; + db::Region rpgate = rpactive & rpoly; + db::Region rpsd = rpactive - rpgate; + + db::Region rnactive = ractive - rnwell; + db::Region rngate = rnactive & rpoly; + db::Region rnsd = rnactive - rngate; + + // return the computed layers into the original layout and write it for debugging purposes + + unsigned int lpgate = ly.insert_layer (db::LayerProperties (20, 0)); // 20/0 -> P Gate + unsigned int lngate = ly.insert_layer (db::LayerProperties (21, 0)); // 21/0 -> N Gate + unsigned int lpdiff = ly.insert_layer (db::LayerProperties (22, 0)); // 22/0 -> P Diffusion + unsigned int lndiff = ly.insert_layer (db::LayerProperties (23, 0)); // 23/0 -> N Diffusion + + rpgate.insert_into (&ly, tc.cell_index (), lpgate); + rngate.insert_into (&ly, tc.cell_index (), lngate); + rpsd.insert_into (&ly, tc.cell_index (), lpdiff); + rnsd.insert_into (&ly, tc.cell_index (), lndiff); + + // perform the extraction + + db::Netlist nl; + db::hier_clusters cl; + + db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS"); + db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS"); + + db::NetlistDeviceExtractor::input_layers dl; + + dss.push_state (); + std::set boc; + boc.insert (dss.layout (0).cell_by_name ("INV").second); + dss.set_breakout_cells (0, boc); + + dl["SD"] = &rpsd; + dl["G"] = &rpgate; + dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes + pmos_ex.extract (dss, 0, dl, nl, cl); + + dl["SD"] = &rnsd; + dl["G"] = &rngate; + dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes + nmos_ex.extract (dss, 0, dl, nl, cl); + + dss.pop_state (); + + // perform the net extraction + + db::NetlistExtractor net_ex; + + db::Connectivity conn; + // Intra-layer + conn.connect (rpsd); + conn.connect (rnsd); + conn.connect (rpoly); + conn.connect (rdiff_cont); + conn.connect (rpoly_cont); + conn.connect (rmetal1); + conn.connect (rvia1); + conn.connect (rmetal2); + // Inter-layer + conn.connect (rpsd, rdiff_cont); + conn.connect (rnsd, 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 + + net_ex.extract_nets (dss, 0, conn, nl, cl); + + // debug layers produced for nets + // 202/0 -> Active + // 203/0 -> Poly + // 204/0 -> Diffusion contacts + // 205/0 -> Poly contacts + // 206/0 -> Metal1 + // 207/0 -> Via1 + // 208/0 -> Metal2 + // 210/0 -> N source/drain + // 211/0 -> P source/drain + std::map dump_map; + dump_map [layer_of (rpsd) ] = ly.insert_layer (db::LayerProperties (210, 0)); + dump_map [layer_of (rnsd) ] = ly.insert_layer (db::LayerProperties (211, 0)); + dump_map [layer_of (rpoly) ] = ly.insert_layer (db::LayerProperties (203, 0)); + dump_map [layer_of (rdiff_cont)] = ly.insert_layer (db::LayerProperties (204, 0)); + dump_map [layer_of (rpoly_cont)] = ly.insert_layer (db::LayerProperties (205, 0)); + dump_map [layer_of (rmetal1) ] = ly.insert_layer (db::LayerProperties (206, 0)); + dump_map [layer_of (rvia1) ] = ly.insert_layer (db::LayerProperties (207, 0)); + dump_map [layer_of (rmetal2) ] = ly.insert_layer (db::LayerProperties (208, 0)); + + // write nets to layout + db::CellMapping cm = dss.cell_mapping_to_original (0, &ly, tc.cell_index ()); + dump_nets_to_layout (nl, cl, ly, dump_map, cm); + + std::string nl_au_string = + "circuit INVCHAIN ();" + " subcircuit INV3 $1 ($1=$9,$2=$7,$3=$8,$4=IN,$5=$9,$6=$6,$7=$2,$8=$6,$9=$4,$10=$3,$11=VDD,$12=VSS);" + " subcircuit INV2 $2 ($1=$8,$2=$11,$3=$9,$4=$10,$5=$8,$6=$11,$7=$3,$8=OUT,$9=$3,$10=OUT,$11=$6,$12=$5,$13=VDD,$14=VSS);" + " subcircuit INV $3 ($1=VSS,$2=VDD,$3=$11,$4=OUT,$5=$5,$6=$5,$7=$10,$8=$10);" + "end;" + "circuit INV2 ($1=$I16,$2=$I15,$3=$I14,$4=$I13,$5=$I12,$6=$I11,$7=$I10,$8=$I9,$9=$I8,$10=$I7,$11=$I6,$12=$I5,$13=$I4,$14=$I2);" + " subcircuit INV $1 ($1=$I2,$2=$I4,$3=$I14,$4=$I6,$5=$I8,$6=$I10,$7=$I16,$8=$I12);" + " subcircuit INV $2 ($1=$I2,$2=$I4,$3=$I13,$4=$I5,$5=$I7,$6=$I9,$7=$I15,$8=$I11);" + "end;" + "circuit INV ($1=$1,$2=$2,$3=$3,$4=$4,$5=$5,$6=$9,$7=$I8,$8=$I7);" + " device PMOS $1 (S=$4,G=$3,D=$2) (L=0.25,W=0.95,AS=0.79325,AD=0.26125,PS=3.57,PD=1.5);" + " device PMOS $2 (S=$2,G=$I8,D=$5) (L=0.25,W=0.95,AS=0.26125,AD=0.03325,PS=1.5,PD=1.97);" + " device NMOS $3 (S=$4,G=$3,D=$1) (L=0.25,W=0.95,AS=0.79325,AD=0.26125,PS=3.57,PD=1.5);" + " device NMOS $4 (S=$1,G=$I7,D=$9) (L=0.25,W=0.95,AS=0.26125,AD=0.03325,PS=1.5,PD=1.97);" + " subcircuit TRANS $1 ($1=$4,$2=$1,$3=$3);" + " subcircuit TRANS $2 ($1=$4,$2=$2,$3=$3);" + "end;" + "circuit TRANS ($1=$1,$2=$2,$3=$3);" + "end;" + "circuit INV3 ($1=$I17,$2=$I16,$3=$I15,$4=$I14,$5=$I12,$6=$I11,$7=$I9,$8=$I8,$9=$I7,$10=$I5,$11=$I4,$12=$I2);" + " subcircuit INV $1 ($1=$I2,$2=$I4,$3=$I15,$4=$I5,$5=$I8,$6=$I11,$7=$I17,$8=$I12);" + " subcircuit INV $2 ($1=$I2,$2=$I4,$3=$I14,$4=$I9,$5=$I7,$6=$I7,$7=$I16,$8=$I16);" + " subcircuit INV $3 ($1=$I2,$2=$I4,$3=$I16,$4=$I7,$5=$I9,$6=$I9,$7=$I14,$8=$I14);" + "end;" + ; + + // compare netlist as string + CHECKPOINT (); + db::compare_netlist (_this, nl, nl_au_string); + + // compare the collected test data + + std::string au = tl::testsrc (); + au = tl::combine_path (au, "testdata"); + au = tl::combine_path (au, "algo"); + au = tl::combine_path (au, "device_extract_au10.gds"); + + db::compare_layouts (_this, ly, au); +} diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 9de025763..1dc2f196f 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -752,6 +752,7 @@ TEST(6_Net) EXPECT_EQ (n.pin_count (), size_t (0)); EXPECT_EQ (n.terminal_count (), size_t (0)); EXPECT_EQ (n.is_floating (), true); + EXPECT_EQ (n.is_passive (), true); EXPECT_EQ (n.is_internal (), false); } @@ -781,6 +782,7 @@ TEST(7_NetTerminalsEditing) EXPECT_EQ (n1->terminal_count (), size_t (1)); EXPECT_EQ (n1->pin_count (), size_t (0)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), false); d2->connect_terminal (1, n1); @@ -789,6 +791,7 @@ TEST(7_NetTerminalsEditing) EXPECT_EQ (n1->terminal_count (), size_t (2)); EXPECT_EQ (n1->pin_count (), size_t (0)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), true); EXPECT_EQ (d1->net_for_terminal (0), n1); @@ -871,7 +874,8 @@ TEST(8_NetSubCircuitsEditing) EXPECT_EQ (n1->terminal_count (), size_t (0)); EXPECT_EQ (n1->pin_count (), size_t (1)); - EXPECT_EQ (n1->is_floating (), true); + EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), true); EXPECT_EQ (n1->is_internal (), false); EXPECT_NE (n1->pin_count (), size_t (0)); @@ -886,6 +890,7 @@ TEST(8_NetSubCircuitsEditing) EXPECT_EQ (n1->pin_count (), size_t (1)); EXPECT_EQ (n1->subcircuit_pin_count (), size_t (1)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), false); sc2->connect_pin (1, n1); @@ -1380,7 +1385,7 @@ TEST(22_BlankCircuit) nl2.purge (); EXPECT_EQ (nl2.to_string (), - "circuit RINGO (IN=(null),OSC=OSC,VSS=VSS,VDD=VDD);\n" + "circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n" " subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n" " subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n" "end;\n" diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 997255a24..1d5879673 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1120,6 +1120,108 @@ module DRC @def_source = layout.clip(*args) nil end + + # %DRC% + # @name cheat + # @brief Hierarchy cheats + # @synopsis cheat(args) { block } + # + # Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation + # for certain cells and consider their local configuration only. + # Cheats are useful for example when dealing with memory arrays. Often + # such arrays are build from unit cells and those often overlap with their + # neighbors. Now, if the hierarchical engine encounters such a situation, it + # will first analyse all these interactions (which can be expensive) and then + # it may come to the conclusion that boundary instances need to be handled + # differently than inside instances. This in turn might lead to propagation of + # shapes and in an LVS context to device externalisation: because some devices + # might have different parameters for boundary cells than for inside cells, the + # device instances can no longer be kept inside the unit cell. Specifically for + # memory arrays, this is not desired as eventually this leads to flattening + # of the whole array. + # + # The solution is to cheat: provided the unit cell is fully fledged and neighbors + # do not disturb the unit cell's configuration in critical ways, the unit cell + # can be treated as being isolated and results are put together in the usual way. + # + # Cheats can be applied on layout operations - specifically booleans - and device + # extraction operations. Cheats are only effective in \deep mode. + # + # For booleans, a cheat means that the cheating cell's boolean results are computed + # locally and are combined afterwards. A cheat is introduced this way: + # + # @code + # deep + # + # l1 = input(1, 0) + # l2 = input(2, 0) + # + # # usual booleans + # l1and2 = l1 & l2 + # + # # will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode: + # l1minus2 = cheat("UNIT_CELL) { l1 - l2 } + # @/code + # + # The cheat block can also be wrapped in do .. end statements and can return multiple + # layer objects: + # + # @code + # deep + # + # l1 = input(1, 0) + # l2 = input(2, 0) + # + # # computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL" + # l1and2, l1minus2 = cheat("UNIT_CELL) do + # [ l1 & l2, l1 - l2 ] + # end + # @/code + # + # (Technically, the cheat code block is a Ruby Proc and cannot create variables + # outside it's scope. Hence the results of this code block have to be passed + # through the "cheat" method). + # + # To apply cheats for device extraction, use the following scheme: + # + # @code + # deep + # + # poly = input(1, 0) + # active = input(2, 0) + # + # sd = active - poly + # gate = active & poly + # + # # device extraction with cheating for "UNIT_CELL": + # cheat("UNIT_CELL") do + # extract_devices(mos3("NMOS"), { "SD" => sd, "G" => gate, "tS" => sd, "tD" => sd, "tG" => poly } + # end + # @/code + # + # The argument to the cheat method is a list of cell name pattern (glob-style + # pattern). For example: + # + # @code + # cheat("UNIT_CELL*") { ... } + # cheat("UNIT_CELL1", "UNIT_CELL2") { ... } + # cheat("UNIT_CELL{1,2}") { ... } + # @/code + # + # For LVS applications, it's usually sufficient to cheat in the device extraction step. + # Cheats have been introduced in version 0.26.1. + + def cheat(*args, &block) + if _dss + _dss.push_state + args.flatten.each { |a| _dss.add_breakout_cells(a.to_s) } + ret = block.call + _dss.pop_state + else + ret = block.call + end + ret + end # make some DRCLayer methods available as functions # for the engine @@ -1461,22 +1563,22 @@ CODE end # save the netlist if required - if @target_netlist_file && @netter && @netter.l2n_data + if @target_netlist_file && @netter && @netter._l2n_data writer = @target_netlist_format || RBA::NetlistSpiceWriter::new netlist_file = _make_path(@target_netlist_file) info("Writing netlist: #{netlist_file} ..") - self.netlist.write(netlist_file, writer, @target_netlist_comment || "") + netlist.write(netlist_file, writer, @target_netlist_comment || "") end # save the netlist database if requested - if @output_l2ndb_file && @netter && @netter.l2n_data + if @output_l2ndb_file && @netter && @netter._l2n_data l2ndb_file = _make_path(@output_l2ndb_file) info("Writing netlist database: #{l2ndb_file} ..") - @netter.l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long) + @netter._l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long) end @@ -1484,7 +1586,7 @@ CODE _before_cleanup # show the data in the browser - if view && @show_l2ndb && @netter && @netter.l2n_data + if view && @show_l2ndb && @netter && @netter._l2n_data # NOTE: to prevent the netter destroying the database, we need to take it l2ndb = _take_data diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 1a7f70ef6..acf00645c 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -383,6 +383,10 @@ module DRC l2ndb end + def _l2n_data + @netlisted && self.l2n_data + end + private def cleanup diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml index ef89cacdd..623d30d1e 100644 --- a/src/lay/lay/doc/about/drc_ref_global.xml +++ b/src/lay/lay/doc/about/drc_ref_global.xml @@ -92,6 +92,98 @@ cell("MACRO") l1 = input(1, 0)

+

"cheat" - Hierarchy cheats

+ +

Usage:

+
    +
  • cheat(args) { block }
  • +
+

+Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation +for certain cells and consider their local configuration only. +Cheats are useful for example when dealing with memory arrays. Often +such arrays are build from unit cells and those often overlap with their +neighbors. Now, if the hierarchical engine encounters such a situation, it +will first analyse all these interactions (which can be expensive) and then +it may come to the conclusion that boundary instances need to be handled +differently than inside instances. This in turn might lead to propagation of +shapes and in an LVS context to device externalisation: because some devices +might have different parameters for boundary cells than for inside cells, the +device instances can no longer be kept inside the unit cell. Specifically for +memory arrays, this is not desired as eventually this leads to flattening +of the whole array. +

+The solution is to cheat: provided the unit cell is fully fledged and neighbors +do not disturb the unit cell's configuration in critical ways, the unit cell +can be treated as being isolated and results are put together in the usual way. +

+Cheats can be applied on layout operations - specifically booleans - and device +extraction operations. Cheats are only effective in deep mode. +

+For booleans, a cheat means that the cheating cell's boolean results are computed +locally and are combined afterwards. A cheat is introduced this way: +

+

+deep
+
+l1 = input(1, 0)
+l2 = input(2, 0)
+
+# usual booleans
+l1and2 = l1 & l2
+
+# will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode:
+l1minus2 = cheat("UNIT_CELL) { l1 - l2 }
+
+

+The cheat block can also be wrapped in do .. end statements and can return multiple +layer objects: +

+

+deep
+
+l1 = input(1, 0)
+l2 = input(2, 0)
+
+# computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL"
+l1and2, l1minus2 = cheat("UNIT_CELL) do
+[ l1 & l2, l1 - l2 ]
+end
+
+

+(Technically, the check code block is a Ruby Proc and cannot create variables +outside it's scope. Hence the results of this code block have to be passed +through the "cheat" method). +

+To apply cheats for device extraction, use the following scheme: +

+

+deep
+
+poly = input(1, 0)
+active = input(2, 0)
+
+sd = active - poly
+gate = active & poly
+
+# device extraction with cheating for "UNIT_CELL":
+cheat("UNIT_CELL") do
+extract_devices(mos3("NMOS"), { "SD" => sd, "G" => gate, "tS" => sd, "tD" => sd, "tG" => poly }
+end
+
+

+The argument to the cheat method is a list of cell name pattern (glob-style +pattern). For example: +

+

+cheat("UNIT_CELL*") { ... }
+cheat("UNIT_CELL1", "UNIT_CELL2") { ... }
+cheat("UNIT_CELL{1,2}") { ... }
+
+

+For LVS applications, it's usually sufficient to cheat in the device extraction step. +Cheats have been introduced in version 0.26.1. +

"clear_connections" - Clears all connections stored so far

Usage:

diff --git a/src/lay/lay/doc/about/drc_ref_layer.xml b/src/lay/lay/doc/about/drc_ref_layer.xml index f996764b9..fb9d591c5 100644 --- a/src/lay/lay/doc/about/drc_ref_layer.xml +++ b/src/lay/lay/doc/about/drc_ref_layer.xml @@ -735,7 +735,7 @@ This method is available for edge layers. The argument must be a polygon layer.

This method selects all shapes or regions from self which touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_interacting. @@ -1085,7 +1085,7 @@ The following image shows the effect of the "not_inside" method (input1: red, in

This method selects all shapes or regions from self which do not touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_not_interacting. @@ -1134,7 +1134,7 @@ The following image shows the effect of the "not_outside" method (input1: red, i

This method selects all shapes or regions from self which do not overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected.

The "not_overlapping" method is equivalent to the outside method. It is provided @@ -1322,7 +1322,7 @@ The following images show the effect of the overlap check (layer1: red, layer2:

This method selects all shapes or regions from self which overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_overlapping. @@ -1372,6 +1372,60 @@ parameter is 0, special edge pairs with an area of 0 will be dropped.

  • layer.polygons?
+

"pull_inside" - Selects shapes or regions of other which are inside polygons from the this region

+ +

Usage:

+
    +
  • layer.pull_inside(other)
  • +
+

+This method selects all shapes or regions from other which are inside polygons from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_inside, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method is available for polygon layers. Other needs to be a polygon layer too. +

+

"pull_interacting" - Selects shapes or edges of other which touch or overlap shapes from the this region

+ +

Usage:

+
    +
  • layer.pull_interacting(other)
  • +
+

+This method selects all shapes or regions from other which touch or overlap shapes from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_interacting, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method will neither modify self nor other. +

+This method is available for polygon layers. Other can be an edge or polygon layer. +Edges or polygons can be selected with respect to polygons of self. +

+

"pull_overlapping" - Selects shapes or regions of other which overlap shapes from the this region

+ +

Usage:

+
    +
  • layer.pull_overlapping(other)
  • +
+

+This method selects all shapes or regions from other which overlap shapes from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_overlapping, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method is available for polygon layers. Other needs to be a polygon layer too. +

"raw" - Marks a layer as raw

Usage:

@@ -1562,7 +1616,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is interacting. @@ -1595,7 +1649,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which do not touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_interacting. @@ -1628,7 +1682,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which do not overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_overlapping. @@ -1661,7 +1715,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is overlapping. diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb index b7a1dc2b7..8186eb2eb 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb @@ -43,11 +43,11 @@ module LVS def _before_cleanup # save the netlist database if requested - if @output_lvsdb_file && @netter && @netter.lvs_data && @netter.lvs_data.xref + if @output_lvsdb_file && @netter && @netter._lvs_data && @netter._lvs_data.xref lvsdb_file = _make_path(@output_lvsdb_file) info("Writing LVS database: #{lvsdb_file} ..") - @netter.lvs_data.write(lvsdb_file, !@output_lvsdb_long) + @netter._lvs_data.write(lvsdb_file, !@output_lvsdb_long) end diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index 23335311b..ca5fcf5fa 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -48,6 +48,7 @@ module LVS def initialize(engine) super + @comparer_config = [] end def _make_data @@ -65,7 +66,6 @@ module LVS @lvs.generator = @engine._generator @l2n = @lvs - @comparer = RBA::NetlistComparer::new end @@ -94,6 +94,10 @@ module LVS data end + def _lvs_data + _l2n_data && @lvs + end + # %LVS% # @name align # @brief Aligns the extracted netlist vs. the schematic @@ -120,7 +124,9 @@ module LVS nl = _ensure_two_netlists - unmatched_a = @comparer.unmatched_circuits_a(*nl) + comparer = self._comparer + + unmatched_a = comparer.unmatched_circuits_a(*nl) # check whether we're about to flatten away the internal top cell - that's bad top_cell = l2n_data.internal_top_cell.name @@ -131,14 +137,15 @@ module LVS # flatten layout cells for which there is no corresponding schematic circuit unmatched_a.each do |c| @engine.info("Flatten layout cell (no schematic): #{c.name}") - nl[0].flatten_circuit(c) end + nl[0].flatten_circuits(unmatched_a) # flatten schematic circuits for which there is no corresponding layout cell - @comparer.unmatched_circuits_b(*nl).each do |c| + unmatched_b = comparer.unmatched_circuits_b(*nl) + unmatched_b.each do |c| @engine.info("Flatten schematic circuit (no layout): #{c.name}") - nl[1].flatten_circuit(c) end + nl[1].flatten_circuits(unmatched_b) end @@ -161,7 +168,20 @@ module LVS nl = _ensure_two_netlists lvs_data.reference = nl[1] - lvs_data.compare(@comparer) + lvs_data.compare(self._comparer) + + end + + def _comparer + + comparer = RBA::NetlistComparer::new + + # execute the configuration commands + @comparer_config.each do |cc| + cc.call(comparer) + end + + return comparer end @@ -217,6 +237,12 @@ module LVS n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") end + @comparer_config << lambda { |comparer| self._same_nets(comparer, ca, a, cb, b) } + + end + + def _same_nets(comparer, ca, a, cb, b) + ( nl_a, nl_b ) = _ensure_two_netlists if ca.is_a?(String) @@ -234,19 +260,19 @@ module LVS if circuit_a && circuit_b if a.is_a?(String) - net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist: #{a} (for circuit #{circuit_a})") + net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist in 'same_nets': #{a} (for circuit #{circuit_a})") else net_a = a end if b.is_a?(String) - net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist: #{b} (for circuit #{circuit_b})") + net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist in 'same_nets': #{b} (for circuit #{circuit_b})") else net_b = b end if net_a && net_b - @comparer.same_nets(net_a, net_b) + comparer.same_nets(net_a, net_b) end end @@ -271,13 +297,19 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_circuits' need to be strings or nil") + @comparer_config << lambda { |comparer| self._same_circuits(comparer, a, b) } + + end + + def _same_circuits(comparer, a, b) + ( nl_a, nl_b ) = _ensure_two_netlists circuit_a = a && nl_a.circuit_by_name(a) circuit_b = b && nl_b.circuit_by_name(b) if circuit_a && circuit_b - @comparer.same_circuits(circuit_a, circuit_b) + comparer.same_circuits(circuit_a, circuit_b) end end @@ -301,15 +333,21 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_device_classes' need to be strings or nil") + @comparer_config << lambda { |comparer| self._same_device_classes(comparer, a, b) } + + end + + def _same_device_classes(comparer, a, b) + ( nl_a, nl_b ) = _ensure_two_netlists - dc_a = a && (nl_a.device_class_by_name(a) || raise("Not a valid device class in extracted netlist: #{a}")) + dc_a = a && (nl_a.device_class_by_name(a) || raise("Not a valid device class in extracted netlist in 'same_device_class': #{a}")) dc_b = b && nl_b.device_class_by_name(b) # NOTE: a device class is allowed to be missing in the reference netlist because the # device may simply not be used there. if dc_b - @comparer.same_device_classes(dc_a, dc_b) + comparer.same_device_classes(dc_a, dc_b) end end @@ -347,6 +385,12 @@ module LVS raise("All pin arguments of 'equivalent_pins' need to be strings or numbers") end + @comparer_config << lambda { |comparer| self._equivalent_pins(comparer, circuit, *pins) } + + end + + def _equivalent_pins(comparer, circuit, *pins) + ( nl_a, nl_b ) = _ensure_two_netlists circuit_b = nl_b.circuit_by_name(circuit) @@ -357,14 +401,14 @@ module LVS pin_ids_b = pins.collect do |p| if p.is_a?(String) - pin = circuit_b.pin_by_name(p) || raise("Not a valid pin name in circuit '#{circuit}': #{p}") + pin = circuit_b.pin_by_name(p) || raise("Not a valid pin name in circuit '#{circuit}' in 'equivalent_pins': #{p}") else - pin = pins_by_index[p.to_i] || raise("Not a valid pin index in circuit '#{circuit}': #{p}") + pin = pins_by_index[p.to_i] || raise("Not a valid pin index in circuit '#{circuit}' in 'equivalent_pins': #{p}") end pin.id end - @comparer.equivalent_pins(circuit_b, pin_ids_b) + comparer.equivalent_pins(circuit_b, pin_ids_b) end @@ -428,8 +472,8 @@ module LVS # with a capacitance values below the given threshold (in Farad). def min_caps(value) - lvs_data - @comparer.min_capacitance = value.to_f + v = value.to_f + @comparer_config << lambda { |comparer| comparer.min_capacitance = v } end # %LVS% @@ -440,8 +484,8 @@ module LVS # with a resistance value above the given threshold (in Farad). def max_res(value) - lvs_data - @comparer.max_resistance = value.to_f + v = value.to_f + @comparer_config << lambda { |comparer| comparer.max_resistance = v } end # %LVS% @@ -459,8 +503,8 @@ module LVS # as the seeds for this deduction path. The default value is 8. def max_depth(value) - lvs_data - @comparer.max_depth = value.to_i + v = value.to_i + @comparer_config << lambda { |comparer| comparer.max_depth = v } end # @name max_branch_complexity @@ -480,8 +524,8 @@ module LVS # complexity. def max_branch_complexity(value) - lvs_data - @comparer.max_branch_complexity = value.to_i + v = value.to_i + @comparer_config << lambda { |comparer| comparer.max_branch_complexity = v } end end diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 2fa9252d2..278369787 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -154,3 +154,14 @@ TEST(16_floating) { run_test (_this, "floating", "floating.gds", false, "TOP"); } + +TEST(17_layout_variants) +{ + run_test (_this, "ringo_layout_var", "ringo_layout_var.gds"); +} + +TEST(18_cheats) +{ + run_test (_this, "invchain_cheat", "invchain_for_cheat.gds"); +} + diff --git a/src/tl/tl/tlGlobPattern.cc b/src/tl/tl/tlGlobPattern.cc index cf27d70cb..9e52c3f7d 100644 --- a/src/tl/tl/tlGlobPattern.cc +++ b/src/tl/tl/tlGlobPattern.cc @@ -238,6 +238,38 @@ private: GlobPatternString &operator= (const GlobPatternString &); }; +class GlobPatternEmpty + : public GlobPatternOp +{ +public: + GlobPatternEmpty () + : GlobPatternOp () + { + // .. nothing yet .. + } + + virtual GlobPatternOp *clone () const + { + GlobPatternEmpty *op = new GlobPatternEmpty (); + init_clone (op); + return op; + } + + virtual bool is_const () const + { + return next () == 0; + } + + virtual bool match (const char *s, std::vector *e) const + { + return GlobPatternOp::match (s, e); + } + +private: + GlobPatternEmpty (const GlobPatternEmpty &); + GlobPatternEmpty &operator= (const GlobPatternString &); +}; + class GlobPatternPass : public GlobPatternOp { @@ -602,6 +634,8 @@ compile_emit_alt (GlobPatternOp *&op_head, GlobPatternOp *&op, const char *&p, b GlobPatternOp *alt = compile (p, false, cs, false, true); if (alt) { alt_op->add_choice (alt); + } else { + alt_op->add_choice (new GlobPatternEmpty ()); } if (*p == ',') { ++p; diff --git a/src/tl/unit_tests/tlGlobPatternTests.cc b/src/tl/unit_tests/tlGlobPatternTests.cc index d53ef95e8..80dacc9a7 100644 --- a/src/tl/unit_tests/tlGlobPatternTests.cc +++ b/src/tl/unit_tests/tlGlobPatternTests.cc @@ -163,6 +163,7 @@ TEST(6) EXPECT_EQ (a.match ("abcg"), true); EXPECT_EQ (a.match ("adg"), true); + EXPECT_EQ (a.match ("ad"), false); EXPECT_EQ (a.match ("ag"), false); EXPECT_EQ (a.match ("abch"), false); EXPECT_EQ (a.match ("adh"), false); @@ -173,11 +174,33 @@ TEST(6) EXPECT_EQ (aa.match ("abcg"), true); EXPECT_EQ (aa.match ("adg"), true); + EXPECT_EQ (aa.match ("ad"), false); EXPECT_EQ (aa.match ("ag"), false); EXPECT_EQ (aa.match ("abch"), false); EXPECT_EQ (aa.match ("adh"), false); EXPECT_EQ (aa.match ("ah"), false); + a = tl::GlobPattern ("a{,d}g"); + + EXPECT_EQ (a.match ("abcg"), false); + EXPECT_EQ (a.match ("ad"), false); + EXPECT_EQ (a.match ("adg"), true); + EXPECT_EQ (a.match ("ag"), true); + EXPECT_EQ (a.match ("a"), false); + EXPECT_EQ (a.match ("abch"), false); + EXPECT_EQ (a.match ("adh"), false); + EXPECT_EQ (a.match ("ah"), false); + + a = tl::GlobPattern ("a{,d}"); + + EXPECT_EQ (a.match ("abcg"), false); + EXPECT_EQ (a.match ("ad"), true); + EXPECT_EQ (a.match ("adg"), false); + EXPECT_EQ (a.match ("ag"), false); + EXPECT_EQ (a.match ("a"), true); + EXPECT_EQ (a.match ("abch"), false); + EXPECT_EQ (a.match ("adh"), false); + EXPECT_EQ (a.match ("ah"), false); } TEST(7) diff --git a/testdata/algo/deep_region_au26.gds b/testdata/algo/deep_region_au26.gds new file mode 100644 index 000000000..48204b202 Binary files /dev/null and b/testdata/algo/deep_region_au26.gds differ diff --git a/testdata/algo/deep_region_l26.gds b/testdata/algo/deep_region_l26.gds new file mode 100644 index 000000000..cc4063959 Binary files /dev/null and b/testdata/algo/deep_region_l26.gds differ diff --git a/testdata/algo/device_extract_au10.gds.1 b/testdata/algo/device_extract_au10.gds.1 new file mode 100644 index 000000000..613e8b0ca Binary files /dev/null and b/testdata/algo/device_extract_au10.gds.1 differ diff --git a/testdata/algo/device_extract_au10.gds.2 b/testdata/algo/device_extract_au10.gds.2 new file mode 100644 index 000000000..6b279ff19 Binary files /dev/null and b/testdata/algo/device_extract_au10.gds.2 differ diff --git a/testdata/algo/device_extract_au10.gds.3 b/testdata/algo/device_extract_au10.gds.3 new file mode 100644 index 000000000..f0be9a440 Binary files /dev/null and b/testdata/algo/device_extract_au10.gds.3 differ diff --git a/testdata/algo/device_extract_au1_rebuild_nr.gds b/testdata/algo/device_extract_au1_rebuild_nr.gds index 0050d5e7d..256f5daf9 100644 Binary files a/testdata/algo/device_extract_au1_rebuild_nr.gds and b/testdata/algo/device_extract_au1_rebuild_nr.gds differ diff --git a/testdata/algo/device_extract_au1_rebuild_pf.gds b/testdata/algo/device_extract_au1_rebuild_pf.gds index ac89085ec..8cb5a621d 100644 Binary files a/testdata/algo/device_extract_au1_rebuild_pf.gds and b/testdata/algo/device_extract_au1_rebuild_pf.gds differ diff --git a/testdata/algo/device_extract_au1_rebuild_pr.gds b/testdata/algo/device_extract_au1_rebuild_pr.gds index 36c92dfb0..948e2a8c6 100644 Binary files a/testdata/algo/device_extract_au1_rebuild_pr.gds and b/testdata/algo/device_extract_au1_rebuild_pr.gds differ diff --git a/testdata/algo/device_extract_au1_with_rec_nets.gds b/testdata/algo/device_extract_au1_with_rec_nets.gds index 1bc3662a1..b03ebd333 100644 Binary files a/testdata/algo/device_extract_au1_with_rec_nets.gds and b/testdata/algo/device_extract_au1_with_rec_nets.gds differ diff --git a/testdata/algo/device_extract_au2_with_rec_nets.gds b/testdata/algo/device_extract_au2_with_rec_nets.gds index 228fa0ef1..231a70056 100644 Binary files a/testdata/algo/device_extract_au2_with_rec_nets.gds and b/testdata/algo/device_extract_au2_with_rec_nets.gds differ diff --git a/testdata/algo/device_extract_au3_with_rec_nets.gds b/testdata/algo/device_extract_au3_with_rec_nets.gds index 766069396..77f48da85 100644 Binary files a/testdata/algo/device_extract_au3_with_rec_nets.gds and b/testdata/algo/device_extract_au3_with_rec_nets.gds differ diff --git a/testdata/algo/device_extract_au4_with_rec_nets.gds b/testdata/algo/device_extract_au4_with_rec_nets.gds index c8000ad0a..69d52a849 100644 Binary files a/testdata/algo/device_extract_au4_with_rec_nets.gds and b/testdata/algo/device_extract_au4_with_rec_nets.gds differ diff --git a/testdata/algo/device_extract_au5_flattened_circuits.gds b/testdata/algo/device_extract_au5_flattened_circuits.gds index 40dc8210f..bb997bf82 100644 Binary files a/testdata/algo/device_extract_au5_flattened_circuits.gds and b/testdata/algo/device_extract_au5_flattened_circuits.gds differ diff --git a/testdata/algo/device_extract_au5_with_rec_nets.gds b/testdata/algo/device_extract_au5_with_rec_nets.gds index 799ab844e..6f30100c6 100644 Binary files a/testdata/algo/device_extract_au5_with_rec_nets.gds and b/testdata/algo/device_extract_au5_with_rec_nets.gds differ diff --git a/testdata/algo/device_extract_l10.gds b/testdata/algo/device_extract_l10.gds new file mode 100644 index 000000000..43446a79f Binary files /dev/null and b/testdata/algo/device_extract_l10.gds differ diff --git a/testdata/algo/l2n_writer_au_2.gds b/testdata/algo/l2n_writer_au_2.gds index ad232c888..35478aff1 100644 Binary files a/testdata/algo/l2n_writer_au_2.gds and b/testdata/algo/l2n_writer_au_2.gds differ diff --git a/testdata/algo/l2n_writer_au_2b.txt b/testdata/algo/l2n_writer_au_2b.txt index c232887a5..8709c5c46 100644 --- a/testdata/algo/l2n_writer_au_2b.txt +++ b/testdata/algo/l2n_writer_au_2b.txt @@ -270,6 +270,12 @@ circuit(INV2PAIR rect(diff_cont (-220 180) (220 220)) ) net(4 + rect(diff_cont (2390 3690) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -2620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + ) + net(5 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 -220) (220 220)) @@ -283,7 +289,7 @@ circuit(INV2PAIR rect(metal1 (-3000 -760) (360 760)) rect(metal1 (-360 -760) (360 760)) ) - net(5 + net(6 rect(diff_cont (4230 490) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 -220) (220 220)) @@ -297,12 +303,6 @@ circuit(INV2PAIR rect(metal1 (-3000 -760) (360 760)) rect(metal1 (-360 -760) (360 760)) ) - net(6 - rect(diff_cont (2390 3690) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -2620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - ) net(7) net(8 rect(diff_cont (5030 3690) (220 220)) @@ -315,8 +315,8 @@ circuit(INV2PAIR # Outgoing pins and their connections to nets pin(1 name(BULK)) pin(2) - pin(4) pin(5) + pin(6) pin(7) pin(8) pin(9) @@ -326,18 +326,18 @@ circuit(INV2PAIR pin(0 9) pin(1 7) pin(2 3) - pin(3 6) - pin(4 5) - pin(5 4) + pin(3 4) + pin(4 6) + pin(5 5) pin(6 1) ) circuit(2 INV2 location(4340 800) pin(0 9) - pin(1 6) + pin(1 4) pin(2 2) pin(3 8) - pin(4 5) - pin(5 4) + pin(4 6) + pin(5 5) pin(6 1) ) diff --git a/testdata/algo/l2n_writer_au_2s.txt b/testdata/algo/l2n_writer_au_2s.txt index c12295b2d..e90dd3e1d 100644 --- a/testdata/algo/l2n_writer_au_2s.txt +++ b/testdata/algo/l2n_writer_au_2s.txt @@ -238,6 +238,12 @@ X(INV2PAIR R(diff_cont (-220 180) (220 220)) ) N(4 + R(diff_cont (2390 3690) (220 220)) + R(diff_cont (-220 -620) (220 220)) + R(diff_cont (-220 -2620) (220 220)) + R(diff_cont (-220 -620) (220 220)) + ) + N(5 R(diff_cont (4230 3290) (220 220)) R(diff_cont (-220 180) (220 220)) R(diff_cont (-220 -220) (220 220)) @@ -251,7 +257,7 @@ X(INV2PAIR R(metal1 (-3000 -760) (360 760)) R(metal1 (-360 -760) (360 760)) ) - N(5 + N(6 R(diff_cont (4230 490) (220 220)) R(diff_cont (-220 180) (220 220)) R(diff_cont (-220 -220) (220 220)) @@ -265,12 +271,6 @@ X(INV2PAIR R(metal1 (-3000 -760) (360 760)) R(metal1 (-360 -760) (360 760)) ) - N(6 - R(diff_cont (2390 3690) (220 220)) - R(diff_cont (-220 -620) (220 220)) - R(diff_cont (-220 -2620) (220 220)) - R(diff_cont (-220 -620) (220 220)) - ) N(7) N(8 R(diff_cont (5030 3690) (220 220)) @@ -281,8 +281,8 @@ X(INV2PAIR N(9) P(1 I(BULK)) P(2) - P(4) P(5) + P(6) P(7) P(8) P(9) @@ -290,18 +290,18 @@ X(INV2PAIR P(0 9) P(1 7) P(2 3) - P(3 6) - P(4 5) - P(5 4) + P(3 4) + P(4 6) + P(5 5) P(6 1) ) X(2 INV2 Y(4340 800) P(0 9) - P(1 6) + P(1 4) P(2 2) P(3 8) - P(4 5) - P(5 4) + P(4 6) + P(5 5) P(6 1) ) ) diff --git a/testdata/algo/lvs_test1_au.lvsdb.1 b/testdata/algo/lvs_test1_au.lvsdb.1 index add09797d..b32d9f40d 100644 --- a/testdata/algo/lvs_test1_au.lvsdb.1 +++ b/testdata/algo/lvs_test1_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test1_au.lvsdb.2 b/testdata/algo/lvs_test1_au.lvsdb.2 index dac6d562b..bba5f19c4 100644 --- a/testdata/algo/lvs_test1_au.lvsdb.2 +++ b/testdata/algo/lvs_test1_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test1b_au.lvsdb.1 b/testdata/algo/lvs_test1b_au.lvsdb.1 index 460cae8e7..556dcc6dd 100644 --- a/testdata/algo/lvs_test1b_au.lvsdb.1 +++ b/testdata/algo/lvs_test1b_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test1b_au.lvsdb.2 b/testdata/algo/lvs_test1b_au.lvsdb.2 index 2853d93ef..bef20e994 100644 --- a/testdata/algo/lvs_test1b_au.lvsdb.2 +++ b/testdata/algo/lvs_test1b_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test2_au.lvsdb.1 b/testdata/algo/lvs_test2_au.lvsdb.1 index 5526f557a..40eb31bb7 100644 --- a/testdata/algo/lvs_test2_au.lvsdb.1 +++ b/testdata/algo/lvs_test2_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) ) diff --git a/testdata/algo/lvs_test2_au.lvsdb.2 b/testdata/algo/lvs_test2_au.lvsdb.2 index 84e349abc..7ceccdcd8 100644 --- a/testdata/algo/lvs_test2_au.lvsdb.2 +++ b/testdata/algo/lvs_test2_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) ) diff --git a/testdata/algo/lvs_test2b_au.lvsdb.1 b/testdata/algo/lvs_test2b_au.lvsdb.1 index 612ed7a51..2b3360370 100644 --- a/testdata/algo/lvs_test2b_au.lvsdb.1 +++ b/testdata/algo/lvs_test2b_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) ) diff --git a/testdata/algo/lvs_test2b_au.lvsdb.2 b/testdata/algo/lvs_test2b_au.lvsdb.2 index 965381b39..92aad1228 100644 --- a/testdata/algo/lvs_test2b_au.lvsdb.2 +++ b/testdata/algo/lvs_test2b_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) ) diff --git a/testdata/buddies/buddies.rb b/testdata/buddies/buddies.rb index 2cdfbbb7f..4f3caddaa 100644 --- a/testdata/buddies/buddies.rb +++ b/testdata/buddies/buddies.rb @@ -56,6 +56,11 @@ class Buddies_TestClass < TestBase "strm2txt" => 0x62656769, } + # Windows CRLF -> LF translation + signature_equiv = { + 0x300d0a53 => 0x300a5345 + } + %w(strm2cif strm2dxf strm2gds strm2gdstxt strm2oas strm2txt).each do |bin| puts "Testing #{bin} ..." @@ -74,6 +79,7 @@ class Buddies_TestClass < TestBase File.open(out_file, "rb") do |file| sig = file.read(4).unpack('N').first + sig = signature_equiv[sig] || sig assert_equal(sig, signatures[bin]) end diff --git a/testdata/lvs/floating.cir b/testdata/lvs/floating.cir index ced9a2759..edd64b16f 100644 --- a/testdata/lvs/floating.cir +++ b/testdata/lvs/floating.cir @@ -43,8 +43,8 @@ X$2 3 5 2 6 INVX1 * net 2 VDD * net 3 IN * net 4 VSS -* device instance $1 r0 *1 0.85,2.135 NMOS -M$1 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U -* device instance $2 r0 *1 0.85,5.8 PMOS -M$2 2 3 1 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 2 3 1 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U .ENDS INVX1 diff --git a/testdata/lvs/floating.lvsdb b/testdata/lvs/floating.lvsdb index 3775e7da4..abb305d27 100644 --- a/testdata/lvs/floating.lvsdb +++ b/testdata/lvs/floating.lvsdb @@ -135,20 +135,7 @@ layout( pin(4 name(VSS)) # Devices and their connections - device(1 D$NMOS - location(850 2135) - param(L 0.25) - param(W 0.95) - param(AS 0.40375) - param(AD 0.40375) - param(PS 2.75) - param(PD 2.75) - terminal(S 4) - terminal(G 3) - terminal(D 1) - terminal(B 4) - ) - device(2 D$PMOS + device(1 D$PMOS location(850 5800) param(L 0.25) param(W 1.5) @@ -161,6 +148,19 @@ layout( terminal(D 1) terminal(B 2) ) + device(2 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 4) + terminal(G 3) + terminal(D 1) + terminal(B 4) + ) ) circuit(DINV @@ -430,8 +430,8 @@ xref( pin(0 1 match) pin(1 2 match) pin(3 3 match) - device(1 1 match) - device(2 2 match) + device(2 1 match) + device(1 2 match) ) ) circuit(TOP TOP match diff --git a/testdata/lvs/invchain_cheat.cir.1 b/testdata/lvs/invchain_cheat.cir.1 new file mode 100644 index 000000000..ebb1e0e31 --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.1 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$9 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$9 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/invchain_cheat.cir.2 b/testdata/lvs/invchain_cheat.cir.2 new file mode 100644 index 000000000..559a90f2a --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.2 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$8 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$8 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/invchain_cheat.cir.3 b/testdata/lvs/invchain_cheat.cir.3 new file mode 100644 index 000000000..be921871d --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.3 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$7 \$10 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$7 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$10 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/invchain_cheat.lvs b/testdata/lvs/invchain_cheat.lvs new file mode 100644 index 000000000..34ff10e5c --- /dev/null +++ b/testdata/lvs/invchain_cheat.lvs @@ -0,0 +1,73 @@ + +source($lvs_test_source) + +report_lvs($lvs_test_target_lvsdb) + +writer = write_spice(true, false) +target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout") + +schematic("invchain_for_cheat.cir") + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +poly = input(3, 0) +diff_cont = input(4, 0) +poly_cont = input(5, 0) +metal1 = input(6, 0) +via1 = input(7, 0) +metal2 = input(8, 0) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell +pgate = pactive & poly +psd = pactive - pgate + +active_outside_nwell = active - nwell +nactive = active_outside_nwell +ngate = nactive & poly +nsd = nactive - ngate + +# Device extraction + +cheat("INV") do + + # PMOS transistor device extraction + extract_devices(mos3("PMOS"), { "SD" => psd, "G" => pgate, + "tS" => psd, "tD" => psd, "tG" => poly }) + + # NMOS transistor device extraction + extract_devices(mos3("NMOS"), { "SD" => nsd, "G" => ngate, + "tS" => nsd, "tD" => nsd, "tG" => poly }) + +end + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, diff_cont) +connect(nsd, diff_cont) +connect(poly, poly_cont) +connect(diff_cont, metal1) +connect(poly_cont, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# Global +connect_global(bulk, "SUBSTRATE") + +# Compare section + +netlist.simplify + +compare + diff --git a/testdata/lvs/invchain_cheat.lvsdb b/testdata/lvs/invchain_cheat.lvsdb new file mode 100644 index 000000000..7f128c691 --- /dev/null +++ b/testdata/lvs/invchain_cheat.lvsdb @@ -0,0 +1,757 @@ +#%lvsdb-klayout +J( + W(INVCHAIN) + U(0.001) + L(l3 '3/0') + L(l6 '4/0') + L(l7 '2/0') + L(l8 '6/0') + L(l9 '7/0') + L(l10 '8/0') + L(l11) + L(l2) + L(l5) + C(l3 l3 l7) + C(l6 l6 l8 l2 l5) + C(l7 l3 l7 l8) + C(l8 l6 l7 l8 l9) + C(l9 l8 l9 l10) + C(l10 l9 l10) + C(l11 l11) + C(l2 l6 l2) + C(l5 l6 l5) + G(l11 SUBSTRATE) + D(D$PMOS PMOS + T(S + R(l2 (-960 -475) (835 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l2 (125 -475) (550 950)) + ) + ) + D(D$PMOS$1 PMOS + T(S + R(l2 (-675 -475) (550 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l2 (125 -475) (35 950)) + ) + ) + D(D$NMOS NMOS + T(S + R(l5 (-960 -475) (835 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l5 (125 -475) (550 950)) + ) + ) + D(D$NMOS$1 NMOS + T(S + R(l5 (-675 -475) (550 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l5 (125 -475) (35 950)) + ) + ) + X(INV + R((-1500 -800) (3000 4600)) + N(1 + R(l6 (290 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l5 (-1375 -925) (550 950)) + ) + N(2 + R(l6 (290 2490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l2 (-1375 -925) (550 950)) + ) + N(3 + R(l3 (-125 -250) (250 2500)) + R(l3 (-250 -3050) (250 1600)) + R(l3 (-250 1200) (250 1600)) + ) + N(4 + R(l6 (-510 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -3530) (360 2840)) + R(l8 (-360 -2800) (360 760)) + R(l8 (-360 2040) (360 760)) + R(l2 (-740 -855) (835 950)) + R(l5 (-835 -3750) (835 950)) + ) + N(5 + R(l2 (925 2325) (35 950)) + ) + N(6 + R(l5 (925 -475) (35 950)) + ) + N(7) + N(8) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + D(1 D$PMOS + Y(0 2800) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 2) + ) + D(2 D$PMOS$1 + Y(800 2800) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 2) + T(G 7) + T(D 5) + ) + D(3 D$NMOS + Y(0 0) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 1) + ) + D(4 D$NMOS$1 + Y(800 0) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 1) + T(G 8) + T(D 6) + ) + ) + X(INV2 + R((0 0) (5500 4600)) + N(1) + N(2) + N(3) + N(4) + N(5) + N(6) + N(7) + N(8) + N(9) + N(10) + N(11 + R(l6 (1790 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(12 + R(l6 (3490 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(13 + R(l6 (990 3290) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(14 + R(l6 (990 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + P(9) + P(10) + P(11) + P(12) + P(13) + P(14) + X(1 INV M O(180) Y(1500 800) + P(0 14) + P(1 13) + P(2 3) + P(3 11) + P(4 9) + P(5 7) + P(6 1) + P(7 5) + ) + X(2 INV Y(4000 800) + P(0 14) + P(1 13) + P(2 4) + P(3 12) + P(4 10) + P(5 8) + P(6 2) + P(7 6) + ) + ) + X(INV3 + R((0 0) (6300 4600)) + N(1) + N(2 + R(l6 (990 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(3) + N(4) + N(5) + N(6) + N(7) + N(8) + N(9 + R(l6 (2590 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(10 + R(l6 (4290 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(11 + R(l6 (1790 3290) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(12 + R(l6 (1790 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + P(9) + P(10) + P(11) + P(12) + X(1 INV Y(1500 800) + P(0 12) + P(1 11) + P(2 5) + P(3 2) + P(4 9) + P(5 9) + P(6 1) + P(7 1) + ) + X(2 INV M O(180) Y(2300 800) + P(0 12) + P(1 11) + P(2 1) + P(3 9) + P(4 2) + P(5 2) + P(6 5) + P(7 5) + ) + X(3 INV Y(4800 800) + P(0 12) + P(1 11) + P(2 4) + P(3 10) + P(4 8) + P(5 7) + P(6 3) + P(7 6) + ) + ) + X(INVCHAIN + R((-1500 -800) (10400 4600)) + N(1 + R(l6 (490 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(2 + R(l6 (3790 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(3 + R(l6 (1405 990) (220 220)) + R(l6 (-535 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (20 -2270) (440 520)) + ) + N(4 + R(l6 (7090 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(5 + R(l6 (4705 990) (220 220)) + R(l6 (-535 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (20 -2270) (440 520)) + ) + N(6 + R(l3 (-1295 925) (1235 350)) + ) + N(7 + R(l3 (445 805) (480 550)) + ) + N(8 + R(l3 (1345 925) (1945 350)) + ) + N(9 + R(l3 (3745 805) (480 550)) + ) + N(10 + R(l3 (4645 925) (1945 350)) + ) + N(11 + R(l3 (7045 805) (480 550)) + ) + N(12 + R(l6 (7690 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(13 + R(l6 (6890 2490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-3520 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-6820 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (3010 -690) (360 760)) + R(l8 (-3660 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + R(l8 (-6960 -760) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(14 + R(l6 (6890 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-3520 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-6820 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (3010 -690) (360 760)) + R(l8 (-3660 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + R(l8 (-6960 -760) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + X(1 INV3 Y(-1500 -800) + P(0 7) + P(1 1) + P(2 9) + P(3 8) + P(4 6) + P(5 9) + P(6 5) + P(7 5) + P(8 3) + P(9 2) + P(10 13) + P(11 14) + ) + X(2 INV2 Y(2600 -800) + P(0 8) + P(1 11) + P(2 9) + P(3 10) + P(4 8) + P(5 11) + P(6 2) + P(7 12) + P(8 2) + P(9 12) + P(10 5) + P(11 4) + P(12 13) + P(13 14) + ) + X(3 INV M O(180) Y(7400 0) + P(0 14) + P(1 13) + P(2 11) + P(3 12) + P(4 4) + P(5 4) + P(6 10) + P(7 10) + ) + ) +) +H( + X(TRANS + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + ) + X(INV + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + D(1 PMOS + I($1) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 2) + T(B 4) + ) + D(2 PMOS + I($2) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 2) + T(G 7) + T(D 5) + T(B 2) + ) + D(3 NMOS + I($3) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 1) + T(B 4) + ) + D(4 NMOS + I($4) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 1) + T(G 8) + T(D 6) + T(B 1) + ) + X(1 TRANS I($1) + P(0 4) + P(1 1) + P(2 3) + ) + X(2 TRANS I($2) + P(0 4) + P(1 2) + P(2 3) + ) + ) + X(INV3 + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + N(9 I('9')) + N(10 I('10')) + N(11 I('11')) + N(12 I('12')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + P(9 I('9')) + P(10 I('10')) + P(11 I('11')) + P(12 I('12')) + X(1 INV I($1) + P(0 12) + P(1 11) + P(2 3) + P(3 10) + P(4 8) + P(5 6) + P(6 1) + P(7 5) + ) + X(2 INV I($2) + P(0 12) + P(1 11) + P(2 4) + P(3 7) + P(4 9) + P(5 9) + P(6 2) + P(7 2) + ) + X(3 INV I($3) + P(0 12) + P(1 11) + P(2 2) + P(3 9) + P(4 7) + P(5 7) + P(6 4) + P(7 4) + ) + ) + X(INV2 + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + N(9 I('9')) + N(10 I('10')) + N(11 I('11')) + N(12 I('12')) + N(13 I('13')) + N(14 I('14')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + P(9 I('9')) + P(10 I('10')) + P(11 I('11')) + P(12 I('12')) + P(13 I('13')) + P(14 I('14')) + X(1 INV I($1) + P(0 14) + P(1 13) + P(2 3) + P(3 11) + P(4 9) + P(5 7) + P(6 1) + P(7 5) + ) + X(2 INV I($2) + P(0 14) + P(1 13) + P(2 4) + P(3 12) + P(4 10) + P(5 8) + P(6 2) + P(7 6) + ) + ) + X(INVCHAIN + N(1 I('9')) + N(2 I('7')) + N(3 I('8')) + N(4 I('6')) + N(5 I('5')) + N(6 I('1')) + N(7 I('3')) + N(8 I('2')) + N(9 I('13')) + N(10 I('14')) + N(11 I('11')) + N(12 I('10')) + N(13 I('12')) + N(14 I('4')) + X(1 INV3 I($1) + P(0 1) + P(1 2) + P(2 3) + P(3 4) + P(4 1) + P(5 5) + P(6 6) + P(7 5) + P(8 7) + P(9 8) + P(10 9) + P(11 10) + ) + X(2 INV2 I($2) + P(0 3) + P(1 11) + P(2 1) + P(3 12) + P(4 3) + P(5 11) + P(6 8) + P(7 13) + P(8 8) + P(9 13) + P(10 5) + P(11 14) + P(12 9) + P(13 10) + ) + X(3 INV I($3) + P(0 10) + P(1 9) + P(2 11) + P(3 13) + P(4 14) + P(5 14) + P(6 12) + P(7 12) + ) + ) +) +Z( + X(() TRANS 0 + Z( + ) + ) + X(INV INV S + Z( + ) + ) + X(INV2 INV2 S + Z( + ) + ) + X(INV3 INV3 S + Z( + ) + ) + X(INVCHAIN INVCHAIN S + Z( + ) + ) +) diff --git a/testdata/lvs/invchain_for_cheat.cir b/testdata/lvs/invchain_for_cheat.cir new file mode 100644 index 000000000..1aae680d3 --- /dev/null +++ b/testdata/lvs/invchain_for_cheat.cir @@ -0,0 +1,85 @@ + +* cell INVCHAIN +.SUBCKT INVCHAIN +* cell instance $1 r0 *1 -1.5,-0.8 +X$1 9 7 8 6 9 5 1 5 3 2 13 14 INV3 +* cell instance $2 r0 *1 2.6,-0.8 +X$2 8 11 9 10 8 11 2 12 2 12 5 4 13 14 INV2 +* cell instance $3 m90 *1 7.4,0 +X$3 14 13 11 12 4 4 10 10 INV +.ENDS INVCHAIN + +* cell INV3 +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV3 1 2 3 4 5 6 7 8 9 10 11 12 +* cell instance $1 r0 *1 4.8,0.8 +X$1 12 11 3 10 8 6 1 5 INV +* cell instance $2 r0 *1 1.5,0.8 +X$2 12 11 4 7 9 9 2 2 INV +* cell instance $3 m90 *1 2.3,0.8 +X$3 12 11 2 9 7 7 4 4 INV +.ENDS INV3 + +* cell INV2 +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +* cell instance $1 m90 *1 1.5,0.8 +X$1 14 13 3 11 9 7 1 5 INV +* cell instance $2 r0 *1 4,0.8 +X$2 14 13 4 12 10 8 2 6 INV +.ENDS INV2 + +* cell INV +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV 1 2 3 4 5 6 7 8 +* cell instance $1 r0 *1 0,0 +X$1 4 1 3 TRANS +* cell instance $2 r0 *1 0,2.8 +X$2 4 2 3 TRANS +* device instance $1 r0 *1 0,2.8 PMOS +M$1 4 3 2 4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U +* device instance $2 r0 *1 0.8,2.8 PMOS +M$2 2 7 5 2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U +* device instance $3 r0 *1 0,0 NMOS +M$3 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U +* device instance $4 r0 *1 0.8,0 NMOS +M$4 1 8 6 1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U +.ENDS INV + +* cell TRANS +* pin +* pin +* pin +.SUBCKT TRANS 1 2 3 +.ENDS TRANS diff --git a/testdata/lvs/invchain_for_cheat.gds b/testdata/lvs/invchain_for_cheat.gds new file mode 100644 index 000000000..43446a79f Binary files /dev/null and b/testdata/lvs/invchain_for_cheat.gds differ diff --git a/testdata/lvs/ringo_layout_var.cir b/testdata/lvs/ringo_layout_var.cir new file mode 100644 index 000000000..93b5336ec --- /dev/null +++ b/testdata/lvs/ringo_layout_var.cir @@ -0,0 +1,102 @@ +* Extracted by KLayout + +* cell RINGO +* pin FB +* pin VDD +* pin OUT +* pin ENABLE +* pin VSS +.SUBCKT RINGO 11 12 13 14 15 +* net 11 FB +* net 12 VDD +* net 13 OUT +* net 14 ENABLE +* net 15 VSS +* cell instance $1 r0 *1 1.8,0 +X$1 12 1 15 12 11 14 15 ND2X1 +* cell instance $2 r0 *1 4.2,0 +X$2 12 2 15 12 1 15 INVX1B +* cell instance $3 r0 *1 6,0 +X$3 12 3 15 12 2 15 INVX1 +* cell instance $4 r0 *1 7.8,0 +X$4 12 4 15 12 3 15 INVX1B +* cell instance $5 r0 *1 9.6,0 +X$5 12 5 15 12 4 15 INVX1 +* cell instance $6 r0 *1 11.4,0 +X$6 12 6 15 12 5 15 INVX1B +* cell instance $7 r0 *1 13.2,0 +X$7 12 7 15 12 6 15 INVX1 +* cell instance $8 r0 *1 15,0 +X$8 12 8 15 12 7 15 INVX1 +* cell instance $9 r0 *1 16.8,0 +X$9 12 9 15 12 8 15 INVX1 +* cell instance $10 r0 *1 18.6,0 +X$10 12 10 15 12 9 15 INVX1 +* cell instance $11 r0 *1 20.4,0 +X$11 12 11 15 12 10 15 INVX1 +* cell instance $12 r0 *1 22.2,0 +X$12 12 13 15 12 11 15 INVX1 +.ENDS RINGO + +* cell INVX1B +* pin VDD +* pin OUT +* pin VSS +* pin +* pin IN +* pin SUBSTRATE +.SUBCKT INVX1B 1 2 3 4 5 6 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 IN +* net 6 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U +.ENDS INVX1B + +* cell INVX1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin IN +* pin SUBSTRATE +.SUBCKT INVX1 1 2 3 4 5 6 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 IN +* net 6 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U +.ENDS INVX1 + +* cell ND2X1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin B +* pin A +* pin SUBSTRATE +.SUBCKT ND2X1 1 2 3 4 5 6 7 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 B +* net 6 A +* net 7 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 2 6 1 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.3375P PS=3.85U PD=1.95U +* device instance $2 r0 *1 1.55,5.8 PMOS +M$2 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.3375P AD=0.6375P PS=1.95U PD=3.85U +* device instance $3 r0 *1 0.85,2.135 NMOS +M$3 3 6 8 7 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.21375P PS=2.75U PD=1.4U +* device instance $4 r0 *1 1.55,2.135 NMOS +M$4 8 5 2 7 NMOS L=0.25U W=0.95U AS=0.21375P AD=0.40375P PS=1.4U PD=2.75U +.ENDS ND2X1 diff --git a/testdata/lvs/ringo_layout_var.gds b/testdata/lvs/ringo_layout_var.gds new file mode 100644 index 000000000..e5a18d6f9 Binary files /dev/null and b/testdata/lvs/ringo_layout_var.gds differ diff --git a/testdata/lvs/ringo_layout_var.lvs b/testdata/lvs/ringo_layout_var.lvs new file mode 100644 index 000000000..afe79c3e2 --- /dev/null +++ b/testdata/lvs/ringo_layout_var.lvs @@ -0,0 +1,78 @@ + +source($lvs_test_source, "RINGO") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +# both INVX1 and INVX1B are the same schematic cell +same_circuits("INVX1", "INVX1") +same_circuits("INVX1B", "INVX1") + +schematic("ringo.cir") + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(8, 0) +metal1 = input(9, 0) +via1 = input(10, 0) +metal2 = input(11, 0) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell & pplus +pgate = pactive & poly +psd = pactive - pgate +ntie = active_in_nwell & nplus + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate +ptie = active_outside_nwell & pplus + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos4("PMOS"), { "SD" => psd, "G" => pgate, "W" => nwell, + "tS" => psd, "tD" => psd, "tG" => poly, "tW" => nwell }) + +# NMOS transistor device extraction +extract_devices(mos4("NMOS"), { "SD" => nsd, "G" => ngate, "W" => bulk, + "tS" => nsd, "tD" => nsd, "tG" => poly, "tW" => bulk }) + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, contact) +connect(nsd, contact) +connect(poly, contact) +connect(ntie, contact) +connect(nwell, ntie) +connect(ptie, contact) +connect(contact, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(ptie, "SUBSTRATE") + +# Compare section + +netlist.simplify + +compare + diff --git a/testdata/lvs/ringo_layout_var.lvsdb.1 b/testdata/lvs/ringo_layout_var.lvsdb.1 new file mode 100644 index 000000000..35a52028c --- /dev/null +++ b/testdata/lvs/ringo_layout_var.lvsdb.1 @@ -0,0 +1,1076 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX1B + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23025 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-20175 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(13 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(15 name(VSS) + rect(l8 (1110 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-21741 -391) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-23700 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-20175 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(11 name(FB)) + pin(12 name(VDD)) + pin(13 name(OUT)) + pin(14 name(ENABLE)) + pin(15 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 12) + pin(1 1) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 14) + pin(6 15) + ) + circuit(2 INVX1B location(4200 0) + pin(0 12) + pin(1 2) + pin(2 15) + pin(3 12) + pin(4 1) + pin(5 15) + ) + circuit(3 INVX1 location(6000 0) + pin(0 12) + pin(1 3) + pin(2 15) + pin(3 12) + pin(4 2) + pin(5 15) + ) + circuit(4 INVX1B location(7800 0) + pin(0 12) + pin(1 4) + pin(2 15) + pin(3 12) + pin(4 3) + pin(5 15) + ) + circuit(5 INVX1 location(9600 0) + pin(0 12) + pin(1 5) + pin(2 15) + pin(3 12) + pin(4 4) + pin(5 15) + ) + circuit(6 INVX1B location(11400 0) + pin(0 12) + pin(1 6) + pin(2 15) + pin(3 12) + pin(4 5) + pin(5 15) + ) + circuit(7 INVX1 location(13200 0) + pin(0 12) + pin(1 7) + pin(2 15) + pin(3 12) + pin(4 6) + pin(5 15) + ) + circuit(8 INVX1 location(15000 0) + pin(0 12) + pin(1 8) + pin(2 15) + pin(3 12) + pin(4 7) + pin(5 15) + ) + circuit(9 INVX1 location(16800 0) + pin(0 12) + pin(1 9) + pin(2 15) + pin(3 12) + pin(4 8) + pin(5 15) + ) + circuit(10 INVX1 location(18600 0) + pin(0 12) + pin(1 10) + pin(2 15) + pin(3 12) + pin(4 9) + pin(5 15) + ) + circuit(11 INVX1 location(20400 0) + pin(0 12) + pin(1 11) + pin(2 15) + pin(3 12) + pin(4 10) + pin(5 15) + ) + circuit(12 INVX1 location(22200 0) + pin(0 12) + pin(1 13) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 15) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX1B INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(10 15 match) + net(2 7 match) + net(3 8 match) + net(4 9 match) + net(5 10 match) + net(6 11 match) + net(7 12 match) + net(8 13 match) + net(9 14 match) + net(14 4 match) + net(11 3 match) + net(13 5 match) + net(12 2 match) + net(15 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(3 3 match) + circuit(5 5 match) + circuit(7 7 match) + circuit(8 8 match) + circuit(9 9 match) + circuit(10 10 match) + circuit(11 11 match) + circuit(12 12 match) + circuit(2 2 match) + circuit(4 4 match) + circuit(6 6 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_layout_var.lvsdb.2 b/testdata/lvs/ringo_layout_var.lvsdb.2 new file mode 100644 index 000000000..f7ed4588d --- /dev/null +++ b/testdata/lvs/ringo_layout_var.lvsdb.2 @@ -0,0 +1,1076 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX1B + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23025 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-20175 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(13 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(15 name(VSS) + rect(l8 (1110 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-21741 -391) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-23700 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-20175 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(11 name(FB)) + pin(12 name(VDD)) + pin(13 name(OUT)) + pin(14 name(ENABLE)) + pin(15 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 12) + pin(1 1) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 14) + pin(6 15) + ) + circuit(2 INVX1B location(4200 0) + pin(0 12) + pin(1 2) + pin(2 15) + pin(3 12) + pin(4 1) + pin(5 15) + ) + circuit(3 INVX1 location(6000 0) + pin(0 12) + pin(1 3) + pin(2 15) + pin(3 12) + pin(4 2) + pin(5 15) + ) + circuit(4 INVX1B location(7800 0) + pin(0 12) + pin(1 4) + pin(2 15) + pin(3 12) + pin(4 3) + pin(5 15) + ) + circuit(5 INVX1 location(9600 0) + pin(0 12) + pin(1 5) + pin(2 15) + pin(3 12) + pin(4 4) + pin(5 15) + ) + circuit(6 INVX1B location(11400 0) + pin(0 12) + pin(1 6) + pin(2 15) + pin(3 12) + pin(4 5) + pin(5 15) + ) + circuit(7 INVX1 location(13200 0) + pin(0 12) + pin(1 7) + pin(2 15) + pin(3 12) + pin(4 6) + pin(5 15) + ) + circuit(8 INVX1 location(15000 0) + pin(0 12) + pin(1 8) + pin(2 15) + pin(3 12) + pin(4 7) + pin(5 15) + ) + circuit(9 INVX1 location(16800 0) + pin(0 12) + pin(1 9) + pin(2 15) + pin(3 12) + pin(4 8) + pin(5 15) + ) + circuit(10 INVX1 location(18600 0) + pin(0 12) + pin(1 10) + pin(2 15) + pin(3 12) + pin(4 9) + pin(5 15) + ) + circuit(11 INVX1 location(20400 0) + pin(0 12) + pin(1 11) + pin(2 15) + pin(3 12) + pin(4 10) + pin(5 15) + ) + circuit(12 INVX1 location(22200 0) + pin(0 12) + pin(1 13) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 15) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX1B INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(10 15 match) + net(2 7 match) + net(3 8 match) + net(4 9 match) + net(5 10 match) + net(6 11 match) + net(7 12 match) + net(8 13 match) + net(9 14 match) + net(14 4 match) + net(11 3 match) + net(13 5 match) + net(12 2 match) + net(15 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(3 3 match) + circuit(5 5 match) + circuit(7 7 match) + circuit(8 8 match) + circuit(9 9 match) + circuit(10 10 match) + circuit(11 11 match) + circuit(12 12 match) + circuit(2 2 match) + circuit(4 4 match) + circuit(6 6 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_mixed_hierarchy.cir b/testdata/lvs/ringo_mixed_hierarchy.cir index 8e98d778a..e82ebea9b 100644 --- a/testdata/lvs/ringo_mixed_hierarchy.cir +++ b/testdata/lvs/ringo_mixed_hierarchy.cir @@ -57,8 +57,8 @@ M$4 15 1 4 16 NMOS L=0.25U W=0.95U AS=0.21375P AD=0.40375P PS=1.4U PD=2.75U * net 3 VSS * net 5 IN * net 6 SUBSTRATE -* device instance $1 r0 *1 0.85,2.135 NMOS -M$1 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U -* device instance $2 r0 *1 0.85,5.8 PMOS -M$2 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U .ENDS INVX1 diff --git a/testdata/lvs/ringo_mixed_hierarchy.lvsdb b/testdata/lvs/ringo_mixed_hierarchy.lvsdb index 796a8d02b..d71d08c6a 100644 --- a/testdata/lvs/ringo_mixed_hierarchy.lvsdb +++ b/testdata/lvs/ringo_mixed_hierarchy.lvsdb @@ -190,20 +190,7 @@ layout( pin(6 name(SUBSTRATE)) # Devices and their connections - device(1 D$NMOS$2 - location(850 2135) - param(L 0.25) - param(W 0.95) - param(AS 0.40375) - param(AD 0.40375) - param(PS 2.75) - param(PD 2.75) - terminal(S 3) - terminal(G 5) - terminal(D 2) - terminal(B 6) - ) - device(2 D$PMOS$2 + device(1 D$PMOS$2 location(850 5800) param(L 0.25) param(W 1.5) @@ -216,6 +203,19 @@ layout( terminal(D 2) terminal(B 4) ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) ) circuit(RINGO @@ -825,8 +825,8 @@ xref( pin(5 5 match) pin(0 0 match) pin(2 2 match) - device(1 2 match) - device(2 1 match) + device(2 2 match) + device(1 1 match) ) ) circuit(RINGO RINGO match diff --git a/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 b/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 index f4780ff2d..3c0b06564 100644 --- a/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 +++ b/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -371,9 +371,9 @@ layout( net(2 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 rect(l8 (6510 3010) (180 180)) diff --git a/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 b/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 new file mode 100644 index 000000000..f4780ff2d --- /dev/null +++ b/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 @@ -0,0 +1,1028 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS$1 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$2 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (27600 7650)) + + # Nets with their geometries + net(1 + rect(l4 (26050 2800) (525 550)) + rect(l4 (-525 -300) (300 300)) + rect(l4 (-25 -2000) (250 1450)) + rect(l8 (-465 310) (180 180)) + rect(l11 (-240 -240) (300 300)) + ) + net(2 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l8 (-26490 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l2 (-24825 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l9 (-21975 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(14 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(16 name(VSS) + rect(l8 (26010 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (520 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-25780 -890) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (1260 -40) (300 1360)) + rect(l11 (400 -1360) (300 1360)) + rect(l11 (-24001 -1711) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l6 (-25500 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3650 -1010) (425 950)) + rect(l6 (-1100 -950) (425 950)) + rect(l10 (-25375 -2150) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(12 name(FB)) + pin(13 name(VDD)) + pin(14 name(OUT)) + pin(15 name(ENABLE)) + pin(16 name(VSS)) + + # Devices and their connections + device(1 D$NMOS + location(26450 2075) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 16) + terminal(G 1) + terminal(D 16) + terminal(B 16) + ) + + # Subcircuits and their connections + circuit(3 ND2X1 location(1800 0) + pin(0 13) + pin(1 2) + pin(2 16) + pin(3 13) + pin(4 12) + pin(5 15) + pin(6 16) + ) + circuit(4 INVX1 location(4200 0) + pin(0 13) + pin(1 3) + pin(2 16) + pin(3 13) + pin(4 2) + pin(5 16) + ) + circuit(5 INVX1 location(6000 0) + pin(0 13) + pin(1 4) + pin(2 16) + pin(3 13) + pin(4 3) + pin(5 16) + ) + circuit(6 INVX1 location(7800 0) + pin(0 13) + pin(1 5) + pin(2 16) + pin(3 13) + pin(4 4) + pin(5 16) + ) + circuit(7 INVX1 location(9600 0) + pin(0 13) + pin(1 6) + pin(2 16) + pin(3 13) + pin(4 5) + pin(5 16) + ) + circuit(8 INVX1 location(11400 0) + pin(0 13) + pin(1 7) + pin(2 16) + pin(3 13) + pin(4 6) + pin(5 16) + ) + circuit(9 INVX1 location(13200 0) + pin(0 13) + pin(1 8) + pin(2 16) + pin(3 13) + pin(4 7) + pin(5 16) + ) + circuit(10 INVX1 location(15000 0) + pin(0 13) + pin(1 9) + pin(2 16) + pin(3 13) + pin(4 8) + pin(5 16) + ) + circuit(11 INVX1 location(16800 0) + pin(0 13) + pin(1 10) + pin(2 16) + pin(3 13) + pin(4 9) + pin(5 16) + ) + circuit(12 INVX1 location(18600 0) + pin(0 13) + pin(1 11) + pin(2 16) + pin(3 13) + pin(4 10) + pin(5 16) + ) + circuit(13 INVX1 location(20400 0) + pin(0 13) + pin(1 12) + pin(2 16) + pin(3 13) + pin(4 11) + pin(5 16) + ) + circuit(14 INVX1 location(22200 0) + pin(0 13) + pin(1 14) + pin(2 16) + pin(3 13) + pin(4 12) + pin(5 16) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(NMOS MOS4) + class(PMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + net(16 name(DUMMY)) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Devices and their connections + device(1 NMOS + name($1) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 16) + terminal(D 1) + terminal(B 1) + ) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(2 6 match) + net(11 15 match) + net(3 7 match) + net(4 8 match) + net(5 9 match) + net(6 10 match) + net(7 11 match) + net(8 12 match) + net(9 13 match) + net(10 14 match) + net(1 16 match) + net(15 4 match) + net(12 3 match) + net(14 5 match) + net(13 2 match) + net(16 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + device(1 1 match) + circuit(4 2 match) + circuit(5 3 match) + circuit(6 4 match) + circuit(7 5 match) + circuit(8 6 match) + circuit(9 7 match) + circuit(10 8 match) + circuit(11 9 match) + circuit(12 10 match) + circuit(13 11 match) + circuit(14 12 match) + circuit(3 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs index 878c69698..7ff601882 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs @@ -7,6 +7,9 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") schematic("ringo.cir") +# preempt configuration (see below) +same_nets("top", "ENABLE", "RINGO", "ENABLE") + deep # Drawing layers @@ -71,7 +74,6 @@ connect_global(ptie, "SUBSTRATE") same_circuits("top", "RINGO") same_circuits("INV", "INVX1") same_circuits("DOESNOTEXIST", "DOESNOTEXIST2") -same_nets("top", "ENABLE", "RINGO", "ENABLE") same_nets("DOESNOTEXIST", "ENABLE", "DOESNOTEXIST2", "ENABLE") netlist.simplify diff --git a/testdata/lvs/ringo_simple_pin_swapping.lvs b/testdata/lvs/ringo_simple_pin_swapping.lvs index dcfa49dd4..d54d3f1fa 100644 --- a/testdata/lvs/ringo_simple_pin_swapping.lvs +++ b/testdata/lvs/ringo_simple_pin_swapping.lvs @@ -7,6 +7,9 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") schematic("ringo_pin_swapping.cir") +# preempt configuration +equivalent_pins("ND2X1", 4, 5) + deep # Drawing layers @@ -68,7 +71,6 @@ connect_global(ptie, "SUBSTRATE") # Compare section -equivalent_pins("ND2X1", 4, 5) equivalent_pins("DOESNOTEXIST", 4, 5) netlist.simplify diff --git a/testdata/lvs/ringo_simple_same_device_classes.lvs b/testdata/lvs/ringo_simple_same_device_classes.lvs index 9a2bad4d1..8005d70cc 100644 --- a/testdata/lvs/ringo_simple_same_device_classes.lvs +++ b/testdata/lvs/ringo_simple_same_device_classes.lvs @@ -8,6 +8,9 @@ target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout") schematic("ringo.cir") +# preempt configuration +same_device_classes("PM", "PMOS") + deep # Drawing layers @@ -90,7 +93,6 @@ connect_global(ptie, "SUBSTRATE") netlist.simplify -same_device_classes("PM", "PMOS") same_device_classes("NM", "NMOS") same_device_classes("PMHV", "PMOSHV") same_device_classes("NMHV", "NMOSHV") diff --git a/testdata/lvs/ringo_simple_simplification.lvsdb.2 b/testdata/lvs/ringo_simple_simplification.lvsdb.2 index 2492067a3..77e688c6e 100644 --- a/testdata/lvs/ringo_simple_simplification.lvsdb.2 +++ b/testdata/lvs/ringo_simple_simplification.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -389,8 +389,8 @@ layout( rect(l11 (1100 -300) (300 300)) rect(l11 (-1101 399) (2 2)) rect(l11 (799 -2101) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) ) net(3 name(OUT) rect(l8 (1110 5160) (180 180)) @@ -486,9 +486,9 @@ layout( net(1 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(2 rect(l8 (6510 3010) (180 180)) @@ -554,9 +554,9 @@ layout( rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) - rect(l2 (4550 -1500) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l2 (-3600 -1500) (425 1500)) rect(l9 (-19575 -450) (500 1500)) rect(l9 (22900 -1500) (500 1500)) ) diff --git a/testdata/lvs/ringo_simple_simplification.lvsdb.3 b/testdata/lvs/ringo_simple_simplification.lvsdb.3 new file mode 100644 index 000000000..2492067a3 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification.lvsdb.3 @@ -0,0 +1,1162 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-225 -1300) (675 450)) + rect(l4 (0 -1100) (250 1950)) + rect(l4 (-1225 -1850) (300 300)) + rect(l4 (675 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-950 -2000) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (450 -5390) (250 1450)) + rect(l4 (-950 -1450) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(2 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-1640 -240) (300 1400)) + rect(l11 (-650 300) (2400 800)) + rect(l11 (-2050 -1100) (300 300)) + rect(l11 (1100 -300) (300 300)) + rect(l11 (-1101 399) (2 2)) + rect(l11 (799 -2101) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + ) + net(3 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(4 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (1220 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-1640 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-650 0) (300 1360)) + rect(l11 (-1101 -1761) (2 2)) + rect(l6 (724 859) (425 950)) + rect(l6 (-1800 -950) (425 950)) + ) + net(5 + rect(l3 (-100 4500) (2600 3500)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(IN)) + pin(2 name(VDD)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + device(D$PMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 5800) + param(L 0.25) + param(W 3) + param(AS 0.975) + param(AD 0.975) + param(PS 5.8) + param(PD 5.8) + terminal(S 2) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 2135) + param(L 0.25) + param(W 1.9) + param(AS 0.6175) + param(AD 0.6175) + param(PS 4.15) + param(PD 4.15) + terminal(S 4) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((600 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 name(VDD) + rect(l3 (1100 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-22341 859) (2 2)) + rect(l11 (-1751 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23625 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (4550 -1500) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-19575 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(7 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(8 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(9 name(VSS) + rect(l8 (1710 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-22341 -391) (2 2)) + rect(l11 (-1301 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-24300 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (4550 -950) (425 950)) + rect(l6 (-1800 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-19575 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + net(10 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(5 name(FB)) + pin(6 name(VDD)) + pin(7 name(OUT)) + pin(8 name(ENABLE)) + pin(9 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 6) + pin(1 1) + pin(2 9) + pin(3 6) + pin(4 5) + pin(5 8) + pin(6 9) + ) + circuit(2 INVX1 location(4200 0) + pin(0 6) + pin(1 2) + pin(2 9) + pin(3 6) + pin(4 1) + pin(5 9) + ) + circuit(3 INVX1 location(6000 0) + pin(0 6) + pin(1 10) + pin(2 9) + pin(3 6) + pin(4 2) + pin(5 9) + ) + circuit(4 INVX1 location(16800 0) + pin(0 6) + pin(1 3) + pin(2 9) + pin(3 6) + pin(4 11) + pin(5 9) + ) + circuit(5 INVX1 location(18600 0) + pin(0 6) + pin(1 4) + pin(2 9) + pin(3 6) + pin(4 3) + pin(5 9) + ) + circuit(6 INVX1 location(20400 0) + pin(0 6) + pin(1 5) + pin(2 9) + pin(3 6) + pin(4 4) + pin(5 9) + ) + circuit(7 INVX2 location(22200 0) + pin(0 5) + pin(1 6) + pin(2 7) + pin(3 9) + pin(4 6) + pin(5 9) + ) + circuit(17 INVX1 location(7800 0) + pin(0 6) + pin(1 12) + pin(2 9) + pin(3 6) + pin(4 10) + pin(5 9) + ) + circuit(18 INVX1 location(9600 0) + pin(0 6) + pin(1 13) + pin(2 9) + pin(3 6) + pin(4 12) + pin(5 9) + ) + circuit(19 INVX1 location(11400 0) + pin(0 6) + pin(1 14) + pin(2 9) + pin(3 6) + pin(4 13) + pin(5 9) + ) + circuit(20 INVX1 location(13200 0) + pin(0 6) + pin(1 15) + pin(2 9) + pin(3 6) + pin(4 14) + pin(5 9) + ) + circuit(21 INVX1 location(15000 0) + pin(0 6) + pin(1 11) + pin(2 9) + pin(3 6) + pin(4 15) + pin(5 9) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 3) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 1.9) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX2 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX2 INVX2 match + xref( + net(5 4 match) + net(1 5 match) + net(3 2 match) + net(6 6 match) + net(2 1 match) + net(4 3 match) + pin(4 3 match) + pin(0 4 match) + pin(2 1 match) + pin(5 5 match) + pin(1 0 match) + pin(3 2 match) + device(3 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(4 15 match) + net(2 7 match) + net(10 8 match) + net(12 9 match) + net(13 10 match) + net(14 11 match) + net(15 12 match) + net(11 13 match) + net(3 14 match) + net(8 4 match) + net(5 3 match) + net(7 5 match) + net(6 2 match) + net(9 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(2 2 match) + circuit(3 3 match) + circuit(17 4 match) + circuit(18 5 match) + circuit(19 6 match) + circuit(20 7 match) + circuit(21 8 match) + circuit(4 9 match) + circuit(5 10 match) + circuit(6 11 match) + circuit(7 12 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.cir b/testdata/lvs/ringo_simple_simplification_with_align.cir index c24088217..3af85ddd7 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.cir +++ b/testdata/lvs/ringo_simple_simplification_with_align.cir @@ -26,16 +26,16 @@ X$5 6 4 9 6 3 9 INVX1 X$6 6 5 9 6 4 9 INVX1 * cell instance $7 r0 *1 22.2,0 X$7 5 6 7 9 6 9 INVX2 -* cell instance $17 r0 *1 7.8,0 -X$17 6 12 9 6 10 9 INVX1 -* cell instance $18 r0 *1 9.6,0 -X$18 6 13 9 6 12 9 INVX1 -* cell instance $19 r0 *1 11.4,0 -X$19 6 14 9 6 13 9 INVX1 -* cell instance $20 r0 *1 13.2,0 -X$20 6 15 9 6 14 9 INVX1 -* cell instance $21 r0 *1 15,0 -X$21 6 11 9 6 15 9 INVX1 +* cell instance $13 r0 *1 7.8,0 +X$13 6 12 9 6 10 9 INVX1 +* cell instance $14 r0 *1 9.6,0 +X$14 6 13 9 6 12 9 INVX1 +* cell instance $15 r0 *1 11.4,0 +X$15 6 14 9 6 13 9 INVX1 +* cell instance $16 r0 *1 13.2,0 +X$16 6 15 9 6 14 9 INVX1 +* cell instance $17 r0 *1 15,0 +X$17 6 11 9 6 15 9 INVX1 .ENDS RINGO * cell INVX2 diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 index b0e4b5871..609357e5f 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 @@ -711,7 +711,7 @@ layout( pin(4 6) pin(5 9) ) - circuit(17 INVX1 location(7800 0) + circuit(13 INVX1 location(7800 0) pin(0 6) pin(1 12) pin(2 9) @@ -719,7 +719,7 @@ layout( pin(4 10) pin(5 9) ) - circuit(18 INVX1 location(9600 0) + circuit(14 INVX1 location(9600 0) pin(0 6) pin(1 13) pin(2 9) @@ -727,7 +727,7 @@ layout( pin(4 12) pin(5 9) ) - circuit(19 INVX1 location(11400 0) + circuit(15 INVX1 location(11400 0) pin(0 6) pin(1 14) pin(2 9) @@ -735,7 +735,7 @@ layout( pin(4 13) pin(5 9) ) - circuit(20 INVX1 location(13200 0) + circuit(16 INVX1 location(13200 0) pin(0 6) pin(1 15) pin(2 9) @@ -743,7 +743,7 @@ layout( pin(4 14) pin(5 9) ) - circuit(21 INVX1 location(15000 0) + circuit(17 INVX1 location(15000 0) pin(0 6) pin(1 11) pin(2 9) @@ -1147,11 +1147,11 @@ xref( pin(4 0 match) circuit(2 2 match) circuit(3 3 match) - circuit(17 4 match) - circuit(18 5 match) - circuit(19 6 match) - circuit(20 7 match) - circuit(21 8 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) circuit(4 9 match) circuit(5 10 match) circuit(6 11 match) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 index 2492067a3..909c14e3d 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -389,8 +389,8 @@ layout( rect(l11 (1100 -300) (300 300)) rect(l11 (-1101 399) (2 2)) rect(l11 (799 -2101) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) ) net(3 name(OUT) rect(l8 (1110 5160) (180 180)) @@ -486,9 +486,9 @@ layout( net(1 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(2 rect(l8 (6510 3010) (180 180)) @@ -554,9 +554,9 @@ layout( rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) - rect(l2 (4550 -1500) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l2 (-3600 -1500) (425 1500)) rect(l9 (-19575 -450) (500 1500)) rect(l9 (22900 -1500) (500 1500)) ) @@ -711,7 +711,7 @@ layout( pin(4 6) pin(5 9) ) - circuit(17 INVX1 location(7800 0) + circuit(13 INVX1 location(7800 0) pin(0 6) pin(1 12) pin(2 9) @@ -719,7 +719,7 @@ layout( pin(4 10) pin(5 9) ) - circuit(18 INVX1 location(9600 0) + circuit(14 INVX1 location(9600 0) pin(0 6) pin(1 13) pin(2 9) @@ -727,7 +727,7 @@ layout( pin(4 12) pin(5 9) ) - circuit(19 INVX1 location(11400 0) + circuit(15 INVX1 location(11400 0) pin(0 6) pin(1 14) pin(2 9) @@ -735,7 +735,7 @@ layout( pin(4 13) pin(5 9) ) - circuit(20 INVX1 location(13200 0) + circuit(16 INVX1 location(13200 0) pin(0 6) pin(1 15) pin(2 9) @@ -743,7 +743,7 @@ layout( pin(4 14) pin(5 9) ) - circuit(21 INVX1 location(15000 0) + circuit(17 INVX1 location(15000 0) pin(0 6) pin(1 11) pin(2 9) @@ -1147,11 +1147,11 @@ xref( pin(4 0 match) circuit(2 2 match) circuit(3 3 match) - circuit(17 4 match) - circuit(18 5 match) - circuit(19 6 match) - circuit(20 7 match) - circuit(21 8 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) circuit(4 9 match) circuit(5 10 match) circuit(6 11 match) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 new file mode 100644 index 000000000..60f468222 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 @@ -0,0 +1,1162 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-225 -1300) (675 450)) + rect(l4 (0 -1100) (250 1950)) + rect(l4 (-1225 -1850) (300 300)) + rect(l4 (675 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-950 -2000) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (450 -5390) (250 1450)) + rect(l4 (-950 -1450) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(2 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-1640 -240) (300 1400)) + rect(l11 (-650 300) (2400 800)) + rect(l11 (-2050 -1100) (300 300)) + rect(l11 (1100 -300) (300 300)) + rect(l11 (-1101 399) (2 2)) + rect(l11 (799 -2101) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + ) + net(3 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(4 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (1220 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-1640 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-650 0) (300 1360)) + rect(l11 (-1101 -1761) (2 2)) + rect(l6 (724 859) (425 950)) + rect(l6 (-1800 -950) (425 950)) + ) + net(5 + rect(l3 (-100 4500) (2600 3500)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(IN)) + pin(2 name(VDD)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + device(D$PMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 5800) + param(L 0.25) + param(W 3) + param(AS 0.975) + param(AD 0.975) + param(PS 5.8) + param(PD 5.8) + terminal(S 2) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 2135) + param(L 0.25) + param(W 1.9) + param(AS 0.6175) + param(AD 0.6175) + param(PS 4.15) + param(PD 4.15) + terminal(S 4) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((600 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 name(VDD) + rect(l3 (1100 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-22341 859) (2 2)) + rect(l11 (-1751 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23625 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (4550 -1500) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-19575 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(7 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(8 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(9 name(VSS) + rect(l8 (1710 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-22341 -391) (2 2)) + rect(l11 (-1301 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-24300 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (4550 -950) (425 950)) + rect(l6 (-1800 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-19575 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + net(10 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(5 name(FB)) + pin(6 name(VDD)) + pin(7 name(OUT)) + pin(8 name(ENABLE)) + pin(9 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 6) + pin(1 1) + pin(2 9) + pin(3 6) + pin(4 5) + pin(5 8) + pin(6 9) + ) + circuit(2 INVX1 location(4200 0) + pin(0 6) + pin(1 2) + pin(2 9) + pin(3 6) + pin(4 1) + pin(5 9) + ) + circuit(3 INVX1 location(6000 0) + pin(0 6) + pin(1 10) + pin(2 9) + pin(3 6) + pin(4 2) + pin(5 9) + ) + circuit(4 INVX1 location(16800 0) + pin(0 6) + pin(1 3) + pin(2 9) + pin(3 6) + pin(4 11) + pin(5 9) + ) + circuit(5 INVX1 location(18600 0) + pin(0 6) + pin(1 4) + pin(2 9) + pin(3 6) + pin(4 3) + pin(5 9) + ) + circuit(6 INVX1 location(20400 0) + pin(0 6) + pin(1 5) + pin(2 9) + pin(3 6) + pin(4 4) + pin(5 9) + ) + circuit(7 INVX2 location(22200 0) + pin(0 5) + pin(1 6) + pin(2 7) + pin(3 9) + pin(4 6) + pin(5 9) + ) + circuit(13 INVX1 location(7800 0) + pin(0 6) + pin(1 12) + pin(2 9) + pin(3 6) + pin(4 10) + pin(5 9) + ) + circuit(14 INVX1 location(9600 0) + pin(0 6) + pin(1 13) + pin(2 9) + pin(3 6) + pin(4 12) + pin(5 9) + ) + circuit(15 INVX1 location(11400 0) + pin(0 6) + pin(1 14) + pin(2 9) + pin(3 6) + pin(4 13) + pin(5 9) + ) + circuit(16 INVX1 location(13200 0) + pin(0 6) + pin(1 15) + pin(2 9) + pin(3 6) + pin(4 14) + pin(5 9) + ) + circuit(17 INVX1 location(15000 0) + pin(0 6) + pin(1 11) + pin(2 9) + pin(3 6) + pin(4 15) + pin(5 9) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 3) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 1.9) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX2 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX2 INVX2 match + xref( + net(5 4 match) + net(1 5 match) + net(3 2 match) + net(6 6 match) + net(2 1 match) + net(4 3 match) + pin(4 3 match) + pin(0 4 match) + pin(2 1 match) + pin(5 5 match) + pin(1 0 match) + pin(3 2 match) + device(3 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(4 15 match) + net(2 7 match) + net(10 8 match) + net(12 9 match) + net(13 10 match) + net(14 11 match) + net(15 12 match) + net(11 13 match) + net(3 14 match) + net(8 4 match) + net(5 3 match) + net(7 5 match) + net(6 2 match) + net(9 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(2 2 match) + circuit(3 3 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) + circuit(4 9 match) + circuit(5 10 match) + circuit(6 11 match) + circuit(7 12 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/python/dbLayoutToNetlist.py b/testdata/python/dbLayoutToNetlist.py index 11e395309..f5faace5c 100644 --- a/testdata/python/dbLayoutToNetlist.py +++ b/testdata/python/dbLayoutToNetlist.py @@ -191,8 +191,8 @@ circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5); end; circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -272,8 +272,8 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -387,14 +387,14 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (); subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD); - subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD); - subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD); + subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21,$7=VDD); + subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5,$7=VDD); subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD); subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD); end; -circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1); - subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK); - subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK); +circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2,$7=$I1); + subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5,BULK=BULK); + subcircuit INV2 $2 ($1=$I1,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5,BULK=BULK); end; circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK); device PMOS $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); @@ -416,14 +416,14 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS); subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD); - subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD); - subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD); + subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21,$7=VDD); + subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5,$7=VDD); subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD); subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD); end; -circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1); - subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK); - subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK); +circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2,$7=$I1); + subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5,BULK=BULK); + subcircuit INV2 $2 ($1=$I1,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5,BULK=BULK); end; circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK); device PMOS $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); diff --git a/testdata/ruby/dbLayoutToNetlist.rb b/testdata/ruby/dbLayoutToNetlist.rb index 727ab064a..aed45f75b 100644 --- a/testdata/ruby/dbLayoutToNetlist.rb +++ b/testdata/ruby/dbLayoutToNetlist.rb @@ -227,8 +227,8 @@ circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5); end; circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -309,8 +309,8 @@ END assert_equal(l2n.netlist.to_s, <