Added GSI binding for join_symmetric_nets, added method to get circuits by name pattern.

This commit is contained in:
Matthias Koefferlein 2020-02-27 12:17:35 +01:00
parent 25d1a65b21
commit 3b31109367
7 changed files with 101 additions and 7 deletions

View File

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

View File

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

View File

@ -1418,6 +1418,22 @@ static void blank_circuit_by_name (db::Netlist *nl, const std::string &name_patt
}
}
static std::vector<db::Circuit *>
circuits_by_name (db::Netlist *netlist, const std::string &name_pattern)
{
std::vector<db::Circuit *> 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<db::Netlist> 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<db::Netlist> 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. "

View File

@ -557,6 +557,20 @@ Class<db::NetlistComparer> 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"

View File

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

View File

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

View File

@ -986,6 +986,57 @@ END
end
def test_11
nls = <<END
circuit RESCUBE (A=A,B=B);
device RES $1 (A=A,B=$1) (R=1000);
device RES $2 (A=A,B=$2) (R=1000);
device RES $3 (A=A,B=$3) (R=1000);
device RES $4 (A=$1,B=$4) (R=1000);
device RES $5 (A=$2,B=$4) (R=1000);
device RES $6 (A=$2,B=$5) (R=1000);
device RES $7 (A=$3,B=$5) (R=1000);
device RES $8 (A=$3,B=$6) (R=1000);
device RES $9 (A=$1,B=$6) (R=1000);
device RES $9 (A=$4,B=B) (R=1000);
device RES $10 (A=$5,B=B) (R=1000);
device RES $11 (A=$6,B=B) (R=1000);
end;
END
nl = RBA::Netlist::new
prep_nl(nl, nls)
comp = RBA::NetlistComparer::new
comp.join_symmetric_nets(nl.circuit_by_name("RESCUBE"))
assert_equal(nl.to_s, <<END)
circuit RESCUBE (A=A,B=B);
device RES $1 (A=A,B=$1) (R=1000,L=0,W=0,A=0,P=0);
device RES $2 (A=A,B=$1) (R=1000,L=0,W=0,A=0,P=0);
device RES $3 (A=A,B=$1) (R=1000,L=0,W=0,A=0,P=0);
device RES $4 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $5 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $6 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $7 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $8 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $9 (A=$1,B=$4) (R=1000,L=0,W=0,A=0,P=0);
device RES $10 (A=$4,B=B) (R=1000,L=0,W=0,A=0,P=0);
device RES $11 (A=$4,B=B) (R=1000,L=0,W=0,A=0,P=0);
device RES $12 (A=$4,B=B) (R=1000,L=0,W=0,A=0,P=0);
end;
END
nl.combine_devices
assert_equal(nl.to_s, <<END)
circuit RESCUBE (A=A,B=B);
device RES $10 (A=A,B=B) (R=833.333333333,L=0,W=0,A=0,P=0);
end;
END
end
end
load("test_epilogue.rb")