From: Clifford Wolf Date: Thu, 23 May 2013 05:48:18 +0000 (+0200) Subject: Some improvements in opt_rmdff X-Git-Tag: yosys-0.2.0~631 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3b8882ae49b82de0339310e854591bc115cb091d;p=yosys.git Some improvements in opt_rmdff --- diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 4870f76b6..a1a9e7f3b 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -25,6 +25,7 @@ #include static SigMap assign_map; +static SigSet mux_drivers; static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) { @@ -66,19 +67,42 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) } else log_error("abort."); - + assign_map.apply(sig_d); assign_map.apply(sig_q); assign_map.apply(sig_c); assign_map.apply(sig_r); + if (dff->type == "$dff" && mux_drivers.has(sig_d)) { + std::set muxes; + mux_drivers.find(sig_d, muxes); + for (auto mux : muxes) { + RTLIL::SigSpec sig_a = assign_map(mux->connections.at("\\A")); + RTLIL::SigSpec sig_b = assign_map(mux->connections.at("\\B")); + if (sig_a == sig_q && sig_b.is_fully_const()) { + RTLIL::SigSig conn(sig_q, sig_b); + mod->connections.push_back(conn); + goto delete_dff; + } + if (sig_b == sig_q && sig_a.is_fully_const()) { + RTLIL::SigSig conn(sig_q, sig_a); + mod->connections.push_back(conn); + goto delete_dff; + } + } + } + if (sig_d.is_fully_const() && sig_r.width == 0) { RTLIL::SigSig conn(sig_q, sig_d); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d == sig_q && sig_r.width == 0) { + if (sig_d == sig_q) { + if (sig_r.width > 0) { + RTLIL::SigSig conn(sig_q, val_rv); + mod->connections.push_back(conn); + } goto delete_dff; } @@ -117,9 +141,15 @@ struct OptRmdffPass : public Pass { continue; assign_map.set(mod_it.second); + mux_drivers.clear(); std::vector dff_list; for (auto &it : mod_it.second->cells) { + if (it.second->type == "$mux" || it.second->type == "$pmux") { + if (it.second->connections.at("\\A").width == it.second->connections.at("\\B").width) + mux_drivers.insert(assign_map(it.second->connections.at("\\Y")), it.second); + continue; + } if (!design->selected(mod_it.second, it.second)) continue; if (it.second->type == "$_DFF_N_") dff_list.push_back(it.first); @@ -144,6 +174,7 @@ struct OptRmdffPass : public Pass { } assign_map.clear(); + mux_drivers.clear(); log("Replaced %d DFF cells.\n", total_count); } } OptRmdffPass;