WIP: netlist compare - using it for more tests

Issue solved: some circuit pins may not have a net - these
need to be ignored.

Requirement: all pins with a net must be mapped.

Detached pins are not present in the mapping table.
A dummy mapping table was introduced to allow dropping
of pins in the second circuit too.

Output of compare should not depend on memory location
anymore and pin mismatch reporting should include all
pins.
This commit is contained in:
Matthias Koefferlein 2019-03-31 23:59:43 +02:00
parent 06e326dfd9
commit 9613ad72c8
5 changed files with 279 additions and 145 deletions

View File

@ -157,6 +157,16 @@ public:
m_rev_pin_map.insert (std::make_pair (other_pin, this_pin));
}
bool has_other_pin_for_this_pin (size_t this_pin) const
{
return m_pin_map.find (this_pin) != m_pin_map.end ();
}
bool has_this_pin_for_other_pin (size_t other_pin) const
{
return m_rev_pin_map.find (other_pin) != m_rev_pin_map.end ();
}
size_t other_pin_from_this_pin (size_t this_pin) const
{
std::map<size_t, size_t>::const_iterator i = m_pin_map.find (this_pin);
@ -440,28 +450,28 @@ public:
size_t pin_id = i->pin ()->id ();
const db::Circuit *cr = sc->circuit_ref ();
const CircuitMapper *cm = 0;
pin_id = pin_map->normalize_pin_id (cr, pin_id);
if (circuit_map) {
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
if (icm == circuit_map->end ()) {
// this can happen if the other circuit is not present - this is allowed for single-pin
// circuits.
continue;
}
cm = & icm->second;
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
if (icm == circuit_map->end ()) {
// this can happen if the other circuit is not present - this is allowed for single-pin
// circuits.
continue;
}
// NOTE: if cm is given, cr and pin_id are given in terms of the "other" circuit
const CircuitMapper *cm = & icm->second;
if (cm) {
cr = cm->other ();
pin_id = cm->other_pin_from_this_pin (pin_id);
// A pin assignment may be missing because there is no net for a pin -> skip this
if (! cm->has_other_pin_for_this_pin (pin_id)) {
continue;
}
if (pin_map) {
pin_id = pin_map->normalize_pin_id (cr, pin_id);
}
// NOTE: if cm is given, cr and pin_id are given in terms of the canonical "other" circuit.
// For c1 this is the c1->c2 mapper, for c2 this is the c2->c2 dummy mapper.
cr = cm->other ();
pin_id = cm->other_pin_from_this_pin (pin_id);
// we cannot afford creating edges from all to all other pins, so we just create edges to the previous and next
// pin. This may take more iterations to solve, but should be equivalent.
@ -469,17 +479,21 @@ public:
std::vector<size_t> pids;
size_t pin_count = cr->pin_count ();
// take the previous, next and second-next pin as targets for edges
// (using the second-next pin avoid isolation of OUT vs. IN in case
// of a pin configuration of VSS-IN-VDD-OUT like for an inverter).
// take a number if additional pins as edges: this allows identifying a pin as dependent
// from other pins hence nets are propagated. We assume that there are 4 power pins max so
// 5 additional pins should be sufficient to capture one additional non-power pin.
if (pin_count >= 2) {
pids.push_back ((pin_id + pin_count - 1) % pin_count);
if (pin_count >= 3) {
pids.push_back ((pin_id + 1) % pin_count);
if (pin_count >= 4) {
pids.push_back ((pin_id + 2) % pin_count);
}
size_t take_additional_pins = 5;
for (size_t n = 0; n < take_additional_pins; ++n) {
size_t add_pin_id = (pin_id + n + 1) % pin_count;
if (add_pin_id == pin_id) {
break;
}
if (cm->has_this_pin_for_other_pin (add_pin_id)) {
pids.push_back (add_pin_id);
} else {
// skip pins without mapping
++take_additional_pins;
}
}
@ -489,9 +503,9 @@ public:
// NOTE: if a pin mapping is given, EdgeDesc::pin1_id and EdgeDesc::pin2_id are given
// as pin ID's of the other circuit.
EdgeDesc ed (sc, circuit_categorizer.cat_for_subcircuit (sc), pin_id, pin_map ? pin_map->normalize_pin_id (cr, pin2_id) : pin2_id);
EdgeDesc ed (sc, circuit_categorizer.cat_for_subcircuit (sc), pin_id, pin_map->normalize_pin_id (cr, pin2_id));
size_t this_pin2_id = cm ? cm->this_pin_from_other_pin (pin2_id) : pin2_id;
size_t this_pin2_id = cm->this_pin_from_other_pin (pin2_id);
const db::Net *net2 = sc->net_for_pin (this_pin2_id);
std::map<const db::Net *, size_t>::const_iterator in = n2entry.find (net2);
@ -966,7 +980,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
}
std::set<const db::Circuit *> verified_circuits_a, verified_circuits_b;
std::map<const db::Circuit *, CircuitMapper> pin_mapping;
std::map<const db::Circuit *, CircuitMapper> c12_pin_mapping, c22_pin_mapping;
for (db::Netlist::const_bottom_up_circuit_iterator c = a->begin_bottom_up (); c != a->end_bottom_up (); ++c) {
@ -994,7 +1008,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
}
bool pin_mismatch = false;
bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, *net_identity, pin_mismatch, pin_mapping);
bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping);
if (! g) {
good = false;
}
@ -1070,29 +1084,30 @@ compute_subcircuit_key (const db::SubCircuit &subcircuit, const db::NetDeviceGra
const db::Circuit *cr = subcircuit.circuit_ref ();
const CircuitMapper *cm = 0;
if (circuit_map) {
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
if (icm == circuit_map->end ()) {
// this can happen if the other circuit does not exist - in this case the key is an invalid one which cannot
// be produced by a regular subcircuit.
return k;
}
cm = & icm->second;
cr = cm->other ();
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
if (icm == circuit_map->end ()) {
// this can happen if the other circuit does not exist - in this case the key is an invalid one which cannot
// be produced by a regular subcircuit.
return k;
}
// NOTE: if cm is given, cr is given in terms of the "other" circuit
const CircuitMapper *cm = & icm->second;
cr = cm->other ();
// NOTE: cr is given in terms of the canonical "other" circuit.
for (db::Circuit::const_pin_iterator p = cr->begin_pins (); p != cr->end_pins (); ++p) {
size_t this_pin_id = cm ? cm->this_pin_from_other_pin (p->id ()) : p->id ();
size_t pin_id = pin_map ? pin_map->normalize_pin_id (cr, p->id ()) : p->id ();
if (cm->has_this_pin_for_other_pin (p->id ())) {
const db::Net *net = subcircuit.net_for_pin (this_pin_id);
size_t net_id = g.node_index_for_net (net);
k.push_back (std::make_pair (pin_id, net_id));
size_t this_pin_id = cm->this_pin_from_other_pin (p->id ());
size_t pin_id = pin_map->normalize_pin_id (cr, p->id ());
const db::Net *net = subcircuit.net_for_pin (this_pin_id);
size_t net_id = g.node_index_for_net (net);
k.push_back (std::make_pair (pin_id, net_id));
}
}
@ -1102,14 +1117,14 @@ compute_subcircuit_key (const db::SubCircuit &subcircuit, const db::NetDeviceGra
}
bool
NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, const std::vector<std::pair<const Net *, const Net *> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &circuit_and_pin_mapping) const
NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, const std::vector<std::pair<const Net *, const Net *> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping) const
{
db::NetDeviceGraph g1, g2;
// NOTE: for normalization we map all subcircuits of c1 to c2.
// Also, pin swapping will only happen there.
g1.build (c1, device_categorizer, circuit_categorizer, &circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
g2.build (c2, device_categorizer, circuit_categorizer, 0, mp_circuit_pin_mapper.get ());
g1.build (c1, device_categorizer, circuit_categorizer, &c12_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
g2.build (c2, device_categorizer, circuit_categorizer, &c22_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
// Match dummy nodes for null nets
g1.identify (0, 0);
@ -1228,48 +1243,54 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
// Report pin assignment
// This step also does the pin identity mapping.
std::multimap<const db::Net *, const db::Pin *> net2pin;
std::multimap<size_t, const db::Pin *> net2pin;
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
const db::Net *net = c2->net_for_pin (p->id ());
tl_assert (net != 0);
net2pin.insert (std::make_pair (net, p.operator-> ()));
if (net) {
net2pin.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
}
}
CircuitMapper &pin_mapping = circuit_and_pin_mapping [c1];
pin_mapping.set_other (c2);
CircuitMapper &c12_pin_mapping = c12_circuit_and_pin_mapping [c1];
c12_pin_mapping.set_other (c2);
for (db::NetDeviceGraph::node_iterator i = g1.begin (); i != g1.end (); ++i) {
// dummy mapping: we show this circuit is used.
CircuitMapper &c22_pin_mapping = c22_circuit_and_pin_mapping [c2];
c22_pin_mapping.set_other (c2);
const db::Net *net = i->net ();
if (! net || net->pin_count () == 0) {
for (db::Circuit::const_pin_iterator p = c1->begin_pins (); p != c1->end_pins (); ++p) {
const db::Net *net = c1->net_for_pin (p->id ());
if (! net) {
continue;
}
if (! i->has_other ()) {
for (db::Net::const_pin_iterator pi = net->begin_pins (); pi != net->end_pins (); ++pi) {
if (mp_logger) {
mp_logger->pin_mismatch (pi->pin (), 0);
}
pin_mismatch = true;
good = false;
const db::NetGraphNode &n = *(g1.begin () + g1.node_index_for_net (net));
if (! n.has_other ()) {
if (mp_logger) {
mp_logger->pin_mismatch (p.operator-> (), 0);
}
pin_mismatch = true;
good = false;
continue;
}
const db::Net *other_net = g2.net_by_node_index (i->other_net_index ());
std::multimap<const db::Net *, const db::Pin *>::iterator np = net2pin.find (other_net);
std::multimap<size_t, const db::Pin *>::iterator np = net2pin.find (n.other_net_index ());
for (db::Net::const_pin_iterator pi = net->begin_pins (); pi != net->end_pins (); ++pi) {
if (np != net2pin.end () && np->first == other_net) {
if (np != net2pin.end () && np->first == n.other_net_index ()) {
if (mp_logger) {
mp_logger->match_pins (pi->pin (), np->second);
}
pin_mapping.map_pin (pi->pin ()->id (), np->second->id ());
c12_pin_mapping.map_pin (pi->pin ()->id (), np->second->id ());
// dummy mapping: we show this pin is used.
c22_pin_mapping.map_pin (np->second->id (), np->second->id ());
std::multimap<const db::Net *, const db::Pin *>::iterator np_delete = np;
std::multimap<size_t, const db::Pin *>::iterator np_delete = np;
++np;
net2pin.erase (np_delete);
@ -1287,7 +1308,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
}
for (std::multimap<const db::Net *, const db::Pin *>::iterator np = net2pin.begin (); np != net2pin.end (); ++np) {
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin.begin (); np != net2pin.end (); ++np) {
if (mp_logger) {
mp_logger->pin_mismatch (0, np->second);
}
@ -1391,7 +1412,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
for (db::Circuit::const_subcircuit_iterator sc = c1->begin_subcircuits (); sc != c1->end_subcircuits (); ++sc) {
std::vector<std::pair<size_t, size_t> > k = compute_subcircuit_key (*sc, g1, &circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
std::vector<std::pair<size_t, size_t> > k = compute_subcircuit_key (*sc, g1, &c12_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
bool mapped = true;
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end () && mapped; ++i) {
@ -1414,7 +1435,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
for (db::Circuit::const_subcircuit_iterator sc = c2->begin_subcircuits (); sc != c2->end_subcircuits (); ++sc) {
std::vector<std::pair<size_t, size_t> > k = compute_subcircuit_key (*sc, g2, 0, mp_circuit_pin_mapper.get ());
std::vector<std::pair<size_t, size_t> > k = compute_subcircuit_key (*sc, g2, &c22_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
bool mapped = true;
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {

View File

@ -201,7 +201,7 @@ public:
bool compare (const db::Netlist *a, const db::Netlist *b) const;
protected:
bool compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, const std::vector<std::pair<const Net *, const Net *> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &circuit_and_pin_mapping) const;
bool compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, const std::vector<std::pair<const Net *, const Net *> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping) const;
bool all_subcircuits_verified (const db::Circuit *c, const std::set<const db::Circuit *> &verified_circuits) const;
NetlistCompareLogger *mp_logger;

View File

@ -1780,7 +1780,7 @@ TEST(6_MoreDeviceTypes)
"circuit TOP ();\n"
" device HVPMOS $1 (S=Z,G=$5,D=VDD2,B=$8) (L=1.5,W=4.05,AS=5.4675,AD=2.73375,PS=10.8,PD=5.4);\n"
" device HVPMOS $2 (S=VDD2,G=Z,D=$5,B=$8) (L=1.5,W=4.05,AS=2.73375,AD=5.4675,PS=5.4,PD=10.8);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=1.11375,AD=3.155625,PS=5.85,PD=7.5);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=4.77675,AD=3.155625,PS=8.81,PD=7.5);\n"
" device HVNMOS $4 (S=Z,G=$6,D=VSS,B=BULK) (L=1.5,W=5.25,AS=7.0875,AD=3.54375,PS=13.2,PD=6.6);\n"
" device HVNMOS $5 (S=VSS,G=A,D=$5,B=BULK) (L=1.5,W=5.25,AS=3.54375,AD=7.0875,PS=6.6,PD=13.2);\n"
" device LVNMOS $6 (S=VSS,G=A,D=$6,B=BULK) (L=1.2,W=1.7,AS=2.346,AD=2.1165,PS=6.16,PD=5.89);\n"
@ -1937,7 +1937,7 @@ TEST(7_MoreByEmptyDeviceTypes)
"circuit TOP ();\n"
" device LVPMOS $1 (S=Z,G=$5,D=VDD2,B=$8) (L=1.5,W=4.05,AS=5.4675,AD=2.73375,PS=10.8,PD=5.4);\n"
" device LVPMOS $2 (S=VDD2,G=Z,D=$5,B=$8) (L=1.5,W=4.05,AS=2.73375,AD=5.4675,PS=5.4,PD=10.8);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=1.11375,AD=3.155625,PS=5.85,PD=7.5);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=4.77675,AD=3.155625,PS=8.81,PD=7.5);\n"
" device LVNMOS $4 (S=VSS,G=A,D=$6,B=BULK) (L=1.2,W=1.7,AS=2.346,AD=2.1165,PS=6.16,PD=5.89);\n"
" device LVNMOS $5 (S=Z,G=$6,D=VSS,B=BULK) (L=1.5,W=5.25,AS=7.0875,AD=3.54375,PS=13.2,PD=6.6);\n"
" device LVNMOS $6 (S=VSS,G=A,D=$5,B=BULK) (L=1.5,W=5.25,AS=3.54375,AD=7.0875,PS=6.6,PD=13.2);\n"
@ -2116,7 +2116,7 @@ TEST(8_FlatExtraction)
"circuit TOP ();\n"
" device HVPMOS $1 (S=Z,G=$5,D=VDD2,B=$8) (L=1.5,W=4.05,AS=5.4675,AD=2.73375,PS=10.8,PD=5.4);\n"
" device HVPMOS $2 (S=VDD2,G=Z,D=$5,B=$8) (L=1.5,W=4.05,AS=2.73375,AD=5.4675,PS=5.4,PD=10.8);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=1.11375,AD=3.155625,PS=5.85,PD=7.5);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=4.77675,AD=3.155625,PS=8.81,PD=7.5);\n"
" device HVNMOS $4 (S=Z,G=$6,D=VSS,B=BULK) (L=1.5,W=5.25,AS=7.0875,AD=3.54375,PS=13.2,PD=6.6);\n"
" device HVNMOS $5 (S=VSS,G=A,D=$5,B=BULK) (L=1.5,W=5.25,AS=3.54375,AD=7.0875,PS=6.6,PD=13.2);\n"
" device LVNMOS $6 (S=VSS,G=A,D=$6,B=BULK) (L=1.2,W=1.7,AS=2.346,AD=2.1165,PS=6.16,PD=5.89);\n"
@ -2300,7 +2300,7 @@ TEST(9_FlatExtractionWithExternalDSS)
"circuit TOP ();\n"
" device LVPMOS $1 (S=Z,G=$5,D=VDD2,B=$8) (L=1.5,W=4.05,AS=5.4675,AD=2.73375,PS=10.8,PD=5.4);\n"
" device LVPMOS $2 (S=VDD2,G=Z,D=$5,B=$8) (L=1.5,W=4.05,AS=2.73375,AD=5.4675,PS=5.4,PD=10.8);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=1.11375,AD=3.155625,PS=5.85,PD=7.5);\n"
" device LVPMOS $3 (S=$10,G=A,D=$6,B=$9) (L=1.5,W=2.475,AS=4.77675,AD=3.155625,PS=8.81,PD=7.5);\n"
" device LVNMOS $4 (S=VSS,G=A,D=$6,B=BULK) (L=1.2,W=1.7,AS=2.346,AD=2.1165,PS=6.16,PD=5.89);\n"
" device LVNMOS $5 (S=Z,G=$6,D=VSS,B=BULK) (L=1.5,W=5.25,AS=7.0875,AD=3.54375,PS=13.2,PD=6.6);\n"
" device LVNMOS $6 (S=VSS,G=A,D=$5,B=BULK) (L=1.5,W=5.25,AS=3.54375,AD=7.0875,PS=6.6,PD=13.2);\n"

View File

@ -228,10 +228,10 @@ TEST(1_SimpleInverter)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH"
@ -274,10 +274,10 @@ TEST(1_SimpleInverterMatchedDeviceClasses)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH"
@ -316,10 +316,10 @@ TEST(2_SimpleInverterWithForcedNetAssignment)
"begin_circuit INV INV\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH"
@ -361,9 +361,9 @@ TEST(3_Buffer)
"match_nets IN IN\n"
"match_nets VSS VSS\n"
"match_nets INT $10\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -417,9 +417,9 @@ TEST(4_BufferTwoPaths)
"match_nets VSS VSS\n"
"match_ambiguous_nets INT $10\n"
"match_ambiguous_nets INT2 $11\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -481,9 +481,9 @@ TEST(5_BufferTwoPathsDifferentParameters)
"match_nets IN IN\n"
"match_ambiguous_nets INT $10\n"
"match_nets INT2 $11\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -545,9 +545,9 @@ TEST(5_BufferTwoPathsDifferentDeviceClasses)
"match_nets INT $10\n"
"match_nets OUT OUT\n"
"match_nets INT2 $11\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -610,9 +610,9 @@ TEST(6_BufferTwoPathsAdditionalResistor)
"match_nets OUT OUT\n"
"match_nets INT2 $11\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -673,9 +673,9 @@ TEST(6_BufferTwoPathsAdditionalDevices)
"match_nets OUT OUT\n"
"match_nets VSS VSS\n"
"match_nets INT2 $10\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $2\n"
"match_devices $5 $1\n"
"match_devices $7 $2\n"
@ -722,8 +722,8 @@ TEST(7_Resistors)
"match_nets P1 P1\n"
"match_nets P3 P3\n"
"match_nets P2 P2\n"
"match_pins $1 $1\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
@ -763,8 +763,8 @@ TEST(7_ResistorsParameterMismatch)
"match_nets P2 P2\n"
"match_nets P1 P1\n"
"match_nets P3 P3\n"
"match_pins $1 $1\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_devices $1 $1\n"
"match_devices_with_different_parameters $3 $2\n"
@ -805,8 +805,8 @@ TEST(7_ResistorsPlusOneDevice)
"match_nets P3 P3\n"
"match_nets P2 P2\n"
"match_nets P1 P1\n"
"match_pins $1 $1\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
@ -848,8 +848,8 @@ TEST(8_Diodes)
"match_nets P3 P3\n"
"match_nets P2 P2\n"
"match_pins $0 $0\n"
"match_pins $2 $2\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_devices $3 $1\n"
"match_devices $2 $2\n"
"match_devices $1 $3\n"
@ -937,10 +937,10 @@ TEST(10_SimpleSubCircuits)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH\n"
@ -950,10 +950,10 @@ TEST(10_SimpleSubCircuits)
"match_nets VSS VSS\n"
"match_nets VDD VDD\n"
"match_nets INT INT\n"
"match_pins $1 $0\n"
"match_pins $0 $2\n"
"match_pins $3 $3\n"
"match_pins $1 $0\n"
"match_pins $2 $1\n"
"match_pins $3 $3\n"
"match_subcircuits $2 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit TOP TOP MATCH"
@ -1004,10 +1004,10 @@ TEST(10_SimpleSubCircuitsMatchedNames)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INVB MATCH\n"
@ -1017,10 +1017,10 @@ TEST(10_SimpleSubCircuitsMatchedNames)
"match_nets VSS VSS\n"
"match_nets VDD VDD\n"
"match_nets INT INT\n"
"match_pins $1 $0\n"
"match_pins $0 $2\n"
"match_pins $3 $3\n"
"match_pins $1 $0\n"
"match_pins $2 $1\n"
"match_pins $3 $3\n"
"match_subcircuits $2 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit TOP TOP MATCH"
@ -1068,10 +1068,10 @@ TEST(11_MismatchingSubcircuits)
"match_nets IN IN\n"
"net_mismatch VDD (null)\n"
"net_mismatch (null) VDD\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"pin_mismatch $2 (null)\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"pin_mismatch (null) $0\n"
"device_mismatch $1 (null)\n"
"match_devices $2 $1\n"
@ -1121,10 +1121,10 @@ TEST(12_MismatchingSubcircuitsDuplicates)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH\n"
@ -1135,10 +1135,10 @@ TEST(12_MismatchingSubcircuitsDuplicates)
"match_nets INT INT\n"
"net_mismatch OUT (null)\n"
"net_mismatch (null) OUT\n"
"pin_mismatch $1 (null)\n"
"match_pins $0 $1\n"
"match_pins $3 $3\n"
"pin_mismatch $1 (null)\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"pin_mismatch (null) $0\n"
"subcircuit_mismatch $2 (null)\n"
"subcircuit_mismatch $3 (null)\n"
@ -1192,10 +1192,10 @@ TEST(13_MismatchingSubcircuitsAdditionalHierarchy)
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $0 $1\n"
"match_pins $1 $3\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH\n"
@ -1205,10 +1205,10 @@ TEST(13_MismatchingSubcircuitsAdditionalHierarchy)
"match_nets VSS VSS\n"
"match_nets VDD VDD\n"
"match_nets INT INT\n"
"match_pins $1 $0\n"
"match_pins $0 $1\n"
"match_pins $3 $3\n"
"match_pins $1 $0\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"match_subcircuits $3 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit TOP TOP MATCH"
@ -1261,11 +1261,11 @@ TEST(14_Subcircuit2Nand)
"match_nets OUT OUT\n"
"match_nets A A\n"
"match_nets INT INT\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $0 $0\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_devices $1 $1\n"
"match_devices $2 $2\n"
"match_devices $3 $3\n"
@ -1276,13 +1276,13 @@ TEST(14_Subcircuit2Nand)
"match_nets IN2 IN2\n"
"match_nets VSS VSS\n"
"match_nets VDD VDD\n"
"match_nets IN1 IN1\n"
"match_nets INT INT\n"
"match_pins $2 $2\n"
"match_pins $1 $1\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_nets IN1 IN1\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_subcircuits $2 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit TOP TOP MATCH"
@ -1335,11 +1335,11 @@ TEST(14_Subcircuit2NandMismatchNoSwap)
"match_nets OUT OUT\n"
"match_nets A A\n"
"match_nets INT INT\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $0 $0\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_devices $1 $1\n"
"match_devices $2 $2\n"
"match_devices $3 $3\n"
@ -1347,22 +1347,22 @@ TEST(14_Subcircuit2NandMismatchNoSwap)
"end_circuit NAND NAND MATCH\n"
"begin_circuit TOP TOP\n"
"match_nets OUT OUT\n"
"match_nets IN1 INT\n"
"match_nets INT IN1\n"
"match_nets VDD VDD\n"
"match_nets VSS VSS\n"
"match_nets IN1 IN2\n"
"net_mismatch IN2 (null)\n"
"net_mismatch (null) INT\n"
"match_pins $2 $2\n"
"net_mismatch (null) IN2\n"
"pin_mismatch $0 (null)\n"
"pin_mismatch $1 (null)\n"
"match_pins $4 $4\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"match_pins $0 $1\n"
"match_pins $4 $4\n"
"pin_mismatch (null) $1\n"
"pin_mismatch (null) $0\n"
"subcircuit_mismatch $1 (null)\n"
"subcircuit_mismatch (null) $1\n"
"match_subcircuits $2 $1\n"
"subcircuit_mismatch (null) $2\n"
"subcircuit_mismatch $2 (null)\n"
"end_circuit TOP TOP NOMATCH"
);
@ -1413,11 +1413,11 @@ TEST(14_Subcircuit2MatchWithSwap)
"match_nets OUT OUT\n"
"match_nets A A\n"
"match_nets INT INT\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $0 $0\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_devices $1 $1\n"
"match_devices $2 $2\n"
"match_devices $3 $3\n"
@ -1427,14 +1427,14 @@ TEST(14_Subcircuit2MatchWithSwap)
"match_nets OUT OUT\n"
"match_nets IN2 IN2\n"
"match_nets VSS VSS\n"
"match_nets INT INT\n"
"match_nets VDD VDD\n"
"match_nets INT INT\n"
"match_nets IN1 IN1\n"
"match_pins $2 $2\n"
"match_pins $1 $1\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_subcircuits $2 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit TOP TOP MATCH"
@ -1488,21 +1488,21 @@ TEST(15_EmptySubCircuitTest)
"match_nets $3 $3\n"
"match_nets $2 $1\n"
"match_nets $1 $2\n"
"match_pins D D\n"
"match_pins G G\n"
"match_pins S S\n"
"match_pins G G\n"
"match_pins D D\n"
"end_circuit TRANS TRANS MATCH\n"
"begin_circuit INV2 INV2\n"
"match_nets IN IN\n"
"match_nets OUT OUT\n"
"match_nets $5 $5\n"
"match_nets $4 $4\n"
"match_nets OUT OUT\n"
"match_nets $2 $2\n"
"match_pins IN IN\n"
"match_pins $4 $4\n"
"match_pins $3 $3\n"
"match_pins OUT OUT\n"
"match_pins $1 $1\n"
"match_pins OUT OUT\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
"match_devices $2 $3\n"
@ -1516,3 +1516,116 @@ TEST(15_EmptySubCircuitTest)
EXPECT_EQ (good, true);
}
TEST(16_UniqueSubCircuitMatching)
{
const char *nls1 =
"circuit RINGO ();\n"
" subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=$I22,$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=$I23,$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=$I24,$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=$I25,$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);\n"
"end;\n"
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
" subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
" subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
"end;\n"
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
" device PMOS4 $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device PMOS4 $2 (S=VDD,G=$3,D=OUT,B=$1) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
" device NMOS4 $3 (S=$3,G=IN,D=VSS,B=BULK) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device NMOS4 $4 (S=VSS,G=$3,D=OUT,B=BULK) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
"end;\n";
const char *nls2 =
"circuit RINGO ();\n"
" subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=$I24,$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=$I23,$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=$I22,$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=$I25,$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);\n"
"end;\n"
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
" subcircuit INV2 $1 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
" subcircuit INV2 $2 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
"end;\n"
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
" device PMOS4 $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device NMOS4 $2 (S=$3,G=IN,D=VSS,B=BULK) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device PMOS4 $3 (S=VDD,G=$3,D=OUT,B=$1) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
" device NMOS4 $4 (S=VSS,G=$3,D=OUT,B=BULK) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
"end;\n";
db::Netlist nl1, nl2;
prep_nl (nl1, nls1);
prep_nl (nl2, nls2);
NetlistCompareTestLogger logger;
db::NetlistComparer comp (&logger);
bool good = comp.compare (&nl1, &nl2);
EXPECT_EQ (logger.text (),
"begin_circuit INV2 INV2\n"
"match_nets VDD VDD\n"
"match_nets $1 $1\n"
"match_nets VSS VSS\n"
"match_nets BULK BULK\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_nets $3 $3\n"
"match_pins $0 $0\n"
"match_pins IN IN\n"
"match_pins $2 $2\n"
"match_pins OUT OUT\n"
"match_pins VSS VSS\n"
"match_pins VDD VDD\n"
"match_pins BULK BULK\n"
"match_devices $1 $1\n"
"match_devices $3 $2\n"
"match_devices $2 $3\n"
"match_devices $4 $4\n"
"end_circuit INV2 INV2 MATCH\n"
"begin_circuit INV2PAIR INV2PAIR\n"
"match_nets $I2 $I2\n"
"match_nets $I3 $I3\n"
"match_nets BULK BULK\n"
"match_nets $I6 $I6\n"
"match_nets $I5 $I5\n"
"match_nets $I4 $I4\n"
"match_nets $I1 $I1\n"
"match_nets $I7 $I7\n"
"match_nets $I8 $I8\n"
"match_pins BULK BULK\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_pins $3 $3\n"
"match_pins $4 $4\n"
"match_pins $5 $5\n"
"match_pins $6 $6\n"
"match_subcircuits $2 $1\n"
"match_subcircuits $1 $2\n"
"end_circuit INV2PAIR INV2PAIR MATCH\n"
"begin_circuit RINGO RINGO\n"
"match_nets OSC OSC\n"
"match_nets FB FB\n"
"match_nets VDD VDD\n"
"match_nets BULK,VSS BULK,VSS\n"
"match_nets $I22 $I22\n"
"match_nets $I13 $I13\n"
"match_nets $I7 $I7\n"
"match_nets $I23 $I23\n"
"match_nets $I5 $I5\n"
"match_nets $I25 $I25\n"
"match_nets $I24 $I24\n"
"match_nets $I6 $I6\n"
"match_subcircuits $1 $1\n"
"match_subcircuits $4 $2\n"
"match_subcircuits $3 $3\n"
"match_subcircuits $2 $4\n"
"match_subcircuits $5 $5\n"
"end_circuit RINGO RINGO MATCH"
);
EXPECT_EQ (good, true);
}

Binary file not shown.