summaryrefslogtreecommitdiff
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-03-29 11:01:26 +0100
committerClifford Wolf <clifford@clifford.at>2013-03-29 11:01:26 +0100
commit0d48b846ac8ed74b607fc4706e742a45ab86f2dd (patch)
treee8e552a15dc584659b3e3790c779f9d8ec336edd /passes
parentd60fbaf6644de91a3d9ea58295ac8e2ddd6cd363 (diff)
Improved opt_share for commutative standard cells
Diffstat (limited to 'passes')
-rw-r--r--passes/opt/opt_share.cc29
1 files changed, 28 insertions, 1 deletions
diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc
index 9f79d060..6dd4daa0 100644
--- a/passes/opt/opt_share.cc
+++ b/passes/opt/opt_share.cc
@@ -65,7 +65,20 @@ struct OptShareWorker
for (auto &it : cell->parameters)
hash_string += "P " + it.first + "=" + it.second.as_string() + "\n";
- for (auto &it : cell->connections) {
+ const std::map<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections;
+ std::map<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
+
+ if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" ||
+ cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") {
+ alt_conn = *conn;
+ if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) {
+ alt_conn["\\A"] = conn->at("\\B");
+ alt_conn["\\B"] = conn->at("\\A");
+ }
+ conn = &alt_conn;
+ }
+
+ for (auto &it : *conn) {
if (ct.cell_output(cell->type, it.first))
continue;
RTLIL::SigSpec sig = it.second;
@@ -126,6 +139,20 @@ struct OptShareWorker
assign_map.apply(it.second);
}
+ if (cell1->type == "$and" || cell1->type == "$or" || cell1->type == "$xor" || cell1->type == "$xnor" || cell1->type == "$add" || cell1->type == "$mul" ||
+ cell1->type == "$logic_and" || cell1->type == "$logic_or" || cell1->type == "$_AND_" || cell1->type == "$_OR_" || cell1->type == "$_XOR_") {
+ if (conn1.at("\\A") < conn1.at("\\B")) {
+ RTLIL::SigSpec tmp = conn1["\\A"];
+ conn1["\\A"] = conn1["\\B"];
+ conn1["\\B"] = tmp;
+ }
+ if (conn2.at("\\A") < conn2.at("\\B")) {
+ RTLIL::SigSpec tmp = conn2["\\A"];
+ conn2["\\A"] = conn2["\\B"];
+ conn2["\\B"] = tmp;
+ }
+ }
+
if (conn1 != conn2) {
lt = conn1 < conn2;
return true;