mirror of https://github.com/KLayout/klayout.git
WIP: added configuration options (complexity, depth) for net compare
This commit is contained in:
parent
92524dcf57
commit
699e94a45f
|
|
@ -29,7 +29,7 @@
|
||||||
#include "tlLog.h"
|
#include "tlLog.h"
|
||||||
|
|
||||||
// verbose debug output
|
// verbose debug output
|
||||||
// #define PRINT_DEBUG_NETCOMPARE
|
#define PRINT_DEBUG_NETCOMPARE
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
@ -874,9 +874,9 @@ public:
|
||||||
* If tentative is true, assignments will not be retained and just the
|
* If tentative is true, assignments will not be retained and just the
|
||||||
* status is reported.
|
* status is reported.
|
||||||
*/
|
*/
|
||||||
size_t derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
size_t derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
||||||
|
|
||||||
size_t derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
size_t derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<NetGraphNode> m_nodes;
|
std::vector<NetGraphNode> m_nodes;
|
||||||
|
|
@ -941,10 +941,6 @@ private:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// @@@ make attribute
|
|
||||||
const size_t depth_max = 8;
|
|
||||||
const size_t n_branch_max = 100;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetDeviceGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map<const db::Circuit *, CircuitMapper> *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper)
|
NetDeviceGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const db::DeviceFilter &device_filter, const std::map<const db::Circuit *, CircuitMapper> *circuit_and_pin_mapping, const CircuitPinMapper *circuit_pin_mapper)
|
||||||
{
|
{
|
||||||
|
|
@ -982,7 +978,7 @@ NetDeviceGraph::build (const db::Circuit *c, DeviceCategorizer &device_categoriz
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
||||||
{
|
{
|
||||||
NetGraphNode *n = & m_nodes[net_index];
|
NetGraphNode *n = & m_nodes[net_index];
|
||||||
NetGraphNode *nother = & other.m_nodes[n->other_net_index ()];
|
NetGraphNode *nother = & other.m_nodes[n->other_net_index ()];
|
||||||
|
|
@ -1076,7 +1072,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
// propagate pairing in picky mode: this means we only accept exact a match if the node set
|
// propagate pairing in picky mode: this means we only accept exact a match if the node set
|
||||||
// is exactly identical and no ambiguous nodes are present when ambiguous nodes are forbidden
|
// is exactly identical and no ambiguous nodes are present when ambiguous nodes are forbidden
|
||||||
|
|
||||||
size_t bt_count = derive_node_identities_from_node_set (nodes, other_nodes, other, depth, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
size_t bt_count = derive_node_identities_from_node_set (nodes, other_nodes, other, depth, max_depth, n_branch, max_n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
|
|
||||||
if (bt_count == std::numeric_limits<size_t>::max ()) {
|
if (bt_count == std::numeric_limits<size_t>::max ()) {
|
||||||
if (tentative) {
|
if (tentative) {
|
||||||
|
|
@ -1102,18 +1098,22 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t max_depth, size_t n_branch, size_t max_n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
||||||
{
|
{
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
std::string indent;
|
std::string indent;
|
||||||
for (size_t d = 0; d < depth; ++d) {
|
for (size_t d = 0; d < depth; ++d) {
|
||||||
indent += " ";
|
indent += " ";
|
||||||
}
|
}
|
||||||
|
indent += "*" + tl::to_string (n_branch) + " ";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t new_nodes = 0;
|
size_t new_nodes = 0;
|
||||||
|
|
||||||
if (depth + 1 == depth_max) {
|
if (depth > max_depth) {
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "max. depth exhausted (" << depth + 1 << ">" << max_depth << ")";
|
||||||
|
#endif
|
||||||
return std::numeric_limits<size_t>::max ();
|
return std::numeric_limits<size_t>::max ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1139,7 +1139,7 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue here.
|
// continue here.
|
||||||
size_t bt_count = derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, max_depth, n_branch, max_n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
|
|
||||||
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
new_nodes += bt_count;
|
new_nodes += bt_count;
|
||||||
|
|
@ -1232,6 +1232,8 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
for (std::vector<NodeRange>::const_iterator nr = node_ranges.begin (); nr != node_ranges.end (); ++nr) {
|
for (std::vector<NodeRange>::const_iterator nr = node_ranges.begin (); nr != node_ranges.end (); ++nr) {
|
||||||
|
|
||||||
|
// @@@ node ranges might have changed - adjust to real count and skip leading pairs assigned already
|
||||||
|
|
||||||
if (nr->num == 1) {
|
if (nr->num == 1) {
|
||||||
|
|
||||||
if (! (*nr->n1)->has_other () && ! (*nr->n2)->has_other ()) {
|
if (! (*nr->n1)->has_other () && ! (*nr->n2)->has_other ()) {
|
||||||
|
|
@ -1254,7 +1256,7 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue here.
|
// continue here.
|
||||||
size_t bt_count = derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, max_depth, n_branch, max_n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
|
|
||||||
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
new_nodes += bt_count;
|
new_nodes += bt_count;
|
||||||
|
|
@ -1277,12 +1279,18 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (nr->num * n_branch > n_branch_max) {
|
} else if (nr->num * n_branch > max_n_branch) {
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << max_n_branch << ") - mismatch.";
|
||||||
|
#endif
|
||||||
return std::numeric_limits<size_t>::max ();
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "analyzing ambiguity group with " << nr->num << " members";
|
||||||
|
#endif
|
||||||
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
|
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
|
||||||
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
|
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
|
||||||
std::set<const NetGraphNode *> seen;
|
std::set<const NetGraphNode *> seen;
|
||||||
|
|
@ -1316,7 +1324,7 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << indent << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name ();
|
tl::info << indent << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name ();
|
||||||
#endif
|
#endif
|
||||||
size_t bt_count = derive_node_identities (ni, other, depth + 1, nr->num * n_branch, logger, circuit_pin_mapper, &tn, with_ambiguous);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, max_depth, nr->num * n_branch, max_n_branch, logger, circuit_pin_mapper, &tn, with_ambiguous);
|
||||||
|
|
||||||
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
|
|
||||||
|
|
@ -1386,7 +1394,7 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
size_t ni = node_index_for_net (p->first->net ());
|
size_t ni = node_index_for_net (p->first->net ());
|
||||||
|
|
||||||
size_t bt_count = derive_node_identities (ni, other, depth + 1, nr->num * n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, max_depth, nr->num * n_branch, max_n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
tl_assert (bt_count != std::numeric_limits<size_t>::max ());
|
tl_assert (bt_count != std::numeric_limits<size_t>::max ());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1404,6 +1412,10 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "finished analysis of ambiguity group with " << nr->num << " members";
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1424,6 +1436,9 @@ NetlistComparer::NetlistComparer (NetlistCompareLogger *logger)
|
||||||
|
|
||||||
m_cap_threshold = -1.0; // not set
|
m_cap_threshold = -1.0; // not set
|
||||||
m_res_threshold = -1.0; // not set
|
m_res_threshold = -1.0; // not set
|
||||||
|
|
||||||
|
m_max_depth = 8;
|
||||||
|
m_max_n_branch = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1737,32 +1752,38 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
||||||
|
|
||||||
for (int pass = 0; pass < 2; ++pass) {
|
for (int pass = 0; pass < 2; ++pass) {
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
if (pass > 0) {
|
||||||
|
tl::info << "including ambiguous nodes now.";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
good = true;
|
good = true;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
++iter;
|
++iter;
|
||||||
tl::info << "new compare iteration #" << iter;
|
tl::info << "new compare iteration #" << iter;
|
||||||
tl::info << "deducing from present nodes ...";
|
tl::info << "deducing from present nodes ...";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t new_identities = 0;
|
size_t new_identities = 0;
|
||||||
|
|
||||||
for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) {
|
for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) {
|
||||||
if (i1->has_other () && i1->net ()) {
|
if (i1->has_other () && i1->net ()) {
|
||||||
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*/);
|
size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, m_max_depth, 1, m_max_n_branch, mp_logger, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||||
new_identities += ni;
|
new_identities += ni;
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << ni << " new identities.";
|
tl::info << ni << " new identities.";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << "checking topological identity ...";
|
tl::info << "checking topological identity ...";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// derive new identities through topology: first collect all nets with the same topological signature
|
// derive new identities through topology: first collect all nets with the same topological signature
|
||||||
|
|
||||||
|
|
@ -1793,12 +1814,12 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
||||||
std::sort (nodes.begin (), nodes.end (), CompareNodePtr ());
|
std::sort (nodes.begin (), nodes.end (), CompareNodePtr ());
|
||||||
std::sort (other_nodes.begin (), other_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, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, g2, 0, m_max_depth, 1, m_max_n_branch, mp_logger, &circuit_pin_mapper, 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||||
new_identities += ni;
|
new_identities += ni;
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << ni << " new identities.";
|
tl::info << ni << " new identities.";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_identities == 0) {
|
if (new_identities == 0) {
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,48 @@ public:
|
||||||
*/
|
*/
|
||||||
void exclude_resistors (double threshold);
|
void exclude_resistors (double threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the maximum seach depth
|
||||||
|
*
|
||||||
|
* This value limits the search depth of the backtracking algorithm to the
|
||||||
|
* given number of jumps.
|
||||||
|
*/
|
||||||
|
void set_max_depth (size_t n)
|
||||||
|
{
|
||||||
|
m_max_depth = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the maximum search depth
|
||||||
|
*/
|
||||||
|
size_t max_depth () const
|
||||||
|
{
|
||||||
|
return m_max_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the maximum branch complexity
|
||||||
|
*
|
||||||
|
* This value limits the maximum branch complexity of the backtracking algorithm.
|
||||||
|
* The complexity is the accumulated number of branch options with ambiguous
|
||||||
|
* net matches. Backtracking will stop when the maximum number of options
|
||||||
|
* has been exceeded.
|
||||||
|
* As the computational complexity is the square of the branch count,
|
||||||
|
* this value should be adjusted carefully.
|
||||||
|
*/
|
||||||
|
void set_max_branch_complexity (size_t n)
|
||||||
|
{
|
||||||
|
m_max_n_branch = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the maximum branch complexity
|
||||||
|
*/
|
||||||
|
size_t max_branch_complexity () const
|
||||||
|
{
|
||||||
|
return m_max_n_branch;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Actually compares the two netlists
|
* @brief Actually compares the two netlists
|
||||||
*/
|
*/
|
||||||
|
|
@ -228,6 +270,8 @@ protected:
|
||||||
std::auto_ptr<CircuitCategorizer> mp_circuit_categorizer;
|
std::auto_ptr<CircuitCategorizer> mp_circuit_categorizer;
|
||||||
double m_cap_threshold;
|
double m_cap_threshold;
|
||||||
double m_res_threshold;
|
double m_res_threshold;
|
||||||
|
size_t m_max_n_branch;
|
||||||
|
size_t m_max_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,29 @@ Class<db::NetlistComparer> decl_dbNetlistComparer ("db", "NetlistComparer",
|
||||||
"@brief Excludes all resistor devices with a resistance values higher than the given threshold.\n"
|
"@brief Excludes all resistor devices with a resistance values higher than the given threshold.\n"
|
||||||
"To reset this constraint, set this attribute to zero."
|
"To reset this constraint, set this attribute to zero."
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("max_depth=", &db::NetlistComparer::set_max_depth, gsi::arg ("n"),
|
||||||
|
"@brief Sets the maximum seach depth\n"
|
||||||
|
"This value limits the search depth of the backtracking algorithm to the\n"
|
||||||
|
"given number of jumps.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("max_depth", &db::NetlistComparer::max_depth,
|
||||||
|
"@brief Gets the maximum seach depth\n"
|
||||||
|
"See \\max_depth= for details."
|
||||||
|
) +
|
||||||
|
gsi::method ("max_branch_complexity=", &db::NetlistComparer::set_max_branch_complexity, gsi::arg ("n"),
|
||||||
|
"@brief Sets the maximum branch complexity\n"
|
||||||
|
"This value limits the maximum branch complexity of the backtracking algorithm.\n"
|
||||||
|
"The complexity is the accumulated number of branch options with ambiguous\n"
|
||||||
|
"net matches. Backtracking will stop when the maximum number of options\n"
|
||||||
|
"has been exceeded.\n"
|
||||||
|
"\n"
|
||||||
|
"As the computational complexity is the square of the branch count,\n"
|
||||||
|
"this value should be adjusted carefully.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("max_branch_complexity", &db::NetlistComparer::max_branch_complexity,
|
||||||
|
"@brief Gets the maximum branch complexity\n"
|
||||||
|
"See \\max_branch_complexity= for details."
|
||||||
|
) +
|
||||||
gsi::method ("compare", &db::NetlistComparer::compare, gsi::arg ("netlist_a"), gsi::arg ("netlist_b"),
|
gsi::method ("compare", &db::NetlistComparer::compare, gsi::arg ("netlist_a"), gsi::arg ("netlist_b"),
|
||||||
"@brief Compares two netlists.\n"
|
"@brief Compares two netlists.\n"
|
||||||
"This method will perform the actual netlist compare. It will return true if both netlists are identical. "
|
"This method will perform the actual netlist compare. It will return true if both netlists are identical. "
|
||||||
|
|
|
||||||
|
|
@ -2193,3 +2193,112 @@ TEST(17_InherentlyAmbiguousDecoder)
|
||||||
EXPECT_EQ (good, true);
|
EXPECT_EQ (good, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(18_ClockTree)
|
||||||
|
{
|
||||||
|
const char *nls1 =
|
||||||
|
"circuit INV (IN=IN,OUT=OUT,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
|
" device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
|
"end;\n"
|
||||||
|
"circuit TREE ();\n"
|
||||||
|
" subcircuit INV T (IN=IN,OUT=S,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TR (IN=S,OUT=SR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TL (IN=S,OUT=SL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRR (IN=SR,OUT=SRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRL (IN=SR,OUT=SRL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLR (IN=SL,OUT=SLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLL (IN=SL,OUT=SLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRRR (IN=SRR,OUT=SRRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRRL (IN=SRR,OUT=SRRL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRLR (IN=SRL,OUT=SRLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRLL (IN=SRL,OUT=SRLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLRR (IN=SLR,OUT=SLRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLRL (IN=SLR,OUT=SLRL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLLR (IN=SLL,OUT=SLLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLLL (IN=SLL,OUT=SLLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
"end;\n";
|
||||||
|
|
||||||
|
const char *nls2 =
|
||||||
|
"circuit INV (IN=IN,OUT=OUT,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
|
" device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
|
"end;\n"
|
||||||
|
"circuit TREE ();\n"
|
||||||
|
" subcircuit INV TLRR (IN=SLR,OUT=SLRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TR (IN=S,OUT=SR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRRL (IN=SRR,OUT=SRRL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRLR (IN=SRL,OUT=SRLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLR (IN=SL,OUT=SLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLL (IN=SL,OUT=SLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRRR (IN=SRR,OUT=SRRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLLL (IN=SLL,OUT=SLLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLRL (IN=SLR,OUT=SLRL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV T (IN=IN,OUT=S,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TLLR (IN=SLL,OUT=SLLR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TL (IN=S,OUT=SL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRR (IN=SR,OUT=SRR,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRLL (IN=SRL,OUT=SRLL,VDD=VDD,VSS=VSS);\n"
|
||||||
|
" subcircuit INV TRL (IN=SR,OUT=SRL,VDD=VDD,VSS=VSS);\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 INV INV\n"
|
||||||
|
"match_nets VDD VDD\n"
|
||||||
|
"match_nets OUT OUT\n"
|
||||||
|
"match_nets IN IN\n"
|
||||||
|
"match_nets VSS VSS\n"
|
||||||
|
"match_pins IN IN\n"
|
||||||
|
"match_pins OUT OUT\n"
|
||||||
|
"match_pins VDD VDD\n"
|
||||||
|
"match_pins VSS VSS\n"
|
||||||
|
"match_devices $1 $1\n"
|
||||||
|
"match_devices $2 $2\n"
|
||||||
|
"end_circuit INV INV MATCH\n"
|
||||||
|
"begin_circuit TREE TREE\n"
|
||||||
|
"match_nets IN IN\n"
|
||||||
|
"match_nets S S\n"
|
||||||
|
"match_nets VDD VDD\n"
|
||||||
|
"match_nets VSS VSS\n"
|
||||||
|
"match_ambiguous_nets SL SR\n"
|
||||||
|
"match_ambiguous_nets SR SL\n"
|
||||||
|
"match_ambiguous_nets SLL SRL\n"
|
||||||
|
"match_ambiguous_nets SLR SRR\n"
|
||||||
|
"match_ambiguous_nets SLLL SRLL\n"
|
||||||
|
"match_ambiguous_nets SLLR SRLR\n"
|
||||||
|
"match_ambiguous_nets SLRL SRRL\n"
|
||||||
|
"match_ambiguous_nets SLRR SRRR\n"
|
||||||
|
"match_ambiguous_nets SRL SLL\n"
|
||||||
|
"match_ambiguous_nets SRR SLR\n"
|
||||||
|
"match_ambiguous_nets SRLL SLLR\n"
|
||||||
|
"match_ambiguous_nets SRLR SLLL\n"
|
||||||
|
"match_ambiguous_nets SRRL SLRR\n"
|
||||||
|
"match_ambiguous_nets SRRR SLRL\n"
|
||||||
|
"match_subcircuits TRRL TLRR\n"
|
||||||
|
"match_subcircuits TL TR\n"
|
||||||
|
"match_subcircuits TLRL TRRL\n"
|
||||||
|
"match_subcircuits TLLR TRLR\n"
|
||||||
|
"match_subcircuits TRR TLR\n"
|
||||||
|
"match_subcircuits TRL TLL\n"
|
||||||
|
"match_subcircuits TLRR TRRR\n"
|
||||||
|
"match_subcircuits TRLR TLLL\n"
|
||||||
|
"match_subcircuits TRRR TLRL\n"
|
||||||
|
"match_subcircuits T T\n"
|
||||||
|
"match_subcircuits TRLL TLLR\n"
|
||||||
|
"match_subcircuits TR TL\n"
|
||||||
|
"match_subcircuits TLR TRR\n"
|
||||||
|
"match_subcircuits TLLL TRLL\n"
|
||||||
|
"match_subcircuits TLL TRL\n"
|
||||||
|
"end_circuit TREE TREE MATCH"
|
||||||
|
);
|
||||||
|
EXPECT_EQ (good, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue