mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-05 09:02:53 +02:00
WIP: to_string for netlist, tests, some bugfixes on device combination.
This commit is contained in:
@@ -0,0 +1,555 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbNetlistDeviceClasses.h"
|
||||
#include "dbNetlist.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
TEST(1_SerialResistors)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->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 r1 (A=n1,B=n2) [R=1]\n"
|
||||
" D r2 (A=n2,B=n3) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n1,B=n3) [R=4]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_SerialResistors1Swapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n3);
|
||||
circuit->connect_pin (pin_b.id (), n3);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1]\n"
|
||||
" D r2 (A=n3,B=n2) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n1,B=n3) [R=4]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_SerialResistors1OtherSwapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->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 r1 (A=n2,B=n1) [R=1]\n"
|
||||
" D r2 (A=n2,B=n3) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n3,B=n1) [R=4]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_SerialResistors2Swapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n3);
|
||||
circuit->connect_pin (pin_b.id (), n3);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n2,B=n1) [R=1]\n"
|
||||
" D r2 (A=n3,B=n2) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3):\n"
|
||||
" D r1 (A=n3,B=n1) [R=4]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_SerialResistorsNoCombination)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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"));
|
||||
db::Pin pin_c = circuit->add_pin (db::Pin ("C"));
|
||||
|
||||
circuit->add_device (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
circuit->connect_pin (pin_c.id (), n2); // prevents combination
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->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,C=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1]\n"
|
||||
" D r2 (A=n2,B=n3) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n3,C=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1]\n"
|
||||
" D r2 (A=n2,B=n3) [R=3]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_ParallelResistors)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
circuit->connect_pin (pin_b.id (), n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=2]\n"
|
||||
" D r2 (A=n1,B=n2) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1.2]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_ParallelResistors1Swapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
circuit->connect_pin (pin_b.id (), n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n2,B=n1) [R=2]\n"
|
||||
" D r2 (A=n1,B=n2) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n2,B=n1) [R=1.2]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_ParallelResistors1OtherSwapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
circuit->connect_pin (pin_b.id (), n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=2]\n"
|
||||
" D r2 (A=n2,B=n1) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1.2]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_ParallelResistors2Swapped)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 2.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 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 (r1);
|
||||
circuit->add_device (r2);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
circuit->connect_pin (pin_b.id (), n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n2,B=n1) [R=2]\n"
|
||||
" D r2 (A=n2,B=n1) [R=3]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n2):\n"
|
||||
" D r1 (A=n2,B=n1) [R=1.2]\n"
|
||||
);
|
||||
};
|
||||
|
||||
TEST(1_ComplexRegistorCombination)
|
||||
{
|
||||
db::DeviceClassResistor *res = new db::DeviceClassResistor ();
|
||||
|
||||
db::Netlist nl;
|
||||
nl.add_device_class (res);
|
||||
|
||||
/**
|
||||
* (n2)
|
||||
* +--[ r1=1.0 ]--+--[ r2=1.0 ]--+
|
||||
* | |
|
||||
* <a> --x (n1) (n3) x--[ r4=0.8 ]--+-- <b>
|
||||
* | | (n4)
|
||||
* +----------[ r3=3.0 ]---------+
|
||||
*/
|
||||
|
||||
db::Device *r1 = new db::Device (res, "r1");
|
||||
r1->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r2 = new db::Device (res, "r2");
|
||||
r2->set_parameter_value (db::DeviceClassResistor::param_id_R, 1.0);
|
||||
db::Device *r3 = new db::Device (res, "r3");
|
||||
r3->set_parameter_value (db::DeviceClassResistor::param_id_R, 3.0);
|
||||
db::Device *r4 = new db::Device (res, "r4");
|
||||
r4->set_parameter_value (db::DeviceClassResistor::param_id_R, 0.8);
|
||||
|
||||
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 (r1);
|
||||
circuit->add_device (r2);
|
||||
circuit->add_device (r3);
|
||||
circuit->add_device (r4);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
circuit->connect_pin (pin_a.id (), n1);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
r3->connect_terminal (db::DeviceClassResistor::terminal_id_A, n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
r1->connect_terminal (db::DeviceClassResistor::terminal_id_B, n2);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_A, n2);
|
||||
|
||||
db::Net *n3 = new db::Net ("n3");
|
||||
circuit->add_net (n3);
|
||||
r2->connect_terminal (db::DeviceClassResistor::terminal_id_B, n3);
|
||||
r3->connect_terminal (db::DeviceClassResistor::terminal_id_B, n3);
|
||||
r4->connect_terminal (db::DeviceClassResistor::terminal_id_A, n3);
|
||||
|
||||
db::Net *n4 = new db::Net ("n4");
|
||||
circuit->add_net (n4);
|
||||
circuit->connect_pin (pin_b.id (), n4);
|
||||
r4->connect_terminal (db::DeviceClassResistor::terminal_id_B, n4);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n4):\n"
|
||||
" D r1 (A=n1,B=n2) [R=1]\n"
|
||||
" D r2 (A=n2,B=n3) [R=1]\n"
|
||||
" D r3 (A=n1,B=n3) [R=3]\n"
|
||||
" D r4 (A=n3,B=n4) [R=0.8]\n"
|
||||
);
|
||||
|
||||
nl.combine_devices ();
|
||||
nl.purge ();
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit (A=n1,B=n4):\n"
|
||||
" D r4 (A=n1,B=n4) [R=2]\n"
|
||||
);
|
||||
};
|
||||
|
||||
@@ -49,11 +49,6 @@ static unsigned int layer_of (const db::Region ®ion)
|
||||
return db::DeepLayer (region).layer ();
|
||||
}
|
||||
|
||||
static std::string net_name (const db::Net *net)
|
||||
{
|
||||
return net ? net->expanded_name () : "(null)";
|
||||
}
|
||||
|
||||
static std::string device_name (const db::Device &device)
|
||||
{
|
||||
if (device.name ().empty ()) {
|
||||
@@ -63,26 +58,6 @@ static std::string device_name (const db::Device &device)
|
||||
}
|
||||
}
|
||||
|
||||
static std::string subcircuit_name (const db::SubCircuit &subcircuit)
|
||||
{
|
||||
if (subcircuit.name ().empty ()) {
|
||||
return "$" + tl::to_string (subcircuit.id ());
|
||||
} else {
|
||||
return subcircuit.name ();
|
||||
}
|
||||
}
|
||||
|
||||
static std::string pin_name (const db::Pin &pin)
|
||||
{
|
||||
if (pin.name ().empty ()) {
|
||||
// the pin ID is zero-based and essentially the index, so we add 1 to make it compliant with the other IDs
|
||||
return "$" + tl::to_string (pin.id () + 1);
|
||||
} else {
|
||||
return pin.name ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MOSFETExtractor
|
||||
: public db::NetlistDeviceExtractor
|
||||
{
|
||||
@@ -229,9 +204,7 @@ static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_la
|
||||
return lid;
|
||||
}
|
||||
|
||||
// @@@ TODO: move this somewhere else
|
||||
|
||||
static void dump_nets (const db::Netlist &nl, const db::hier_clusters<db::PolygonRef> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap)
|
||||
static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<db::PolygonRef> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap)
|
||||
{
|
||||
for (db::Netlist::const_circuit_iterator c = nl.begin_circuits (); c != nl.end_circuits (); ++c) {
|
||||
|
||||
@@ -248,7 +221,7 @@ static void dump_nets (const db::Netlist &nl, const db::hier_clusters<db::Polygo
|
||||
|
||||
if (any_shapes) {
|
||||
|
||||
std::string nn = "NET_" + c->name () + "_" + net_name (n.operator-> ());
|
||||
std::string nn = "NET_" + c->name () + "_" + n->expanded_name ();
|
||||
db::Cell &net_cell = ly.cell (ly.add_cell (nn.c_str ()));
|
||||
cell.insert (db::CellInstArray (db::CellInst (net_cell.cell_index ()), db::Trans ()));
|
||||
|
||||
@@ -266,66 +239,6 @@ static void dump_nets (const db::Netlist &nl, const db::hier_clusters<db::Polygo
|
||||
}
|
||||
}
|
||||
|
||||
static std::string netlist2string (const db::Netlist &nl)
|
||||
{
|
||||
std::string res;
|
||||
for (db::Netlist::const_circuit_iterator c = nl.begin_circuits (); c != nl.end_circuits (); ++c) {
|
||||
|
||||
std::string ps;
|
||||
for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) {
|
||||
if (! ps.empty ()) {
|
||||
ps += ",";
|
||||
}
|
||||
ps += pin_name (*p) + "=" + net_name (c->net_for_pin (p->id ()));
|
||||
}
|
||||
|
||||
res += std::string ("Circuit ") + c->name () + " (" + ps + "):\n";
|
||||
|
||||
#if 0 // for debugging
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
for (db::Circuit::const_device_iterator d = c->begin_devices (); d != c->end_devices (); ++d) {
|
||||
std::string ts;
|
||||
const std::vector<db::DeviceTerminalDefinition> &td = d->device_class ()->terminal_definitions ();
|
||||
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
||||
if (t != td.begin ()) {
|
||||
ts += ",";
|
||||
}
|
||||
ts += t->name () + "=" + net_name (d->net_for_terminal (t->id ()));
|
||||
}
|
||||
std::string ps;
|
||||
const std::vector<db::DeviceParameterDefinition> &pd = d->device_class ()->parameter_definitions ();
|
||||
for (std::vector<db::DeviceParameterDefinition>::const_iterator p = pd.begin (); p != pd.end (); ++p) {
|
||||
if (p != pd.begin ()) {
|
||||
ps += ",";
|
||||
}
|
||||
ps += p->name () + "=" + tl::to_string (d->parameter_value (p->id ()));
|
||||
}
|
||||
res += std::string (" D") + d->device_class ()->name () + " " + device_name (*d) + " (" + ts + ") [" + ps + "]\n";
|
||||
}
|
||||
|
||||
for (db::Circuit::const_subcircuit_iterator sc = c->begin_subcircuits (); sc != c->end_subcircuits (); ++sc) {
|
||||
std::string ps;
|
||||
const db::SubCircuit &subcircuit = *sc;
|
||||
const db::Circuit *circuit = sc->circuit_ref ();
|
||||
for (db::Circuit::const_pin_iterator p = circuit->begin_pins (); p != circuit->end_pins (); ++p) {
|
||||
if (p != circuit->begin_pins ()) {
|
||||
ps += ",";
|
||||
}
|
||||
const db::Pin &pin = *p;
|
||||
ps += pin_name (pin) + "=" + net_name (subcircuit.net_for_pin (pin.id ()));
|
||||
}
|
||||
res += std::string (" X") + circuit->name () + " " + subcircuit_name (*sc) + " (" + ps + ")\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(1_DeviceAndNetExtraction)
|
||||
{
|
||||
db::Layout ly;
|
||||
@@ -475,10 +388,10 @@ TEST(1_DeviceAndNetExtraction)
|
||||
|
||||
// write nets to layout
|
||||
db::CellMapping cm = dss.cell_mapping_to_original (0, &ly, tc.cell_index ());
|
||||
dump_nets (nl, net_ex.clusters (), ly, dump_map, cm);
|
||||
dump_nets_to_layout (nl, net_ex.clusters (), ly, dump_map, cm);
|
||||
|
||||
// compare netlist as string
|
||||
EXPECT_EQ (netlist2string (nl),
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit RINGO ():\n"
|
||||
" XINV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD)\n"
|
||||
" XINV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD)\n"
|
||||
@@ -510,7 +423,7 @@ TEST(1_DeviceAndNetExtraction)
|
||||
nl.purge ();
|
||||
|
||||
// compare netlist as string
|
||||
EXPECT_EQ (netlist2string (nl),
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit RINGO (FB=FB,OSC=OSC,VSS=VSS,VDD=VDD):\n"
|
||||
" XINV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD)\n"
|
||||
" XINV2 $2 (IN=FB,$2=(null),OUT=$I19,$4=VSS,$5=VDD)\n"
|
||||
|
||||
@@ -62,7 +62,8 @@ SOURCES = \
|
||||
dbNetlistPropertyTests.cc \
|
||||
dbNetlistTests.cc \
|
||||
dbNetlistExtractorTests.cc \
|
||||
dbNetlistDeviceExtractorTests.cc
|
||||
dbNetlistDeviceExtractorTests.cc \
|
||||
dbNetlistDeviceClassesTests.cc
|
||||
|
||||
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
|
||||
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC
|
||||
|
||||
Reference in New Issue
Block a user