aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt/opt_merge.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-03-31 09:58:55 +0200
committerClifford Wolf <clifford@clifford.at>2016-03-31 09:58:55 +0200
commit6cafd08ac1090f405168187632fab4308129c599 (patch)
tree6c6ee7190741f8e0e2333391c819ff0342ca23fa /passes/opt/opt_merge.cc
parent6f1b6dc322bf6cceeadef7c666b8ff333ec6f2bf (diff)
downloadyosys-6cafd08ac1090f405168187632fab4308129c599.tar.gz
yosys-6cafd08ac1090f405168187632fab4308129c599.tar.bz2
yosys-6cafd08ac1090f405168187632fab4308129c599.zip
Improved opt_merge support for $pmux cells
Diffstat (limited to 'passes/opt/opt_merge.cc')
-rw-r--r--passes/opt/opt_merge.cc50
1 files changed, 46 insertions, 4 deletions
diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc
index 13b3082fd..07019aac9 100644
--- a/passes/opt/opt_merge.cc
+++ b/passes/opt/opt_merge.cc
@@ -45,6 +45,29 @@ struct OptMergeWorker
dict<const RTLIL::Cell*, std::string> cell_hash_cache;
#endif
+ static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
+ {
+ SigSpec sig_s = conn.at("\\S");
+ SigSpec sig_b = conn.at("\\B");
+
+ int s_width = GetSize(sig_s);
+ int width = GetSize(sig_b) / s_width;
+
+ vector<pair<SigBit, SigSpec>> sb_pairs;
+ for (int i = 0; i < s_width; i++)
+ sb_pairs.push_back(pair<SigBit, SigSpec>(sig_s[i], sig_b.extract(i*width, width)));
+
+ std::sort(sb_pairs.begin(), sb_pairs.end());
+
+ conn["\\S"] = SigSpec();
+ conn["\\B"] = SigSpec();
+
+ for (auto &it : sb_pairs) {
+ conn["\\S"].append(it.first);
+ conn["\\B"].append(it.second);
+ }
+ }
+
#ifdef USE_CELL_HASH_CACHE
std::string int_to_hash_string(unsigned int v)
{
@@ -91,25 +114,40 @@ struct OptMergeWorker
assign_map.apply(alt_conn.at("\\A"));
alt_conn.at("\\A").sort_and_unify();
conn = &alt_conn;
+ } else
+ if (cell->type == "$pmux") {
+ alt_conn = *conn;
+ assign_map.apply(alt_conn.at("\\A"));
+ assign_map.apply(alt_conn.at("\\B"));
+ assign_map.apply(alt_conn.at("\\S"));
+ sort_pmux_conn(alt_conn);
+ conn = &alt_conn;
}
+ vector<string> hash_conn_strings;
+
for (auto &it : *conn) {
if (cell->output(it.first))
continue;
RTLIL::SigSpec sig = it.second;
assign_map.apply(sig);
- hash_string += "C " + it.first.str() + "=";
+ string s = "C " + it.first.str() + "=";
for (auto &chunk : sig.chunks()) {
if (chunk.wire)
- hash_string += "{" + chunk.wire->name.str() + " " +
+ s += "{" + chunk.wire->name.str() + " " +
int_to_hash_string(chunk.offset) + " " +
int_to_hash_string(chunk.width) + "}";
else
- hash_string += RTLIL::Const(chunk.data).as_string();
+ s += RTLIL::Const(chunk.data).as_string();
}
- hash_string += "\n";
+ hash_conn_strings.push_back(s + "\n");
}
+ std::sort(hash_conn_strings.begin(), hash_conn_strings.end());
+
+ for (auto it : hash_conn_strings)
+ hash_string += it;
+
cell_hash_cache[cell] = sha1(hash_string);
return cell_hash_cache[cell];
}
@@ -171,6 +209,10 @@ struct OptMergeWorker
if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") {
conn1["\\A"].sort_and_unify();
conn2["\\A"].sort_and_unify();
+ } else
+ if (cell1->type == "$pmux") {
+ sort_pmux_conn(conn1);
+ sort_pmux_conn(conn2);
}
if (conn1 != conn2) {