Implemented fix for issue #1832 (enhancements for Netlist#simplify and Netlist#combine_devices)

This commit is contained in:
Matthias Koefferlein 2024-09-07 23:14:51 +02:00
parent 20099a38b9
commit ac2d20ae76
6 changed files with 130 additions and 1 deletions

View File

@ -825,6 +825,41 @@ void Circuit::do_purge_nets (bool keep_pins)
}
}
static bool can_purge_device (const db::Device &device)
{
if (! device.device_class ()) {
return false;
}
const std::vector<db::DeviceTerminalDefinition> &tdefs = device.device_class ()->terminal_definitions ();
if (tdefs.size () <= 1) {
return false;
}
const db::Net *net = device.net_for_terminal (tdefs.front ().id ());
for (auto t = tdefs.begin () + 1; t != tdefs.end (); ++t) {
if (net != device.net_for_terminal (t->id ())) {
return false;
}
}
return true;
}
void Circuit::purge_devices ()
{
std::vector<db::Device *> devices_to_be_purged;
for (device_iterator d = begin_devices (); d != end_devices (); ++d) {
if (can_purge_device (*d)) {
devices_to_be_purged.push_back (d.operator-> ());
}
}
for (auto d = devices_to_be_purged.begin (); d != devices_to_be_purged.end (); ++d) {
remove_device (*d);
}
}
/**
* @brief Sanity check for device to be removed
*/

View File

@ -732,6 +732,14 @@ public:
*/
void purge_nets_keep_pins ();
/**
* @brief Purges invalid devices
*
* This method will purge all invalid devices, i.e. those
* whose terminals are all connected to the same net.
*/
void purge_devices ();
/**
* @brief Combine devices
*

View File

@ -619,6 +619,13 @@ void Netlist::purge_nets ()
}
}
void Netlist::purge_devices ()
{
for (bottom_up_circuit_iterator c = begin_bottom_up (); c != end_bottom_up (); ++c) {
c->purge_devices ();
}
}
void Netlist::make_top_level_pins ()
{
size_t ntop = top_circuit_count ();
@ -651,6 +658,9 @@ void Netlist::purge ()
Circuit *circuit = c.operator-> ();
// purge invalid devices
circuit->purge_devices ();
// purge floating, disconnected nets
circuit->purge_nets ();
@ -684,6 +694,8 @@ void Netlist::simplify ()
{
make_top_level_pins ();
purge ();
// combine devices are purge nets that are created in that step
combine_devices ();
purge_nets ();
}

View File

@ -508,6 +508,14 @@ public:
*/
void purge_nets ();
/**
* @brief Purges invalid devices
*
* This method will purge all invalid devices, i.e. those
* whose terminals are all connected to the same net.
*/
void purge_devices ();
/**
* @brief Creates pins for top-level circuits
*

View File

@ -1809,6 +1809,12 @@ Class<db::Circuit> decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit",
"For example, serial or parallel resistors can be combined into "
"a single resistor.\n"
) +
gsi::method ("purge_devices", &db::Circuit::purge_devices,
"@brief Purges invalid devices.\n"
"Purges devices which are considered invalid. Such devices are for example those whose terminals are all connected to a single net.\n"
"\n"
"This method has been added in version 0.29.7."
) +
gsi::method ("purge_nets", &db::Circuit::purge_nets,
"@brief Purges floating nets.\n"
"Floating nets are nets with no device or subcircuit attached to. Such floating "
@ -2176,9 +2182,15 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
"Floating nets can be created as effect of reconnections of devices or pins. "
"This method will eliminate all nets that make less than two connections."
) +
gsi::method ("purge_devices", &db::Netlist::purge_devices,
"@brief Purges invalid devices.\n"
"Purges devices which are considered invalid. Such devices are for example those whose terminals are all connected to a single net.\n"
"\n"
"This method has been added in version 0.29.7."
) +
gsi::method ("simplify", &db::Netlist::simplify,
"@brief Convenience method that combines the simplification.\n"
"This method is a convenience method that runs \\make_top_level_pins, \\purge, \\combine_devices and \\purge_nets."
"This method is a convenience method that runs \\make_top_level_pins, \\purge, \\combine_devices, \\purge_devices and \\purge_nets."
) +
gsi::method_ext ("read", &read_netlist, gsi::arg ("file"), gsi::arg ("reader"),
"@brief Writes the netlist to the given file using the given reader object to parse the file\n"

View File

@ -1988,3 +1988,57 @@ TEST(27_CombineSmallL)
"end;\n"
);
}
TEST(28_EliminateShortedDevices)
{
db::Netlist nl;
db::Circuit *circuit = new db::Circuit ();
circuit->set_name ("TOP");
nl.add_circuit (circuit);
db::DeviceClass *device = new db::DeviceClassCapacitor ();
device->set_name ("model_name");
nl.add_device_class (device);
db::Net *n1 = new db::Net ("n1");
circuit->add_net (n1);
db::Net *n2 = new db::Net ("n2");
circuit->add_net (n2);
auto p1 = circuit->add_pin ("p1");
auto p2 = circuit->add_pin ("p2");
circuit->connect_pin (p1.id (), n1);
circuit->connect_pin (p2.id (), n2);
db::Device *c1 = new db::Device (device, "c1");
circuit->add_device (c1);
c1->set_parameter_value (db::DeviceClassInductor::param_id_L, 1e-15);
db::Device *c2 = new db::Device (device, "c2");
circuit->add_device (c2);
c2->set_parameter_value (db::DeviceClassInductor::param_id_L, 2e-15);
c1->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1);
c1->connect_terminal (db::DeviceClassInductor::terminal_id_B, n1);
c2->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1);
c2->connect_terminal (db::DeviceClassInductor::terminal_id_B, n2);
EXPECT_EQ (nl.to_string (),
"circuit TOP (p1=n1,p2=n2);\n"
" device model_name c1 (A=n1,B=n1) (C=1e-15,A=0,P=0);\n"
" device model_name c2 (A=n1,B=n2) (C=2e-15,A=0,P=0);\n"
"end;\n"
);
nl.simplify ();
EXPECT_EQ (nl.to_string (),
"circuit TOP (p1=n1,p2=n2);\n"
" device model_name c2 (A=n1,B=n2) (C=2e-15,A=0,P=0);\n"
"end;\n"
);
}