diff options
author | Ahmed Irfan <ahmedirfan1983@gmail.com> | 2014-09-22 11:35:04 +0200 |
---|---|---|
committer | Ahmed Irfan <ahmedirfan1983@gmail.com> | 2014-09-22 11:35:04 +0200 |
commit | d3c67ad9b61f602de1100cd264efd227dcacb417 (patch) | |
tree | 88c462c53bdab128cd1edbded42483772f82612a /passes/opt/opt_muxtree.cc | |
parent | b783dbe148e6d246ebd107c0913de2989ab5af48 (diff) | |
parent | 13117bb346dd02d2345f716b4403239aebe3d0e2 (diff) | |
download | yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.tar.gz yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.tar.bz2 yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.zip |
Merge branch 'master' of https://github.com/cliffordwolf/yosys into btor
added case for memwr cell that is used in muxes (same cell is used more than one time)
corrected bug for xnor and logic_not
added pmux cell translation
Conflicts:
backends/btor/btor.cc
Diffstat (limited to 'passes/opt/opt_muxtree.cc')
-rw-r--r-- | passes/opt/opt_muxtree.cc | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 47100869c..2c5dcf668 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -17,13 +17,11 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" #include <stdlib.h> -#include <assert.h> #include <stdio.h> #include <set> @@ -36,7 +34,11 @@ struct OptMuxtreeWorker SigMap assign_map; int removed_count; - typedef std::pair<RTLIL::Wire*,int> bitDef_t; + struct bitDef_t : public std::pair<RTLIL::Wire*, int> { + bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { } + bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { } + }; + struct bitinfo_t { int num; @@ -79,21 +81,20 @@ struct OptMuxtreeWorker // .ctrl_sigs // .input_sigs // .const_activated - for (auto &cell_it : module->cells) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") + if (cell->type == "$mux" || cell->type == "$pmux") { - RTLIL::SigSpec sig_a = cell->connections["\\A"]; - RTLIL::SigSpec sig_b = cell->connections["\\B"]; - RTLIL::SigSpec sig_s = cell->connections["\\S"]; - RTLIL::SigSpec sig_y = cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_s = cell->getPort("\\S"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); muxinfo_t muxinfo; muxinfo.cell = cell; - for (int i = 0; i < sig_s.width; i++) { - RTLIL::SigSpec sig = sig_b.extract(i*sig_a.width, sig_a.width); + for (int i = 0; i < sig_s.size(); i++) { + RTLIL::SigSpec sig = sig_b.extract(i*sig_a.size(), sig_a.size()); RTLIL::SigSpec ctrl_sig = assign_map(sig_s.extract(i, 1)); portinfo_t portinfo; for (int idx : sig2bits(sig)) { @@ -126,15 +127,15 @@ struct OptMuxtreeWorker } else { - for (auto &it : cell->connections) { + for (auto &it : cell->connections()) { for (int idx : sig2bits(it.second)) bit2info[idx].seen_non_mux = true; } } } - for (auto &it : module->wires) { - if (it.second->port_output) - for (int idx : sig2bits(RTLIL::SigSpec(it.second))) + for (auto wire : module->wires()) { + if (wire->port_output) + for (int idx : sig2bits(RTLIL::SigSpec(wire))) bit2info[idx].seen_non_mux = true; } @@ -177,7 +178,6 @@ struct OptMuxtreeWorker } else { log(" dead port %zd/%zd on %s %s.\n", port_idx+1, mi.ports.size(), mi.cell->type.c_str(), mi.cell->name.c_str()); - OPT_DID_SOMETHING = true; removed_count++; } } @@ -186,32 +186,30 @@ struct OptMuxtreeWorker continue; if (live_ports.size() == 0) { - module->cells.erase(mi.cell->name); - delete mi.cell; + module->remove(mi.cell); continue; } - RTLIL::SigSpec sig_a = mi.cell->connections["\\A"]; - RTLIL::SigSpec sig_b = mi.cell->connections["\\B"]; - RTLIL::SigSpec sig_s = mi.cell->connections["\\S"]; - RTLIL::SigSpec sig_y = mi.cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = mi.cell->getPort("\\A"); + RTLIL::SigSpec sig_b = mi.cell->getPort("\\B"); + RTLIL::SigSpec sig_s = mi.cell->getPort("\\S"); + RTLIL::SigSpec sig_y = mi.cell->getPort("\\Y"); RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); if (live_ports.size() == 1) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.width, sig_a.width); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_in)); - module->cells.erase(mi.cell->name); - delete mi.cell; + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.size(), sig_a.size()); + module->connect(RTLIL::SigSig(sig_y, sig_in)); + module->remove(mi.cell); } else { RTLIL::SigSpec new_sig_a, new_sig_b, new_sig_s; for (size_t i = 0; i < live_ports.size(); i++) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.width, sig_a.width); + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.size(), sig_a.size()); if (i == live_ports.size()-1) { new_sig_a = sig_in; } else { @@ -220,14 +218,14 @@ struct OptMuxtreeWorker } } - mi.cell->connections["\\A"] = new_sig_a; - mi.cell->connections["\\B"] = new_sig_b; - mi.cell->connections["\\S"] = new_sig_s; - if (new_sig_s.width == 1) { + mi.cell->setPort("\\A", new_sig_a); + mi.cell->setPort("\\B", new_sig_b); + mi.cell->setPort("\\S", new_sig_s); + if (new_sig_s.size() == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); } else { - mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.width); + mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } } } @@ -259,10 +257,8 @@ struct OptMuxtreeWorker { std::vector<int> results; assign_map.apply(sig); - sig.expand(); - for (auto &c : sig.chunks) - if (c.wire != NULL) { - bitDef_t bit(c.wire, c.offset); + for (auto &bit : sig) + if (bit.wire != NULL) { if (bit2num.count(bit) == 0) { bitinfo_t info; info.num = bit2info.size(); @@ -309,13 +305,17 @@ struct OptMuxtreeWorker if (port_idx < int(muxinfo.ports.size())-1 && !muxinfo.ports[port_idx].const_activated) knowledge.known_active.push_back(muxinfo.ports[port_idx].ctrl_sigs); + std::vector<int> parent_muxes; for (int m : muxinfo.ports[port_idx].input_muxes) { if (knowledge.visited_muxes.count(m) > 0) continue; knowledge.visited_muxes.insert(m); + parent_muxes.push_back(m); + } + for (int m : parent_muxes) eval_mux(knowledge, m); + for (int m : parent_muxes) knowledge.visited_muxes.erase(m); - } if (port_idx < int(muxinfo.ports.size())-1 && !muxinfo.ports[port_idx].const_activated) knowledge.known_active.pop_back(); @@ -393,6 +393,7 @@ struct OptMuxtreeWorker void eval_root_mux(int mux_idx) { knowledge_t knowledge; + knowledge.visited_muxes.insert(mux_idx); eval_mux(knowledge, mux_idx); } }; @@ -418,19 +419,21 @@ struct OptMuxtreePass : public Pass { extra_args(args, 1, design); int total_count = 0; - for (auto &mod_it : design->modules) { - if (!design->selected_whole_module(mod_it.first)) { - if (design->selected(mod_it.second)) - log("Skipping module %s as it is only partially selected.\n", id2cstr(mod_it.second->name)); + for (auto mod : design->modules()) { + if (!design->selected_whole_module(mod)) { + if (design->selected(mod)) + log("Skipping module %s as it is only partially selected.\n", log_id(mod)); continue; } - if (mod_it.second->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", id2cstr(mod_it.second->name)); + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); } else { - OptMuxtreeWorker worker(design, mod_it.second); + OptMuxtreeWorker worker(design, mod); total_count += worker.removed_count; } } + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); log("Removed %d multiplexer ports.\n", total_count); } } OptMuxtreePass; |