summaryrefslogtreecommitdiff
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-05-23 10:14:53 +0200
committerClifford Wolf <clifford@clifford.at>2015-05-23 10:14:53 +0200
commit9f772eb970924f39df8c334acb319c34ef2b3db9 (patch)
treec95e4f5a22c409f1541cebb37518d0c13872ce2a /passes
parent4b6221478ecc2dbb998dcf7753b0e1ebe685860f (diff)
Improved "flatten" handlings of inout ports
Diffstat (limited to 'passes')
-rw-r--r--passes/techmap/techmap.cc28
1 files changed, 26 insertions, 2 deletions
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index c404eb9d..c36eb2ed 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -220,6 +220,18 @@ struct TechmapWorker
design->select(module, w);
}
+ SigMap tpl_sigmap(tpl);
+ pool<SigBit> tpl_written_bits;
+
+ for (auto &it1 : tpl->cells_)
+ for (auto &it2 : it1.second->connections_)
+ if (it1.second->output(it2.first))
+ for (auto bit : tpl_sigmap(it2.second))
+ tpl_written_bits.insert(bit);
+ for (auto &it1 : tpl->connections_)
+ for (auto bit : tpl_sigmap(it1.first))
+ tpl_written_bits.insert(bit);
+
SigMap port_signal_map;
for (auto &it : cell->connections()) {
@@ -233,14 +245,26 @@ struct TechmapWorker
}
RTLIL::Wire *w = tpl->wires_.at(portname);
RTLIL::SigSig c;
- if (w->port_output) {
+ if (w->port_output && !w->port_input) {
c.first = it.second;
c.second = RTLIL::SigSpec(w);
apply_prefix(cell->name.str(), c.second, module);
- } else {
+ } else if (!w->port_output && w->port_input) {
c.first = RTLIL::SigSpec(w);
c.second = it.second;
apply_prefix(cell->name.str(), c.first, module);
+ } else {
+ SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second;
+ apply_prefix(cell->name.str(), sig_tpl_pf, module);
+ for (int i = 0; i < GetSize(sig_tpl); i++) {
+ if (tpl_written_bits.count(tpl_sigmap(sig_tpl[i]))) {
+ c.first.append(sig_mod[i]);
+ c.second.append(sig_tpl_pf[i]);
+ } else {
+ c.first.append(sig_tpl_pf[i]);
+ c.second.append(sig_mod[i]);
+ }
+ }
}
if (c.second.size() > c.first.size())
c.second.remove(c.first.size(), c.second.size() - c.first.size());