Fixed Spice reader: must not use Netlist::purge_nets to remove dummy nets. Updated golden test data.

This commit is contained in:
Matthias Koefferlein 2019-11-23 23:36:52 +01:00
parent aa28aa807a
commit ed00503d41
5 changed files with 85 additions and 38 deletions

View File

@ -575,7 +575,17 @@ void Circuit::connect_pin (size_t pin_id, Net *net)
}
}
void Circuit::purge_nets_keep_pins ()
{
do_purge_nets (true);
}
void Circuit::purge_nets ()
{
do_purge_nets (false);
}
void Circuit::do_purge_nets (bool keep_pins)
{
std::vector<db::Net *> nets_to_be_purged;
for (net_iterator n = begin_nets (); n != end_nets (); ++n) {
@ -587,29 +597,35 @@ void Circuit::purge_nets ()
std::set<size_t> pins_to_delete;
for (std::vector<db::Net *>::const_iterator n = nets_to_be_purged.begin (); n != nets_to_be_purged.end (); ++n) {
for (db::Net::pin_iterator p = (*n)->begin_pins (); p != (*n)->end_pins (); ++p) {
pins_to_delete.insert (p->pin_id ());
if (! keep_pins) {
for (db::Net::pin_iterator p = (*n)->begin_pins (); p != (*n)->end_pins (); ++p) {
pins_to_delete.insert (p->pin_id ());
}
}
delete *n;
}
// remove the pin references of the pins we're going to delete
for (refs_iterator r = begin_refs (); r != end_refs (); ++r) {
db::SubCircuit *subcircuit = r.operator-> ();
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
db::Net *net = subcircuit->net_for_pin (*p);
for (db::Net::subcircuit_pin_iterator sp = net->begin_subcircuit_pins (); sp != net->end_subcircuit_pins (); ++sp) {
if (sp->pin_id () == *p && sp->subcircuit () == subcircuit) {
net->erase_subcircuit_pin (sp);
break;
if (! pins_to_delete.empty ()) {
// remove the pin references of the pins we're going to delete
for (refs_iterator r = begin_refs (); r != end_refs (); ++r) {
db::SubCircuit *subcircuit = r.operator-> ();
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
db::Net *net = subcircuit->net_for_pin (*p);
for (db::Net::subcircuit_pin_iterator sp = net->begin_subcircuit_pins (); sp != net->end_subcircuit_pins (); ++sp) {
if (sp->pin_id () == *p && sp->subcircuit () == subcircuit) {
net->erase_subcircuit_pin (sp);
break;
}
}
}
}
}
// and actually remove those pins
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
remove_pin (*p);
// and actually remove those pins
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
remove_pin (*p);
}
}
}

View File

@ -713,10 +713,19 @@ public:
/**
* @brief Purge unused nets
*
* This method will purge all nets which return "floating".
* This method will purge all nets which return "is_passive".
* Pins on these nets will also be removed.
*/
void purge_nets ();
/**
* @brief Purge unused nets but
*
* This method will purge all nets which return "is_passive".
* Pins on these nets will be kept but their net will be 0.
*/
void purge_nets_keep_pins ();
/**
* @brief Combine devices
*
@ -786,6 +795,7 @@ private:
void set_netlist (Netlist *netlist);
bool combine_parallel_devices (const db::DeviceClass &cls);
bool combine_serial_devices (const db::DeviceClass &cls);
void do_purge_nets (bool keep_pins);
void devices_changed ();
void subcircuits_changed ();

View File

@ -282,15 +282,37 @@ void NetlistSpiceReader::read (tl::InputStream &stream, db::Netlist &netlist)
}
}
/**
* @brief Removes dummy nets which are just there to define a pin for a subcircuit
*/
static void
remove_dummy_nets (db::Circuit &circuit)
{
std::vector<db::Net *> nets_to_be_purged;
for (db::Circuit::net_iterator n = circuit.begin_nets (); n != circuit.end_nets (); ++n) {
if (n->subcircuit_pin_count () == 1 && (n->terminal_count () + n->pin_count ()) == 0) {
nets_to_be_purged.push_back (n.operator-> ());
}
}
for (std::vector<db::Net *>::const_iterator n = nets_to_be_purged.begin (); n != nets_to_be_purged.end (); ++n) {
delete *n;
}
}
void NetlistSpiceReader::finish ()
{
while (! m_streams.empty ()) {
pop_stream ();
}
// purge nets with single connections (this way unconnected pins can be realized)
if (mp_netlist) {
mp_netlist->purge_nets ();
// purge nets with single connections (this way unconnected pins can be realized)
// NOTE: we don't use Netlist::purge_nets as this method has too many side effects
db::NetlistLocker locker (mp_netlist);
for (db::Netlist::bottom_up_circuit_iterator c = mp_netlist->begin_bottom_up (); c != mp_netlist->end_bottom_up (); ++c) {
remove_dummy_nets (*c);
}
}
mp_stream.reset (0);

View File

@ -1316,8 +1316,16 @@ Class<db::Circuit> decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit",
) +
gsi::method ("purge_nets", &db::Circuit::purge_nets,
"@brief Purges floating nets.\n"
"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."
"Floating nets are nets with no device or subcircuit attached to. Such floating "
"nets are removed in this step. If these nets are connected outward to a circuit pin, this "
"circuit pin is also removed."
) +
gsi::method ("purge_nets_keep_pins", &db::Circuit::purge_nets_keep_pins,
"@brief Purges floating nets but keep pins.\n"
"This method will remove floating nets like \\purge_nets, but if these nets are attached "
"to a pin, the pin will be left disconnected from any net.\n"
"\n"
"This method has been introduced in version 0.26.2.\n"
),
"@brief Circuits are the basic building blocks of the netlist\n"
"A circuit has pins by which it can connect to the outside. Pins are "

View File

@ -951,11 +951,8 @@ reference(
net(4 name('4'))
net(5 name('6'))
net(6 name('5'))
net(7 name('101'))
net(8 name('8'))
net(9 name('102'))
net(10 name('7'))
net(11 name('103'))
net(7 name('8'))
net(8 name('7'))
# Outgoing pins and their connections to nets
pin(1 name('1'))
@ -986,26 +983,23 @@ reference(
pin(0 4)
pin(1 3)
pin(2 4)
pin(3 7)
pin(4 6)
pin(5 8)
pin(5 7)
pin(6 3)
)
circuit(4 INV2PAIR name($4)
pin(0 4)
pin(1 3)
pin(2 4)
pin(3 9)
pin(4 8)
pin(5 10)
pin(4 7)
pin(5 8)
pin(6 3)
)
circuit(5 INV2PAIR name($5)
pin(0 4)
pin(1 3)
pin(2 4)
pin(3 11)
pin(4 10)
pin(4 8)
pin(5 5)
pin(6 3)
)
@ -1090,11 +1084,8 @@ xref(
)
circuit(RINGO RINGO nomatch
xref(
net(() 7 mismatch)
net(() 9 mismatch)
net(() 11 mismatch)
net(() 6 mismatch)
net(() 8 mismatch)
net(() 7 mismatch)
net(5 () mismatch)
net(6 () mismatch)
net(7 () mismatch)
@ -1102,7 +1093,7 @@ xref(
net(11 () mismatch)
net(12 () mismatch)
net(10 1 mismatch)
net(8 10 mismatch)
net(8 8 mismatch)
net(1 5 mismatch)
net(2 2 match)
net(3 3 match)
@ -1120,7 +1111,7 @@ xref(
circuit(3 () mismatch)
circuit(4 () mismatch)
circuit(5 () mismatch)
circuit(1 1 mismatch)
circuit(1 1 match)
)
)
)