mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
4561eebdc0
commit
50e0923ff6
|
|
@ -262,6 +262,21 @@ void LayoutToNetlist::ensure_netlist ()
|
|||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::register_device_class (const DeviceClass &device_class)
|
||||
{
|
||||
m_device_classes.push_back (device_class.clone ());
|
||||
}
|
||||
|
||||
const DeviceClass *LayoutToNetlist::device_class_by_name (const std::string &name) const
|
||||
{
|
||||
for (auto d = m_device_classes.begin (); d != m_device_classes.end (); ++d) {
|
||||
if (d->name () == name) {
|
||||
return d.operator-> ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, const std::map<std::string, db::ShapeCollection *> &layers)
|
||||
{
|
||||
if (m_netlist_extracted) {
|
||||
|
|
@ -271,7 +286,34 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
|
|||
ensure_netlist ();
|
||||
|
||||
extractor.clear_log_entries ();
|
||||
extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters, m_device_scaling);
|
||||
|
||||
extractor.initialize (mp_netlist.get ());
|
||||
|
||||
// Try finding the device class in the registered devices in the following order:
|
||||
// 1.) Registered by the extractor during setup() (called by initialize())
|
||||
// 2.) A corresponding device class already present in the netlist (done during initialize())
|
||||
// 3.) Registered in LayoutToNetlist through register_device_class()
|
||||
// 4.) The default class
|
||||
|
||||
if (! extractor.device_class ()) {
|
||||
const db::DeviceClass *dc = device_class_by_name (extractor.name ());
|
||||
if (dc) {
|
||||
extractor.register_device_class (dc->clone ());
|
||||
}
|
||||
}
|
||||
|
||||
if (! extractor.device_class ()) {
|
||||
db::DeviceClass *ddc = extractor.default_device_class ();
|
||||
if (ddc) {
|
||||
extractor.register_device_class (ddc);
|
||||
}
|
||||
}
|
||||
|
||||
if (! extractor.device_class ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("No device class registered for device extractor '%s' - cannot extract devices.")), extractor.name ());
|
||||
}
|
||||
|
||||
extractor.extract (dss (), m_layout_index, layers, m_net_clusters, m_device_scaling);
|
||||
|
||||
// transfer errors to log entries
|
||||
m_log_entries.insert (m_log_entries.end (), extractor.begin_log_entries (), extractor.end_log_entries ());
|
||||
|
|
|
|||
|
|
@ -725,6 +725,25 @@ public:
|
|||
return m_netlist_extracted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers a device class
|
||||
*
|
||||
* This method registers a device class for device extraction.
|
||||
* This way of registering device classes is provided alternatively to
|
||||
* the private device class provided by the device extractors.
|
||||
* This way, device class management is centralized, which is in
|
||||
* favor of device-class specific configurations such as SPICE
|
||||
* profiles.
|
||||
*/
|
||||
void register_device_class (const DeviceClass &device_class);
|
||||
|
||||
/**
|
||||
* @brief Gets a device class by device class name
|
||||
*
|
||||
* If there is no class with that name, a null pointer is returned.
|
||||
*/
|
||||
const DeviceClass *device_class_by_name (const std::string &name) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the internal DeepShapeStore object
|
||||
*
|
||||
|
|
@ -1226,6 +1245,7 @@ private:
|
|||
db::Connectivity m_conn;
|
||||
db::hier_clusters<db::NetShape> m_net_clusters;
|
||||
std::unique_ptr<db::Netlist> mp_netlist;
|
||||
tl::shared_collection<db::DeviceClass> m_device_classes;
|
||||
std::set<db::DeepLayer> m_dlrefs;
|
||||
std::map<std::string, db::DeepLayer> m_named_dls;
|
||||
std::map<unsigned int, std::string> m_name_of_layer;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ void NetlistDeviceExtractor::initialize (db::Netlist *nl)
|
|||
m_netlist.reset (nl);
|
||||
|
||||
setup ();
|
||||
|
||||
if (! mp_device_class.get () && nl) {
|
||||
mp_device_class.reset (nl->device_class_by_name (m_name));
|
||||
}
|
||||
}
|
||||
|
||||
static void insert_into_region (const db::NetShape &s, const db::ICplxTrans &tr, db::Region ®ion)
|
||||
|
|
@ -88,10 +92,8 @@ static void insert_into_region (const db::NetShape &s, const db::ICplxTrans &tr,
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, hier_clusters_type &clusters, double device_scaling)
|
||||
{
|
||||
initialize (&nl);
|
||||
|
||||
std::vector<unsigned int> layers;
|
||||
layers.reserve (m_layer_definitions.size ());
|
||||
|
||||
|
|
@ -153,9 +155,9 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo
|
|||
extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling, dss.breakout_cells (layout_index));
|
||||
}
|
||||
|
||||
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, const std::set<db::cell_index_type> *breakout_cells)
|
||||
// @@@ needed?
|
||||
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, hier_clusters_type &clusters, double device_scaling, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
initialize (nl);
|
||||
extract_without_initialize (layout, cell, clusters, layers, device_scaling, breakout_cells);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,13 @@ public:
|
|||
*/
|
||||
static const tl::Variant &device_class_property_name ();
|
||||
|
||||
/**
|
||||
* @brief Initializes the extractor and connects to a netlist
|
||||
*
|
||||
* This method needs to be called before "extract"
|
||||
*/
|
||||
void initialize (Netlist *netlist);
|
||||
|
||||
/**
|
||||
* @brief Performs the extraction
|
||||
*
|
||||
|
|
@ -140,7 +147,7 @@ public:
|
|||
*
|
||||
* The definition of the input layers is device class specific.
|
||||
*/
|
||||
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Extracts the devices from a list of regions
|
||||
|
|
@ -149,7 +156,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, double device_scaling = 1.0);
|
||||
void extract (DeepShapeStore &dss, unsigned int layout_index, const input_layers &layers, hier_clusters_type &clusters, double device_scaling = 1.0);
|
||||
|
||||
/**
|
||||
* @brief Clears the log entries
|
||||
|
|
@ -283,6 +290,23 @@ public:
|
|||
return mp_device_class.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the default device class
|
||||
*
|
||||
* The default device class is a fallback device class which is used when
|
||||
* 1.) No device class is registered in the constructor
|
||||
* 2.) No corresponding device class is present in the netlist on extraction
|
||||
* 3.) No corresponding device class is registered in the LayoutToNetlist object
|
||||
* The object returned is a new object and must be deleted by the caller.
|
||||
*
|
||||
* This method is mainly used by internal device extractors to link them
|
||||
* to a default class.
|
||||
*/
|
||||
virtual DeviceClass *default_device_class ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Defines a device terminal in the layout (a region)
|
||||
*/
|
||||
|
|
@ -425,13 +449,6 @@ public:
|
|||
*/
|
||||
std::string cell_name () const;
|
||||
|
||||
/**
|
||||
* @brief Initializes the extractor
|
||||
* This method will produce the device classes required for the device extraction.
|
||||
* It is mainly provided for test purposes. Don't call it directly.
|
||||
*/
|
||||
void initialize (db::Netlist *nl);
|
||||
|
||||
private:
|
||||
struct DeviceCellKey
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace db
|
|||
// NetlistDeviceExtractorMOS3Transistor implementation
|
||||
|
||||
NetlistDeviceExtractorMOS3Transistor::NetlistDeviceExtractorMOS3Transistor (const std::string &name, bool strict, db::DeviceClassFactory *factory)
|
||||
: db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory<DeviceClassMOS3Transistor> ()),
|
||||
: db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory<DeviceClassMOS3Transistor> (strict)),
|
||||
m_strict (strict)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -65,10 +65,6 @@ void NetlistDeviceExtractorMOS3Transistor::setup ()
|
|||
define_layer ("tD", 1, "Drain terminal output (default is D)"); // #6
|
||||
|
||||
}
|
||||
|
||||
db::DeviceClass *cls = make_class ();
|
||||
cls->set_strict (m_strict);
|
||||
register_device_class (cls);
|
||||
}
|
||||
|
||||
db::Connectivity NetlistDeviceExtractorMOS3Transistor::get_connectivity (const db::Layout & /*layout*/, const std::vector<unsigned int> &layers) const
|
||||
|
|
@ -323,7 +319,7 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
// NetlistDeviceExtractorMOS4Transistor implementation
|
||||
|
||||
NetlistDeviceExtractorMOS4Transistor::NetlistDeviceExtractorMOS4Transistor (const std::string &name, bool strict, db::DeviceClassFactory *factory)
|
||||
: NetlistDeviceExtractorMOS3Transistor (name, strict, factory ? factory : new db::device_class_factory<db::DeviceClassMOS4Transistor> ())
|
||||
: NetlistDeviceExtractorMOS3Transistor (name, strict, factory ? factory : new db::device_class_factory<db::DeviceClassMOS4Transistor> (strict))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -366,10 +362,6 @@ void NetlistDeviceExtractorMOS4Transistor::setup ()
|
|||
define_layer ("tB", 7, "Well (bulk) terminal output"); // #8 -> W
|
||||
|
||||
}
|
||||
|
||||
db::DeviceClass *cls = make_class ();
|
||||
cls->set_strict (is_strict ());
|
||||
register_device_class (cls);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractorMOS4Transistor::modify_device (const db::Polygon &rgate, const std::vector<db::Region> & /*layer_geometry*/, db::Device *device)
|
||||
|
|
@ -395,8 +387,6 @@ void NetlistDeviceExtractorResistor::setup ()
|
|||
define_layer ("C", "Contacts"); // #1
|
||||
define_layer ("tA", 1, "A terminal output"); // #2 -> C
|
||||
define_layer ("tB", 1, "B terminal output"); // #3 -> C
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
db::Connectivity NetlistDeviceExtractorResistor::get_connectivity (const db::Layout & /*layout*/, const std::vector<unsigned int> &layers) const
|
||||
|
|
@ -508,8 +498,6 @@ void NetlistDeviceExtractorResistorWithBulk::setup ()
|
|||
define_layer ("tB", 1, "B terminal output"); // #3 -> C
|
||||
define_layer ("W", "Well/Bulk"); // #4
|
||||
define_layer ("tW", 4, "W terminal output"); // #5 -> W
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractorResistorWithBulk::modify_device (const db::Polygon &res, const std::vector<db::Region> & /*layer_geometry*/, db::Device *device)
|
||||
|
|
@ -533,8 +521,6 @@ void NetlistDeviceExtractorCapacitor::setup ()
|
|||
define_layer ("P2", "Plate 2"); // #1
|
||||
define_layer ("tA", 0, "A terminal output"); // #2 -> P1
|
||||
define_layer ("tB", 1, "B terminal output"); // #3 -> P2
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
db::Connectivity NetlistDeviceExtractorCapacitor::get_connectivity (const db::Layout & /*layout*/, const std::vector<unsigned int> &layers) const
|
||||
|
|
@ -610,8 +596,6 @@ void NetlistDeviceExtractorCapacitorWithBulk::setup ()
|
|||
define_layer ("tB", 1, "B terminal output"); // #3 -> P2
|
||||
define_layer ("W", "Well/Bulk"); // #4
|
||||
define_layer ("tW", 4, "W terminal output"); // #5 -> W
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractorCapacitorWithBulk::modify_device (const db::Polygon &cap, const std::vector<db::Region> & /*layer_geometry*/, db::Device *device)
|
||||
|
|
@ -639,8 +623,6 @@ void NetlistDeviceExtractorBJT3Transistor::setup ()
|
|||
define_layer ("tC", 0, "Collector terminal output"); // #3 -> C
|
||||
define_layer ("tB", 1, "Base terminal output"); // #4 -> B
|
||||
define_layer ("tE", 2, "Emitter terminal output"); // #5 -> E
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
db::Connectivity NetlistDeviceExtractorBJT3Transistor::get_connectivity (const db::Layout & /*layout*/, const std::vector<unsigned int> &layers) const
|
||||
|
|
@ -774,8 +756,6 @@ void NetlistDeviceExtractorBJT4Transistor::setup ()
|
|||
define_layer ("S", "Substrate (bulk) terminal output"); // #6
|
||||
|
||||
define_layer ("tS", 6, "Substrate (bulk) terminal output"); // #7 -> S
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractorBJT4Transistor::modify_device (const db::Polygon &emitter, const std::vector<db::Region> & /*layer_geometry*/, db::Device *device)
|
||||
|
|
@ -799,8 +779,6 @@ void NetlistDeviceExtractorDiode::setup ()
|
|||
define_layer ("N", "N region"); // #1
|
||||
define_layer ("tA", 0, "A terminal output"); // #2 -> P
|
||||
define_layer ("tC", 1, "C terminal output"); // #3 -> N
|
||||
|
||||
register_device_class (make_class ());
|
||||
}
|
||||
|
||||
db::Connectivity NetlistDeviceExtractorDiode::get_connectivity (const db::Layout & /*layout*/, const std::vector<unsigned int> &layers) const
|
||||
|
|
|
|||
|
|
@ -49,7 +49,20 @@ class DB_PUBLIC_TEMPLATE device_class_factory
|
|||
: public DeviceClassFactory
|
||||
{
|
||||
public:
|
||||
virtual db::DeviceClass *create_class () const { return new C (); }
|
||||
device_class_factory () : m_strict (-1) { }
|
||||
device_class_factory (bool strict) : m_strict (strict ? 1 : 0) { }
|
||||
|
||||
virtual db::DeviceClass *create_class () const
|
||||
{
|
||||
C *c = new C ();
|
||||
if (m_strict >= 0) {
|
||||
c->set_strict (m_strict != 0);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_strict;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -71,9 +84,9 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the device class object
|
||||
* @brief Creates the default device class object
|
||||
*/
|
||||
db::DeviceClass *make_class ()
|
||||
db::DeviceClass *default_device_class ()
|
||||
{
|
||||
return mp_factory->create_class ();
|
||||
}
|
||||
|
|
@ -108,7 +121,7 @@ public:
|
|||
virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector<unsigned int> &layers) const;
|
||||
virtual void extract_devices (const std::vector<db::Region> &layer_geometry);
|
||||
|
||||
bool is_strict () const
|
||||
virtual bool is_strict () const
|
||||
{
|
||||
return m_strict;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -657,6 +657,30 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.27.1.\n"
|
||||
) +
|
||||
gsi::method ("register_device_class", &db::LayoutToNetlist::register_device_class, gsi::arg ("device_class"),
|
||||
"@brief Registers a device class for device extraction\n"
|
||||
"\n"
|
||||
"There are two ways of defining the device class for the devices a specific device extractor "
|
||||
"delivers: locally inside the device extractor, and globally inside the \\LayoutToNetlist object. "
|
||||
"The global approach allows to centrally manage device classes outside the device extractors. "
|
||||
"This enables reusing the same device class for SPICE reading and generation and is the key "
|
||||
"for using SPICE profiles in LVS decks for example.\n"
|
||||
"\n"
|
||||
"When you use this method, the given device class is registered and associated with a device "
|
||||
"extractor in \\extract_devices by name. In that case, the device extractor should not register "
|
||||
"a local device class inside a reimplementation of \\GenericDeviceExtractor#setup.\n"
|
||||
"\n"
|
||||
"A corresponding method to query device classes is \\device_class_by_name.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.31.0.\n"
|
||||
) +
|
||||
gsi::method ("device_class_by_name", &db::LayoutToNetlist::device_class_by_name, gsi::arg ("name"),
|
||||
"@brief Gets a device class by name\n"
|
||||
"\n"
|
||||
"See \\register_device_class for details about this feature.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.31.0.\n"
|
||||
) +
|
||||
gsi::method ("connect", (void (db::LayoutToNetlist::*) (const db::Region &)) &db::LayoutToNetlist::connect, gsi::arg ("l"),
|
||||
"@brief Defines an intra-layer connection for the given layer.\n"
|
||||
"The layer as a Region object, representing either an original layer created with \\make_layer and its variants or\n"
|
||||
|
|
|
|||
|
|
@ -321,101 +321,106 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
"to the new devices.\n"
|
||||
) +
|
||||
gsi::method ("register_device_class", &GenericDeviceExtractor::register_device_class, gsi::arg ("device_class"),
|
||||
"@brief Registers a device class.\n"
|
||||
"The device class object will become owned by the netlist and must not be deleted by\n"
|
||||
"the caller. The name of the device class will be changed to the name given to\n"
|
||||
"the device extractor.\n"
|
||||
"This method shall be used inside the implementation of \\setup to register\n"
|
||||
"the device classes.\n"
|
||||
"@brief Registers a device class.\n"
|
||||
"The device class object will become owned by the netlist and must not be deleted by\n"
|
||||
"the caller. The name of the device class will be changed to the name given to\n"
|
||||
"the device extractor.\n"
|
||||
"This method shall be used inside the implementation of \\setup to register\n"
|
||||
"the device classes.\n"
|
||||
"\n"
|
||||
"Registering a device class in the Extractor is optional. Alternatively, the device class can also "
|
||||
"be registered inside the \\Netter object. In that case the device class corresponding to the "
|
||||
"extractor's name will be used during \\Netter#extract_devices.\n"
|
||||
) +
|
||||
gsi::method ("define_layer", (const db::NetlistDeviceExtractorLayerDefinition &(GenericDeviceExtractor::*) (const std::string &name, const std::string &)) &GenericDeviceExtractor::define_layer, gsi::arg ("name"), gsi::arg ("description"),
|
||||
"@brief Defines a layer.\n"
|
||||
"@return The layer descriptor object created for this layer (use 'index' to get the layer's index)\n"
|
||||
"Each call will define one more layer for the device extraction.\n"
|
||||
"This method shall be used inside the implementation of \\setup to define\n"
|
||||
"the device layers. The actual geometries are later available to \\extract_devices\n"
|
||||
"in the order the layers are defined.\n"
|
||||
"@brief Defines a layer.\n"
|
||||
"@return The layer descriptor object created for this layer (use 'index' to get the layer's index)\n"
|
||||
"Each call will define one more layer for the device extraction.\n"
|
||||
"This method shall be used inside the implementation of \\setup to define\n"
|
||||
"the device layers. The actual geometries are later available to \\extract_devices\n"
|
||||
"in the order the layers are defined.\n"
|
||||
) +
|
||||
gsi::method ("define_opt_layer", (const db::NetlistDeviceExtractorLayerDefinition &(GenericDeviceExtractor::*) (const std::string &name, size_t fallback, const std::string &)) &GenericDeviceExtractor::define_layer, gsi::arg ("name"), gsi::arg ("fallback"), gsi::arg ("description"),
|
||||
"@brief Defines a layer with a fallback layer.\n"
|
||||
"@return The layer descriptor object created for this layer (use 'index' to get the layer's index)\n"
|
||||
"As \\define_layer, this method allows specification of device extraction layer. In addition to \\define_layout, it features "
|
||||
"a fallback layer. If in the device extraction statement, the primary layer is not given, "
|
||||
"the fallback layer will be used. Hence, this layer is optional. The fallback layer is given by its "
|
||||
"index and must be defined before the layer using the fallback layer is defined. "
|
||||
"For the index, 0 is the first layer defined, 1 the second and so forth."
|
||||
"@brief Defines a layer with a fallback layer.\n"
|
||||
"@return The layer descriptor object created for this layer (use 'index' to get the layer's index)\n"
|
||||
"As \\define_layer, this method allows specification of device extraction layer. In addition to \\define_layer, it features "
|
||||
"a fallback layer. If in the device extraction statement, the primary layer is not given, "
|
||||
"the fallback layer will be used. Hence, this layer is optional. The fallback layer is given by its "
|
||||
"index and must be defined before the layer using the fallback layer is defined. "
|
||||
"For the index, 0 is the first layer defined, 1 the second and so forth."
|
||||
) +
|
||||
gsi::method ("create_device", &GenericDeviceExtractor::create_device,
|
||||
"@brief Creates a device.\n"
|
||||
"The device object returned can be configured by the caller, e.g. set parameters.\n"
|
||||
"It will be owned by the netlist and must not be deleted by the caller.\n"
|
||||
"@brief Creates a device.\n"
|
||||
"The device object returned can be configured by the caller, e.g. set parameters.\n"
|
||||
"It will be owned by the netlist and must not be deleted by the caller.\n"
|
||||
"The device created will have the device class specified by \\register_device_class.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (GenericDeviceExtractor::*) (db::Device *, size_t, size_t, const db::Polygon &)) &GenericDeviceExtractor::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the polygon. Note that the polygon is\n"
|
||||
"specified in database units.\n"
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the polygon. Note that the polygon is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (GenericDeviceExtractor::*) (db::Device *, size_t, size_t, const db::Box &)) &GenericDeviceExtractor::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the box. Note that the box is\n"
|
||||
"specified in database units.\n"
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the box. Note that the box is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (GenericDeviceExtractor::*) (db::Device *, size_t, size_t, const db::Point &)) &GenericDeviceExtractor::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("point"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a point-like terminal. Note that the point is\n"
|
||||
"specified in database units.\n"
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a point-like terminal. Note that the point is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method_ext ("define_terminal", &define_terminal_by_names<db::Polygon>,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_name"), gsi::arg ("layer_name"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::method_ext ("define_terminal", &define_terminal_by_names<db::Box>,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_name"), gsi::arg ("layer_name"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::method_ext ("define_terminal", &define_terminal_by_names<db::Point>,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_name"), gsi::arg ("layer_name"), gsi::arg ("point"),
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
"@brief Defines a device terminal using names for terminal and layer.\n"
|
||||
"\n"
|
||||
"This convenience version of the ID-based \\define_terminal methods allows using names for terminal and layer.\n"
|
||||
"It has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::method ("dbu", &GenericDeviceExtractor::dbu,
|
||||
"@brief Gets the database unit\n"
|
||||
"@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."
|
||||
"@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"
|
||||
"@brief Issues an error with the given message\n"
|
||||
) +
|
||||
gsi::method ("error", (void (GenericDeviceExtractor::*) (const std::string &, const db::DPolygon &)) &GenericDeviceExtractor::error,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and micrometer-units polygon geometry\n"
|
||||
"@brief Issues an error with the given message and micrometer-units polygon geometry\n"
|
||||
) +
|
||||
gsi::method_ext ("error", &error1,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
|
|
|
|||
|
|
@ -149,7 +149,8 @@ TEST(3_ClassFactoryTest)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// the generated objects are of MyDeviceClassType
|
||||
EXPECT_EQ (dynamic_cast<const MyDeviceClass *> (ex.device_class ()) != 0, true);
|
||||
|
|
@ -199,7 +200,8 @@ TEST(10_MOS3DeviceExtractorTest)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -254,7 +256,8 @@ TEST(11_MOS3DeviceExtractorTestNotRectangularGate)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -309,7 +312,8 @@ TEST(12_MOS3DeviceExtractorTestCircular)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -368,7 +372,8 @@ TEST(20_MOS4DeviceExtractorTest)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -428,7 +433,8 @@ TEST(21_MOS4DeviceExtractorTestNotRectangularGate)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -488,7 +494,8 @@ TEST(22_MOS4DeviceExtractorTestCircular)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -546,7 +553,8 @@ TEST(30_DMOS3DeviceExtractorTest)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -603,7 +611,8 @@ TEST(31_DMOS3DeviceExtractorTestNotRectangularGate)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -660,7 +669,8 @@ TEST(32_DMOS3DeviceExtractorTestCircular)
|
|||
dl["tS"] = &o1;
|
||||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -721,7 +731,8 @@ TEST(40_DMOS4DeviceExtractorTest)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -783,7 +794,8 @@ TEST(41_DMOS4DeviceExtractorTestNotRectangularGate)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -845,7 +857,8 @@ TEST(42_DMOS4DeviceExtractorTestCircular)
|
|||
dl["tD"] = &o2;
|
||||
dl["tG"] = &o3;
|
||||
dl["tB"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -903,7 +916,8 @@ TEST(50_BJT3DeviceExtractorTest)
|
|||
dl["tE"] = &o1;
|
||||
dl["tB"] = &o2;
|
||||
dl["tC"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -960,7 +974,8 @@ TEST(51_BJT3DeviceExtractorTest)
|
|||
dl["tE"] = &o1;
|
||||
dl["tB"] = &o2;
|
||||
dl["tC"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -1017,7 +1032,8 @@ TEST(52_BJT3DeviceExtractorTestLateral)
|
|||
dl["tE"] = &o1;
|
||||
dl["tB"] = &o2;
|
||||
dl["tC"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -1074,7 +1090,8 @@ TEST(53_BJT3DeviceExtractorTestMultEmitter)
|
|||
dl["tE"] = &o1;
|
||||
dl["tB"] = &o2;
|
||||
dl["tC"] = &o3;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
@ -1136,7 +1153,8 @@ TEST(54_BJT4DeviceExtractorTest)
|
|||
dl["tB"] = &o2;
|
||||
dl["tC"] = &o3;
|
||||
dl["tS"] = &o4;
|
||||
ex.extract (dss, 0, dl, nl, cl);
|
||||
ex.initialize (&nl);
|
||||
ex.extract (dss, 0, dl, cl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
|
|
|
|||
|
|
@ -259,12 +259,14 @@ TEST(1_DeviceAndNetExtraction)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -495,12 +497,14 @@ TEST(1a_DeviceAndNetExtractionWithTextsAsLabels)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -693,12 +697,14 @@ TEST(2_DeviceAndNetExtractionFlat)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -925,12 +931,14 @@ TEST(3_DeviceAndNetExtractionWithImplicitConnections)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -1196,7 +1204,8 @@ TEST(4_ResAndCapExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rpsd;
|
||||
dl["tD"] = &rpsd;
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["SD"] = &rnsd;
|
||||
|
|
@ -1205,7 +1214,8 @@ TEST(4_ResAndCapExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rnsd;
|
||||
dl["tD"] = &rnsd;
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["R"] = &rpoly_res;
|
||||
|
|
@ -1213,7 +1223,8 @@ TEST(4_ResAndCapExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rpoly;
|
||||
dl["tB"] = &rpoly;
|
||||
res_ex.extract (dss, 0, dl, nl, cl);
|
||||
res_ex.initialize (&nl);
|
||||
res_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["P1"] = &rcap1;
|
||||
|
|
@ -1221,7 +1232,8 @@ TEST(4_ResAndCapExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rmetal1;
|
||||
dl["tB"] = &rmetal2;
|
||||
cap_ex.extract (dss, 0, dl, nl, cl);
|
||||
cap_ex.initialize (&nl);
|
||||
cap_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
|
||||
// perform the net extraction
|
||||
|
|
@ -1446,7 +1458,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rpsd;
|
||||
dl["tD"] = &rpsd;
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["SD"] = &rnsd;
|
||||
|
|
@ -1456,7 +1469,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rnsd;
|
||||
dl["tD"] = &rnsd;
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["R"] = &rpoly_res_sub;
|
||||
|
|
@ -1465,7 +1479,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rpoly;
|
||||
dl["tB"] = &rpoly;
|
||||
res_substrate_ex.extract (dss, 0, dl, nl, cl);
|
||||
res_substrate_ex.initialize (&nl);
|
||||
res_substrate_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["R"] = &rpoly_res_nw;
|
||||
|
|
@ -1474,7 +1489,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rpoly;
|
||||
dl["tB"] = &rpoly;
|
||||
res_nwell_ex.extract (dss, 0, dl, nl, cl);
|
||||
res_nwell_ex.initialize (&nl);
|
||||
res_nwell_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["P1"] = &rcap1_sub;
|
||||
|
|
@ -1483,7 +1499,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rmetal1;
|
||||
dl["tB"] = &rmetal2;
|
||||
cap_substrate_ex.extract (dss, 0, dl, nl, cl);
|
||||
cap_substrate_ex.initialize (&nl);
|
||||
cap_substrate_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["P1"] = &rcap1_nw;
|
||||
|
|
@ -1492,7 +1509,8 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
// terminal patches
|
||||
dl["tA"] = &rmetal1;
|
||||
dl["tB"] = &rmetal2;
|
||||
cap_nwell_ex.extract (dss, 0, dl, nl, cl);
|
||||
cap_nwell_ex.initialize (&nl);
|
||||
cap_nwell_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
|
||||
// perform the net extraction
|
||||
|
|
@ -1710,7 +1728,8 @@ TEST(6_BJT3TransistorExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rpsd;
|
||||
dl["tD"] = &rpsd;
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["SD"] = &rnsd;
|
||||
|
|
@ -1720,7 +1739,8 @@ TEST(6_BJT3TransistorExtraction)
|
|||
dl["tG"] = &rpoly;
|
||||
dl["tS"] = &rnsd;
|
||||
dl["tD"] = &rnsd;
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["E"] = &remitter;
|
||||
|
|
@ -1728,8 +1748,8 @@ TEST(6_BJT3TransistorExtraction)
|
|||
dl["C"] = &rbulk;
|
||||
// terminal patches
|
||||
dl["tB"] = &rnwell;
|
||||
bjt_ex.extract (dss, 0, dl, nl, cl);
|
||||
|
||||
bjt_ex.initialize (&nl);
|
||||
bjt_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -1911,7 +1931,8 @@ TEST(7_DiodeExtraction)
|
|||
dl["N"] = &rn;
|
||||
dl["P"] = &rpplus;
|
||||
dl["tC"] = &rnwell;
|
||||
diode_ex.extract (dss, 0, dl, nl, cl);
|
||||
diode_ex.initialize (&nl);
|
||||
diode_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
|
||||
// perform the net extraction
|
||||
|
|
@ -2045,7 +2066,8 @@ TEST(8_DiodeExtractionScaled)
|
|||
dl["N"] = &rn;
|
||||
dl["P"] = &rpplus;
|
||||
dl["tC"] = &rnwell;
|
||||
diode_ex.extract (dss, 0, dl, nl, cl, 2.0);
|
||||
diode_ex.initialize (&nl);
|
||||
diode_ex.extract (dss, 0, dl, cl, 2.0);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -2208,13 +2230,15 @@ TEST(9_StrictDeviceExtraction)
|
|||
dl["D"] = &rpd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["S"] = &rns;
|
||||
dl["D"] = &rnd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -2443,12 +2467,14 @@ TEST(10_DeviceExtractionWithBreakoutCells)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dss.pop_state ();
|
||||
|
||||
|
|
@ -2602,12 +2628,14 @@ TEST(11_DeviceExtractionWithSameClass)
|
|||
db::NetlistDeviceExtractor::input_layers dl;
|
||||
dl["R"] = &rpoly_res;
|
||||
dl["C"] = &rpoly_cap;
|
||||
polyres_ex.extract (dss, 0, dl, nl, cl);
|
||||
polyres_ex.initialize (&nl);
|
||||
polyres_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl.clear ();
|
||||
dl["R"] = &rdiff_res;
|
||||
dl["C"] = &rdiff_cap;
|
||||
diffres_ex.extract (dss, 0, dl, nl, cl);
|
||||
diffres_ex.initialize (&nl);
|
||||
diffres_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -2725,12 +2753,14 @@ TEST(12_FloatingSubcircuitExtraction)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -2878,12 +2908,14 @@ TEST(13_RemoveDummyPins)
|
|||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -3027,13 +3059,15 @@ TEST(14_JoinNets)
|
|||
dl["G"] = &rpgate;
|
||||
dl["W"] = &rnwell;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["W"] = &bulk;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -3315,13 +3349,15 @@ TEST(15_SoftConnections)
|
|||
dl["G"] = &rpgate;
|
||||
dl["W"] = &rnwell;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["W"] = &bulk;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
nmos_ex.initialize (&nl);
|
||||
nmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
@ -3578,7 +3614,8 @@ TEST(100_issue954)
|
|||
dl["G"] = &rpgate;
|
||||
dl["W"] = &bulk;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
pmos_ex.initialize (&nl);
|
||||
pmos_ex.extract (dss, 0, dl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
|
|
|
|||
|
|
@ -2550,6 +2550,18 @@ CODE
|
|||
# The netlist is a RBA::Netlist object. If no netlist is extracted
|
||||
# yet, this method will trigger the extraction process.
|
||||
# See \Netter#netlist for a description of this function.
|
||||
|
||||
# %DRC%
|
||||
# @name register_device_class
|
||||
# Registers a device class for extraction and netlist output.
|
||||
# Registering a device class is optional. However, using registered
|
||||
# device classed simplify SPICE netlist writing, as device classes
|
||||
# can be configured with SPICE profiles to customize SPICE output.
|
||||
# In the LVS context, \register_device_class also controls the way
|
||||
# schematic netlists are read from SPICE.
|
||||
# See \Netter#register_device_class for a description of this function.
|
||||
# Also see \Netter#extract_devices for how to use it with registered
|
||||
# device classes.
|
||||
|
||||
%w(
|
||||
antenna_check
|
||||
|
|
@ -2567,6 +2579,7 @@ CODE
|
|||
top_level
|
||||
ignore_extraction_errors
|
||||
extract_devices
|
||||
register_device_class
|
||||
netlist
|
||||
l2n_data
|
||||
_l2n_object
|
||||
|
|
|
|||
|
|
@ -217,7 +217,6 @@ module DRC
|
|||
# @name extract_devices
|
||||
# @brief Extracts devices based on the given extractor class, name and device layer selection
|
||||
# @synopsis extract_devices(extractor, layer_hash)
|
||||
# @synopsis extract_devices(extractor_class, name, layer_hash)
|
||||
# Runs the device extraction for given device extractor class. In the first
|
||||
# form, the extractor object is given. In the second form, the extractor's
|
||||
# class object and the new extractor's name is given.
|
||||
|
|
@ -1039,6 +1038,23 @@ module DRC
|
|||
|
||||
end
|
||||
|
||||
def _register_device_class(cls)
|
||||
if @devcls_by_name && @devcls_by_name[cls]
|
||||
raise("A device class with name '#{cls.name}' is already registered")
|
||||
end
|
||||
@devcls ||= []
|
||||
@devcls_by_name ||= {}
|
||||
@devcls << cls
|
||||
@devcls_by_name[cls.name] = cls
|
||||
end
|
||||
|
||||
def _devcls_by_name(name)
|
||||
if ! @devcls_by_name || ! @devcls_by_name[name]
|
||||
raise("No device class registered with name #{name}")
|
||||
end
|
||||
@devcls_by_name[name]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cleanup
|
||||
|
|
|
|||
|
|
@ -231,10 +231,20 @@ module LVS
|
|||
# @synopsis flag_missing_ports
|
||||
# See \Netter#flag_missing_ports for a description of that function.
|
||||
|
||||
# %LVS%
|
||||
# @name register_device_class
|
||||
# Registers a device class for extraction and netlist input and output.
|
||||
# Registering a device class is optional. However, using registered
|
||||
# device classed simplify SPICE netlist reading and writing, as device classes
|
||||
# can be configured with SPICE profiles to customize SPICE input and output.
|
||||
# See \Netter#register_device_class for a description of this function.
|
||||
# Also see \Netter#extract_devices for how to use it with registered
|
||||
# device classes.
|
||||
|
||||
%w(schematic compare split_gates join_symmetric_nets tolerance ignore_parameter enable_parameter disable_parameter
|
||||
blank_circuit align same_nets same_nets! same_circuits same_device_classes equivalent_pins
|
||||
min_caps max_res max_depth max_branch_complexity consider_net_names lvs_data no_lvs_hints
|
||||
flag_missing_ports).each do |f|
|
||||
flag_missing_ports register_device_class).each do |f|
|
||||
eval <<"CODE"
|
||||
def #{f}(*args)
|
||||
_netter.#{f}(*args)
|
||||
|
|
|
|||
|
|
@ -171,6 +171,13 @@ TEST(13_simple_ringo_device_subcircuits)
|
|||
run_test (_this, "ringo_device_subcircuits", "ringo.gds", false, true, std::string (), true);
|
||||
}
|
||||
|
||||
TEST(13b_simple_ringo_device_subcircuits_devcls)
|
||||
{
|
||||
run_test (_this, "ringo_device_subcircuits_devcls", "ringo.gds");
|
||||
// change case
|
||||
run_test (_this, "ringo_device_subcircuits_devcls", "ringo.gds", false, true, std::string (), true);
|
||||
}
|
||||
|
||||
TEST(14_simple_ringo_mixed_hierarchy)
|
||||
{
|
||||
run_test (_this, "ringo_mixed_hierarchy", "ringo_mixed_hierarchy.gds");
|
||||
|
|
|
|||
Loading…
Reference in New Issue