From 44b5b2742e86e75b4f388d2111305deef802033c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 29 Dec 2018 22:58:29 +0100 Subject: [PATCH] WIP: tests for specialized device classes and device combination --- src/db/db/dbNetlistDeviceClasses.cc | 36 +- src/db/db/dbNetlistDeviceClasses.h | 34 + .../unit_tests/dbNetlistDeviceClassesTests.cc | 983 +++++++++++++++++- src/db/unit_tests/dbNetlistExtractorTests.cc | 10 +- 4 files changed, 1048 insertions(+), 15 deletions(-) diff --git a/src/db/db/dbNetlistDeviceClasses.cc b/src/db/db/dbNetlistDeviceClasses.cc index 29213cd8a..11f125a71 100644 --- a/src/db/db/dbNetlistDeviceClasses.cc +++ b/src/db/db/dbNetlistDeviceClasses.cc @@ -98,6 +98,11 @@ void DeviceClassResistor::serial (Device *a, Device *b) const // ------------------------------------------------------------------------------------ // DeviceClassCapacitor implementation +DB_PUBLIC size_t DeviceClassCapacitor::param_id_C = 0; + +DB_PUBLIC size_t DeviceClassCapacitor::terminal_id_A = 0; +DB_PUBLIC size_t DeviceClassCapacitor::terminal_id_B = 1; + DeviceClassCapacitor::DeviceClassCapacitor () { add_terminal_definition (db::DeviceTerminalDefinition ("A", "Terminal A")); @@ -123,6 +128,11 @@ void DeviceClassCapacitor::parallel (Device *a, Device *b) const // ------------------------------------------------------------------------------------ // DeviceClassInductor implementation +DB_PUBLIC size_t DeviceClassInductor::param_id_L = 0; + +DB_PUBLIC size_t DeviceClassInductor::terminal_id_A = 0; +DB_PUBLIC size_t DeviceClassInductor::terminal_id_B = 1; + DeviceClassInductor::DeviceClassInductor () { add_terminal_definition (db::DeviceTerminalDefinition ("A", "Terminal A")); @@ -148,6 +158,11 @@ void DeviceClassInductor::serial (Device *a, Device *b) const // ------------------------------------------------------------------------------------ // DeviceClassInductor implementation +DB_PUBLIC size_t DeviceClassDiode::param_id_A = 0; + +DB_PUBLIC size_t DeviceClassDiode::terminal_id_A = 0; +DB_PUBLIC size_t DeviceClassDiode::terminal_id_C = 1; + DeviceClassDiode::DeviceClassDiode () { add_terminal_definition (db::DeviceTerminalDefinition ("A", "Anode")); @@ -164,7 +179,7 @@ bool DeviceClassDiode::combine_devices (Device *a, Device *b) const const db::Net *nb2 = b->net_for_terminal (1); // only parallel diodes can be combined and their areas will add - if ((na1 == nb1 && na2 == nb2) || (na1 == nb2 && na2 == nb1)) { + if (na1 == nb1 && na2 == nb2) { a->set_parameter_value (0, a->parameter_value (0) + b->parameter_value (0)); b->connect_terminal (0, 0); @@ -180,6 +195,15 @@ bool DeviceClassDiode::combine_devices (Device *a, Device *b) const // ------------------------------------------------------------------------------------ // DeviceClassMOS3Transistor implementation +DB_PUBLIC size_t DeviceClassMOS3Transistor::param_id_L = 0; +DB_PUBLIC size_t DeviceClassMOS3Transistor::param_id_W = 1; +DB_PUBLIC size_t DeviceClassMOS3Transistor::param_id_AS = 2; +DB_PUBLIC size_t DeviceClassMOS3Transistor::param_id_AD = 3; + +DB_PUBLIC size_t DeviceClassMOS3Transistor::terminal_id_S = 0; +DB_PUBLIC size_t DeviceClassMOS3Transistor::terminal_id_G = 1; +DB_PUBLIC size_t DeviceClassMOS3Transistor::terminal_id_D = 2; + DeviceClassMOS3Transistor::DeviceClassMOS3Transistor () { add_terminal_definition (db::DeviceTerminalDefinition ("S", "Source")); @@ -226,6 +250,16 @@ bool DeviceClassMOS3Transistor::combine_devices (Device *a, Device *b) const // ------------------------------------------------------------------------------------ // DeviceClassMOS4Transistor implementation +DB_PUBLIC size_t DeviceClassMOS4Transistor::param_id_L = 0; +DB_PUBLIC size_t DeviceClassMOS4Transistor::param_id_W = 1; +DB_PUBLIC size_t DeviceClassMOS4Transistor::param_id_AS = 2; +DB_PUBLIC size_t DeviceClassMOS4Transistor::param_id_AD = 3; + +DB_PUBLIC size_t DeviceClassMOS4Transistor::terminal_id_S = 0; +DB_PUBLIC size_t DeviceClassMOS4Transistor::terminal_id_G = 1; +DB_PUBLIC size_t DeviceClassMOS4Transistor::terminal_id_D = 2; +DB_PUBLIC size_t DeviceClassMOS4Transistor::terminal_id_B = 3; + DeviceClassMOS4Transistor::DeviceClassMOS4Transistor () { add_terminal_definition (db::DeviceTerminalDefinition ("S", "Source")); diff --git a/src/db/db/dbNetlistDeviceClasses.h b/src/db/db/dbNetlistDeviceClasses.h index b40b1a985..dccc580d9 100644 --- a/src/db/db/dbNetlistDeviceClasses.h +++ b/src/db/db/dbNetlistDeviceClasses.h @@ -85,6 +85,11 @@ public: return new DeviceClassCapacitor (*this); } + static size_t param_id_C; + + static size_t terminal_id_A; + static size_t terminal_id_B; + virtual void parallel (Device *a, Device *b) const; virtual void serial (Device *a, Device *b) const; }; @@ -105,6 +110,11 @@ public: return new DeviceClassInductor (*this); } + static size_t param_id_L; + + static size_t terminal_id_A; + static size_t terminal_id_B; + virtual void parallel (Device *a, Device *b) const; virtual void serial (Device *a, Device *b) const; }; @@ -121,6 +131,11 @@ class DB_PUBLIC DeviceClassDiode public: DeviceClassDiode (); + static size_t param_id_A; + + static size_t terminal_id_A; + static size_t terminal_id_C; + virtual db::DeviceClass *clone () const { return new DeviceClassDiode (*this); @@ -142,6 +157,15 @@ class DB_PUBLIC DeviceClassMOS3Transistor public: DeviceClassMOS3Transistor (); + static size_t param_id_L; + static size_t param_id_W; + static size_t param_id_AS; + static size_t param_id_AD; + + static size_t terminal_id_S; + static size_t terminal_id_G; + static size_t terminal_id_D; + virtual db::DeviceClass *clone () const { return new DeviceClassMOS3Transistor (*this); @@ -162,6 +186,16 @@ class DB_PUBLIC DeviceClassMOS4Transistor public: DeviceClassMOS4Transistor (); + static size_t param_id_L; + static size_t param_id_W; + static size_t param_id_AS; + static size_t param_id_AD; + + static size_t terminal_id_S; + static size_t terminal_id_G; + static size_t terminal_id_D; + static size_t terminal_id_B; + virtual db::DeviceClass *clone () const { return new DeviceClassMOS4Transistor (*this); diff --git a/src/db/unit_tests/dbNetlistDeviceClassesTests.cc b/src/db/unit_tests/dbNetlistDeviceClassesTests.cc index 9670944b8..2864e8cfe 100644 --- a/src/db/unit_tests/dbNetlistDeviceClassesTests.cc +++ b/src/db/unit_tests/dbNetlistDeviceClassesTests.cc @@ -79,7 +79,7 @@ TEST(1_SerialResistors) ); }; -TEST(1_SerialResistors1Swapped) +TEST(2_SerialResistors1Swapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -130,7 +130,7 @@ TEST(1_SerialResistors1Swapped) ); }; -TEST(1_SerialResistors1OtherSwapped) +TEST(3_SerialResistors1OtherSwapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -181,7 +181,7 @@ TEST(1_SerialResistors1OtherSwapped) ); }; -TEST(1_SerialResistors2Swapped) +TEST(4_SerialResistors2Swapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -232,7 +232,7 @@ TEST(1_SerialResistors2Swapped) ); }; -TEST(1_SerialResistorsNoCombination) +TEST(5_SerialResistorsNoCombination) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -286,7 +286,7 @@ TEST(1_SerialResistorsNoCombination) ); }; -TEST(1_ParallelResistors) +TEST(6_ParallelResistors) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -334,7 +334,7 @@ TEST(1_ParallelResistors) ); }; -TEST(1_ParallelResistors1Swapped) +TEST(7_ParallelResistors1Swapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -382,7 +382,7 @@ TEST(1_ParallelResistors1Swapped) ); }; -TEST(1_ParallelResistors1OtherSwapped) +TEST(8_ParallelResistors1OtherSwapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -430,7 +430,7 @@ TEST(1_ParallelResistors1OtherSwapped) ); }; -TEST(1_ParallelResistors2Swapped) +TEST(9_ParallelResistors2Swapped) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -478,7 +478,7 @@ TEST(1_ParallelResistors2Swapped) ); }; -TEST(1_ComplexRegistorCombination) +TEST(10_ComplexRegistorCombination) { db::DeviceClassResistor *res = new db::DeviceClassResistor (); @@ -553,3 +553,968 @@ TEST(1_ComplexRegistorCombination) ); }; +TEST(11_SerialInductors) +{ + db::DeviceClassInductor *ind = new db::DeviceClassInductor (); + + db::Netlist nl; + nl.add_device_class (ind); + + db::Device *l1 = new db::Device (ind, "l1"); + l1->set_parameter_value (db::DeviceClassInductor::param_id_L, 1.0); + db::Device *l2 = new db::Device (ind, "l2"); + l2->set_parameter_value (db::DeviceClassInductor::param_id_L, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (l1); + circuit->add_device (l2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + l1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + l1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2); + l2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + l2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n3); + circuit->connect_pin (pin_b.id (), n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D l1 (A=n1,B=n2) [L=1]\n" + " D l2 (A=n2,B=n3) [L=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D l1 (A=n1,B=n3) [L=4]\n" + ); +}; + +TEST(12_ParallelInductors) +{ + db::DeviceClassInductor *ind = new db::DeviceClassInductor (); + + db::Netlist nl; + nl.add_device_class (ind); + + db::Device *l1 = new db::Device (ind, "l1"); + l1->set_parameter_value (db::DeviceClassInductor::param_id_L, 2.0); + db::Device *l2 = new db::Device (ind, "l2"); + l2->set_parameter_value (db::DeviceClassInductor::param_id_L, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (l1); + circuit->add_device (l2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + l1->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1); + l2->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + l1->connect_terminal (db::DeviceClassInductor::terminal_id_B, n2); + l2->connect_terminal (db::DeviceClassInductor::terminal_id_B, n2); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D l1 (A=n1,B=n2) [L=2]\n" + " D l2 (A=n1,B=n2) [L=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D l1 (A=n1,B=n2) [L=1.2]\n" + ); +}; + +TEST(13_SerialCapacitors) +{ + db::DeviceClassCapacitor *cap = new db::DeviceClassCapacitor (); + + db::Netlist nl; + nl.add_device_class (cap); + + db::Device *c1 = new db::Device (cap, "c1"); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 2.0); + db::Device *c2 = new db::Device (cap, "c2"); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (c1); + circuit->add_device (c2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n2); + c2->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + c2->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n3); + circuit->connect_pin (pin_b.id (), n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D c1 (A=n1,B=n2) [C=2]\n" + " D c2 (A=n2,B=n3) [C=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D c1 (A=n1,B=n3) [C=1.2]\n" + ); +}; + +TEST(14_ParallelCapacitors) +{ + db::DeviceClassCapacitor *cap = new db::DeviceClassCapacitor (); + + db::Netlist nl; + nl.add_device_class (cap); + + db::Device *c1 = new db::Device (cap, "c1"); + c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 1.0); + db::Device *c2 = new db::Device (cap, "c2"); + c2->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (c1); + circuit->add_device (c2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n1); + c2->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n2); + c2->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n2); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D c1 (A=n1,B=n2) [C=1]\n" + " D c2 (A=n1,B=n2) [C=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D c1 (A=n1,B=n2) [C=4]\n" + ); +}; + +TEST(15_SerialDiodes) +{ + db::DeviceClassDiode *diode = new db::DeviceClassDiode (); + + db::Netlist nl; + nl.add_device_class (diode); + + db::Device *d1 = new db::Device (diode, "d1"); + d1->set_parameter_value (db::DeviceClassDiode::param_id_A, 2.0); + db::Device *d2 = new db::Device (diode, "d2"); + d2->set_parameter_value (db::DeviceClassDiode::param_id_A, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassDiode::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + d1->connect_terminal (db::DeviceClassDiode::terminal_id_C, n2); + d2->connect_terminal (db::DeviceClassDiode::terminal_id_A, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + d2->connect_terminal (db::DeviceClassDiode::terminal_id_C, n3); + circuit->connect_pin (pin_b.id (), n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D d1 (A=n1,C=n2) [A=2]\n" + " D d2 (A=n2,C=n3) [A=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // serial diodes are not combined! + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n3):\n" + " D d1 (A=n1,C=n2) [A=2]\n" + " D d2 (A=n2,C=n3) [A=3]\n" + ); +}; + +TEST(16_ParallelDiodes) +{ + db::DeviceClassDiode *diode = new db::DeviceClassDiode (); + + db::Netlist nl; + nl.add_device_class (diode); + + db::Device *d1 = new db::Device (diode, "d1"); + d1->set_parameter_value (db::DeviceClassDiode::param_id_A, 1.0); + db::Device *d2 = new db::Device (diode, "d2"); + d2->set_parameter_value (db::DeviceClassDiode::param_id_A, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassDiode::terminal_id_A, n1); + d2->connect_terminal (db::DeviceClassDiode::terminal_id_A, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassDiode::terminal_id_C, n2); + d2->connect_terminal (db::DeviceClassDiode::terminal_id_C, n2); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D d1 (A=n1,C=n2) [A=1]\n" + " D d2 (A=n1,C=n2) [A=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D d1 (A=n1,C=n2) [A=4]\n" + ); +}; + +TEST(17_AntiParallelDiodes) +{ + db::DeviceClassDiode *diode = new db::DeviceClassDiode (); + + db::Netlist nl; + nl.add_device_class (diode); + + db::Device *d1 = new db::Device (diode, "d1"); + d1->set_parameter_value (db::DeviceClassDiode::param_id_A, 1.0); + db::Device *d2 = new db::Device (diode, "d2"); + d2->set_parameter_value (db::DeviceClassDiode::param_id_A, 3.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassDiode::terminal_id_A, n1); + d2->connect_terminal (db::DeviceClassDiode::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::DeviceClassDiode::terminal_id_C, n2); + d2->connect_terminal (db::DeviceClassDiode::terminal_id_A, n2); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D d1 (A=n1,C=n2) [A=1]\n" + " D d2 (A=n2,C=n1) [A=3]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // anti-parallel diodes are not combined + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2):\n" + " D d1 (A=n1,C=n2) [A=1]\n" + " D d2 (A=n2,C=n1) [A=3]\n" + ); +}; + +TEST(20_ParallelMOS3Transistors) +{ + db::DeviceClassMOS3Transistor *cls = new db::DeviceClassMOS3Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=3,AS=5,AD=7]\n" + ); +}; + +TEST(21_AntiParallelMOS3Transistors) +{ + db::DeviceClassMOS3Transistor *cls = new db::DeviceClassMOS3Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n2,G=n3,D=n1) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=3,AS=5,AD=7]\n" + ); +}; + +TEST(22_ParallelMOS3TransistorsDisconnectedGates) +{ + db::DeviceClassMOS3Transistor *cls = new db::DeviceClassMOS3Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c1 = circuit->add_pin (db::Pin ("C1")); + db::Pin pin_c2 = circuit->add_pin (db::Pin ("C2")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c1.id (), n3); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + + db::Net *n4 = new db::Net ("n4"); + circuit->add_net (n4); + circuit->connect_pin (pin_c2.id (), n4); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n4); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C1=n3,C2=n4):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n4,D=n2) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // because of the disconnected gates, devices will no be joined: + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C1=n3,C2=n4):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n4,D=n2) [L=0.5,W=2,AS=3,AD=4]\n" + ); +}; + +TEST(23_ParallelMOS3TransistorsDifferentLength) +{ + db::DeviceClassMOS3Transistor *cls = new db::DeviceClassMOS3Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, 0.75); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS3Transistor::terminal_id_G, n3); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2) [L=0.75,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // because of different length, the devices will not be combined: + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3):\n" + " D d1 (S=n1,G=n3,D=n2) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2) [L=0.75,W=2,AS=3,AD=4]\n" + ); +}; + +TEST(30_ParallelMOS4Transistors) +{ + db::DeviceClassMOS4Transistor *cls = new db::DeviceClassMOS4Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + db::Pin pin_d = circuit->add_pin (db::Pin ("D")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + + db::Net *n0 = new db::Net ("n0"); + circuit->add_net (n0); + circuit->connect_pin (pin_d.id (), n0); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=3,AS=5,AD=7]\n" + ); +}; + +TEST(31_AntiParallelMOS4Transistors) +{ + db::DeviceClassMOS4Transistor *cls = new db::DeviceClassMOS4Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + db::Pin pin_d = circuit->add_pin (db::Pin ("D")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + + db::Net *n0 = new db::Net ("n0"); + circuit->add_net (n0); + circuit->connect_pin (pin_d.id (), n0); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n2,G=n3,D=n1,B=n0) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=3,AS=5,AD=7]\n" + ); +}; + +TEST(32_ParallelMOS4TransistorsDisconnectedGates) +{ + db::DeviceClassMOS4Transistor *cls = new db::DeviceClassMOS4Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c1 = circuit->add_pin (db::Pin ("C1")); + db::Pin pin_c2 = circuit->add_pin (db::Pin ("C2")); + db::Pin pin_d = circuit->add_pin (db::Pin ("D")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + + db::Net *n3a = new db::Net ("n3a"); + circuit->add_net (n3a); + circuit->connect_pin (pin_c1.id (), n3a); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3a); + + db::Net *n3b = new db::Net ("n3b"); + circuit->add_net (n3b); + circuit->connect_pin (pin_c2.id (), n3b); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3b); + + db::Net *n0 = new db::Net ("n0"); + circuit->add_net (n0); + circuit->connect_pin (pin_d.id (), n0); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C1=n3a,C2=n3b,D=n0):\n" + " D d1 (S=n1,G=n3a,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3b,D=n2,B=n0) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // not combined because gate is different: + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C1=n3a,C2=n3b,D=n0):\n" + " D d1 (S=n1,G=n3a,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3b,D=n2,B=n0) [L=0.5,W=2,AS=3,AD=4]\n" + ); +}; + +TEST(33_ParallelMOS4TransistorsDisconnectedBulk) +{ + db::DeviceClassMOS4Transistor *cls = new db::DeviceClassMOS4Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + db::Pin pin_d1 = circuit->add_pin (db::Pin ("D1")); + db::Pin pin_d2 = circuit->add_pin (db::Pin ("D2")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + + db::Net *n0a = new db::Net ("n0a"); + circuit->add_net (n0a); + circuit->connect_pin (pin_d1.id (), n0a); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0a); + + db::Net *n0b = new db::Net ("n0b"); + circuit->add_net (n0b); + circuit->connect_pin (pin_d2.id (), n0b); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0b); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D1=n0a,D2=n0b):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0a) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2,B=n0b) [L=0.5,W=2,AS=3,AD=4]\n" + ); + + // not combined because bulk is different: + + nl.combine_devices (); + nl.purge (); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D1=n0a,D2=n0b):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0a) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2,B=n0b) [L=0.5,W=2,AS=3,AD=4]\n" + ); +}; + +TEST(34_ParallelMOS4TransistorsDifferentLength) +{ + db::DeviceClassMOS4Transistor *cls = new db::DeviceClassMOS4Transistor (); + + db::Netlist nl; + nl.add_device_class (cls); + + db::Device *d1 = new db::Device (cls, "d1"); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.5); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 1.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 2.0); + d1->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 3.0); + db::Device *d2 = new db::Device (cls, "d2"); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_L, 0.75); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_W, 2.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AS, 3.0); + d2->set_parameter_value (db::DeviceClassMOS4Transistor::param_id_AD, 4.0); + + db::Circuit *circuit = new db::Circuit (); + nl.add_circuit (circuit); + + db::Pin pin_a = circuit->add_pin (db::Pin ("A")); + db::Pin pin_b = circuit->add_pin (db::Pin ("B")); + db::Pin pin_c = circuit->add_pin (db::Pin ("C")); + db::Pin pin_d = circuit->add_pin (db::Pin ("D")); + + circuit->add_device (d1); + circuit->add_device (d2); + + db::Net *n1 = new db::Net ("n1"); + circuit->add_net (n1); + circuit->connect_pin (pin_a.id (), n1); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_S, n1); + + db::Net *n2 = new db::Net ("n2"); + circuit->add_net (n2); + circuit->connect_pin (pin_b.id (), n2); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_D, n2); + + db::Net *n3 = new db::Net ("n3"); + circuit->add_net (n3); + circuit->connect_pin (pin_c.id (), n3); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_G, n3); + + db::Net *n0 = new db::Net ("n0"); + circuit->add_net (n0); + circuit->connect_pin (pin_d.id (), n0); + d1->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + d2->connect_terminal (db::DeviceClassMOS4Transistor::terminal_id_B, n0); + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2,B=n0) [L=0.75,W=2,AS=3,AD=4]\n" + ); + + nl.combine_devices (); + nl.purge (); + + // not combined because length is different: + + EXPECT_EQ (nl.to_string (), + "Circuit (A=n1,B=n2,C=n3,D=n0):\n" + " D d1 (S=n1,G=n3,D=n2,B=n0) [L=0.5,W=1,AS=2,AD=3]\n" + " D d2 (S=n1,G=n3,D=n2,B=n0) [L=0.75,W=2,AS=3,AD=4]\n" + ); +}; + diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index 52dd66406..3ee586167 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -133,8 +133,8 @@ public: db::Device *device = create_device (); - device->set_parameter_value ("W", dbu () * edges.length () * 0.5); - device->set_parameter_value ("L", dbu () * (p->perimeter () - edges.length ()) * 0.5); + device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_W, dbu () * edges.length () * 0.5); + device->set_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, dbu () * (p->perimeter () - edges.length ()) * 0.5); int diff_index = 0; for (db::Region::const_iterator d = rdiff2gate.begin (); !d.at_end () && diff_index < 2; ++d, ++diff_index) { @@ -144,13 +144,13 @@ public: int n = rgates.selected_interacting (db::Region (*d)).size (); tl_assert (n > 0); - device->set_parameter_value (diff_index == 0 ? "AS" : "AD", dbu () * dbu () * d->area () / double (n)); + device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, dbu () * dbu () * d->area () / double (n)); - define_terminal (device, device->device_class ()->terminal_id_for_name (diff_index == 0 ? "S" : "D"), terminal_geometry_index, *d); + define_terminal (device, diff_index == 0 ? db::DeviceClassMOS3Transistor::terminal_id_S : db::DeviceClassMOS3Transistor::terminal_id_D, terminal_geometry_index, *d); } - define_terminal (device, device->device_class ()->terminal_id_for_name ("G"), gate_geometry_index, *p); + define_terminal (device, db::DeviceClassMOS3Transistor::terminal_id_G, gate_geometry_index, *p); // output the device for debugging device_out (device, rdiff2gate, rgate);