WIP: netlist compare - bugfixed latest version and updated tests.

This commit is contained in:
Matthias Koefferlein 2019-04-13 19:56:08 +02:00
parent 4e85ae7db0
commit 92524dcf57
4 changed files with 134 additions and 37 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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