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

View File

@ -713,10 +713,19 @@ public:
/** /**
* @brief Purge unused nets * @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 (); 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 * @brief Combine devices
* *
@ -786,6 +795,7 @@ private:
void set_netlist (Netlist *netlist); void set_netlist (Netlist *netlist);
bool combine_parallel_devices (const db::DeviceClass &cls); bool combine_parallel_devices (const db::DeviceClass &cls);
bool combine_serial_devices (const db::DeviceClass &cls); bool combine_serial_devices (const db::DeviceClass &cls);
void do_purge_nets (bool keep_pins);
void devices_changed (); void devices_changed ();
void subcircuits_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 () void NetlistSpiceReader::finish ()
{ {
while (! m_streams.empty ()) { while (! m_streams.empty ()) {
pop_stream (); pop_stream ();
} }
// purge nets with single connections (this way unconnected pins can be realized)
if (mp_netlist) { 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); 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, gsi::method ("purge_nets", &db::Circuit::purge_nets,
"@brief Purges floating nets.\n" "@brief Purges floating nets.\n"
"Floating nets can be created as effect of reconnections of devices or pins. " "Floating nets are nets with no device or subcircuit attached to. Such floating "
"This method will eliminate all nets that make less than two connections." "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" "@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 " "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(4 name('4'))
net(5 name('6')) net(5 name('6'))
net(6 name('5')) net(6 name('5'))
net(7 name('101')) net(7 name('8'))
net(8 name('8')) net(8 name('7'))
net(9 name('102'))
net(10 name('7'))
net(11 name('103'))
# Outgoing pins and their connections to nets # Outgoing pins and their connections to nets
pin(1 name('1')) pin(1 name('1'))
@ -986,26 +983,23 @@ reference(
pin(0 4) pin(0 4)
pin(1 3) pin(1 3)
pin(2 4) pin(2 4)
pin(3 7)
pin(4 6) pin(4 6)
pin(5 8) pin(5 7)
pin(6 3) pin(6 3)
) )
circuit(4 INV2PAIR name($4) circuit(4 INV2PAIR name($4)
pin(0 4) pin(0 4)
pin(1 3) pin(1 3)
pin(2 4) pin(2 4)
pin(3 9) pin(4 7)
pin(4 8) pin(5 8)
pin(5 10)
pin(6 3) pin(6 3)
) )
circuit(5 INV2PAIR name($5) circuit(5 INV2PAIR name($5)
pin(0 4) pin(0 4)
pin(1 3) pin(1 3)
pin(2 4) pin(2 4)
pin(3 11) pin(4 8)
pin(4 10)
pin(5 5) pin(5 5)
pin(6 3) pin(6 3)
) )
@ -1090,11 +1084,8 @@ xref(
) )
circuit(RINGO RINGO nomatch circuit(RINGO RINGO nomatch
xref( xref(
net(() 7 mismatch)
net(() 9 mismatch)
net(() 11 mismatch)
net(() 6 mismatch) net(() 6 mismatch)
net(() 8 mismatch) net(() 7 mismatch)
net(5 () mismatch) net(5 () mismatch)
net(6 () mismatch) net(6 () mismatch)
net(7 () mismatch) net(7 () mismatch)
@ -1102,7 +1093,7 @@ xref(
net(11 () mismatch) net(11 () mismatch)
net(12 () mismatch) net(12 () mismatch)
net(10 1 mismatch) net(10 1 mismatch)
net(8 10 mismatch) net(8 8 mismatch)
net(1 5 mismatch) net(1 5 mismatch)
net(2 2 match) net(2 2 match)
net(3 3 match) net(3 3 match)
@ -1120,7 +1111,7 @@ xref(
circuit(3 () mismatch) circuit(3 () mismatch)
circuit(4 () mismatch) circuit(4 () mismatch)
circuit(5 () mismatch) circuit(5 () mismatch)
circuit(1 1 mismatch) circuit(1 1 match)
) )
) )
) )