From afb5cea57644e9b0b5401b1ef30933dbb5abdfa9 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 24 Jul 2019 00:16:47 +0200 Subject: [PATCH] Added "device_scaling" to LVS Plus: added some missing files Implementation details: * scaling factor was introduced in DeviceExtractor::extract * for easy implementation this is available in "sdbu" * "sdbu" is made available in GSI * to test this, the db::compare_netlist had to be enhanced to exactly check device parameters * enhancement of LVS script framework and doc updates --- src/db/db/dbDeviceClass.cc | 35 + src/db/db/dbDeviceClass.h | 16 + src/db/db/dbLayoutToNetlist.cc | 18 +- src/db/db/dbLayoutToNetlist.h | 13 + src/db/db/dbNetlistDeviceExtractor.cc | 14 +- src/db/db/dbNetlistDeviceExtractor.h | 17 +- src/db/db/dbNetlistDeviceExtractorClasses.cc | 36 +- src/db/db/dbTestSupport.cc | 30 +- src/db/db/dbTestSupport.h | 4 +- src/db/db/gsiDeclDbLayoutToNetlist.cc | 9 + src/db/db/gsiDeclDbNetlist.cc | 9 + src/db/db/gsiDeclDbNetlistDeviceExtractor.cc | 5 + src/db/unit_tests/dbNetlistExtractorTests.cc | 154 ++- src/drc/drc/built-in-macros/_drc_engine.rb | 8 +- src/drc/drc/built-in-macros/_drc_netter.rb | 15 + src/lay/lay/doc/about/drc_ref_global.xml | 9 + src/lay/lay/doc/about/drc_ref_netter.xml | 11 + src/lvs/unit_tests/lvsSimpleTests.cc | 5 + testdata/drc/drcSimpleTests_11.drc | 7 +- testdata/lvs/ringo_scaled.cir | 27 + testdata/lvs/ringo_simple_device_scaling.cir | 83 ++ testdata/lvs/ringo_simple_device_scaling.lvs | 76 ++ .../lvs/ringo_simple_device_scaling.lvsdb | 971 ++++++++++++++ ...ringo_simple_simplification_with_align.cir | 102 ++ ...ringo_simple_simplification_with_align.lvs | 76 ++ ...ngo_simple_simplification_with_align.lvsdb | 1142 +++++++++++++++++ testdata/lvs/vexriscv_align.lvs | 111 ++ 27 files changed, 2944 insertions(+), 59 deletions(-) create mode 100644 testdata/lvs/ringo_scaled.cir create mode 100644 testdata/lvs/ringo_simple_device_scaling.cir create mode 100644 testdata/lvs/ringo_simple_device_scaling.lvs create mode 100644 testdata/lvs/ringo_simple_device_scaling.lvsdb create mode 100644 testdata/lvs/ringo_simple_simplification_with_align.cir create mode 100644 testdata/lvs/ringo_simple_simplification_with_align.lvs create mode 100644 testdata/lvs/ringo_simple_simplification_with_align.lvsdb create mode 100644 testdata/lvs/vexriscv_align.lvs diff --git a/src/db/db/dbDeviceClass.cc b/src/db/db/dbDeviceClass.cc index 322885071..7ff6619f3 100644 --- a/src/db/db/dbDeviceClass.cc +++ b/src/db/db/dbDeviceClass.cc @@ -97,6 +97,41 @@ EqualDeviceParameters &EqualDeviceParameters::operator+= (const EqualDeviceParam return *this; } +// -------------------------------------------------------------------------------- +// AllDeviceParametersAreEqual class implementation + +AllDeviceParametersAreEqual::AllDeviceParametersAreEqual (double relative) + : m_relative (relative) +{ + // .. nothing yet .. +} + +bool AllDeviceParametersAreEqual::less (const db::Device &a, const db::Device &b) const +{ + const std::vector ¶meters = a.device_class ()->parameter_definitions (); + for (std::vector::const_iterator c = parameters.begin (); c != parameters.end (); ++c) { + int cmp = compare_parameters (a.parameter_value (c->id ()), b.parameter_value (c->id ()), 0.0, m_relative); + if (cmp != 0) { + return cmp < 0; + } + } + + return false; +} + +bool AllDeviceParametersAreEqual::equal (const db::Device &a, const db::Device &b) const +{ + const std::vector ¶meters = a.device_class ()->parameter_definitions (); + for (std::vector::const_iterator c = parameters.begin (); c != parameters.end (); ++c) { + int cmp = compare_parameters (a.parameter_value (c->id ()), b.parameter_value (c->id ()), 0.0, m_relative); + if (cmp != 0) { + return false; + } + } + + return true; +} + // -------------------------------------------------------------------------------- // DeviceClass class implementation diff --git a/src/db/db/dbDeviceClass.h b/src/db/db/dbDeviceClass.h index bb433ea92..62530e712 100644 --- a/src/db/db/dbDeviceClass.h +++ b/src/db/db/dbDeviceClass.h @@ -286,6 +286,22 @@ private: std::vector > > m_compare_set; }; +/** + * @brief A parameter compare delegate that compares all parameters in a relative fashion + */ +class DB_PUBLIC AllDeviceParametersAreEqual + : public DeviceParameterCompareDelegate +{ +public: + AllDeviceParametersAreEqual (double relative); + + virtual bool less (const db::Device &a, const db::Device &b) const; + virtual bool equal (const db::Device &a, const db::Device &b) const; + +private: + double m_relative; +}; + /** * @brief A device class * diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 4e339c96e..7ff0666c0 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -58,7 +58,7 @@ LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter) } LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index) - : mp_dss (dss), m_layout_index (layout_index), m_netlist_extracted (false), m_is_flat (false) + : mp_dss (dss), m_layout_index (layout_index), m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0) { if (dss->is_valid_layout_index (m_layout_index)) { m_iter = db::RecursiveShapeIterator (dss->layout (m_layout_index), dss->initial_cell (m_layout_index), std::set ()); @@ -66,7 +66,7 @@ LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_i } LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu) - : m_iter (), m_netlist_extracted (false), m_is_flat (true) + : m_iter (), m_netlist_extracted (false), m_is_flat (true), m_device_scaling (1.0) { mp_internal_dss.reset (new db::DeepShapeStore (topcell_name, dbu)); mp_dss.reset (mp_internal_dss.get ()); @@ -77,7 +77,7 @@ LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu) LayoutToNetlist::LayoutToNetlist () : m_iter (), mp_internal_dss (new db::DeepShapeStore ()), mp_dss (mp_internal_dss.get ()), m_layout_index (0), - m_netlist_extracted (false), m_is_flat (false) + m_netlist_extracted (false), m_is_flat (false), m_device_scaling (1.0) { init (); } @@ -136,6 +136,16 @@ size_t LayoutToNetlist::max_vertex_count () const return dss ().max_vertex_count (); } +void LayoutToNetlist::set_device_scaling (double s) +{ + m_device_scaling = s; +} + +double LayoutToNetlist::device_scaling () const +{ + return m_device_scaling; +} + db::Region *LayoutToNetlist::make_layer (const std::string &n) { db::RecursiveShapeIterator si (m_iter); @@ -195,7 +205,7 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co if (! mp_netlist.get ()) { mp_netlist.reset (new db::Netlist ()); } - extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters); + extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters, m_device_scaling); } void LayoutToNetlist::connect (const db::Region &l) diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index cb5485a8b..79d97e71f 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -220,6 +220,18 @@ public: */ size_t max_vertex_count () const; + /** + * @brief Sets the device scaling factor + * This factor will scale the physical properties of the extracted devices + * accordingly. The scale factor applies an isotropic shrink (<1) or expansion (>1). + */ + void set_device_scaling (double s); + + /** + * @brief Gets the device scaling factor + */ + double device_scaling () const; + /** * @brief Register a layer under the given name * This is a formal name for the layer. Using a name or layer properties @@ -711,6 +723,7 @@ private: std::map m_name_of_layer; bool m_netlist_extracted; bool m_is_flat; + double m_device_scaling; db::DeepLayer m_dummy_layer; struct CellReuseTableKey diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index 77df10bd1..5f1bc66c0 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), mp_circuit (0) + : mp_layout (0), m_cell_index (0), m_device_scaling (1.0), mp_circuit (0) { m_name = name; m_terminal_id_propname_id = 0; @@ -110,6 +110,7 @@ void NetlistDeviceExtractor::initialize (db::Netlist *nl) { m_layer_definitions.clear (); mp_device_class = 0; + m_device_scaling = 1.0; m_terminal_id_propname_id = 0; m_device_id_propname_id = 0; m_device_class_propname_id = 0; @@ -123,7 +124,7 @@ static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &t region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ()))); } -void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters) +void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters, double device_scaling) { initialize (&nl); @@ -183,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); + extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling); } -void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters) +void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling) { initialize (nl); - extract_without_initialize (layout, cell, clusters, layers); + extract_without_initialize (layout, cell, clusters, layers, device_scaling); } namespace { @@ -202,7 +203,7 @@ struct ExtractorCacheValueType { } -void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers) +void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling) { tl_assert (layers.size () == m_layer_definitions.size ()); @@ -212,6 +213,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db: mp_layout = &layout; m_layers = layers; mp_clusters = &clusters; + m_device_scaling = device_scaling; // 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 ()); diff --git a/src/db/db/dbNetlistDeviceExtractor.h b/src/db/db/dbNetlistDeviceExtractor.h index 1cec36080..5143b9c7f 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); + void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0); /** * @brief Extracts the devices from a list of regions @@ -272,7 +272,7 @@ public: * named regions for input. These regions need to be of deep region type and * originate from the same layout than the DeepShapeStore. */ - void extract (DeepShapeStore &dss, unsigned int layout_index, const input_layers &layers, Netlist &netlist, hier_clusters_type &clusters); + void extract (DeepShapeStore &dss, unsigned int layout_index, const input_layers &layers, Netlist &netlist, hier_clusters_type &clusters, double device_scaling = 1.0); /** * @brief Gets the error iterator, begin @@ -416,6 +416,16 @@ public: return mp_layout->dbu (); } + /** + * @brief Gets the scaled database unit + * Use this unit to compute device properties. It is the database unit multiplied with the + * device scaling factor. + */ + double sdbu () const + { + return m_device_scaling * mp_layout->dbu (); + } + /** * @brief Gets the layout the shapes are taken from * NOTE: this method is provided for testing purposes mainly. @@ -523,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; + double m_device_scaling; db::Circuit *mp_circuit; db::DeviceClass *mp_device_class; std::string m_name; @@ -542,7 +553,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); + void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling); 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 75dc62542..394c74bad 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -112,8 +112,8 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vectorset_trans (db::DCplxTrans ((p->box ().center () - db::Point ()) * dbu ())); - device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, dbu () * edges.length () * 0.5); - device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, dbu () * (p->perimeter () - edges.length ()) * 0.5); + device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, sdbu () * edges.length () * 0.5); + device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, sdbu () * (p->perimeter () - edges.length ()) * 0.5); int diff_index = 0; for (db::Region::const_iterator d = rdiff2gate.begin (); !d.at_end () && diff_index < 2; ++d, ++diff_index) { @@ -123,8 +123,8 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector 0); - device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, dbu () * dbu () * d->area () / double (n)); - device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_PS : db::DeviceClassMOS3Transistor::param_id_PD, dbu () * d->perimeter () / double (n)); + device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, sdbu () * sdbu () * d->area () / double (n)); + device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_PS : db::DeviceClassMOS3Transistor::param_id_PD, sdbu () * d->perimeter () / double (n)); unsigned int sd_index = diff_index == 0 ? source_terminal_geometry_index : drain_terminal_geometry_index; define_terminal (device, diff_index == 0 ? db::DeviceClassMOS3Transistor::terminal_id_S : db::DeviceClassMOS3Transistor::terminal_id_D, sd_index, *d); @@ -262,10 +262,10 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vectorset_parameter_value (db::DeviceClassResistor::param_id_R, m_sheet_rho * double (length) / double (width)); - device->set_parameter_value (db::DeviceClassResistor::param_id_L, dbu () * length); - device->set_parameter_value (db::DeviceClassResistor::param_id_W, dbu () * width); - device->set_parameter_value (db::DeviceClassResistor::param_id_A, dbu () * dbu () * p->area ()); - device->set_parameter_value (db::DeviceClassResistor::param_id_P, dbu () * p->perimeter ()); + device->set_parameter_value (db::DeviceClassResistor::param_id_L, sdbu () * length); + device->set_parameter_value (db::DeviceClassResistor::param_id_W, sdbu () * width); + device->set_parameter_value (db::DeviceClassResistor::param_id_A, sdbu () * sdbu () * p->area ()); + device->set_parameter_value (db::DeviceClassResistor::param_id_P, sdbu () * p->perimeter ()); int cont_index = 0; for (db::Region::const_iterator d = contacts_per_res.begin (); !d.at_end () && cont_index < 2; ++d, ++cont_index) { @@ -366,11 +366,11 @@ void NetlistDeviceExtractorCapacitor::extract_devices (const std::vectorset_trans (db::DCplxTrans ((p->box ().center () - db::Point ()) * dbu ())); - double area = p->area () * dbu () * dbu (); + double area = p->area () * sdbu () * sdbu (); device->set_parameter_value (db::DeviceClassCapacitor::param_id_C, m_area_cap * area); device->set_parameter_value (db::DeviceClassCapacitor::param_id_A, area); - device->set_parameter_value (db::DeviceClassCapacitor::param_id_P, dbu () * p->perimeter ()); + device->set_parameter_value (db::DeviceClassCapacitor::param_id_P, sdbu () * p->perimeter ()); define_terminal (device, db::DeviceClassCapacitor::terminal_id_A, a_terminal_geometry_index, *p); define_terminal (device, db::DeviceClassCapacitor::terminal_id_B, b_terminal_geometry_index, *p); @@ -498,11 +498,11 @@ void NetlistDeviceExtractorBJT3Transistor::extract_devices (const std::vectorarea (); - double pb = dbu () * p->perimeter (); + double ab = sdbu () * sdbu () * p->area (); + double pb = sdbu () * p->perimeter (); - double ac = dbu () * dbu () * rcollector2base.area (); - double pc = dbu () * rcollector2base.perimeter (); + double ac = sdbu () * sdbu () * rcollector2base.area (); + double pc = sdbu () * rcollector2base.perimeter (); for (db::Region::const_iterator pe = remitter2base.begin_merged (); !pe.at_end (); ++pe) { @@ -512,8 +512,8 @@ void NetlistDeviceExtractorBJT3Transistor::extract_devices (const std::vectorset_parameter_value (db::DeviceClassBJT3Transistor::param_id_NE, 1.0); - device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, dbu () * dbu () * pe->area ()); - device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, dbu () * pe->perimeter ()); + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, sdbu () * sdbu () * pe->area ()); + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, sdbu () * pe->perimeter ()); device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, ab); device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, pb); @@ -629,10 +629,10 @@ void NetlistDeviceExtractorDiode::extract_devices (const std::vector device->set_trans (db::DCplxTrans ((p->box ().center () - db::Point ()) * dbu ())); - double area = p->area () * dbu () * dbu (); + double area = p->area () * sdbu () * sdbu (); device->set_parameter_value (db::DeviceClassDiode::param_id_A, area); - device->set_parameter_value (db::DeviceClassDiode::param_id_P, dbu () * p->perimeter ()); + device->set_parameter_value (db::DeviceClassDiode::param_id_P, sdbu () * p->perimeter ()); define_terminal (device, db::DeviceClassDiode::terminal_id_A, a_terminal_geometry_index, *p); define_terminal (device, db::DeviceClassDiode::terminal_id_C, c_terminal_geometry_index, *p); diff --git a/src/db/db/dbTestSupport.cc b/src/db/db/dbTestSupport.cc index 1d71cacca..86707a236 100644 --- a/src/db/db/dbTestSupport.cc +++ b/src/db/db/dbTestSupport.cc @@ -291,7 +291,7 @@ private: } }; -void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const std::string &au_nl_string) +void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const std::string &au_nl_string, bool exact_parameter_match) { db::Netlist au_nl; for (db::Netlist::const_device_class_iterator d = netlist.begin_device_classes (); d != netlist.end_device_classes (); ++d) { @@ -300,27 +300,29 @@ void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, au_nl.from_string (au_nl_string); - db::NetlistComparer comp (0); - - if (! comp.compare (&netlist, &au_nl)) { - _this->raise ("Compare failed - see log for details.\n\nActual:\n" + netlist.to_string () + "\nGolden:\n" + au_nl_string); - // Compare once again - this time with logger - CompareLogger logger; - db::NetlistComparer comp (&logger); - comp.compare (&netlist, &au_nl); - } + compare_netlist (_this, netlist, au_nl, exact_parameter_match); } -void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const db::Netlist &netlist_au) +void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const db::Netlist &netlist_au, bool exact_parameter_match) { db::NetlistComparer comp (0); - if (! comp.compare (&netlist, &netlist_au)) { - _this->raise ("Compare failed - see log for details.\n\nActual:\n" + netlist.to_string () + "\nGolden:\n" + netlist_au.to_string ()); + db::Netlist netlist_copy (netlist); + + if (exact_parameter_match) { + // install a "all parameters are equal" device parameter comparer so we make sure the devices are compared exactly + for (db::Netlist::device_class_iterator dc = netlist_copy.begin_device_classes (); dc != netlist_copy.end_device_classes (); ++dc) { + db::DeviceClass &cls = *dc; + cls.set_parameter_compare_delegate (new db::AllDeviceParametersAreEqual (0.01)); + } + } + + if (! comp.compare (&netlist_copy, &netlist_au)) { + _this->raise ("Compare failed - see log for details.\n\nActual:\n" + netlist_copy.to_string () + "\nGolden:\n" + netlist_au.to_string ()); // Compare once again - this time with logger CompareLogger logger; db::NetlistComparer comp (&logger); - comp.compare (&netlist, &netlist_au); + comp.compare (&netlist_copy, &netlist_au); } } diff --git a/src/db/db/dbTestSupport.h b/src/db/db/dbTestSupport.h index e079cf05b..6a9278040 100644 --- a/src/db/db/dbTestSupport.h +++ b/src/db/db/dbTestSupport.h @@ -77,12 +77,12 @@ void DB_PUBLIC compare_layouts (tl::TestBase *_this, const db::Layout &layout, c /** * @brief Compares a netlist against a string */ -void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const std::string &au_nl_string); +void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const std::string &au_nl_string, bool exact_parameter_match = false); /** * @brief Compares a netlist against another netlist */ -void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const db::Netlist &netlist_au); +void DB_PUBLIC compare_netlist (tl::TestBase *_this, const db::Netlist &netlist, const db::Netlist &netlist_au, bool exact_parameter_match = false); } diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index e1369989f..02ba6b3c9 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -198,6 +198,15 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", gsi::method ("max_vertex_count", &db::LayoutToNetlist::max_vertex_count, "See \\max_vertex_count= for details about this attribute." ) + + gsi::method ("device_scaling=", &db::LayoutToNetlist::set_device_scaling, gsi::arg ("f"), + "@brief Sets the device scaling factor\n" + "This factor will scale the physical properties of the extracted devices\n" + "accordingly. The scale factor applies an isotropic shrink (<1) or expansion (>1).\n" + ) + + gsi::method ("device_scaling", &db::LayoutToNetlist::device_scaling, + "@brief Gets the device scaling factor\n" + "See \\device_scaling= for details about this attribute." + ) + gsi::method ("name", (const std::string &(db::LayoutToNetlist::*) () const) &db::LayoutToNetlist::name, "@brief Gets the name of the database\n" ) + diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 911262002..9523e7b7f 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -283,6 +283,15 @@ Class decl_dbDevice ("db", "Device", gsi::method ("name", &db::Device::name, "@brief Gets the name of the device.\n" ) + + gsi::method ("trans=", &db::Device::set_trans, gsi::arg ("t"), + "@brief Sets the location of the device.\n" + "The device location is essentially describing the position of the device. The position is typically the center of some " + "recognition shape. In this case the transformation is a plain displacement to the center of this shape." + ) + + gsi::method ("trans", &db::Device::trans, + "@brief Gets the location of the device.\n" + "See \\trans= for details about this method." + ) + gsi::method ("expanded_name", &db::Device::expanded_name, "@brief Gets the expanded name of the device.\n" "The expanded name takes the name of the device. If the name is empty, the numeric ID will be used to build a name. " diff --git a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc index 2afd835f0..0851b5f4f 100644 --- a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc +++ b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc @@ -331,6 +331,11 @@ Class decl_GenericDeviceExtractor (decl_dbNetlistDeviceE gsi::method ("dbu", &GenericDeviceExtractor::dbu, "@brief Gets the database unit\n" ) + + gsi::method ("sdbu", &GenericDeviceExtractor::sdbu, + "@brief Gets the scaled database unit\n" + "Use this unit to compute device properties. It is the database unit multiplied with the\n" + "device scaling factor." + ) + gsi::method ("error", (void (GenericDeviceExtractor::*) (const std::string &)) &GenericDeviceExtractor::error, gsi::arg ("message"), "@brief Issues an error with the given message\n" diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index 7bc49b804..e841c2cb8 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -1066,10 +1066,11 @@ TEST(4_ResAndCapExtraction) " device PMOS $2 (S=VDD,G=IN,D=$3) (L=0.4,W=2.3,AS=1.38,AD=1.38,PS=5.8,PD=5.8);\n" " device NMOS $3 (S=VSS,G=$4,D=OUT) (L=0.4,W=4.6,AS=2.185,AD=2.185,PS=8.8,PD=8.8);\n" " device MIM_CAP $5 (A=$4,B=VSS) (C=2.622e-14,A=26.22,P=29.8);\n" - " device POLY_RES $7 (A=$3,B=$4) (R=750,A=2.4,P=13.6);\n" - " device POLY_RES $9 (A=$4,B=VSS) (R=1825,A=5.84,P=30);\n" + " device POLY_RES $7 (A=$3,B=$4) (R=750,L=12,W=0.8,A=2.4,P=13.6);\n" + " device POLY_RES $9 (A=$4,B=VSS) (R=1825,L=29.2,W=0.8,A=5.84,P=30);\n" " device NMOS $10 (S=VSS,G=IN,D=$3) (L=0.4,W=3.1,AS=1.86,AD=1.86,PS=7.4,PD=7.4);\n" - "end;\n" + "end;\n", + true /*exact parameter compare*/ ); // compare the collected test data @@ -1339,10 +1340,11 @@ TEST(5_ResAndCapWithBulkExtraction) " device NMOS $3 (S=VSS,G=$4,D=OUT,B=BULK) (L=0.4,W=4.6,AS=2.185,AD=2.185,PS=8.8,PD=8.8);\n" " device MIM_CAP_SUBSTRATE $5 (A=$4,B=VSS,W=BULK) (C=1.334e-14,A=13.34,P=15);\n" " device MIM_CAP_NWELL $6 (A=$4,B=VSS,W=NWELL) (C=1.288e-14,A=12.88,P=14.8);\n" - " device POLY_RES_NWELL $7 (A=$3,B=$4,W=NWELL) (R=750,A=2.4,P=13.6);\n" - " device POLY_RES_SUBSTRATE $9 (A=$4,B=VSS,W=BULK) (R=1825,A=5.84,P=30);\n" + " device POLY_RES_NWELL $7 (A=$3,B=$4,W=NWELL) (R=750,L=12,W=0.8,A=2.4,P=13.6);\n" + " device POLY_RES_SUBSTRATE $9 (A=$4,B=VSS,W=BULK) (R=1825,L=29.2,W=0.8,A=5.84,P=30);\n" " device NMOS $10 (S=VSS,G=IN,D=$3,B=BULK) (L=0.4,W=3.1,AS=1.86,AD=1.86,PS=7.4,PD=7.4);\n" - "end;\n" + "end;\n", + true /*exact parameter compare*/ ); // compare the collected test data @@ -1582,9 +1584,10 @@ TEST(6_BJT3TransistorExtraction) " device PMOS $3 (S=VDD,G=IN,D=$3,B=VDD) (L=0.4,W=2.3,AS=1.38,AD=1.38,PS=5.8,PD=5.8);\n" " device NMOS $4 (S=VSS,G=$4,D=OUT,B=BULK) (L=0.4,W=4.6,AS=2.185,AD=2.185,PS=8.8,PD=8.8);\n" " device PNP $6 (C=BULK,B=$3,E=$3) (AE=3.06,PE=7,AB=25.2,PB=21.2,AC=25.2,PC=21.2,NE=1);\n" - " device PNP $7 (C=BULK,B=$3,E=$4) (AE=6.12,PE=14,AB=50.4,PB=42.4,AC=50.4,PC=42.4,NE=2);\n" + " device PNP $7 (C=BULK,B=$3,E=$4) (AE=6.12,PE=14,AB=25.2,PB=21.2,AC=25.2,PC=21.2,NE=2);\n" " device NMOS $9 (S=VSS,G=IN,D=$3,B=BULK) (L=0.4,W=3.1,AS=1.86,AD=1.86,PS=7.4,PD=7.4);\n" - "end;\n" + "end;\n", + true /*exact parameter compare*/ ); // compare the collected test data @@ -1716,7 +1719,140 @@ TEST(7_DiodeExtraction) db::compare_netlist (_this, nl, "circuit TOP (A=A,C=C);\n" " device DIODE $1 (A=A,C=C) (A=9.18,P=21);\n" - "end;\n" + "end;\n", + true /*exact parameter compare*/ + ); + + // 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, "diode_devices_nets.gds"); + + db::compare_layouts (_this, ly, au); +} + +TEST(8_DiodeExtractionScaled) +{ + db::Layout ly; + db::LayerMap lmap; + + unsigned int nwell = define_layer (ly, lmap, 1); + unsigned int active = define_layer (ly, lmap, 2); + unsigned int diff_cont = define_layer (ly, lmap, 4); + unsigned int metal1 = define_layer (ly, lmap, 6); + unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1); + unsigned int pplus = define_layer (ly, lmap, 9); + unsigned int nplus = define_layer (ly, lmap, 10); + + { + 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, "diode_devices_test.oas"); + + 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 rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss); + db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss); + db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss); + db::Region rpplus (db::RecursiveShapeIterator (ly, tc, pplus), dss); + db::Region rnplus (db::RecursiveShapeIterator (ly, tc, nplus), dss); + + // derived regions + + db::Region rn = ractive & rnwell; + db::Region rntie = rnwell & rnplus; + + // return the computed layers into the original layout and write it for debugging purposes + + unsigned int ln = ly.insert_layer (db::LayerProperties (10, 0)); // 10/0 -> N layer + unsigned int lntie = ly.insert_layer (db::LayerProperties (11, 0)); // 11/0 -> N contact + rn.insert_into (&ly, tc.cell_index (), ln); + rntie.insert_into (&ly, tc.cell_index (), lntie); + + // perform the extraction + + db::Netlist nl; + db::hier_clusters cl; + + db::NetlistDeviceExtractorDiode diode_ex ("DIODE"); + + db::NetlistDeviceExtractor::input_layers dl; + + dl["N"] = &rn; + dl["P"] = &rpplus; + dl["tC"] = &rnwell; + diode_ex.extract (dss, 0, dl, nl, cl, 2.0); + + // perform the net extraction + + db::NetlistExtractor net_ex; + + db::Connectivity conn; + // Intra-layer + conn.connect (rnwell); + conn.connect (rntie); + conn.connect (rpplus); + conn.connect (rdiff_cont); + conn.connect (rmetal1); + // Inter-layer + conn.connect (rntie, rnwell); + conn.connect (rntie, rdiff_cont); + conn.connect (rpplus, rdiff_cont); + conn.connect (rdiff_cont, rmetal1); + conn.connect (rmetal1, rmetal1_lbl); // attaches labels + + // extract the nets + + net_ex.extract_nets (dss, 0, conn, nl, cl, "*"); + + // cleanup + completion + nl.combine_devices (); + nl.make_top_level_pins (); + nl.purge (); + + EXPECT_EQ (all_net_names_unique (nl), true); + + // debug layers produced for nets + // 201/0 -> n well + // 204/0 -> Diffusion contacts + // 206/0 -> Metal1 + // 210/0 -> N tiedown + std::map dump_map; + dump_map [layer_of (rntie) ] = ly.insert_layer (db::LayerProperties (210, 0)); + dump_map [layer_of (rnwell) ] = ly.insert_layer (db::LayerProperties (201, 0)); + dump_map [layer_of (rdiff_cont)] = ly.insert_layer (db::LayerProperties (204, 0)); + dump_map [layer_of (rmetal1) ] = ly.insert_layer (db::LayerProperties (206, 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, true /*with device cells*/); + + // compare netlist as string + CHECKPOINT (); + db::compare_netlist (_this, nl, + "circuit TOP (A=A,C=C);\n" + " device DIODE $1 (A=A,C=C) (A=36.72,P=42);\n" + "end;\n", + true /*exact parameter compare*/ ); // compare the collected test data diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 81de7f124..9ffaf7d79 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1159,6 +1159,12 @@ CODE # @synopsis l2n_data # See \Netter#l2n_data for a description of that function. + # %DRC% + # @name device_scaling + # @brief Specifies a dimension scale factor for the geometrical device properties + # @synopsis device_scaling(factor) + # See \Netter#device_scaling for a description of that function. + # %DRC% # @name extract_devices # @brief Extracts devices for a given device extractor and device layer selection @@ -1173,7 +1179,7 @@ CODE # yet, this method will trigger the extraction process. # See \Netter#netlist for a description of this function. - %w(connect connect_global clear_connections connect_implicit antenna_check l2n_data extract_devices netlist).each do |f| + %w(connect connect_global clear_connections connect_implicit antenna_check l2n_data device_scaling extract_devices netlist).each do |f| eval <<"CODE" def #{f}(*args) _netter.#{f}(*args) diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 9d4712261..c16e4c359 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -68,6 +68,7 @@ module DRC @connect_implicit = [] @l2n = nil @lnum = 0 + @device_scaling = 1.0 end # %DRC% @@ -178,6 +179,19 @@ module DRC @engine._cmd(@l2n, :extract_devices, devex, ls) end + + # %DRC% + # @name device_scaling + # @brief Specifies a dimension scale factor for the geometrical device properties + # @synopsis device_scaling(factor) + # Specifying a factor of 2 will make all devices being extracted as if the + # geometries were two times larger. This feature is useful when the drawn layout + # does not correspond to the physical dimensions. + + def device_scaling(factor) + @device_scaling = factor + @l2n && @l2n.device_scaling = factor + end # %DRC% # @name clear_connections @@ -378,6 +392,7 @@ module DRC if !@l2n @layers = {} _make_data + @l2n.device_scaling = @device_scaling end end diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml index 07e837418..0b3b3b2a6 100644 --- a/src/lay/lay/doc/about/drc_ref_global.xml +++ b/src/lay/lay/doc/about/drc_ref_global.xml @@ -185,6 +185,15 @@ implied always. Sometimes cell variants will be created.

Deep mode can be cancelled with tiles or flat.

+

"device_scaling" - Specifies a dimension scale factor for the geometrical device properties

+ +

Usage:

+
    +
  • device_scaling(factor)
  • +
+

+See Netter#device_scaling for a description of that function. +

"diode" - Supplies the diode extractor class

Usage:

diff --git a/src/lay/lay/doc/about/drc_ref_netter.xml b/src/lay/lay/doc/about/drc_ref_netter.xml index 4e56513b9..a131bad28 100644 --- a/src/lay/lay/doc/about/drc_ref_netter.xml +++ b/src/lay/lay/doc/about/drc_ref_netter.xml @@ -198,6 +198,17 @@ component. The implicit connections are applied on the next net extraction and cleared on "clear_connections".

+

"device_scaling" - Specifies a dimension scale factor for the geometrical device properties

+ +

Usage:

+
    +
  • device_scaling(factor)
  • +
+

+Specifying a factor of 2 will make all devices being extracted as if the +geometries were two times larger. This feature is useful when the drawn layout +does not correspond to the physical dimensions. +

"extract_devices" - Extracts devices based on the given extractor class, name and device layer selection

Usage:

diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index f39253968..5c3319b22 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -124,3 +124,8 @@ TEST(10_simplification_with_align) run_test (_this, "ringo_simple_simplification_with_align", "ringo_for_simplification.gds"); } +TEST(11_device_scaling) +{ + run_test (_this, "ringo_simple_device_scaling", "ringo.gds"); +} + diff --git a/testdata/drc/drcSimpleTests_11.drc b/testdata/drc/drcSimpleTests_11.drc index e9a059603..9f23a1b5f 100644 --- a/testdata/drc/drcSimpleTests_11.drc +++ b/testdata/drc/drcSimpleTests_11.drc @@ -91,8 +91,8 @@ class CustomResistorExtraction < RBA::GenericDeviceExtractor # -> W = p-sqrt(p*p-A) # (p=P/4) - p = 0.25 * r.perimeter - a = r.area + p = sdbu * 0.25 * r.perimeter + a = sdbu * sdbu * r.area d = Math.sqrt(p * p - a) l = p + d @@ -102,7 +102,10 @@ class CustomResistorExtraction < RBA::GenericDeviceExtractor device = create_device + device.trans = RBA::DCplxTrans::new(RBA::CplxTrans::new(dbu) * (r.bbox.center - RBA::Point::new)); + device.set_parameter(RBA::DeviceClassResistor::PARAM_R, @sheet_rho * l / w); + device.set_parameter(RBA::DeviceClassResistor::PARAM_A, a); define_terminal(device, RBA::DeviceClassResistor::TERMINAL_A, conductor_geometry_index, terminals[0]); define_terminal(device, RBA::DeviceClassResistor::TERMINAL_B, conductor_geometry_index, terminals[1]); diff --git a/testdata/lvs/ringo_scaled.cir b/testdata/lvs/ringo_scaled.cir new file mode 100644 index 000000000..3cb10be81 --- /dev/null +++ b/testdata/lvs/ringo_scaled.cir @@ -0,0 +1,27 @@ + +.SUBCKT RINGO VSS VDD FB ENABLE OUT +X$1 VDD 1 VSS VDD FB ENABLE VSS ND2X1 +X$2 VDD 2 VSS VDD 1 VSS INVX1 +X$3 VDD 3 VSS VDD 2 VSS INVX1 +X$4 VDD 4 VSS VDD 3 VSS INVX1 +X$5 VDD 5 VSS VDD 4 VSS INVX1 +X$6 VDD 6 VSS VDD 5 VSS INVX1 +X$7 VDD 7 VSS VDD 6 VSS INVX1 +X$8 VDD 8 VSS VDD 7 VSS INVX1 +X$9 VDD 9 VSS VDD 8 VSS INVX1 +X$10 VDD 10 VSS VDD 9 VSS INVX1 +X$11 VDD FB VSS VDD 10 VSS INVX1 +X$12 VDD OUT VSS VDD FB VSS INVX1 +.ENDS RINGO + +.SUBCKT ND2X1 VDD OUT VSS NWELL B A BULK +M$1 OUT A VDD NWELL PMOS L=0.5U W=3U +M$2 VDD B OUT NWELL PMOS L=0.5U W=3U +M$3 VSS A 1 BULK NMOS L=0.5U W=1.9U +M$4 1 B OUT BULK NMOS L=0.5U W=1.9U +.ENDS ND2X1 + +.SUBCKT INVX1 VDD OUT VSS NWELL IN BULK +M$1 VDD IN OUT NWELL PMOS L=0.5U W=3U +M$2 VSS IN OUT BULK NMOS L=0.5U W=1.9U +.ENDS INVX1 diff --git a/testdata/lvs/ringo_simple_device_scaling.cir b/testdata/lvs/ringo_simple_device_scaling.cir new file mode 100644 index 000000000..44196cb11 --- /dev/null +++ b/testdata/lvs/ringo_simple_device_scaling.cir @@ -0,0 +1,83 @@ +* 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 INVX1 +* 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 INVX1 +* 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 INVX1 +* 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 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.5U W=3U AS=2.55P AD=2.55P PS=7.7U PD=7.7U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.5U W=1.9U AS=1.615P AD=1.615P PS=5.5U PD=5.5U +.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.5U W=3U AS=2.55P AD=1.35P PS=7.7U PD=3.9U +* device instance $2 r0 *1 1.55,5.8 PMOS +M$2 1 5 2 4 PMOS L=0.5U W=3U AS=1.35P AD=2.55P PS=3.9U PD=7.7U +* device instance $3 r0 *1 0.85,2.135 NMOS +M$3 3 6 8 7 NMOS L=0.5U W=1.9U AS=1.615P AD=0.855P PS=5.5U PD=2.8U +* device instance $4 r0 *1 1.55,2.135 NMOS +M$4 8 5 2 7 NMOS L=0.5U W=1.9U AS=0.855P AD=1.615P PS=2.8U PD=5.5U +.ENDS ND2X1 diff --git a/testdata/lvs/ringo_simple_device_scaling.lvs b/testdata/lvs/ringo_simple_device_scaling.lvs new file mode 100644 index 000000000..afb3caebb --- /dev/null +++ b/testdata/lvs/ringo_simple_device_scaling.lvs @@ -0,0 +1,76 @@ + +source($lvs_test_source, "RINGO") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("ringo_scaled.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 + +device_scaling(2.0) + +# 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_simple_device_scaling.lvsdb b/testdata/lvs/ringo_simple_device_scaling.lvsdb new file mode 100644 index 000000000..35378e140 --- /dev/null +++ b/testdata/lvs/ringo_simple_device_scaling.lvsdb @@ -0,0 +1,971 @@ +#%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(l1) + layer(l9) + layer(l5) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l1 l9 l5 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l1 l8 l1) + connect(l9 l3 l8 l9) + connect(l5 l8 l5) + 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(l1 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l1 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l1 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l5 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l5 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l5 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (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(l1 (-276 -2151) (425 1500)) + rect(l1 (-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(l1 (-1750 -1450) (425 1500)) + rect(l1 (950 -1500) (425 1500)) + rect(l5 (-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(l5 (-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(l5 (975 1660) (425 950)) + rect(l5 (-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.5) + param(W 3) + param(AS 2.55) + param(AD 1.35) + param(PS 7.7) + param(PD 3.9) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.5) + param(W 3) + param(AS 1.35) + param(AD 2.55) + param(PS 3.9) + param(PD 7.7) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.5) + param(W 1.9) + param(AS 1.615) + param(AD 0.855) + param(PS 5.5) + param(PD 2.8) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.5) + param(W 1.9) + param(AS 0.855) + param(AD 1.615) + param(PS 2.8) + param(PD 5.5) + 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(l1 (-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(l1 (-226 1049) (425 1500)) + rect(l5 (-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(l5 (-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.5) + param(W 3) + param(AS 2.55) + param(AD 2.55) + param(PS 7.7) + param(PD 7.7) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.5) + param(W 1.9) + param(AS 1.615) + param(AD 1.615) + param(PS 5.5) + param(PD 5.5) + 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(l1 (-2550 1800) (425 1500)) + rect(l1 (950 -1500) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-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(l1 (-245 850) (425 1500)) + rect(l5 (-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(l1 (-23025 -2550) (425 1500)) + rect(l1 (-400 -1500) (425 1500)) + rect(l1 (1275 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l9 (-21975 -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(l1 (-625 850) (425 1500)) + rect(l5 (-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(l5 (-23700 460) (425 950)) + rect(l5 (1975 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l10 (-21975 -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 INVX1 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 INVX1 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 INVX1 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.5) + param(W 3) + 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.5) + 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(3 NMOS + name($3) + param(L 0.5) + param(W 1.9) + 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.5) + param(W 1.9) + 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.5) + 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.5) + 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 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(1 1 match) + device(2 2 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(1 1 match) + device(2 2 match) + device(3 3 match) + device(4 4 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(1 1 match) + circuit(10 10 match) + circuit(11 11 match) + circuit(12 12 match) + circuit(2 2 match) + circuit(3 3 match) + circuit(4 4 match) + circuit(5 5 match) + circuit(6 6 match) + circuit(7 7 match) + circuit(8 8 match) + circuit(9 9 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.cir b/testdata/lvs/ringo_simple_simplification_with_align.cir new file mode 100644 index 000000000..c24088217 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification_with_align.cir @@ -0,0 +1,102 @@ +* Extracted by KLayout + +* cell RINGO +* pin FB +* pin VDD +* pin OUT +* pin ENABLE +* pin VSS +.SUBCKT RINGO 5 6 7 8 9 +* net 5 FB +* net 6 VDD +* net 7 OUT +* net 8 ENABLE +* net 9 VSS +* cell instance $1 r0 *1 1.8,0 +X$1 6 1 9 6 5 8 9 ND2X1 +* cell instance $2 r0 *1 4.2,0 +X$2 6 2 9 6 1 9 INVX1 +* cell instance $3 r0 *1 6,0 +X$3 6 10 9 6 2 9 INVX1 +* cell instance $4 r0 *1 16.8,0 +X$4 6 3 9 6 11 9 INVX1 +* cell instance $5 r0 *1 18.6,0 +X$5 6 4 9 6 3 9 INVX1 +* cell instance $6 r0 *1 20.4,0 +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 +.ENDS RINGO + +* cell INVX2 +* pin IN +* pin VDD +* pin OUT +* pin VSS +* pin +* pin SUBSTRATE +.SUBCKT INVX2 1 2 3 4 5 6 +* net 1 IN +* net 2 VDD +* net 3 OUT +* net 4 VSS +* net 6 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 2 1 3 5 PMOS L=0.25U W=3U AS=0.975P AD=0.975P PS=5.8U PD=5.8U +* device instance $3 r0 *1 0.85,2.135 NMOS +M$3 4 1 3 6 NMOS L=0.25U W=1.9U AS=0.6175P AD=0.6175P PS=4.15U PD=4.15U +.ENDS INVX2 + +* 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_simple_simplification_with_align.lvs b/testdata/lvs/ringo_simple_simplification_with_align.lvs new file mode 100644 index 000000000..4591cf3e6 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvs @@ -0,0 +1,76 @@ + +source($lvs_test_source, "RINGO") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("ringo_for_simplification.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 + +align + +netlist.simplify + +compare + diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb new file mode 100644 index 000000000..278aa58a8 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb @@ -0,0 +1,1142 @@ +#%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(l1) + layer(l9) + layer(l5) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l1 l9 l5 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l1 l8 l1) + connect(l9 l3 l8 l9) + connect(l5 l8 l5) + 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(l1 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l1 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l1 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l1 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l5 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l5 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l5 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l5 (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(l1 (-276 -2151) (425 1500)) + rect(l1 (-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(l1 (-1750 -1450) (425 1500)) + rect(l1 (950 -1500) (425 1500)) + rect(l5 (-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(l5 (-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(l5 (975 1660) (425 950)) + rect(l5 (-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(l1 (-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(l1 (-226 1049) (425 1500)) + rect(l5 (-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(l5 (-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(l1 (-1750 -1450) (425 1500)) + rect(l1 (950 -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(l1 (-226 1049) (425 1500)) + rect(l1 (-400 -1500) (425 1500)) + rect(l5 (-450 -4890) (425 950)) + rect(l5 (-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(l5 (-651 859) (425 950)) + rect(l5 (950 -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(l1 (-2550 1800) (425 1500)) + rect(l1 (950 -1500) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-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(l1 (-245 850) (425 1500)) + rect(l5 (-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(l1 (-23625 -2550) (425 1500)) + rect(l1 (-400 -1500) (425 1500)) + rect(l1 (1275 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (3175 -1500) (425 1500)) + rect(l1 (-2225 -1500) (425 1500)) + rect(l1 (3175 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (1375 -1500) (425 1500)) + rect(l1 (3175 -1500) (425 1500)) + rect(l1 (950 -1500) (425 1500)) + rect(l1 (-3600 -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(l1 (-625 850) (425 1500)) + rect(l1 (-400 -1500) (425 1500)) + rect(l5 (-450 -4890) (425 950)) + rect(l5 (-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(l5 (-24300 460) (425 950)) + rect(l5 (1975 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (3175 -950) (425 950)) + rect(l5 (-2225 -950) (425 950)) + rect(l5 (3175 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (1375 -950) (425 950)) + rect(l5 (3175 -950) (425 950)) + rect(l5 (950 -950) (425 950)) + rect(l5 (-3600 -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(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l1 (-1275 1800) (425 1500)) + rect(l5 (-425 -4890) (425 950)) + ) + net(12) + net(13) + net(14) + net(15) + + # 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(1 1 match) + device(2 2 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(1 1 match) + device(3 2 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(1 1 match) + device(2 2 match) + device(3 3 match) + device(4 4 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(1 1 match) + circuit(5 10 match) + circuit(6 11 match) + circuit(7 12 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) + ) + ) +) diff --git a/testdata/lvs/vexriscv_align.lvs b/testdata/lvs/vexriscv_align.lvs new file mode 100644 index 000000000..194924b80 --- /dev/null +++ b/testdata/lvs/vexriscv_align.lvs @@ -0,0 +1,111 @@ + +source($lvs_test_source) + +# will get pretty big: +# report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice(true), "Extracted by KLayout") + +schematic("vexriscv_schematic.cir.gz") + +deep + +# Drawing layers + +nwell = input(1, 0) +pactive = input(4, 0) +nactive = input(3, 0) +ntie = input(5, 0) +ptie = input(6, 0) + +poly = input(7, 0) +cont = input(10, 0) +metal1 = input(11, 0) +via1 = input(14, 0) +metal2 = input(16, 0) +via2 = input(18, 0) +metal3 = input(19, 0) +via3 = input(21, 0) +metal4 = input(22, 0) +via4 = input(25, 0) +metal5 = input(26, 0) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +poly_cont = cont & poly +diff_cont = cont - poly + +pgate = pactive & poly +psd = pactive - pgate + +ngate = nactive & poly +nsd = nactive - ngate + +# 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, diff_cont) +connect(nsd, diff_cont) +connect(poly, poly_cont) +connect(poly_cont, metal1) +connect(diff_cont, metal1) +connect(diff_cont, ntie) +connect(diff_cont, ptie) +connect(nwell, ntie) +connect(metal1, via1) +connect(via1, metal2) +connect(metal2, via2) +connect(via2, metal3) +connect(metal3, via3) +connect(via3, metal4) +connect(metal4, via4) +connect(via4, metal5) + +# Global +connect_global(ptie, "BULK") +connect_global(bulk, "BULK") + +# Implicit +connect_implicit("VDD") +connect_implicit("VSS") + +# Compare section + +same_device_classes("PMOS", "TP") +same_device_classes("NMOS", "TN") + +# Ignore all caps from the schematic +same_device_classes(nil, "CAP") + +# Increase the default complexity from 100 to 200 +# This is required because the clock tree is incorrect and exhibits manifold ambiguities +# (the netlists are just samples, not necessarily functional). +# The algorithm needs enough freedom to follow all these branches and different variants. +max_branch_complexity(200) + +schematic.combine_devices + +netlist.combine_devices + +align + +if ! compare + raise "Netlists don't match" +else + puts "Congratulations! Netlists match." +end +