mirror of https://github.com/KLayout/klayout.git
WIP: netlist compare - bugfixed latest version and updated tests.
This commit is contained in:
parent
4e85ae7db0
commit
92524dcf57
|
|
@ -29,7 +29,7 @@
|
|||
#include "tlLog.h"
|
||||
|
||||
// verbose debug output
|
||||
#define PRINT_DEBUG_NETCOMPARE
|
||||
// #define PRINT_DEBUG_NETCOMPARE
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -100,6 +100,16 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
size_t is_mapped (const db::Circuit *circuit, size_t pin_id) const
|
||||
{
|
||||
std::map<const db::Circuit *, tl::equivalence_clusters<size_t> >::const_iterator pm = m_pin_map.find (circuit);
|
||||
if (pm != m_pin_map.end ()) {
|
||||
return pm->second.has_attribute (pin_id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t normalize_pin_id (const db::Circuit *circuit, size_t pin_id) const
|
||||
{
|
||||
std::map<const db::Circuit *, tl::equivalence_clusters<size_t> >::const_iterator pm = m_pin_map.find (circuit);
|
||||
|
|
@ -1468,6 +1478,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
|||
// we need to create a copy because this method is supposed to be const.
|
||||
db::CircuitCategorizer circuit_categorizer = *mp_circuit_categorizer;
|
||||
db::DeviceCategorizer device_categorizer = *mp_device_categorizer;
|
||||
db::CircuitPinMapper circuit_pin_mapper = *mp_circuit_pin_mapper;
|
||||
|
||||
bool good = true;
|
||||
|
||||
|
|
@ -1553,7 +1564,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, c12_pin_mapping, c22_pin_mapping);
|
||||
bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping);
|
||||
if (! g) {
|
||||
good = false;
|
||||
}
|
||||
|
|
@ -1563,6 +1574,8 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
|||
verified_circuits_b.insert (cb);
|
||||
}
|
||||
|
||||
derive_pin_equivalence (ca, cb, &circuit_pin_mapper);
|
||||
|
||||
if (mp_logger) {
|
||||
mp_logger->end_circuit (ca, cb, g);
|
||||
}
|
||||
|
|
@ -1586,6 +1599,36 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
|||
return good;
|
||||
}
|
||||
|
||||
static
|
||||
std::vector<size_t> collect_pins_with_empty_nets (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper)
|
||||
{
|
||||
std::vector<size_t> pins;
|
||||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
const db::Net *net = n.operator-> ();
|
||||
if (net->pin_count () > 0 && net->terminal_count () == 0 && net->subcircuit_pin_count () == 0) {
|
||||
for (db::Net::const_pin_iterator p = net->begin_pins (); p != net->end_pins (); ++p) {
|
||||
if (! circuit_pin_mapper->is_mapped (c, p->pin_id ())) {
|
||||
pins.push_back (p->pin_id ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pins;
|
||||
}
|
||||
|
||||
void
|
||||
NetlistComparer::derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper)
|
||||
{
|
||||
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);
|
||||
|
||||
circuit_pin_mapper->map_pins (ca, pa);
|
||||
circuit_pin_mapper->map_pins (cb, pb);
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistComparer::all_subcircuits_verified (const db::Circuit *c, const std::set<const db::Circuit *> &verified_circuits) const
|
||||
{
|
||||
|
|
@ -1662,7 +1705,7 @@ 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> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping) const
|
||||
NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, db::CircuitPinMapper &circuit_pin_mapper, 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::DeviceFilter device_filter (m_cap_threshold, m_res_threshold);
|
||||
|
||||
|
|
@ -1670,8 +1713,8 @@ 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.
|
||||
g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
|
||||
g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
|
||||
g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper);
|
||||
g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper);
|
||||
|
||||
// Match dummy nodes for null nets
|
||||
g1.identify (0, 0);
|
||||
|
|
@ -1707,7 +1750,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
|
||||
for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) {
|
||||
if (i1->has_other () && i1->net ()) {
|
||||
size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||
size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, 1, mp_logger, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||
new_identities += ni;
|
||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||
|
|
@ -1750,7 +1793,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
std::sort (nodes.begin (), nodes.end (), CompareNodePtr ());
|
||||
std::sort (other_nodes.begin (), other_nodes.end (), CompareNodePtr ());
|
||||
|
||||
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, g2, 0, 1, mp_logger, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||
new_identities += ni;
|
||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||
|
|
@ -1960,7 +2003,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, &c12_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, &circuit_pin_mapper);
|
||||
|
||||
bool mapped = true;
|
||||
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end () && mapped; ++i) {
|
||||
|
|
@ -1983,7 +2026,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, &c22_circuit_and_pin_mapping, mp_circuit_pin_mapper.get ());
|
||||
std::vector<std::pair<size_t, size_t> > k = compute_subcircuit_key (*sc, g2, &c22_circuit_and_pin_mapping, &circuit_pin_mapper);
|
||||
|
||||
bool mapped = true;
|
||||
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {
|
||||
|
|
|
|||
|
|
@ -217,8 +217,9 @@ 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> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping) const;
|
||||
bool compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, db::CircuitPinMapper &circuit_pin_mapper, 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;
|
||||
static void derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper);
|
||||
|
||||
NetlistCompareLogger *mp_logger;
|
||||
std::map<std::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<const Net *, const Net *> > > m_same_nets;
|
||||
|
|
|
|||
|
|
@ -335,8 +335,9 @@ TEST(1_SimpleInverter)
|
|||
EXPECT_EQ (logger.text (),
|
||||
"begin_circuit INV INV\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $3\n"
|
||||
"match_pins $2 $0\n"
|
||||
|
|
@ -880,8 +881,8 @@ TEST(5_BufferTwoPathsDifferentDeviceClasses)
|
|||
"begin_circuit BUF BUF\n"
|
||||
"match_nets INT $10\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets INT2 $11\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"
|
||||
|
|
@ -945,8 +946,8 @@ TEST(6_BufferTwoPathsAdditionalResistor)
|
|||
"begin_circuit BUF BUF\n"
|
||||
"match_nets INT $10\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets INT2 $11\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"
|
||||
|
|
@ -1007,9 +1008,9 @@ TEST(6_BufferTwoPathsAdditionalDevices)
|
|||
"match_nets INT $11\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets INT2 $10\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets INT2 $10\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $3\n"
|
||||
"match_pins $2 $0\n"
|
||||
|
|
@ -1617,9 +1618,9 @@ TEST(14_Subcircuit2Nand)
|
|||
"end_circuit NAND NAND MATCH\n"
|
||||
"begin_circuit TOP TOP\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets IN1 IN1\n"
|
||||
"match_nets IN2 IN2\n"
|
||||
"match_nets INT INT\n"
|
||||
"match_nets IN2 IN2\n"
|
||||
"match_nets IN1 IN1\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_pins $0 $0\n"
|
||||
|
|
@ -1767,9 +1768,9 @@ TEST(14_Subcircuit2MatchWithSwap)
|
|||
"end_circuit NAND NAND MATCH\n"
|
||||
"begin_circuit TOP TOP\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets IN1 IN1\n"
|
||||
"match_nets IN2 IN2\n"
|
||||
"match_nets INT INT\n"
|
||||
"match_nets IN2 IN2\n"
|
||||
"match_nets IN1 IN1\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_pins $0 $0\n"
|
||||
|
|
@ -1886,7 +1887,8 @@ TEST(15_EmptySubCircuitWithoutPinNames)
|
|||
" subcircuit TRANS $3 ($1=OUT,$2=$5,$3=$2);\n"
|
||||
" subcircuit TRANS $4 ($1=OUT,$2=$4,$3=$2);\n"
|
||||
"end;\n"
|
||||
// This circuit is an abstract and it's pins are defined by the pin names
|
||||
// This circuit is an abstract and it's pins are not defined by the pin names ->
|
||||
// they are internally marked as swappable
|
||||
"circuit TRANS ($1=$1,$2=$2,$3=$3);\n"
|
||||
"end;\n";
|
||||
|
||||
|
|
@ -2110,27 +2112,27 @@ TEST(17_InherentlyAmbiguousDecoder)
|
|||
"match_devices $4 $4\n"
|
||||
"end_circuit NAND NAND MATCH\n"
|
||||
"begin_circuit DECODER DECODER\n"
|
||||
"match_nets NA NB\n"
|
||||
"match_nets A B\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets B A\n"
|
||||
"match_nets NB NA\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_ambiguous_nets NQ0 NQ0\n"
|
||||
"match_ambiguous_nets NQ2 NQ1\n"
|
||||
"match_ambiguous_nets NQ1 NQ2\n"
|
||||
"match_ambiguous_nets NQ3 NQ3\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $0\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_ambiguous_nets A B\n"
|
||||
"match_ambiguous_nets B A\n"
|
||||
"match_nets NB NA\n"
|
||||
"match_nets NA NB\n"
|
||||
"match_nets NQ0 NQ0\n"
|
||||
"match_nets NQ2 NQ1\n"
|
||||
"match_nets NQ1 NQ2\n"
|
||||
"match_nets NQ3 NQ3\n"
|
||||
"match_pins $0 $0\n"
|
||||
"match_pins $1 $1\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $3\n"
|
||||
"match_pins $5 $5\n"
|
||||
"match_pins $6 $6\n"
|
||||
"match_pins $7 $7\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $5 $2\n"
|
||||
"match_subcircuits $2 $3\n"
|
||||
"match_subcircuits $2 $1\n"
|
||||
"match_subcircuits $1 $2\n"
|
||||
"match_subcircuits $5 $3\n"
|
||||
"match_subcircuits $6 $4\n"
|
||||
"match_subcircuits $3 $5\n"
|
||||
"match_subcircuits $4 $6\n"
|
||||
|
|
@ -2138,5 +2140,56 @@ TEST(17_InherentlyAmbiguousDecoder)
|
|||
);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
logger.clear ();
|
||||
comp.same_nets (nl1.circuit_by_name ("DECODER")->net_by_name ("A"), nl2.circuit_by_name ("DECODER")->net_by_name ("A"));
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (logger.text (),
|
||||
"begin_circuit NAND NAND\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets INT INT\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets B B\n"
|
||||
"match_nets A A\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_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit NAND NAND MATCH\n"
|
||||
"begin_circuit DECODER DECODER\n"
|
||||
"match_nets NB NB\n"
|
||||
"match_nets B B\n"
|
||||
"match_nets NA NA\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets NQ0 NQ0\n"
|
||||
"match_nets NQ2 NQ2\n"
|
||||
"match_nets NQ1 NQ1\n"
|
||||
"match_nets NQ3 NQ3\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $0\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_pins $7 $7\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $4 $3\n"
|
||||
"match_subcircuits $6 $4\n"
|
||||
"match_subcircuits $3 $5\n"
|
||||
"match_subcircuits $5 $6\n"
|
||||
"end_circuit DECODER DECODER MATCH"
|
||||
);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -616,8 +616,8 @@ END
|
|||
begin_circuit BUF BUF
|
||||
match_nets INT $10
|
||||
match_nets IN IN
|
||||
match_nets INT2 $11
|
||||
match_nets OUT OUT
|
||||
match_nets INT2 $11
|
||||
match_pins $0 $1
|
||||
match_pins $1 $3
|
||||
match_pins $2 $0
|
||||
|
|
@ -686,8 +686,8 @@ END
|
|||
begin_circuit BUF BUF
|
||||
match_nets INT $10
|
||||
match_nets IN IN
|
||||
match_nets INT2 $11
|
||||
match_nets OUT OUT
|
||||
match_nets INT2 $11
|
||||
match_pins $0 $1
|
||||
match_pins $1 $3
|
||||
match_pins $2 $0
|
||||
|
|
@ -840,9 +840,9 @@ match_devices $4 $4
|
|||
end_circuit NAND NAND MATCH
|
||||
begin_circuit TOP TOP
|
||||
match_nets OUT OUT
|
||||
match_nets IN1 IN1
|
||||
match_nets IN2 IN2
|
||||
match_nets INT INT
|
||||
match_nets IN2 IN2
|
||||
match_nets IN1 IN1
|
||||
match_nets VDD VDD
|
||||
match_nets VSS VSS
|
||||
match_pins $0 $0
|
||||
|
|
|
|||
Loading…
Reference in New Issue