From 4b6221478ecc2dbb998dcf7753b0e1ebe685860f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 May 2015 09:45:48 +0200 Subject: [PATCH] Added simple $dlatch support to opt_rmdff --- passes/opt/opt_rmdff.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 2939c4847..84af64823 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -29,6 +29,33 @@ PRIVATE_NAMESPACE_BEGIN SigMap assign_map, dff_init_map; SigSet mux_drivers; +bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) +{ + SigSpec sig_e = dlatch->getPort("\\EN"); + + if (sig_e == State::S0) + { + RTLIL::Const val_init; + for (auto bit : dff_init_map(dlatch->getPort("\\Q"))) + val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx); + mod->connect(dlatch->getPort("\\Q"), val_init); + goto delete_dlatch; + } + + if (sig_e == State::S1) + { + mod->connect(dlatch->getPort("\\Q"), dlatch->getPort("\\D")); + goto delete_dlatch; + } + + return false; + +delete_dlatch: + log("Removing %s (%s) from module %s.\n", dlatch->name.c_str(), dlatch->type.c_str(), mod->name.c_str()); + mod->remove(dlatch); + return true; +} + bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) { RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r; @@ -178,6 +205,7 @@ struct OptRmdffPass : public Pass { mux_drivers.clear(); std::vector dff_list; + std::vector dlatch_list; for (auto &it : mod_it.second->cells_) { if (it.second->type == "$mux" || it.second->type == "$pmux") { if (it.second->getPort("\\A").size() == it.second->getPort("\\B").size()) @@ -198,6 +226,7 @@ struct OptRmdffPass : public Pass { if (it.second->type == "$_DFF_PP1_") dff_list.push_back(it.first); if (it.second->type == "$dff") dff_list.push_back(it.first); if (it.second->type == "$adff") dff_list.push_back(it.first); + if (it.second->type == "$dlatch") dlatch_list.push_back(it.first); } for (auto &id : dff_list) { @@ -205,6 +234,12 @@ struct OptRmdffPass : public Pass { handle_dff(mod_it.second, mod_it.second->cells_[id])) total_count++; } + + for (auto &id : dlatch_list) { + if (mod_it.second->cells_.count(id) > 0 && + handle_dlatch(mod_it.second, mod_it.second->cells_[id])) + total_count++; + } } assign_map.clear(); -- 2.30.2