mirror of https://github.com/KLayout/klayout.git
Fixed Spice reader: must not use Netlist::purge_nets to remove dummy nets. Updated golden test data.
This commit is contained in:
parent
aa28aa807a
commit
ed00503d41
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 "
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue