mirror of https://github.com/KLayout/klayout.git
Bugfix: blackbox mode/abstract pins
Abstract pins are created when pins are not attached to any or only to passive nets (passive nets are those without device terminals or subcircuit pins). 1. Such pins were treated swappable. Now named pins will not be treated swappable but are mapped by name. This enables blackbox models where the pins are labelled and must correspond to schematic pins. 2. A bug was present which lead to incorrect handling of abstract nets in net compare.
This commit is contained in:
parent
d65148ed0b
commit
c24c0933bf
|
|
@ -776,8 +776,9 @@ public:
|
|||
{
|
||||
if (is_for_subcircuit ()) {
|
||||
const db::SubCircuit *sc = subcircuit_pair ().first;
|
||||
size_t pin_id = std::numeric_limits<size_t>::max () - m_id1;
|
||||
const db::Circuit *c = sc->circuit_ref ();
|
||||
return std::string ("X") + sc->expanded_name () + " " + c->name ();
|
||||
return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)";
|
||||
} else {
|
||||
size_t term_id1 = m_id1;
|
||||
size_t term_id2 = m_id2;
|
||||
|
|
@ -3168,14 +3169,16 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
|||
}
|
||||
|
||||
static
|
||||
std::vector<size_t> collect_pins_with_empty_nets (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper)
|
||||
std::vector<size_t> collect_anonymous_empty_pins (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper)
|
||||
{
|
||||
std::vector<size_t> pins;
|
||||
|
||||
for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) {
|
||||
const db::Net *net = c->net_for_pin (p->id ());
|
||||
if ((! net || net->is_passive ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) {
|
||||
pins.push_back (p->id ());
|
||||
if (p->name ().empty () && ! circuit_pin_mapper->is_mapped (c, p->id ())) {
|
||||
const db::Net *net = c->net_for_pin (p->id ());
|
||||
if (! net || net->is_passive ()) {
|
||||
pins.push_back (p->id ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3185,13 +3188,11 @@ std::vector<size_t> collect_pins_with_empty_nets (const db::Circuit *c, CircuitP
|
|||
void
|
||||
NetlistComparer::derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper)
|
||||
{
|
||||
// TODO: All pins with empty nets are treated as equivalent - this as a quick way to
|
||||
// treat circuits abstracts, although it's not really valid. By doing this, we
|
||||
// don't capture the case of multiple (abstract) subcircuits wired in different ways.
|
||||
// NOTE: All unnamed pins with empty nets are treated as equivalent. There is no other criterion to match these pins.
|
||||
|
||||
std::vector<size_t> pa, pb;
|
||||
pa = collect_pins_with_empty_nets (ca, circuit_pin_mapper);
|
||||
pb = collect_pins_with_empty_nets (cb, circuit_pin_mapper);
|
||||
pa = collect_anonymous_empty_pins (ca, circuit_pin_mapper);
|
||||
pb = collect_anonymous_empty_pins (cb, circuit_pin_mapper);
|
||||
|
||||
circuit_pin_mapper->map_pins (ca, pa);
|
||||
circuit_pin_mapper->map_pins (cb, pb);
|
||||
|
|
@ -3537,7 +3538,13 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
|
||||
// NOTE: for normalization we map all subcircuits of c1 to c2.
|
||||
// Also, pin swapping will only happen there.
|
||||
if (options ()->debug_netgraph) {
|
||||
tl::info << "Netlist graph:";
|
||||
}
|
||||
g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper);
|
||||
if (options ()->debug_netgraph) {
|
||||
tl::info << "Other netlist graph:";
|
||||
}
|
||||
g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper);
|
||||
|
||||
// Match dummy nodes for null nets
|
||||
|
|
@ -3851,7 +3858,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
mp_logger->match_pins (p.operator-> (), fp->second);
|
||||
}
|
||||
c12_pin_mapping.map_pin (p->id (), fp->second->id ());
|
||||
c22_pin_mapping.map_pin (fp->second->id (), p->id ());
|
||||
c22_pin_mapping.map_pin (fp->second->id (), fp->second->id ());
|
||||
|
||||
} else if (next_abstract != abstract_pins2.end ()) {
|
||||
|
||||
|
|
@ -3861,7 +3868,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
mp_logger->match_pins (p.operator-> (), *next_abstract);
|
||||
}
|
||||
c12_pin_mapping.map_pin (p->id (), (*next_abstract)->id ());
|
||||
c22_pin_mapping.map_pin ((*next_abstract)->id (), p->id ());
|
||||
c22_pin_mapping.map_pin ((*next_abstract)->id (), (*next_abstract)->id ());
|
||||
|
||||
++next_abstract;
|
||||
|
||||
|
|
|
|||
|
|
@ -3822,24 +3822,24 @@ TEST(21_BusLikeAmbiguousConnections)
|
|||
"match_pins VSS VSS\n"
|
||||
"end_circuit INV8 INV8 MATCH\n"
|
||||
"begin_circuit INV8_WRAP INV8_WRAP\n"
|
||||
"match_ambiguous_nets VDD VDD\n"
|
||||
"match_ambiguous_nets VSS VSS\n"
|
||||
"match_ambiguous_nets IN1 A1\n"
|
||||
"match_ambiguous_nets IN2 A2\n"
|
||||
"match_ambiguous_nets IN3 A3\n"
|
||||
"match_ambiguous_nets IN4 A4\n"
|
||||
"match_ambiguous_nets IN5 A5\n"
|
||||
"match_ambiguous_nets IN6 A6\n"
|
||||
"match_ambiguous_nets IN7 A7\n"
|
||||
"match_ambiguous_nets IN8 A8\n"
|
||||
"match_ambiguous_nets OUT1 Q1\n"
|
||||
"match_ambiguous_nets OUT2 Q2\n"
|
||||
"match_ambiguous_nets OUT3 Q3\n"
|
||||
"match_ambiguous_nets OUT4 Q4\n"
|
||||
"match_ambiguous_nets OUT5 Q5\n"
|
||||
"match_ambiguous_nets OUT6 Q6\n"
|
||||
"match_ambiguous_nets OUT7 Q7\n"
|
||||
"match_ambiguous_nets OUT8 Q8\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT8 Q8\n"
|
||||
"match_nets IN8 A8\n"
|
||||
"match_nets OUT7 Q7\n"
|
||||
"match_nets IN7 A7\n"
|
||||
"match_nets OUT6 Q6\n"
|
||||
"match_nets IN6 A6\n"
|
||||
"match_nets OUT5 Q5\n"
|
||||
"match_nets IN5 A5\n"
|
||||
"match_nets OUT4 Q4\n"
|
||||
"match_nets IN4 A4\n"
|
||||
"match_nets OUT3 Q3\n"
|
||||
"match_nets IN3 A3\n"
|
||||
"match_nets OUT2 Q2\n"
|
||||
"match_nets IN2 A2\n"
|
||||
"match_nets OUT1 Q1\n"
|
||||
"match_nets IN1 A1\n"
|
||||
"match_pins IN1 A1\n"
|
||||
"match_pins OUT1 Q1\n"
|
||||
"match_pins IN2 A2\n"
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ M$2 3 5 2 7 LVNMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U
|
|||
* cell TIE
|
||||
* pin VDD
|
||||
* pin BULK,VSS
|
||||
.SUBCKT TIE 2 3
|
||||
* net 2 VDD
|
||||
* net 3 BULK,VSS
|
||||
.SUBCKT TIE 1 2
|
||||
* net 1 VDD
|
||||
* net 2 BULK,VSS
|
||||
.ENDS TIE
|
||||
|
||||
* cell EMPTY
|
||||
|
|
|
|||
|
|
@ -158,8 +158,8 @@ xref(
|
|||
)
|
||||
circuit(empty_subcells EMPTY_SUBCELLS match
|
||||
xref(
|
||||
net(1 1 warning)
|
||||
net(2 2 warning)
|
||||
net(1 1 match)
|
||||
net(2 2 match)
|
||||
circuit(2 1 match)
|
||||
circuit(1 2 match)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -516,8 +516,8 @@ xref(
|
|||
net(8 4 match)
|
||||
net(5 3 match)
|
||||
net(7 5 match)
|
||||
net(6 2 warning)
|
||||
net(9 1 warning)
|
||||
net(6 2 match)
|
||||
net(9 1 match)
|
||||
pin(3 3 match)
|
||||
pin(0 2 match)
|
||||
pin(2 4 match)
|
||||
|
|
|
|||
Loading…
Reference in New Issue