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
This commit is contained in:
Matthias Koefferlein 2019-07-24 00:16:47 +02:00
parent 5dabd6093d
commit afb5cea576
27 changed files with 2944 additions and 59 deletions

View File

@ -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<db::DeviceParameterDefinition> &parameters = a.device_class ()->parameter_definitions ();
for (std::vector<db::DeviceParameterDefinition>::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<db::DeviceParameterDefinition> &parameters = a.device_class ()->parameter_definitions ();
for (std::vector<db::DeviceParameterDefinition>::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

View File

@ -286,6 +286,22 @@ private:
std::vector<std::pair<size_t, std::pair<double, double> > > 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
*

View File

@ -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<unsigned int> ());
@ -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)

View File

@ -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<unsigned int, std::string> m_name_of_layer;
bool m_netlist_extracted;
bool m_is_flat;
double m_device_scaling;
db::DeepLayer m_dummy_layer;
struct CellReuseTableKey

View File

@ -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<unsigned int> &layers, db::Netlist *nl, hier_clusters_type &clusters)
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &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<unsigned int> &layers)
void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &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 ());

View File

@ -263,7 +263,7 @@ public:
*
* NOTE: The extractor expects "PolygonRef" type layers.
*/
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters);
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &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<unsigned int> &layers);
void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers, double device_scaling);
void push_new_devices (const Vector &disp_cache);
void push_cached_devices (const tl::vector<Device *> &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp);
};

View File

@ -112,8 +112,8 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
device->set_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<db
size_t n = rgates.selected_interacting (db::Region (*d)).size ();
tl_assert (n > 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::vector<db::Regi
}
device->set_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::vector<db::Reg
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::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::vector<db
// emitter wins over collector for the collector contact
rcollector -= remitter2base;
double ab = dbu () * dbu () * p->area ();
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::vector<db
device->set_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<db::Region>
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);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -198,6 +198,15 @@ Class<db::LayoutToNetlist> 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"
) +

View File

@ -283,6 +283,15 @@ Class<db::Device> 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. "

View File

@ -331,6 +331,11 @@ Class<GenericDeviceExtractor> 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"

View File

@ -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<db::CommonReaderOptions> ().layer_map = lmap;
options.get_options<db::CommonReaderOptions> ().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<db::PolygonRef> 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<unsigned int, unsigned int> 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

View File

@ -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)

View File

@ -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

View File

@ -185,6 +185,15 @@ implied always. Sometimes cell variants will be created.
</p><p>
Deep mode can be cancelled with <a href="#tiles">tiles</a> or <a href="#flat">flat</a>.
</p>
<h2>"device_scaling" - Specifies a dimension scale factor for the geometrical device properties</h2>
<keyword name="device_scaling"/>
<a name="device_scaling"/><p>Usage:</p>
<ul>
<li><tt>device_scaling(factor)</tt></li>
</ul>
<p>
See <a href="/about/drc_ref_netter.xml#device_scaling">Netter#device_scaling</a> for a description of that function.
</p>
<h2>"diode" - Supplies the diode extractor class</h2>
<keyword name="diode"/>
<a name="diode"/><p>Usage:</p>

View File

@ -198,6 +198,17 @@ component.
The implicit connections are applied on the next net extraction and cleared
on "clear_connections".
</p>
<h2>"device_scaling" - Specifies a dimension scale factor for the geometrical device properties</h2>
<keyword name="device_scaling"/>
<a name="device_scaling"/><p>Usage:</p>
<ul>
<li><tt>device_scaling(factor)</tt></li>
</ul>
<p>
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.
</p>
<h2>"extract_devices" - Extracts devices based on the given extractor class, name and device layer selection</h2>
<keyword name="extract_devices"/>
<a name="extract_devices"/><p>Usage:</p>

View File

@ -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");
}

View File

@ -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]);

27
testdata/lvs/ringo_scaled.cir vendored Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
)
)
)

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

111
testdata/lvs/vexriscv_align.lvs vendored Normal file
View File

@ -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