diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 04e58dcf2..99c3cec22 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -3712,7 +3712,7 @@ static bool derive_symmetry_groups (const db::NetGraph &graph, const tl::equival } void -NetlistComparer::join_symmetric_nodes (db::Circuit *circuit) +NetlistComparer::join_symmetric_nets (db::Circuit *circuit) { tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Join symmetric nodes for circuit: ")) + circuit->name ()); diff --git a/src/db/db/dbNetlistCompare.h b/src/db/db/dbNetlistCompare.h index bacf209b3..d639ed12f 100644 --- a/src/db/db/dbNetlistCompare.h +++ b/src/db/db/dbNetlistCompare.h @@ -314,7 +314,7 @@ public: * condition (device filtering, device compare tolerances, device class * equivalence etc.). */ - void join_symmetric_nodes (db::Circuit *circuit); + void join_symmetric_nets (db::Circuit *circuit); private: // No copying diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 7300b2a09..79a91fc2c 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -1418,6 +1418,22 @@ static void blank_circuit_by_name (db::Netlist *nl, const std::string &name_patt } } +static std::vector +circuits_by_name (db::Netlist *netlist, const std::string &name_pattern) +{ + std::vector res; + + tl::GlobPattern glob (name_pattern); + for (db::Netlist::circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) { + db::Circuit *circuit = c.operator-> (); + if (glob.match (circuit->name ())) { + res.push_back (circuit); + } + } + + return res; +} + Class decl_dbNetlist ("db", "Netlist", gsi::method_ext ("add", &gsi::add_circuit, gsi::arg ("circuit"), "@brief Adds the circuit to the netlist\n" @@ -1475,6 +1491,12 @@ Class decl_dbNetlist ("db", "Netlist", "@brief Gets the circuit object for a given name.\n" "If the name is not a valid circuit name, nil is returned." ) + + gsi::method_ext ("circuits_by_name", &circuits_by_name, gsi::arg ("name_pattern"), + "@brief Gets the circuit objects for a given name filter.\n" + "The name filter is a glob pattern. This method will return all \\Circuit objects matching the glob pattern.\n" + "\n" + "This method has been introduced in version 0.26.4.\n" + ) + gsi::iterator ("each_circuit_top_down", (db::Netlist::top_down_circuit_iterator (db::Netlist::*) ()) &db::Netlist::begin_top_down, (db::Netlist::top_down_circuit_iterator (db::Netlist::*) ()) &db::Netlist::end_top_down, "@brief Iterates over the circuits top-down\n" "Iterating top-down means the parent circuits come before the child circuits. " diff --git a/src/db/db/gsiDeclDbNetlistCompare.cc b/src/db/db/gsiDeclDbNetlistCompare.cc index 31e4275a2..df91db260 100644 --- a/src/db/db/gsiDeclDbNetlistCompare.cc +++ b/src/db/db/gsiDeclDbNetlistCompare.cc @@ -557,6 +557,20 @@ Class decl_dbNetlistComparer ("db", "NetlistComparer", "This method will perform the actual netlist compare using the given logger. It will return true if both netlists are identical. " "If the comparer has been configured with \\same_nets or similar methods, the objects given there must " "be located inside 'circuit_a' and 'circuit_b' respectively." + ) + + gsi::method ("join_symmetric_nets", &db::NetlistComparer::join_symmetric_nets, gsi::arg ("circuit"), + "@brief Joins symmetric nodes in the given circuit.\n" + "\n" + "Nodes are symmetrical if swapping them would not modify the circuit.\n" + "Hence they will carry the same potential and can be connected (joined).\n" + "This will simplify the circuit and can be applied before device combination\n" + "to render a schematic-equivalent netlist in some cases (split gate option).\n" + "\n" + "This algorithm will apply the comparer's settings to the symmetry\n" + "condition (device filtering, device compare tolerances, device class\n" + "equivalence etc.).\n" + "\n" + "This method has been introduced in version 0.26.4.\n" ), "@brief Compares two netlists\n" "This class performs a comparison of two netlists.\n" diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 5c89e8012..0b06a7a04 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -3721,7 +3721,7 @@ TEST(25_JoinSymmetricNets) prep_nl (nl, nls); db::NetlistComparer comp; - comp.join_symmetric_nodes (nl.circuit_by_name ("NAND2")); + comp.join_symmetric_nets (nl.circuit_by_name ("NAND2")); // NOTE $1 and $2 are joined because they are symmetric EXPECT_EQ (nl.to_string (), @@ -3758,7 +3758,7 @@ TEST(26_JoinSymmetricNets) prep_nl (nl, nls); db::NetlistComparer comp; - comp.join_symmetric_nodes (nl.circuit_by_name ("RESCUBE")); + comp.join_symmetric_nets (nl.circuit_by_name ("RESCUBE")); EXPECT_EQ (nl.to_string (), "circuit RESCUBE (A=A,B=B);\n" @@ -3802,7 +3802,7 @@ TEST(27_DontJoinSymmetricNetsWithPins) prep_nl (nl, nls); db::NetlistComparer comp; - comp.join_symmetric_nodes (nl.circuit_by_name ("NAND2")); + comp.join_symmetric_nets (nl.circuit_by_name ("NAND2")); // NOTE $1 and $2 are NOT joined because they have pins EXPECT_EQ (nl.to_string (), @@ -3836,7 +3836,7 @@ TEST(28_NoSymmetryDetectionCases) db::NetlistComparer comp; std::string sref = nl.to_string (); - comp.join_symmetric_nodes (nl.circuit_by_name ("NAND2")); + comp.join_symmetric_nets (nl.circuit_by_name ("NAND2")); EXPECT_EQ (nl.to_string (), sref); } @@ -3858,7 +3858,7 @@ TEST(28_NoSymmetryDetectionCases) db::NetlistComparer comp; std::string sref = nl.to_string (); - comp.join_symmetric_nodes (nl.circuit_by_name ("NAND2")); + comp.join_symmetric_nets (nl.circuit_by_name ("NAND2")); EXPECT_EQ (nl.to_string (), sref); } diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index d73d9921b..7f40be626 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -90,6 +90,13 @@ class DBNetlist_TestClass < TestBase nl.each_circuit { |i| names << i.name } assert_equal(names, [ c.name, cc.name ]) + assert_equal(nl.circuits_by_name("X*").collect { |c| c.name }, [ "XYZ" ]) + assert_equal(nl.circuits_by_name("???").collect { |c| c.name }, [ "XYZ", "UVW" ]) + assert_equal(nl.circuits_by_name("*").collect { |c| c.name }, [ "XYZ", "UVW" ]) + assert_equal(nl.circuits_by_name("P*").collect { |c| c.name }, []) + assert_equal(nl.circuits_by_name("x*").collect { |c| c.name }, []) + assert_equal(nl.circuits_by_name("").collect { |c| c.name }, []) + # same as _destroy nl.remove(c) diff --git a/testdata/ruby/dbNetlistCompare.rb b/testdata/ruby/dbNetlistCompare.rb index be77f5bb4..d256aa849 100644 --- a/testdata/ruby/dbNetlistCompare.rb +++ b/testdata/ruby/dbNetlistCompare.rb @@ -986,6 +986,57 @@ END end + def test_11 + + nls = <