aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt/opt_rmdff.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-05-23 09:45:48 +0200
committerClifford Wolf <clifford@clifford.at>2015-05-23 09:45:48 +0200
commit4b6221478ecc2dbb998dcf7753b0e1ebe685860f (patch)
treec5c0268d5c16b79e6f1f413a423629f9a98af09a /passes/opt/opt_rmdff.cc
parent264eb8eb6e846f01bf008feadc564ce88798041b (diff)
downloadyosys-4b6221478ecc2dbb998dcf7753b0e1ebe685860f.tar.gz
yosys-4b6221478ecc2dbb998dcf7753b0e1ebe685860f.tar.bz2
yosys-4b6221478ecc2dbb998dcf7753b0e1ebe685860f.zip
Added simple $dlatch support to opt_rmdff
Diffstat (limited to 'passes/opt/opt_rmdff.cc')
-rw-r--r--passes/opt/opt_rmdff.cc35
1 files changed, 35 insertions, 0 deletions
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<RTLIL::Cell*> 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<RTLIL::IdString> dff_list;
+ std::vector<RTLIL::IdString> 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();