From c62592ede18d0b63151b388c279a184448a016a0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 5 Jul 2021 19:55:55 +0200 Subject: [PATCH] Added test for device class factory. --- src/db/db/dbNetlistDeviceExtractorClasses.cc | 54 +++---- src/db/db/dbNetlistDeviceExtractorClasses.h | 82 +++++++++-- src/db/db/gsiDeclDbNetlist.cc | 2 +- src/db/db/gsiDeclDbNetlistDeviceExtractor.cc | 133 +++++++++++++----- .../dbNetlistDeviceExtractorTests.cc | 62 ++++++++ 5 files changed, 254 insertions(+), 79 deletions(-) diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index 81b0c4d0b..957c9e8bb 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -30,8 +30,8 @@ namespace db // --------------------------------------------------------------------------------- // NetlistDeviceExtractorMOS3Transistor implementation -NetlistDeviceExtractorMOS3Transistor::NetlistDeviceExtractorMOS3Transistor (const std::string &name, bool strict) - : db::NetlistDeviceExtractor (name), +NetlistDeviceExtractorMOS3Transistor::NetlistDeviceExtractorMOS3Transistor (const std::string &name, bool strict, db::DeviceClassFactory *factory) + : db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory ()), m_strict (strict) { // .. nothing yet .. @@ -66,7 +66,7 @@ void NetlistDeviceExtractorMOS3Transistor::setup () } - db::DeviceClass *cls = new db::DeviceClassMOS3Transistor (); + db::DeviceClass *cls = make_class (); cls->set_strict (m_strict); register_device_class (cls); } @@ -322,8 +322,8 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector ()) { // .. nothing yet .. } @@ -367,7 +367,7 @@ void NetlistDeviceExtractorMOS4Transistor::setup () } - db::DeviceClass *cls = new db::DeviceClassMOS4Transistor (); + db::DeviceClass *cls = make_class (); cls->set_strict (is_strict ()); register_device_class (cls); } @@ -383,8 +383,8 @@ void NetlistDeviceExtractorMOS4Transistor::modify_device (const db::Polygon &rga // --------------------------------------------------------------------------------- // NetlistDeviceExtractorResistor implementation -NetlistDeviceExtractorResistor::NetlistDeviceExtractorResistor (const std::string &name, double sheet_rho) - : db::NetlistDeviceExtractor (name), m_sheet_rho (sheet_rho) +NetlistDeviceExtractorResistor::NetlistDeviceExtractorResistor (const std::string &name, double sheet_rho, db::DeviceClassFactory *factory) + : db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory ()), m_sheet_rho (sheet_rho) { // .. nothing yet .. } @@ -396,7 +396,7 @@ void NetlistDeviceExtractorResistor::setup () define_layer ("tA", 1, "A terminal output"); // #2 -> C define_layer ("tB", 1, "B terminal output"); // #3 -> C - register_device_class (new db::DeviceClassResistor ()); + register_device_class (make_class ()); } db::Connectivity NetlistDeviceExtractorResistor::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const @@ -494,8 +494,8 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vector ()) { // .. nothing yet .. } @@ -509,7 +509,7 @@ void NetlistDeviceExtractorResistorWithBulk::setup () define_layer ("W", "Well/Bulk"); // #4 define_layer ("tW", 4, "W terminal output"); // #5 -> W - register_device_class (new db::DeviceClassResistorWithBulk ()); + register_device_class (make_class ()); } void NetlistDeviceExtractorResistorWithBulk::modify_device (const db::Polygon &res, const std::vector & /*layer_geometry*/, db::Device *device) @@ -521,8 +521,8 @@ void NetlistDeviceExtractorResistorWithBulk::modify_device (const db::Polygon &r // --------------------------------------------------------------------------------- // NetlistDeviceExtractorCapacitor implementation -NetlistDeviceExtractorCapacitor::NetlistDeviceExtractorCapacitor (const std::string &name, double area_cap) - : db::NetlistDeviceExtractor (name), m_area_cap (area_cap) +NetlistDeviceExtractorCapacitor::NetlistDeviceExtractorCapacitor (const std::string &name, double area_cap, db::DeviceClassFactory *factory) + : db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory ()), m_area_cap (area_cap) { // .. nothing yet .. } @@ -534,7 +534,7 @@ void NetlistDeviceExtractorCapacitor::setup () define_layer ("tA", 0, "A terminal output"); // #2 -> P1 define_layer ("tB", 1, "B terminal output"); // #3 -> P2 - register_device_class (new db::DeviceClassCapacitor ()); + register_device_class (make_class ()); } db::Connectivity NetlistDeviceExtractorCapacitor::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const @@ -596,8 +596,8 @@ void NetlistDeviceExtractorCapacitor::extract_devices (const std::vector ()) { // .. nothing yet .. } @@ -611,7 +611,7 @@ void NetlistDeviceExtractorCapacitorWithBulk::setup () define_layer ("W", "Well/Bulk"); // #4 define_layer ("tW", 4, "W terminal output"); // #5 -> W - register_device_class (new db::DeviceClassCapacitorWithBulk ()); + register_device_class (make_class ()); } void NetlistDeviceExtractorCapacitorWithBulk::modify_device (const db::Polygon &cap, const std::vector & /*layer_geometry*/, db::Device *device) @@ -623,8 +623,8 @@ void NetlistDeviceExtractorCapacitorWithBulk::modify_device (const db::Polygon & // --------------------------------------------------------------------------------- // NetlistDeviceExtractorBJT3Transistor implementation -NetlistDeviceExtractorBJT3Transistor::NetlistDeviceExtractorBJT3Transistor (const std::string &name) - : db::NetlistDeviceExtractor (name) +NetlistDeviceExtractorBJT3Transistor::NetlistDeviceExtractorBJT3Transistor (const std::string &name, db::DeviceClassFactory *factory) + : db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory ()) { // .. nothing yet .. } @@ -640,7 +640,7 @@ void NetlistDeviceExtractorBJT3Transistor::setup () define_layer ("tB", 1, "Base terminal output"); // #4 -> B define_layer ("tE", 2, "Emitter terminal output"); // #5 -> E - register_device_class (new db::DeviceClassBJT3Transistor ()); + register_device_class (make_class ()); } db::Connectivity NetlistDeviceExtractorBJT3Transistor::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const @@ -750,8 +750,8 @@ void NetlistDeviceExtractorBJT3Transistor::extract_devices (const std::vector ()) { // .. nothing yet .. } @@ -772,7 +772,7 @@ void NetlistDeviceExtractorBJT4Transistor::setup () define_layer ("tS", 6, "Substrate (bulk) terminal output"); // #7 -> S - register_device_class (new db::DeviceClassBJT4Transistor ()); + register_device_class (make_class ()); } void NetlistDeviceExtractorBJT4Transistor::modify_device (const db::Polygon &emitter, const std::vector & /*layer_geometry*/, db::Device *device) @@ -784,8 +784,8 @@ void NetlistDeviceExtractorBJT4Transistor::modify_device (const db::Polygon &emi // --------------------------------------------------------------------------------- // NetlistDeviceExtractorDiode implementation -NetlistDeviceExtractorDiode::NetlistDeviceExtractorDiode (const std::string &name) - : db::NetlistDeviceExtractor (name) +NetlistDeviceExtractorDiode::NetlistDeviceExtractorDiode (const std::string &name, db::DeviceClassFactory *factory) + : db::NetlistDeviceExtractorImplBase (name, factory ? factory : new db::device_class_factory ()) { // .. nothing yet .. } @@ -797,7 +797,7 @@ void NetlistDeviceExtractorDiode::setup () define_layer ("tA", 0, "A terminal output"); // #2 -> P define_layer ("tC", 1, "C terminal output"); // #3 -> N - register_device_class (new db::DeviceClassDiode ()); + register_device_class (make_class ()); } db::Connectivity NetlistDeviceExtractorDiode::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.h b/src/db/db/dbNetlistDeviceExtractorClasses.h index 3a157b7aa..1f1f07429 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.h +++ b/src/db/db/dbNetlistDeviceExtractorClasses.h @@ -24,10 +24,64 @@ #define _HDR_dbNetlistDeviceExtractorClasses #include "dbNetlistDeviceExtractor.h" +#include "gsiObject.h" namespace db { +/** + * @brief A device class factory base class + */ +class DB_PUBLIC DeviceClassFactory + : public gsi::ObjectBase +{ +public: + DeviceClassFactory () { } + ~DeviceClassFactory () { } + virtual db::DeviceClass *create_class () const = 0; +}; + +/** + * @brief A specific factory + */ +template +class DB_PUBLIC device_class_factory + : public DeviceClassFactory +{ +public: + virtual db::DeviceClass *create_class () const { return new C (); } +}; + +/** + * @brief A base class for the specialized device extractors + * + * The main feature of this class is to supply a device class factory + * which actually creates the device class object. + * + * The NetlistDeviceExtractorImplBase object will own the factory object. + */ +class DB_PUBLIC NetlistDeviceExtractorImplBase + : public db::NetlistDeviceExtractor +{ +public: + NetlistDeviceExtractorImplBase (const std::string &name, DeviceClassFactory *factory) + : db::NetlistDeviceExtractor (name), mp_factory (factory) + { + mp_factory->keep (); + } + + /** + * @brief Creates the device class object + */ + db::DeviceClass *make_class () + { + return mp_factory->create_class (); + } + +private: + std::unique_ptr mp_factory; +}; + /** * @brief A device extractor for a three-terminal MOS transistor * @@ -45,10 +99,10 @@ namespace db * the particular source or drain area. */ class DB_PUBLIC NetlistDeviceExtractorMOS3Transistor - : public db::NetlistDeviceExtractor + : public db::NetlistDeviceExtractorImplBase { public: - NetlistDeviceExtractorMOS3Transistor (const std::string &name, bool strict = false); + NetlistDeviceExtractorMOS3Transistor (const std::string &name, bool strict = false, DeviceClassFactory *factory = 0); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; @@ -94,7 +148,7 @@ class DB_PUBLIC NetlistDeviceExtractorMOS4Transistor : public NetlistDeviceExtractorMOS3Transistor { public: - NetlistDeviceExtractorMOS4Transistor (const std::string &name, bool strict = false); + NetlistDeviceExtractorMOS4Transistor (const std::string &name, bool strict = false, DeviceClassFactory *factory = 0); virtual void setup (); @@ -121,10 +175,10 @@ private: * terminals are produced. */ class DB_PUBLIC NetlistDeviceExtractorResistor - : public db::NetlistDeviceExtractor + : public db::NetlistDeviceExtractorImplBase { public: - NetlistDeviceExtractorResistor (const std::string &name, double sheet_rho); + NetlistDeviceExtractorResistor (const std::string &name, double sheet_rho, DeviceClassFactory *factory = 0); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; @@ -162,7 +216,7 @@ class DB_PUBLIC NetlistDeviceExtractorResistorWithBulk : public db::NetlistDeviceExtractorResistor { public: - NetlistDeviceExtractorResistorWithBulk (const std::string &name, double sheet_rho); + NetlistDeviceExtractorResistorWithBulk (const std::string &name, double sheet_rho, DeviceClassFactory *factory = 0); virtual void setup (); virtual void modify_device (const db::Polygon &res, const std::vector & /*layer_geometry*/, db::Device *device); @@ -186,10 +240,10 @@ public: * the terminals for A and B are produced respectively. */ class DB_PUBLIC NetlistDeviceExtractorCapacitor - : public db::NetlistDeviceExtractor + : public db::NetlistDeviceExtractorImplBase { public: - NetlistDeviceExtractorCapacitor (const std::string &name, double area_cap); + NetlistDeviceExtractorCapacitor (const std::string &name, double area_cap, DeviceClassFactory *factory = 0); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; @@ -227,7 +281,7 @@ class DB_PUBLIC NetlistDeviceExtractorCapacitorWithBulk : public db::NetlistDeviceExtractorCapacitor { public: - NetlistDeviceExtractorCapacitorWithBulk (const std::string &name, double cap_area); + NetlistDeviceExtractorCapacitorWithBulk (const std::string &name, double cap_area, DeviceClassFactory *factory = 0); virtual void setup (); virtual void modify_device (const db::Polygon &cap, const std::vector & /*layer_geometry*/, db::Device *device); @@ -256,10 +310,10 @@ public: * The terminal output layer names are 'tC' (collector), 'tB' (base) and 'tE' (emitter). */ class DB_PUBLIC NetlistDeviceExtractorBJT3Transistor - : public db::NetlistDeviceExtractor + : public db::NetlistDeviceExtractorImplBase { public: - NetlistDeviceExtractorBJT3Transistor (const std::string &name); + NetlistDeviceExtractorBJT3Transistor (const std::string &name, DeviceClassFactory *factory = 0); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; @@ -296,7 +350,7 @@ class DB_PUBLIC NetlistDeviceExtractorBJT4Transistor : public NetlistDeviceExtractorBJT3Transistor { public: - NetlistDeviceExtractorBJT4Transistor (const std::string &name); + NetlistDeviceExtractorBJT4Transistor (const std::string &name, DeviceClassFactory *factory = 0); virtual void setup (); @@ -321,10 +375,10 @@ private: * cathode respectively. */ class DB_PUBLIC NetlistDeviceExtractorDiode - : public db::NetlistDeviceExtractor + : public db::NetlistDeviceExtractorImplBase { public: - NetlistDeviceExtractorDiode (const std::string &name); + NetlistDeviceExtractorDiode (const std::string &name, DeviceClassFactory *factory = 0); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 7d677e5f2..cfdc5a341 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -843,7 +843,7 @@ public: } } - gsi::Callback cb_less, cb_equal; + gsi::Callback cb_less; }; } diff --git a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc index 24dc1fe2c..0dc5f9a05 100644 --- a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc +++ b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc @@ -27,7 +27,7 @@ namespace { /** - * @brief A NetlistDeviceExtractor implementation that allows reimplementation of the virtual methods + * @brief A NetlistDeviceExtractor implementation that allows reimplementing the virtual methods */ class GenericDeviceExtractor : public db::NetlistDeviceExtractor @@ -110,6 +110,55 @@ template<> struct type_traits : public tl::type_traits (&db::DeviceClassFactory::create_class); + } else { + return 0; + } + } + + gsi::Callback cb_create_class; +}; + +} + +Class decl_dbDeviceClassFactoryBase ("db", "DeviceClassFactory", + gsi::factory_callback ("create_class", &DeviceClassFactoryImpl::create_class, &DeviceClassFactoryImpl::cb_create_class, + "@brief Creates the DeviceClass object\n" + ), + "@brief A factory for creating specific device classes for the standard device extractors\n" + "Use a reimplementation of this class to provide a device class generator for built-in device extractors " + "such as \\DeviceExtractorMOS3Transistor. The constructor of this extractor has a 'factory' parameter " + "which takes an object of \\DeviceClassFactory type. If such an object is provided, this factory is used " + "to create the actual device class.\n" + "\n" + "@code\n" + "class MyFactory < RBA::DeviceClassMOS3Transistor\n" + " ... overrides some methods ...\n" + "end\n" + "\n" + "extractor = RBA::DeviceExtractorMOS3Transistor::new(\"NMOS\", false, MyFactor.new)\n" + "@/code\n" +); + Class decl_dbNetlistDeviceExtractorError ("db", "NetlistDeviceExtractorError", gsi::method ("message", &db::NetlistDeviceExtractorError::message, "@brief Gets the message text.\n" @@ -408,16 +457,18 @@ Class decl_GenericDeviceExtractor (decl_dbNetlistDeviceE "This class has been introduced in version 0.26." ); -static db::NetlistDeviceExtractorMOS3Transistor *make_mos3_extractor (const std::string &name, bool strict) +static db::NetlistDeviceExtractorMOS3Transistor *make_mos3_extractor (const std::string &name, bool strict, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorMOS3Transistor (name, strict); + return new db::NetlistDeviceExtractorMOS3Transistor (name, strict, factory); } Class decl_NetlistDeviceExtractorMOS3Transistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorMOS3Transistor", - gsi::constructor ("new", &make_mos3_extractor, gsi::arg ("name"), gsi::arg ("strict", false), + gsi::constructor ("new", &make_mos3_extractor, gsi::arg ("name"), gsi::arg ("strict", false), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), "@brief Creates a new device extractor with the given name.\n" "If \\strict is true, the MOS device extraction will happen in strict mode. That is, source and drain " - "are not interchangeable." + "are not interchangeable.\n" + "\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ) + gsi::method ("strict?", &db::NetlistDeviceExtractorMOS3Transistor::is_strict, "@brief Returns a value indicating whether extraction happens in strict mode." @@ -465,14 +516,15 @@ Class decl_NetlistDeviceExtractorMOS3T "This class has been introduced in version 0.26." ); -static db::NetlistDeviceExtractorMOS4Transistor *make_mos4_extractor (const std::string &name, bool strict) +static db::NetlistDeviceExtractorMOS4Transistor *make_mos4_extractor (const std::string &name, bool strict, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorMOS4Transistor (name, strict); + return new db::NetlistDeviceExtractorMOS4Transistor (name, strict, factory); } Class decl_NetlistDeviceExtractorMOS4Transistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorMOS4Transistor", - gsi::constructor ("new", &make_mos4_extractor, gsi::arg ("name"), gsi::arg ("strict", false), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_mos4_extractor, gsi::arg ("name"), gsi::arg ("strict", false), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a four-terminal MOS transistor\n" "\n" @@ -503,14 +555,15 @@ Class decl_NetlistDeviceExtractorMOS4T "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorResistor *make_res_extractor (const std::string &name, double sheet_rho) +db::NetlistDeviceExtractorResistor *make_res_extractor (const std::string &name, double sheet_rho, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorResistor (name, sheet_rho); + return new db::NetlistDeviceExtractorResistor (name, sheet_rho, factory); } Class decl_NetlistDeviceExtractorResistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorResistor", - gsi::constructor ("new", &make_res_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_res_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a two-terminal resistor\n" "\n" @@ -553,14 +606,15 @@ Class decl_NetlistDeviceExtractorResistor (d "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorResistorWithBulk *make_res_with_bulk_extractor (const std::string &name, double sheet_rho) +db::NetlistDeviceExtractorResistorWithBulk *make_res_with_bulk_extractor (const std::string &name, double sheet_rho, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorResistorWithBulk (name, sheet_rho); + return new db::NetlistDeviceExtractorResistorWithBulk (name, sheet_rho, factory); } Class decl_NetlistDeviceExtractorResistorWithBulk (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorResistorWithBulk", - gsi::constructor ("new", &make_res_with_bulk_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_res_with_bulk_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a resistor with a bulk terminal\n" "\n" @@ -598,14 +652,15 @@ Class decl_NetlistDeviceExtractorRes "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorCapacitor *make_cap_extractor (const std::string &name, double area_cap) +db::NetlistDeviceExtractorCapacitor *make_cap_extractor (const std::string &name, double area_cap, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorCapacitor (name, area_cap); + return new db::NetlistDeviceExtractorCapacitor (name, area_cap, factory); } Class decl_NetlistDeviceExtractorCapacitor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorCapacitor", - gsi::constructor ("new", &make_cap_extractor, gsi::arg ("name"), gsi::arg ("area_cap"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_cap_extractor, gsi::arg ("name"), gsi::arg ("area_cap"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a two-terminal capacitor\n" "\n" @@ -643,14 +698,15 @@ Class decl_NetlistDeviceExtractorCapacitor "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorCapacitorWithBulk *make_cap_with_bulk_extractor (const std::string &name, double area_cap) +db::NetlistDeviceExtractorCapacitorWithBulk *make_cap_with_bulk_extractor (const std::string &name, double area_cap, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorCapacitorWithBulk (name, area_cap); + return new db::NetlistDeviceExtractorCapacitorWithBulk (name, area_cap, factory); } Class decl_NetlistDeviceExtractorCapacitorWithBulk (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorCapacitorWithBulk", - gsi::constructor ("new", &make_cap_with_bulk_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_cap_with_bulk_extractor, gsi::arg ("name"), gsi::arg ("sheet_rho"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a capacitor with a bulk terminal\n" "\n" @@ -687,14 +743,15 @@ Class decl_NetlistDeviceExtractorCa "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorBJT3Transistor *make_bjt3_extractor (const std::string &name) +db::NetlistDeviceExtractorBJT3Transistor *make_bjt3_extractor (const std::string &name, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorBJT3Transistor (name); + return new db::NetlistDeviceExtractorBJT3Transistor (name, factory); } Class decl_dbNetlistDeviceExtractorBJT3Transistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorBJT3Transistor", - gsi::constructor ("new", &make_bjt3_extractor, gsi::arg ("name"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_bjt3_extractor, gsi::arg ("name"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a bipolar transistor (BJT)\n" "\n" @@ -740,14 +797,15 @@ Class decl_dbNetlistDeviceExtractorBJT "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorBJT4Transistor *make_bjt4_extractor (const std::string &name) +db::NetlistDeviceExtractorBJT4Transistor *make_bjt4_extractor (const std::string &name, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorBJT4Transistor (name); + return new db::NetlistDeviceExtractorBJT4Transistor (name, factory); } Class decl_NetlistDeviceExtractorBJT4Transistor (decl_dbNetlistDeviceExtractorBJT3Transistor, "db", "DeviceExtractorBJT4Transistor", - gsi::constructor ("new", &make_bjt4_extractor, gsi::arg ("name"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_bjt4_extractor, gsi::arg ("name"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a four-terminal bipolar transistor (BJT)\n" "\n" @@ -774,14 +832,15 @@ Class decl_NetlistDeviceExtractorBJT4T "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorDiode *make_diode_extractor (const std::string &name) +db::NetlistDeviceExtractorDiode *make_diode_extractor (const std::string &name, db::DeviceClassFactory *factory) { - return new db::NetlistDeviceExtractorDiode (name); + return new db::NetlistDeviceExtractorDiode (name, factory); } Class decl_NetlistDeviceExtractorDiode (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorDiode", - gsi::constructor ("new", &make_diode_extractor, gsi::arg ("name"), - "@brief Creates a new device extractor with the given name." + gsi::constructor ("new", &make_diode_extractor, gsi::arg ("name"), gsi::arg ("factory", (db::DeviceClassFactory *)0, "none"), + "@brief Creates a new device extractor with the given name\n" + "For the 'factory' parameter see \\DeviceClassFactory. It has been added in version 0.27.3.\n" ), "@brief A device extractor for a planar diode\n" "\n" diff --git a/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc b/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc index e77984177..c6077ce61 100644 --- a/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistDeviceExtractorTests.cc @@ -25,6 +25,7 @@ #include "dbReader.h" #include "dbRecursiveShapeIterator.h" #include "dbNetlistDeviceExtractorClasses.h" +#include "dbNetlistDeviceClasses.h" #include "tlUnitTest.h" #include "tlFileUtils.h" @@ -90,6 +91,67 @@ TEST(2_NetlistDeviceExtractorErrors) EXPECT_EQ (error2string (errors [3]), ":cat1:desc1:(10,11;10,13;12,13;12,11):msg3"); } +namespace { + +class MyDeviceClass + : public db::DeviceClassMOS3Transistor +{ +public: + MyDeviceClass () : db::DeviceClassMOS3Transistor () { } +}; + +} + +TEST(3_ClassFactoryTest) +{ + db::Layout ly; + + { + db::LoadLayoutOptions options; + + std::string fn (tl::testdata ()); + fn = tl::combine_path (fn, "algo"); + fn = tl::combine_path (fn, "mos3_1.gds"); + + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly, options); + } + + db::Cell &tc = ly.cell (*ly.begin_top_down ()); + + db::DeepShapeStore dss; + dss.set_text_enlargement (1); + dss.set_text_property_name (tl::Variant ("LABEL")); + + // original layers + db::Region l1 (db::RecursiveShapeIterator (ly, tc, ly.get_layer (db::LayerProperties(1, 0))), dss); + db::Region l2 (db::RecursiveShapeIterator (ly, tc, ly.get_layer (db::LayerProperties(2, 0))), dss); + db::Region o1 (dss); + db::Region o2 (dss); + db::Region o3 (dss); + + // perform the extraction + + db::Netlist nl; + db::hier_clusters cl; + + db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3", false, new db::device_class_factory ()); + + db::NetlistDeviceExtractor::input_layers dl; + + dl["SD"] = &l1; + dl["G"] = &l2; + dl["tS"] = &o1; + dl["tD"] = &o2; + dl["tG"] = &o3; + ex.extract (dss, 0, dl, nl, cl); + + // the generated objects are of MyDeviceClassType + EXPECT_EQ (dynamic_cast (ex.device_class ()) != 0, true); + EXPECT_EQ (dynamic_cast (nl.device_class_by_name ("MOS3")) != 0, true); +} + TEST(10_MOS3DeviceExtractorTest) { db::Layout ly;