diff --git a/src/db/db/dbNetlistDeviceClasses.cc b/src/db/db/dbNetlistDeviceClasses.cc index c2357fd58..f4dd10f60 100644 --- a/src/db/db/dbNetlistDeviceClasses.cc +++ b/src/db/db/dbNetlistDeviceClasses.cc @@ -96,8 +96,10 @@ bool DeviceClassTwoTerminalDevice::combine_devices (Device *a, Device *b) const // DeviceClassResistor implementation DB_PUBLIC size_t DeviceClassResistor::param_id_R = 0; -DB_PUBLIC size_t DeviceClassResistor::param_id_A = 1; -DB_PUBLIC size_t DeviceClassResistor::param_id_P = 2; +DB_PUBLIC size_t DeviceClassResistor::param_id_L = 1; +DB_PUBLIC size_t DeviceClassResistor::param_id_W = 2; +DB_PUBLIC size_t DeviceClassResistor::param_id_A = 3; +DB_PUBLIC size_t DeviceClassResistor::param_id_P = 4; DB_PUBLIC size_t DeviceClassResistor::terminal_id_A = 0; DB_PUBLIC size_t DeviceClassResistor::terminal_id_B = 1; @@ -108,6 +110,8 @@ DeviceClassResistor::DeviceClassResistor () add_terminal_definition (db::DeviceTerminalDefinition ("B", "Terminal B")); add_parameter_definition (db::DeviceParameterDefinition ("R", "Resistance (Ohm)", 0.0)); + add_parameter_definition (db::DeviceParameterDefinition ("L", "Length (micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("W", "Width (micrometer)", 0.0, false)); add_parameter_definition (db::DeviceParameterDefinition ("A", "Area (square micrometer)", 0.0, false)); add_parameter_definition (db::DeviceParameterDefinition ("P", "Perimeter (micrometer)", 0.0, false)); } @@ -118,15 +122,31 @@ void DeviceClassResistor::parallel (Device *a, Device *b) const double vb = b->parameter_value (0); a->set_parameter_value (0, va + vb < 1e-10 ? 0.0 : va * vb / (va + vb)); - // TODO: does this implementation make sense? - double aa = a->parameter_value (1); - double ab = b->parameter_value (1); - a->set_parameter_value (1, aa + ab); + // parallel width is sum of both, length is the one that gives the same value of resistance + // R = 1/(1/R1 + 1/R2) + // R = L/(W1+W2) + // R1 = L1/W1 + // R2 = L2/W2 + // -> L = (L1*L2*(W1+W2))/(L2*W1+L1*W2)) + double l1 = a->parameter_value (1); + double w1 = a->parameter_value (2); + double l2 = b->parameter_value (1); + double w2 = b->parameter_value (2); + double dnom = (l2 * w1 + l1 * w2); + if (fabs (dnom) > 1e-15) { + a->set_parameter_value (1, (l1 * l2 * (w1 + w2)) / dnom); + } + a->set_parameter_value (2, w1 + w2); - // TODO: does this implementation make sense? - double pa = a->parameter_value (2); - double pb = b->parameter_value (2); - a->set_parameter_value (2, pa + pb); + // TODO: does this implementation make sense? (area) + double aa = a->parameter_value (3); + double ab = b->parameter_value (3); + a->set_parameter_value (3, aa + ab); + + // TODO: does this implementation make sense? (perimeter) + double pa = a->parameter_value (4); + double pb = b->parameter_value (4); + a->set_parameter_value (4, pa + pb); } void DeviceClassResistor::serial (Device *a, Device *b) const @@ -135,13 +155,30 @@ void DeviceClassResistor::serial (Device *a, Device *b) const double vb = b->parameter_value (0); a->set_parameter_value (0, va + vb); - double aa = a->parameter_value (1); - double ab = b->parameter_value (1); - a->set_parameter_value (1, aa + ab); + // parallel length is sum of both, width is the one that gives the same value of resistance + // assuming same sheet rho + // R = R1+R2 + // R = (L1+L2)/W + // R1 = L1/W1 + // R2 = L2/W2 + // -> W = ((L1+L2)*W1*W2)/(W1*L2+W2*L1) + double l1 = a->parameter_value (1); + double w1 = a->parameter_value (2); + double l2 = b->parameter_value (1); + double w2 = b->parameter_value (2); + a->set_parameter_value (1, l1 + l2); + double dnom = (l2 * w1 + l1 * w2); + if (fabs (dnom) > 1e-15) { + a->set_parameter_value (2, (w1 * w2 * (l1 + l2)) / dnom); + } - double pa = a->parameter_value (2); - double pb = b->parameter_value (2); - a->set_parameter_value (2, pa + pb); + double aa = a->parameter_value (3); + double ab = b->parameter_value (3); + a->set_parameter_value (3, aa + ab); + + double pa = a->parameter_value (4); + double pb = b->parameter_value (4); + a->set_parameter_value (4, pa + pb); } // ------------------------------------------------------------------------------------ @@ -288,8 +325,8 @@ DeviceClassDiode::DeviceClassDiode () add_terminal_definition (db::DeviceTerminalDefinition ("A", "Anode")); add_terminal_definition (db::DeviceTerminalDefinition ("C", "Cathode")); - add_parameter_definition (db::DeviceParameterDefinition ("A", "Area (square micrometer)", 0.0)); - add_parameter_definition (db::DeviceParameterDefinition ("P", "Perimeter (micrometer)", 0.0)); + add_parameter_definition (db::DeviceParameterDefinition ("A", "Area (square micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("P", "Perimeter (micrometer)", 0.0, false)); } bool DeviceClassDiode::combine_devices (Device *a, Device *b) const @@ -438,16 +475,20 @@ bool DeviceClassMOS4Transistor::combine_devices (Device *a, Device *b) const } // ------------------------------------------------------------------------------------ -// DeviceClassBipolarTransistor implementation +// DeviceClassBJT3Transistor implementation -DB_PUBLIC size_t DeviceClassBipolarTransistor::param_id_AE = 0; -DB_PUBLIC size_t DeviceClassBipolarTransistor::param_id_PE = 1; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_AE = 0; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_PE = 1; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_AB = 2; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_PB = 3; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_AC = 4; +DB_PUBLIC size_t DeviceClassBJT3Transistor::param_id_PC = 5; -DB_PUBLIC size_t DeviceClassBipolarTransistor::terminal_id_C = 0; -DB_PUBLIC size_t DeviceClassBipolarTransistor::terminal_id_B = 1; -DB_PUBLIC size_t DeviceClassBipolarTransistor::terminal_id_E = 2; +DB_PUBLIC size_t DeviceClassBJT3Transistor::terminal_id_C = 0; +DB_PUBLIC size_t DeviceClassBJT3Transistor::terminal_id_B = 1; +DB_PUBLIC size_t DeviceClassBJT3Transistor::terminal_id_E = 2; -DeviceClassBipolarTransistor::DeviceClassBipolarTransistor () +DeviceClassBJT3Transistor::DeviceClassBJT3Transistor () { add_terminal_definition (db::DeviceTerminalDefinition ("C", "Collector")); add_terminal_definition (db::DeviceTerminalDefinition ("B", "Base")); @@ -455,9 +496,13 @@ DeviceClassBipolarTransistor::DeviceClassBipolarTransistor () add_parameter_definition (db::DeviceParameterDefinition ("AE", "Emitter area (square micrometer)", 0.0, false)); add_parameter_definition (db::DeviceParameterDefinition ("PE", "Emitter perimeter (micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("AB", "Base area (square micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("PB", "Base perimeter (micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("AC", "Collector area (square micrometer)", 0.0, false)); + add_parameter_definition (db::DeviceParameterDefinition ("PC", "Collector perimeter (micrometer)", 0.0, false)); } -bool DeviceClassBipolarTransistor::combine_devices (Device *a, Device *b) const +bool DeviceClassBJT3Transistor::combine_devices (Device *a, Device *b) const { const db::Net *nac = a->net_for_terminal (0); const db::Net *nab = a->net_for_terminal (1); @@ -482,10 +527,34 @@ bool DeviceClassBipolarTransistor::combine_devices (Device *a, Device *b) const return false; } -void DeviceClassBipolarTransistor::combine_parameters (Device *a, Device *b) const +void DeviceClassBJT3Transistor::combine_parameters (Device *a, Device *b) const { - a->set_parameter_value (0, a->parameter_value (0) + b->parameter_value (0)); - a->set_parameter_value (1, a->parameter_value (1) + b->parameter_value (1)); + for (size_t i = 0; i < 6; ++i) { + a->set_parameter_value (i, a->parameter_value (i) + b->parameter_value (i)); + } +} + +// ------------------------------------------------------------------------------------ +// DeviceClassBJT4Transistor implementation + +DB_PUBLIC size_t DeviceClassBJT4Transistor::terminal_id_S = 3; + +DeviceClassBJT4Transistor::DeviceClassBJT4Transistor () +{ + add_terminal_definition (db::DeviceTerminalDefinition ("S", "Substrate")); +} + +bool DeviceClassBJT4Transistor::combine_devices (Device *a, Device *b) const +{ + const db::Net *nas = a->net_for_terminal (3); + const db::Net *nbs = b->net_for_terminal (3); + + // combination is possible only if the substrate nets are the same + if (nas == nbs) { + return combine_devices (a, b); + } else { + return false; + } } } diff --git a/src/db/db/dbNetlistDeviceClasses.h b/src/db/db/dbNetlistDeviceClasses.h index 439ec7039..14bd51526 100644 --- a/src/db/db/dbNetlistDeviceClasses.h +++ b/src/db/db/dbNetlistDeviceClasses.h @@ -61,6 +61,8 @@ public: } static size_t param_id_R; + static size_t param_id_L; + static size_t param_id_W; static size_t param_id_A; static size_t param_id_P; @@ -279,14 +281,18 @@ public: * in micrometers. * The bipolar transistor defines three terminals, "C", "B" and "E" for collector, base and emitter. */ -class DB_PUBLIC DeviceClassBipolarTransistor +class DB_PUBLIC DeviceClassBJT3Transistor : public db::DeviceClass { public: - DeviceClassBipolarTransistor (); + DeviceClassBJT3Transistor (); static size_t param_id_AE; static size_t param_id_PE; + static size_t param_id_AB; + static size_t param_id_PB; + static size_t param_id_AC; + static size_t param_id_PC; static size_t terminal_id_C; static size_t terminal_id_B; @@ -294,7 +300,7 @@ public: virtual db::DeviceClass *clone () const { - return new DeviceClassBipolarTransistor (*this); + return new DeviceClassBJT3Transistor (*this); } virtual bool combine_devices (Device *a, Device *b) const; @@ -304,6 +310,27 @@ protected: void combine_parameters (Device *a, Device *b) const; }; +/** + * @brief A basic bipolar transistor class with four terminals + * The four-terminal BJT behaves identical to the three-terminal one but adds one more + * terminal for the substrate. + */ +class DB_PUBLIC DeviceClassBJT4Transistor + : public DeviceClassBJT3Transistor +{ +public: + DeviceClassBJT4Transistor (); + + static size_t terminal_id_S; + + virtual db::DeviceClass *clone () const + { + return new DeviceClassBJT4Transistor (*this); + } + + virtual bool combine_devices (Device *a, Device *b) const; +}; + } #endif diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index ef114cbb6..4a4b33296 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -262,6 +262,8 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vectorset_parameter_value (db::DeviceClassResistor::param_id_R, m_sheet_rho * double (length) / double (width)); + device->set_parameter_value (db::DeviceClassResistor::param_id_L, dbu () * length); + device->set_parameter_value (db::DeviceClassResistor::param_id_W, dbu () * width); device->set_parameter_value (db::DeviceClassResistor::param_id_A, dbu () * dbu () * p->area ()); device->set_parameter_value (db::DeviceClassResistor::param_id_P, dbu () * p->perimeter ()); @@ -410,15 +412,15 @@ void NetlistDeviceExtractorCapacitorWithBulk::modify_device (const db::Polygon & } // --------------------------------------------------------------------------------- -// NetlistDeviceExtractorBipolarTransistor implementation +// NetlistDeviceExtractorBJT3Transistor implementation -NetlistDeviceExtractorBipolarTransistor::NetlistDeviceExtractorBipolarTransistor (const std::string &name) +NetlistDeviceExtractorBJT3Transistor::NetlistDeviceExtractorBJT3Transistor (const std::string &name) : db::NetlistDeviceExtractor (name) { // .. nothing yet .. } -void NetlistDeviceExtractorBipolarTransistor::setup () +void NetlistDeviceExtractorBJT3Transistor::setup () { define_layer ("C", "Collector"); // #0 define_layer ("B", "Base"); // #1 @@ -429,10 +431,10 @@ void NetlistDeviceExtractorBipolarTransistor::setup () define_layer ("tB", 1, "Base terminal output"); // #4 -> B define_layer ("tE", 2, "Emitter terminal output"); // #5 -> E - register_device_class (new db::DeviceClassBipolarTransistor ()); + register_device_class (new db::DeviceClassBJT3Transistor ()); } -db::Connectivity NetlistDeviceExtractorBipolarTransistor::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const +db::Connectivity NetlistDeviceExtractorBJT3Transistor::get_connectivity (const db::Layout & /*layout*/, const std::vector &layers) const { tl_assert (layers.size () >= 3); @@ -449,7 +451,7 @@ db::Connectivity NetlistDeviceExtractorBipolarTransistor::get_connectivity (cons return conn; } -void NetlistDeviceExtractorBipolarTransistor::extract_devices (const std::vector &layer_geometry) +void NetlistDeviceExtractorBJT3Transistor::extract_devices (const std::vector &layer_geometry) { unsigned int collector_geometry_index = 0; unsigned int base_geometry_index = 1; @@ -478,18 +480,30 @@ void NetlistDeviceExtractorBipolarTransistor::extract_devices (const std::vector error (tl::to_string (tr ("Base shape without emitters - ignored")), *p); } else { + double ab = dbu () * dbu () * p->area (); + double pb = dbu () * p->perimeter (); + + double ac = dbu () * dbu () * rcollector2base.area (); + double pc = dbu () * rcollector2base.perimeter (); + for (db::Region::const_iterator pe = remitter2base.begin_merged (); !pe.at_end (); ++pe) { db::Device *device = create_device (); device->set_trans (db::DCplxTrans ((pe->box ().center () - db::Point ()) * dbu ())); - device->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_AE, dbu () * dbu () * pe->area ()); - device->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_PE, dbu () * pe->perimeter ()); + 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 ()); - define_terminal (device, db::DeviceClassBipolarTransistor::terminal_id_C, collector_terminal_geometry_index, rcollector2base); - define_terminal (device, db::DeviceClassBipolarTransistor::terminal_id_B, base_terminal_geometry_index, *p); - define_terminal (device, db::DeviceClassBipolarTransistor::terminal_id_E, emitter_terminal_geometry_index, *pe); + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, ab); + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, pb); + + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AC, ac); + device->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PC, pc); + + define_terminal (device, db::DeviceClassBJT3Transistor::terminal_id_C, collector_terminal_geometry_index, rcollector2base); + define_terminal (device, db::DeviceClassBJT3Transistor::terminal_id_B, base_terminal_geometry_index, *p); + define_terminal (device, db::DeviceClassBJT3Transistor::terminal_id_E, emitter_terminal_geometry_index, *pe); // allow derived classes to modify the device modify_device (*p, layer_geometry, device); @@ -504,6 +518,40 @@ void NetlistDeviceExtractorBipolarTransistor::extract_devices (const std::vector } } +// --------------------------------------------------------------------------------- +// NetlistDeviceExtractorBJT4Transistor implementation + +NetlistDeviceExtractorBJT4Transistor::NetlistDeviceExtractorBJT4Transistor (const std::string &name) + : NetlistDeviceExtractorBJT3Transistor (name) +{ + // .. nothing yet .. +} + +void NetlistDeviceExtractorBJT4Transistor::setup () +{ + define_layer ("C", "Collector"); // #0 + define_layer ("B", "Base"); // #1 + define_layer ("E", "Emitter"); // #2 + + // terminal output + 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 + + // for convenience and consistency with MOS4 + define_layer ("S", "Substrate (bulk) terminal output"); // #6 + + define_layer ("tS", 6, "Substrate (bulk) terminal output"); // #7 -> S + + register_device_class (new db::DeviceClassBJT4Transistor ()); +} + +void NetlistDeviceExtractorBJT4Transistor::modify_device (const db::Polygon &emitter, const std::vector & /*layer_geometry*/, db::Device *device) +{ + unsigned int substrate_terminal_geometry_index = 7; + define_terminal (device, db::DeviceClassBJT4Transistor::terminal_id_S, substrate_terminal_geometry_index, emitter); +} + // --------------------------------------------------------------------------------- // NetlistDeviceExtractorDiode implementation diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.h b/src/db/db/dbNetlistDeviceExtractorClasses.h index 50ab9eef0..f4fc1ece6 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.h +++ b/src/db/db/dbNetlistDeviceExtractorClasses.h @@ -242,17 +242,17 @@ public: * region will be output to the 'tC' terminal output layer. This layer then needs to be connected to a global net * to form the net connection. * - * The device class produced by this extractor is \\DeviceClassBipolarTransistor. + * The device class produced by this extractor is \\DeviceClassBJT3Transistor. * The extractor extracts the two parameters of this class: AE and PE. * * The device recognition layer names are 'C' (collector), 'B' (base) and 'E' (emitter). * The terminal output layer names are 'tC' (collector), 'tB' (base) and 'tE' (emitter). */ -class DB_PUBLIC NetlistDeviceExtractorBipolarTransistor +class DB_PUBLIC NetlistDeviceExtractorBJT3Transistor : public db::NetlistDeviceExtractor { public: - NetlistDeviceExtractorBipolarTransistor (const std::string &name); + NetlistDeviceExtractorBJT3Transistor (const std::string &name); virtual void setup (); virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector &layers) const; @@ -277,6 +277,26 @@ protected: } }; +/** + * @brief A device extractor for a four-terminal BJT transistor + * + * This class is like the BJT3Transistor extractor, but requires a forth + * input layer (Substrate). This layer will be used to output the substrate terminal. + * + * The device class produced by this extractor is DeviceClassBJT4Transistor. + */ +class DB_PUBLIC NetlistDeviceExtractorBJT4Transistor + : public NetlistDeviceExtractorBJT3Transistor +{ +public: + NetlistDeviceExtractorBJT4Transistor (const std::string &name); + + virtual void setup (); + +private: + virtual void modify_device (const db::Polygon &emitter, const std::vector &layer_geometry, db::Device *device); +}; + /** * @brief A device extractor for a planar diode * @@ -363,7 +383,7 @@ template<> struct type_traits : publ typedef tl::false_tag has_default_constructor; }; -template<> struct type_traits : public tl::type_traits +template<> struct type_traits : public tl::type_traits { typedef tl::false_tag has_copy_constructor; typedef tl::false_tag has_default_constructor; diff --git a/src/db/db/dbNetlistSpiceWriter.cc b/src/db/db/dbNetlistSpiceWriter.cc index 654855e49..935220609 100644 --- a/src/db/db/dbNetlistSpiceWriter.cc +++ b/src/db/db/dbNetlistSpiceWriter.cc @@ -97,6 +97,8 @@ void NetlistSpiceWriterDelegate::write_device (const db::Device &dev) const const db::DeviceClassDiode *diode = dynamic_cast (dc); const db::DeviceClassMOS3Transistor *mos3 = dynamic_cast (dc); const db::DeviceClassMOS4Transistor *mos4 = dynamic_cast (dc); + const db::DeviceClassBJT3Transistor *bjt3 = dynamic_cast (dc); + const db::DeviceClassBJT3Transistor *bjt4 = dynamic_cast (dc); std::ostringstream os; @@ -130,10 +132,13 @@ void NetlistSpiceWriterDelegate::write_device (const db::Device &dev) const os << format_name (dev.expanded_name ()); os << format_terminals (dev); - // Use "D" + device class name for the model - os << " D"; + // Use device class name for the model + os << " "; os << format_name (dev.device_class ()->name ()); + os << " A=" << tl::sprintf ("%.12gP", dev.parameter_value (db::DeviceClassDiode::param_id_A)); + os << " P=" << tl::sprintf ("%.12gP", dev.parameter_value (db::DeviceClassDiode::param_id_P)); + } else if (mos3 || mos4) { os << "M"; @@ -157,6 +162,23 @@ void NetlistSpiceWriterDelegate::write_device (const db::Device &dev) const os << " PS=" << tl::sprintf ("%.12gU", dev.parameter_value (db::DeviceClassMOS3Transistor::param_id_PS)); os << " PD=" << tl::sprintf ("%.12gU", dev.parameter_value (db::DeviceClassMOS3Transistor::param_id_PD)); + } else if (bjt3 || bjt4) { + + os << "Q"; + os << format_name (dev.expanded_name ()); + os << format_terminals (dev); + + // Use device class name for the model + os << " "; + os << format_name (dev.device_class ()->name ()); + + os << " AE=" << tl::sprintf ("%.12gP", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_AE)); + os << " AB=" << tl::sprintf ("%.12gP", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_AB)); + os << " AC=" << tl::sprintf ("%.12gP", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_AC)); + os << " PE=" << tl::sprintf ("%.12gU", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_PE)); + os << " PB=" << tl::sprintf ("%.12gU", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_PB)); + os << " PC=" << tl::sprintf ("%.12gU", dev.parameter_value (db::DeviceClassBJT3Transistor::param_id_PC)); + } else { // Write unknown devices as subcircuits (CAUTION: potential name clash) diff --git a/src/db/db/gsiDeclDbNetlistDeviceClasses.cc b/src/db/db/gsiDeclDbNetlistDeviceClasses.cc index 58cb7f6ab..8281061ff 100644 --- a/src/db/db/gsiDeclDbNetlistDeviceClasses.cc +++ b/src/db/db/gsiDeclDbNetlistDeviceClasses.cc @@ -37,33 +37,40 @@ Class decl_dbDeviceClassResistor (decl_dbDeviceClass, " ) + gsi::constant ("PARAM_R", db::DeviceClassResistor::param_id_R, "@brief A constant giving the parameter ID for parameter R" + ) + + gsi::constant ("PARAM_L", db::DeviceClassResistor::param_id_L, + "@brief A constant giving the parameter ID for parameter L" + ) + + gsi::constant ("PARAM_W", db::DeviceClassResistor::param_id_W, + "@brief A constant giving the parameter ID for parameter W" + ) + + gsi::constant ("PARAM_A", db::DeviceClassResistor::param_id_A, + "@brief A constant giving the parameter ID for parameter A" + ) + + gsi::constant ("PARAM_P", db::DeviceClassResistor::param_id_P, + "@brief A constant giving the parameter ID for parameter P" ), "@brief A device class for a resistor.\n" "This class describes a resistor. Resistors are defined by their combination behavior and " "the basic parameter 'R' which is the resistance in Ohm.\n" "\n" "A resistor has two terminals, A and B.\n" + "The parameters of a resistor are R (the value in Ohms), L and W (length and width in micrometers) and " + "A and P (area and perimeter in square micrometers and micrometers respectively).\n" "\n" "This class has been introduced in version 0.26." ); -Class decl_dbDeviceClassResistorWithBulk (decl_dbDeviceClass, "db", "DeviceClassResistorWithBulk", - gsi::constant ("TERMINAL_A", db::DeviceClassResistorWithBulk::terminal_id_A, - "@brief A constant giving the terminal ID for terminal A" - ) + - gsi::constant ("TERMINAL_B", db::DeviceClassResistorWithBulk::terminal_id_B, - "@brief A constant giving the terminal ID for terminal B" - ) + +Class decl_dbDeviceClassResistorWithBulk (decl_dbDeviceClassResistor, "db", "DeviceClassResistorWithBulk", gsi::constant ("TERMINAL_W", db::DeviceClassResistorWithBulk::terminal_id_W, "@brief A constant giving the terminal ID for terminal W (well, bulk)" - ) + - gsi::constant ("PARAM_R", db::DeviceClassResistorWithBulk::param_id_R, - "@brief A constant giving the parameter ID for parameter R" ), "@brief A device class for a resistor with a bulk terminal (substrate, well).\n" "This class is similar to \\DeviceClassResistor, but provides an additional terminal (BULK) for the " "well or substrate the resistor is embedded in.\n" "\n" + "The additional terminal is 'W' for the well/substrate terminal.\n" + "\n" "This class has been introduced in version 0.26." ); @@ -76,33 +83,34 @@ Class decl_dbDeviceClassCapacitor (decl_dbDeviceClass, ) + gsi::constant ("PARAM_C", db::DeviceClassCapacitor::param_id_C, "@brief A constant giving the parameter ID for parameter C" + ) + + gsi::constant ("PARAM_A", db::DeviceClassCapacitor::param_id_A, + "@brief A constant giving the parameter ID for parameter A" + ) + + gsi::constant ("PARAM_P", db::DeviceClassCapacitor::param_id_P, + "@brief A constant giving the parameter ID for parameter P" ), "@brief A device class for a capacitor.\n" "This describes a capacitor. Capacitors are defined by their combination behavior and " "the basic parameter 'C' which is the capacitance in Farad.\n" "\n" "A capacitor has two terminals, A and B.\n" + "The parameters of a capacitor are C (the value in Farad) and " + "A and P (area and perimeter in square micrometers and micrometers respectively).\n" "\n" "This class has been introduced in version 0.26." ); -Class decl_dbDeviceClassCapacitorWithBulk (decl_dbDeviceClass, "db", "DeviceClassCapacitorWithBulk", - gsi::constant ("TERMINAL_A", db::DeviceClassCapacitorWithBulk::terminal_id_A, - "@brief A constant giving the terminal ID for terminal A" - ) + - gsi::constant ("TERMINAL_B", db::DeviceClassCapacitorWithBulk::terminal_id_B, - "@brief A constant giving the terminal ID for terminal B" - ) + +Class decl_dbDeviceClassCapacitorWithBulk (decl_dbDeviceClassCapacitor, "db", "DeviceClassCapacitorWithBulk", gsi::constant ("TERMINAL_W", db::DeviceClassCapacitorWithBulk::terminal_id_W, "@brief A constant giving the terminal ID for terminal W (well, bulk)" - ) + - gsi::constant ("PARAM_C", db::DeviceClassCapacitorWithBulk::param_id_C, - "@brief A constant giving the parameter ID for parameter C" ), "@brief A device class for a capacitor with a bulk terminal (substrate, well).\n" "This class is similar to \\DeviceClassCapacitor, but provides an additional terminal (BULK) for the " "well or substrate the capacitor is embedded in.\n" "\n" + "The additional terminal is 'W' for the well/substrate terminal.\n" + "\n" "This class has been introduced in version 0.26." ); @@ -148,26 +156,54 @@ Class decl_dbDeviceClassDiode (decl_dbDeviceClass, "db", " "This class has been introduced in version 0.26." ); -Class decl_DeviceClassBipolarTransistor (decl_dbDeviceClass, "db", "DeviceClassBipolarTransistor", - gsi::constant ("TERMINAL_C", db::DeviceClassBipolarTransistor::terminal_id_C, +Class decl_dbDeviceClassBJT3Transistor (decl_dbDeviceClass, "db", "DeviceClassBJT3Transistor", + gsi::constant ("TERMINAL_C", db::DeviceClassBJT3Transistor::terminal_id_C, "@brief A constant giving the terminal ID for terminal C (collector)" ) + - gsi::constant ("TERMINAL_B", db::DeviceClassBipolarTransistor::terminal_id_B, + gsi::constant ("TERMINAL_B", db::DeviceClassBJT3Transistor::terminal_id_B, "@brief A constant giving the terminal ID for terminal B (base)" ) + - gsi::constant ("TERMINAL_E", db::DeviceClassBipolarTransistor::terminal_id_E, + gsi::constant ("TERMINAL_E", db::DeviceClassBJT3Transistor::terminal_id_E, "@brief A constant giving the terminal ID for terminal E (emitter)" ) + - gsi::constant ("PARAM_AE", db::DeviceClassBipolarTransistor::param_id_AE, + gsi::constant ("PARAM_AE", db::DeviceClassBJT3Transistor::param_id_AE, "@brief A constant giving the parameter ID for parameter AE (emitter area)" ) + - gsi::constant ("PARAM_PE", db::DeviceClassBipolarTransistor::param_id_PE, + gsi::constant ("PARAM_PE", db::DeviceClassBJT3Transistor::param_id_PE, "@brief A constant giving the parameter ID for parameter PE (emitter perimeter)" + ) + + gsi::constant ("PARAM_AB", db::DeviceClassBJT3Transistor::param_id_AB, + "@brief A constant giving the parameter ID for parameter AB (base area)" + ) + + gsi::constant ("PARAM_PB", db::DeviceClassBJT3Transistor::param_id_PB, + "@brief A constant giving the parameter ID for parameter PB (base perimeter)" + ) + + gsi::constant ("PARAM_AC", db::DeviceClassBJT3Transistor::param_id_AC, + "@brief A constant giving the parameter ID for parameter AC (collector area)" + ) + + gsi::constant ("PARAM_PC", db::DeviceClassBJT3Transistor::param_id_PC, + "@brief A constant giving the parameter ID for parameter PC (collector perimeter)" ), "@brief A device class for a bipolar transistor.\n" "This class describes a bipolar transistor. Bipolar transistors have tree terminals: the collector (C), the base (B) and the emitter (E).\n" - "Multi-emitter transistors are resolved in individual devices. The basic parameter of a transistor is the emitter area (AE). " - "In addition, the emitter perimeter is extracted too (PE)." + "Multi-emitter transistors are resolved in individual devices." + "\n" + "The parameters are AE, AB and AC for the emitter, base and collector areas in square micrometers and " + "PE, PB and PC for the emitter, base and collector perimeters in micrometers.\n" + "\n" + "This class has been introduced in version 0.26." +); + +Class decl_dbDeviceClassBJT4Transistor (decl_dbDeviceClassBJT3Transistor, "db", "DeviceClassBJT4Transistor", + gsi::constant ("TERMINAL_S", db::DeviceClassBJT4Transistor::terminal_id_S, + "@brief A constant giving the terminal ID for terminal S" + ), + "@brief A device class for a 4-terminal bipolar transistor.\n" + "This class describes a bipolar transistor with a substrate terminal. " + "A device class for a bipolar transistor without a substrate terminal is \\DeviceClassBJT3Transistor. " + "\n" + "The additional terminal is 'S' for the substrate terminal.\n" + "BJT4 transistors combine in parallel if both substrate terminals are connected to the same net.\n" "\n" "This class has been introduced in version 0.26." ); @@ -217,50 +253,17 @@ Class decl_dbDeviceClassMOS3Transistor (decl_dbDe "This class has been introduced in version 0.26." ); -Class decl_dbDeviceClassMOS4Transistor (decl_dbDeviceClass, "db", "DeviceClassMOS4Transistor", - gsi::constant ("TERMINAL_S", db::DeviceClassMOS4Transistor::terminal_id_S, - "@brief A constant giving the terminal ID for terminal S" - ) + - gsi::constant ("TERMINAL_D", db::DeviceClassMOS4Transistor::terminal_id_D, - "@brief A constant giving the terminal ID for terminal D" - ) + - gsi::constant ("TERMINAL_G", db::DeviceClassMOS4Transistor::terminal_id_G, - "@brief A constant giving the terminal ID for terminal G" - ) + +Class decl_dbDeviceClassMOS4Transistor (decl_dbDeviceClassMOS3Transistor, "db", "DeviceClassMOS4Transistor", gsi::constant ("TERMINAL_B", db::DeviceClassMOS4Transistor::terminal_id_B, "@brief A constant giving the terminal ID for terminal B" - ) + - gsi::constant ("PARAM_L", db::DeviceClassMOS4Transistor::param_id_L, - "@brief A constant giving the parameter ID for parameter L" - ) + - gsi::constant ("PARAM_W", db::DeviceClassMOS4Transistor::param_id_W, - "@brief A constant giving the parameter ID for parameter W" - ) + - gsi::constant ("PARAM_AS", db::DeviceClassMOS4Transistor::param_id_AS, - "@brief A constant giving the parameter ID for parameter AS" - ) + - gsi::constant ("PARAM_AD", db::DeviceClassMOS4Transistor::param_id_AD, - "@brief A constant giving the parameter ID for parameter AD" - ) + - gsi::constant ("PARAM_PS", db::DeviceClassMOS4Transistor::param_id_PS, - "@brief A constant giving the parameter ID for parameter PS" - ) + - gsi::constant ("PARAM_PD", db::DeviceClassMOS4Transistor::param_id_PD, - "@brief A constant giving the parameter ID for parameter PD" ), "@brief A device class for a 4-terminal MOS transistor.\n" "This class describes a MOS transistor with a bulk terminal. " "A device class for a MOS transistor without a bulk terminal is \\DeviceClassMOS3Transistor. " "MOS transistors are defined by their combination behavior and the basic parameters.\n" "\n" - "The parameters are L, W, AS, AD, PS and PD for the gate length and width in micrometers, source and drain area " - "in square micrometers and the source and drain perimeter in micrometers.\n" - "\n" - "The terminals are S, G, D and B for source, gate, drain and bulk.\n" - "\n" - "MOS transistors combine in parallel mode, when both gate lengths are identical and " - "their gates and bulk terminals are connected (source and drain can be swapped). In this case, their widths and source and drain " - "areas are added.\n" + "The additional terminal is 'B' for the bulk terminal.\n" + "MOS4 transistors combine in parallel if both bulk terminals are connected to the same net.\n" "\n" "This class has been introduced in version 0.26." ); diff --git a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc index 40e759fbc..e1532187d 100644 --- a/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc +++ b/src/db/db/gsiDeclDbNetlistDeviceExtractor.cc @@ -588,12 +588,12 @@ Class decl_NetlistDeviceExtractorCa "This class has been introduced in version 0.26." ); -db::NetlistDeviceExtractorBipolarTransistor *make_bjt_extractor (const std::string &name) +db::NetlistDeviceExtractorBJT3Transistor *make_bjt_extractor (const std::string &name) { - return new db::NetlistDeviceExtractorBipolarTransistor (name); + return new db::NetlistDeviceExtractorBJT3Transistor (name); } -Class decl_NetlistDeviceExtractorBipolarTransistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorBipolarTransistor", +Class decl_NetlistDeviceExtractorBJT3Transistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorBJT3Transistor", gsi::constructor ("new", &make_bjt_extractor, gsi::arg ("name"), "@brief Creates a new device extractor with the given name." ), @@ -610,7 +610,7 @@ Class decl_NetlistDeviceExtractorBi "region will be output to the 'tC' terminal output layer. This layer then needs to be connected to a global net " "to form the net connection.\n" "\n" - "The device class produced by this extractor is \\DeviceClassBipolarTransistor.\n" + "The device class produced by this extractor is \\DeviceClassBJT3Transistor.\n" "The extractor extracts the two parameters of this class: AE and PE.\n" "\n" "The device recognition layer names are 'C' (collector), 'B' (base) and 'E' (emitter).\n" diff --git a/src/db/unit_tests/dbNetlistDeviceClassesTests.cc b/src/db/unit_tests/dbNetlistDeviceClassesTests.cc index 5a97e9c71..83bf957bd 100644 --- a/src/db/unit_tests/dbNetlistDeviceClassesTests.cc +++ b/src/db/unit_tests/dbNetlistDeviceClassesTests.cc @@ -37,10 +37,14 @@ TEST(1_SerialResistors) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -70,8 +74,8 @@ TEST(1_SerialResistors) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n1,B=n2) (R=1,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -80,7 +84,7 @@ TEST(1_SerialResistors) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n1,B=n3) (R=4,A=6,P=12);\n" + " device '' r1 (A=n1,B=n3) (R=4,L=18,W=1.5,A=6,P=12);\n" "end;\n" ); } @@ -94,10 +98,14 @@ TEST(2_SerialResistors1Swapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -127,8 +135,8 @@ TEST(2_SerialResistors1Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n1,B=n2) (R=1,A=5,P=10);\n" - " device '' r2 (A=n3,B=n2) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n3,B=n2) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -137,7 +145,7 @@ TEST(2_SerialResistors1Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n1,B=n3) (R=4,A=6,P=12);\n" + " device '' r1 (A=n1,B=n3) (R=4,L=18,W=1.5,A=6,P=12);\n" "end;\n" ); } @@ -151,10 +159,14 @@ TEST(3_SerialResistors1OtherSwapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -184,8 +196,8 @@ TEST(3_SerialResistors1OtherSwapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n2,B=n1) (R=1,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3) (R=3,A=1,P=2);\n" + " device '' r1 (A=n2,B=n1) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -194,7 +206,7 @@ TEST(3_SerialResistors1OtherSwapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n3,B=n1) (R=4,A=6,P=12);\n" + " device '' r1 (A=n3,B=n1) (R=4,L=18,W=1.5,A=6,P=12);\n" "end;\n" ); } @@ -208,10 +220,14 @@ TEST(4_SerialResistors2Swapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -241,8 +257,8 @@ TEST(4_SerialResistors2Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n2,B=n1) (R=1,A=5,P=10);\n" - " device '' r2 (A=n3,B=n2) (R=3,A=1,P=2);\n" + " device '' r1 (A=n2,B=n1) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n3,B=n2) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -251,7 +267,7 @@ TEST(4_SerialResistors2Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3);\n" - " device '' r1 (A=n3,B=n1) (R=4,A=6,P=12);\n" + " device '' r1 (A=n3,B=n1) (R=4,L=18,W=1.5,A=6,P=12);\n" "end;\n" ); } @@ -265,10 +281,14 @@ TEST(5_SerialResistorsNoCombination) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -300,8 +320,8 @@ TEST(5_SerialResistorsNoCombination) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,C=n2);\n" - " device '' r1 (A=n1,B=n2) (R=1,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -310,8 +330,8 @@ TEST(5_SerialResistorsNoCombination) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,C=n2);\n" - " device '' r1 (A=n1,B=n2) (R=1,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=1,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); } @@ -325,10 +345,14 @@ TEST(6_ParallelResistors) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -355,8 +379,8 @@ TEST(6_ParallelResistors) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n1,B=n2) (R=2,A=5,P=10);\n" - " device '' r2 (A=n1,B=n2) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=2,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n1,B=n2) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -365,7 +389,7 @@ TEST(6_ParallelResistors) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n1,B=n2) (R=1.2,A=6,P=12);\n" + " device '' r1 (A=n1,B=n2) (R=1.2,L=9,W=3,A=6,P=12);\n" "end;\n" ); } @@ -379,10 +403,14 @@ TEST(7_ParallelResistors1Swapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -409,8 +437,8 @@ TEST(7_ParallelResistors1Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n2,B=n1) (R=2,A=5,P=10);\n" - " device '' r2 (A=n1,B=n2) (R=3,A=1,P=2);\n" + " device '' r1 (A=n2,B=n1) (R=2,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n1,B=n2) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -419,7 +447,7 @@ TEST(7_ParallelResistors1Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n2,B=n1) (R=1.2,A=6,P=12);\n" + " device '' r1 (A=n2,B=n1) (R=1.2,L=9,W=3,A=6,P=12);\n" "end;\n" ); } @@ -433,10 +461,14 @@ TEST(8_ParallelResistors1OtherSwapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -463,8 +495,8 @@ TEST(8_ParallelResistors1OtherSwapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n1,B=n2) (R=2,A=5,P=10);\n" - " device '' r2 (A=n2,B=n1) (R=3,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2) (R=2,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n1) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -473,7 +505,7 @@ TEST(8_ParallelResistors1OtherSwapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n1,B=n2) (R=1.2,A=6,P=12);\n" + " device '' r1 (A=n1,B=n2) (R=1.2,L=9,W=3,A=6,P=12);\n" "end;\n" ); } @@ -487,10 +519,14 @@ TEST(9_ParallelResistors2Swapped) db::Device *r1 = new db::Device (res, "r1"); r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_L, 6.0); + r1->set_parameter_value (db::DeviceClassResistor::param_id_W, 1.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); r1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); db::Device *r2 = new db::Device (res, "r2"); r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_L, 12.0); + r2->set_parameter_value (db::DeviceClassResistor::param_id_W, 2.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); r2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); @@ -517,8 +553,8 @@ TEST(9_ParallelResistors2Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n2,B=n1) (R=2,A=5,P=10);\n" - " device '' r2 (A=n2,B=n1) (R=3,A=1,P=2);\n" + " device '' r1 (A=n2,B=n1) (R=2,L=6,W=1,A=5,P=10);\n" + " device '' r2 (A=n2,B=n1) (R=3,L=12,W=2,A=1,P=2);\n" "end;\n" ); @@ -527,12 +563,12 @@ TEST(9_ParallelResistors2Swapped) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2);\n" - " device '' r1 (A=n2,B=n1) (R=1.2,A=6,P=12);\n" + " device '' r1 (A=n2,B=n1) (R=1.2,L=9,W=3,A=6,P=12);\n" "end;\n" ); } -TEST(10_ComplexRegistorCombination) +TEST(10_ComplexResistorCombination) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -600,10 +636,10 @@ TEST(10_ComplexRegistorCombination) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n4);\n" - " device '' r1 (A=n1,B=n2) (R=1,A=2,P=3);\n" - " device '' r2 (A=n2,B=n3) (R=1,A=4,P=10);\n" - " device '' r3 (A=n1,B=n3) (R=3,A=1,P=1);\n" - " device '' r4 (A=n3,B=n4) (R=0.8,A=1,P=1);\n" + " device '' r1 (A=n1,B=n2) (R=1,L=0,W=0,A=2,P=3);\n" + " device '' r2 (A=n2,B=n3) (R=1,L=0,W=0,A=4,P=10);\n" + " device '' r3 (A=n1,B=n3) (R=3,L=0,W=0,A=1,P=1);\n" + " device '' r4 (A=n3,B=n4) (R=0.8,L=0,W=0,A=1,P=1);\n" "end;\n" ); @@ -612,7 +648,7 @@ TEST(10_ComplexRegistorCombination) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n4);\n" - " device '' r4 (A=n1,B=n4) (R=2,A=8,P=15);\n" + " device '' r4 (A=n1,B=n4) (R=2,L=0,W=0,A=8,P=15);\n" "end;\n" ); } @@ -729,12 +765,12 @@ TEST(13_SerialCapacitors) db::Device *c1 = new db::Device (cap, "c1"); c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 2.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 5.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 10.0); db::Device *c2 = new db::Device (cap, "c2"); c2->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 3.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 1.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 2.0); db::Circuit *circuit = new db::Circuit (); nl.add_circuit (circuit); @@ -786,12 +822,12 @@ TEST(14_ParallelCapacitors) db::Device *c1 = new db::Device (cap, "c1"); c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 1.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 5.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 10.0); db::Device *c2 = new db::Device (cap, "c2"); c2->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 3.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 1.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 2.0); db::Circuit *circuit = new db::Circuit (); nl.add_circuit (circuit); @@ -1673,12 +1709,12 @@ TEST(35_SerialCapacitorsWithBulk) db::Device *c1 = new db::Device (cap, "c1"); c1->set_parameter_value (db::DeviceClassCapacitorWithBulk::param_id_C, 2.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 5.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 10.0); db::Device *c2 = new db::Device (cap, "c2"); c2->set_parameter_value (db::DeviceClassCapacitorWithBulk::param_id_C, 3.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 1.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 2.0); db::Circuit *circuit = new db::Circuit (); nl.add_circuit (circuit); @@ -1755,12 +1791,12 @@ TEST(36_ParallelCapacitorsWithBulk) db::Device *c1 = new db::Device (cap, "c1"); c1->set_parameter_value (db::DeviceClassCapacitorWithBulk::param_id_C, 1.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_A, 5.0); - c1->set_parameter_value (db::DeviceClassResistor::param_id_P, 10.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 5.0); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 10.0); db::Device *c2 = new db::Device (cap, "c2"); c2->set_parameter_value (db::DeviceClassCapacitorWithBulk::param_id_C, 3.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_A, 1.0); - c2->set_parameter_value (db::DeviceClassResistor::param_id_P, 2.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_A, 1.0); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_P, 2.0); db::Circuit *circuit = new db::Circuit (); nl.add_circuit (circuit); @@ -1874,8 +1910,8 @@ TEST(37_SerialResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3,W=n2) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3,W=n2) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1884,8 +1920,8 @@ TEST(37_SerialResistorsWithBulk) // no combination because bulk terminals are connected differently EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3,W=n2) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3,W=n2) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1893,8 +1929,8 @@ TEST(37_SerialResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n2,B=n3,W=nb) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n2,B=n3,W=nb) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1902,7 +1938,7 @@ TEST(37_SerialResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n3,BULK=nb);\n" - " device '' r1 (A=n1,B=n3,W=nb) (R=2.5,A=6,P=12);\n" + " device '' r1 (A=n1,B=n3,W=nb) (R=2.5,L=0,W=0,A=6,P=12);\n" "end;\n" ); } @@ -1953,8 +1989,8 @@ TEST(38_ParallelResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n1,B=n2,W=n2) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n1,B=n2,W=n2) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1963,8 +1999,8 @@ TEST(38_ParallelResistorsWithBulk) // devices are not combined as the bulk terminals are connected differently EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n1,B=n2,W=n2) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n1,B=n2,W=n2) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1972,8 +2008,8 @@ TEST(38_ParallelResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=2,A=5,P=10);\n" - " device '' r2 (A=n1,B=n2,W=nb) (R=0.5,A=1,P=2);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=2,L=0,W=0,A=5,P=10);\n" + " device '' r2 (A=n1,B=n2,W=nb) (R=0.5,L=0,W=0,A=1,P=2);\n" "end;\n" ); @@ -1981,24 +2017,32 @@ TEST(38_ParallelResistorsWithBulk) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,BULK=nb);\n" - " device '' r1 (A=n1,B=n2,W=nb) (R=0.4,A=6,P=12);\n" + " device '' r1 (A=n1,B=n2,W=nb) (R=0.4,L=0,W=0,A=6,P=12);\n" "end;\n" ); } -TEST(39_ParallelBipolarTransistors) +TEST(39_ParallelBJT3Transistors) { - db::DeviceClassBipolarTransistor *cls = new db::DeviceClassBipolarTransistor (); + db::DeviceClassBJT3Transistor *cls = new db::DeviceClassBJT3Transistor (); db::Netlist nl; nl.add_device_class (cls); db::Device *d1 = new db::Device (cls, "d1"); - d1->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_AE, 2.0); - d1->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_PE, 12.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, 2.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, 12.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, 3.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, 13.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AC, 4.0); + d1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PC, 14.0); db::Device *d2 = new db::Device (cls, "d2"); - d2->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_AE, 3.0); - d2->set_parameter_value (db::DeviceClassBipolarTransistor::param_id_PE, 13.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, 3.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, 13.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, 4.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, 14.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AC, 5.0); + d2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PC, 15.0); db::Circuit *circuit = new db::Circuit (); nl.add_circuit (circuit); @@ -2013,25 +2057,25 @@ TEST(39_ParallelBipolarTransistors) db::Net *n1 = new db::Net ("n1"); circuit->add_net (n1); circuit->connect_pin (pin_a.id (), n1); - d1->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_C, n1); - d2->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_C, n1); + d1->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_C, n1); + d2->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_C, n1); db::Net *n2 = new db::Net ("n2"); circuit->add_net (n2); circuit->connect_pin (pin_b.id (), n2); - d1->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_B, n2); - d2->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_B, n2); - d2->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_E, n2); + d1->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_B, n2); + d2->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_B, n2); + d2->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_E, n2); db::Net *n3 = new db::Net ("n3"); circuit->add_net (n3); circuit->connect_pin (pin_c.id (), n3); - d1->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_E, n3); + d1->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_E, n3); EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,C=n3);\n" - " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12);\n" - " device '' d2 (C=n1,B=n2,E=n2) (AE=3,PE=13);\n" + " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12,AB=3,PB=13,AC=4,PC=14);\n" + " device '' d2 (C=n1,B=n2,E=n2) (AE=3,PE=13,AB=4,PB=14,AC=5,PC=15);\n" "end;\n" ); @@ -2040,17 +2084,17 @@ TEST(39_ParallelBipolarTransistors) // no combination as emitters are connected differently EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,C=n3);\n" - " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12);\n" - " device '' d2 (C=n1,B=n2,E=n2) (AE=3,PE=13);\n" + " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12,AB=3,PB=13,AC=4,PC=14);\n" + " device '' d2 (C=n1,B=n2,E=n2) (AE=3,PE=13,AB=4,PB=14,AC=5,PC=15);\n" "end;\n" ); - d2->connect_terminal (db::DeviceClassBipolarTransistor::terminal_id_E, n3); + d2->connect_terminal (db::DeviceClassBJT3Transistor::terminal_id_E, n3); EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,C=n3);\n" - " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12);\n" - " device '' d2 (C=n1,B=n2,E=n3) (AE=3,PE=13);\n" + " device '' d1 (C=n1,B=n2,E=n3) (AE=2,PE=12,AB=3,PB=13,AC=4,PC=14);\n" + " device '' d2 (C=n1,B=n2,E=n3) (AE=3,PE=13,AB=4,PB=14,AC=5,PC=15);\n" "end;\n" ); @@ -2058,7 +2102,7 @@ TEST(39_ParallelBipolarTransistors) EXPECT_EQ (nl.to_string (), "circuit '' (A=n1,B=n2,C=n3);\n" - " device '' d1 (C=n1,B=n2,E=n3) (AE=5,PE=25);\n" + " device '' d1 (C=n1,B=n2,E=n3) (AE=5,PE=25,AB=7,PB=27,AC=9,PC=29);\n" "end;\n" ); } diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index 9d219670b..ef779b680 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -1355,7 +1355,7 @@ TEST(5_ResAndCapWithBulkExtraction) db::compare_layouts (_this, ly, au); } -TEST(6_BipolarTransistorExtraction) +TEST(6_BJT3TransistorExtraction) { db::Layout ly; db::LayerMap lmap; @@ -1454,7 +1454,7 @@ TEST(6_BipolarTransistorExtraction) db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS"); db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS"); - db::NetlistDeviceExtractorBipolarTransistor bjt_ex ("PNP"); + db::NetlistDeviceExtractorBJT3Transistor bjt_ex ("PNP"); db::NetlistDeviceExtractor::input_layers dl; diff --git a/src/db/unit_tests/dbNetlistReaderTests.cc b/src/db/unit_tests/dbNetlistReaderTests.cc index d48d0cf85..bfa6a5a70 100644 --- a/src/db/unit_tests/dbNetlistReaderTests.cc +++ b/src/db/unit_tests/dbNetlistReaderTests.cc @@ -40,9 +40,9 @@ TEST(1_BasicReader) EXPECT_EQ (nl.to_string (), "circuit TOP ($1='1',$2='2',$3='4',$4='7');\n" - " device RES $1 (A='6',B='1') (R=7650,A=0,P=0);\n" - " device RES $2 (A='3',B='1') (R=7650,A=0,P=0);\n" - " device RES $3 (A='3',B='2') (R=2670,A=0,P=0);\n" + " device RES $1 (A='6',B='1') (R=7650,L=0,W=0,A=0,P=0);\n" + " device RES $2 (A='3',B='1') (R=7650,L=0,W=0,A=0,P=0);\n" + " device RES $3 (A='3',B='2') (R=2670,L=0,W=0,A=0,P=0);\n" " device MHVPMOS $4 (S='6',G='4',D='7',B='7') (L=0.25,W=1.5,AS=0.63,AD=0.63,PS=3.84,PD=3.84);\n" "end;\n" ); @@ -177,4 +177,3 @@ TEST(5_CircuitParameters) "end;\n" ); } - diff --git a/src/db/unit_tests/dbNetlistWriterTests.cc b/src/db/unit_tests/dbNetlistWriterTests.cc index 7c2cad26a..4420117aa 100644 --- a/src/db/unit_tests/dbNetlistWriterTests.cc +++ b/src/db/unit_tests/dbNetlistWriterTests.cc @@ -1057,6 +1057,192 @@ TEST(12_UniqueNetNames) compare_netlists (_this, path, au_path); } +TEST(13_WriterBJT3Devices) +{ + db::Netlist nl; + + db::DeviceClass *rcls = new db::DeviceClassResistor (); + db::DeviceClass *ccls = new db::DeviceClassCapacitor (); + db::DeviceClass *lcls = new db::DeviceClassInductor (); + db::DeviceClass *dcls = new db::DeviceClassDiode (); + db::DeviceClass *b3cls = new db::DeviceClassBJT3Transistor (); + db::DeviceClass *b4cls = new db::DeviceClassBJT4Transistor (); + + rcls->set_name ("RCLS"); + lcls->set_name ("LCLS"); + ccls->set_name ("CCLS"); + dcls->set_name ("DCLS"); + b3cls->set_name ("B3CLS"); + b4cls->set_name ("B4CLS"); + + nl.add_device_class (rcls); + nl.add_device_class (lcls); + nl.add_device_class (ccls); + nl.add_device_class (dcls); + nl.add_device_class (b3cls); + nl.add_device_class (b4cls); + + db::Circuit *circuit1 = new db::Circuit (); + circuit1->set_name ("C1"); + nl.add_circuit (circuit1); + + db::Net *n1, *n2, *n3, *n4; + n1 = new db::Net (); + n1->set_name ("n1"); + circuit1->add_net (n1); + n2 = new db::Net (); + n2->set_name ("n2"); + circuit1->add_net (n2); + n3 = new db::Net (); + n3->set_name ("n3"); + circuit1->add_net (n3); + n4 = new db::Net (); + n4->set_name ("n4"); + circuit1->add_net (n4); + + db::Device *ddev1 = new db::Device (b3cls); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, 0.25); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, 0.18); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, 1.2); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, 0.75); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AC, 1.0); + ddev1->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PC, 0.6); + db::Device *ddev2 = new db::Device (b3cls); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AE, 1.2); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PE, 2.5); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AB, 1.4); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PB, 2.8); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_AC, 1.5); + ddev2->set_parameter_value (db::DeviceClassBJT3Transistor::param_id_PC, 3.0); + circuit1->add_device (ddev1); + circuit1->add_device (ddev2); + + size_t pid1 = circuit1->add_pin ("p1").id (); + size_t pid2 = circuit1->add_pin ("p2").id (); + size_t pid3 = circuit1->add_pin ("p3").id (); + + circuit1->connect_pin (pid1, n1); + circuit1->connect_pin (pid2, n2); + circuit1->connect_pin (pid3, n4); + + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("E"), n1); + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("B"), n4); + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("C"), n3); + ddev2->connect_terminal (ddev2->device_class ()->terminal_id_for_name ("E"), n3); + ddev2->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("B"), n4); + ddev2->connect_terminal (ddev2->device_class ()->terminal_id_for_name ("C"), n2); + + // verify against the input + + std::string path = tmp_file ("tmp_nwriter13.txt"); + { + tl::OutputStream stream (path); + db::NetlistSpiceWriter writer; + writer.write (stream, nl, "written by unit test"); + } + + std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nwriter13_au.txt"); + + compare_netlists (_this, path, au_path); +} + +TEST(14_WriterBJT4Devices) +{ + db::Netlist nl; + + db::DeviceClass *rcls = new db::DeviceClassResistor (); + db::DeviceClass *ccls = new db::DeviceClassCapacitor (); + db::DeviceClass *lcls = new db::DeviceClassInductor (); + db::DeviceClass *dcls = new db::DeviceClassDiode (); + db::DeviceClass *b3cls = new db::DeviceClassBJT3Transistor (); + db::DeviceClass *b4cls = new db::DeviceClassBJT4Transistor (); + + rcls->set_name ("RCLS"); + lcls->set_name ("LCLS"); + ccls->set_name ("CCLS"); + dcls->set_name ("DCLS"); + b3cls->set_name ("B3CLS"); + b4cls->set_name ("B4CLS"); + + nl.add_device_class (rcls); + nl.add_device_class (lcls); + nl.add_device_class (ccls); + nl.add_device_class (dcls); + nl.add_device_class (b3cls); + nl.add_device_class (b4cls); + + db::Circuit *circuit1 = new db::Circuit (); + circuit1->set_name ("C1"); + nl.add_circuit (circuit1); + + db::Net *n1, *n2, *n3, *n4, *n5; + n1 = new db::Net (); + n1->set_name ("n1"); + circuit1->add_net (n1); + n2 = new db::Net (); + n2->set_name ("n2"); + circuit1->add_net (n2); + n3 = new db::Net (); + n3->set_name ("n3"); + circuit1->add_net (n3); + n4 = new db::Net (); + n4->set_name ("n4"); + circuit1->add_net (n4); + n5 = new db::Net (); + n5->set_name ("n5"); + circuit1->add_net (n5); + + db::Device *ddev1 = new db::Device (b4cls); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AE, 0.25); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PE, 0.18); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AB, 1.2); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PB, 0.75); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AC, 1.0); + ddev1->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PC, 0.6); + db::Device *ddev2 = new db::Device (b4cls); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AE, 1.2); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PE, 2.5); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AB, 1.4); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PB, 2.8); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_AC, 1.5); + ddev2->set_parameter_value (db::DeviceClassBJT4Transistor::param_id_PC, 3.0); + circuit1->add_device (ddev1); + circuit1->add_device (ddev2); + + size_t pid1 = circuit1->add_pin ("p1").id (); + size_t pid2 = circuit1->add_pin ("p2").id (); + size_t pid3 = circuit1->add_pin ("p3").id (); + size_t pid4 = circuit1->add_pin ("p4").id (); + + circuit1->connect_pin (pid1, n1); + circuit1->connect_pin (pid2, n2); + circuit1->connect_pin (pid3, n4); + circuit1->connect_pin (pid4, n5); + + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("E"), n1); + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("B"), n4); + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("C"), n3); + ddev1->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("S"), n5); + ddev2->connect_terminal (ddev2->device_class ()->terminal_id_for_name ("E"), n3); + ddev2->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("B"), n4); + ddev2->connect_terminal (ddev2->device_class ()->terminal_id_for_name ("C"), n2); + ddev2->connect_terminal (ddev1->device_class ()->terminal_id_for_name ("S"), n5); + + // verify against the input + + std::string path = tmp_file ("tmp_nwriter14.txt"); + { + tl::OutputStream stream (path); + db::NetlistSpiceWriter writer; + writer.write (stream, nl, "written by unit test"); + } + + std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nwriter14_au.txt"); + + compare_netlists (_this, path, au_path); +} + + namespace { class MyDelegate diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.cc b/src/laybasic/laybasic/layNetlistBrowserModel.cc index acf94560f..6672f0700 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserModel.cc @@ -1532,7 +1532,7 @@ static QIcon icon_for_device (const db::DeviceClass *dc) icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_diode_32.png"))); icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_diode_24.png"))); icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_diode_16.png"))); - } else if (dynamic_cast (dc)) { + } else if (dynamic_cast (dc)) { icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_bjt_48.png"))); icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_bjt_32.png"))); icon.addPixmap (QPixmap (QString::fromUtf8 (":/images/icon_device_bjt_24.png"))); diff --git a/testdata/algo/nwriter4_au.txt b/testdata/algo/nwriter4_au.txt index 6048bee16..181fefac7 100644 --- a/testdata/algo/nwriter4_au.txt +++ b/testdata/algo/nwriter4_au.txt @@ -8,7 +8,7 @@ * net 2 n2 * net 3 n3 * device instance $1 r0 *1 0,0 DCLS -D$1 1 3 DDCLS +D$1 1 3 DCLS A=1.7e-10P P=0P * device instance $2 r0 *1 0,0 DCLS -D$2 3 2 DDCLS +D$2 3 2 DCLS A=4.2e-08P P=0P .ENDS C1