diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-05-28 09:30:53 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-05-28 09:30:53 -0700 |
commit | ba9513b325433f9232e1c4312a2b526ca7dacdd4 (patch) | |
tree | 995de7437e31e2c383a0185049e4e844df4d27e0 /passes/opt | |
parent | f745727de5af085412b2e5f8161aa1018cc5e276 (diff) | |
parent | 8e647901ef6ea484bfe41628f258c53590ae4114 (diff) | |
download | yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.tar.gz yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.tar.bz2 yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.zip |
Merge remote-tracking branch 'origin/master' into xc7mux
Diffstat (limited to 'passes/opt')
-rw-r--r-- | passes/opt/opt_clean.cc | 5 | ||||
-rw-r--r-- | passes/opt/opt_rmdff.cc | 57 |
2 files changed, 49 insertions, 13 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index bf8020169..7011d4602 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -319,8 +319,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos wire->attributes.erase("\\init"); if (GetSize(wire) == 0) { - // delete zero-width wires - goto delete_this_wire; + // delete zero-width wires, unless they are module ports + if (wire->port_id == 0) + goto delete_this_wire; } else if (wire->port_id != 0 || wire->get_bool_attribute("\\keep") || !initval.is_fully_undef()) { // do not delete anything with "keep" or module ports or initialized wires diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 3cb8e2b1e..2abffa2a9 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -338,16 +338,6 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx); } - if (sig_e.size()) { - if (!sig_e.is_fully_const()) - return false; - if (sig_e != val_ep) { - if (has_init) - mod->connect(sig_q, val_init); - goto delete_dff; - } - } - if (dff->type.in("$ff", "$dff") && mux_drivers.has(sig_d)) { std::set<RTLIL::Cell*> muxes; mux_drivers.find(sig_d, muxes); @@ -365,39 +355,60 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) } } + // If clock is driven by a constant and (i) no reset signal + // (ii) Q has no initial value + // (iii) initial value is same as reset value if (!sig_c.empty() && sig_c.is_fully_const() && (!sig_r.size() || !has_init || val_init == val_rv)) { if (val_rv.bits.size() == 0) val_rv = val_init; + // Q is permanently reset value or initial value mod->connect(sig_q, val_rv); goto delete_dff; } + // If D is fully undefined and reset signal present and (i) Q has no initial value + // (ii) initial value is same as reset value if (sig_d.is_fully_undef() && sig_r.size() && (!has_init || val_init == val_rv)) { + // Q is permanently reset value mod->connect(sig_q, val_rv); goto delete_dff; } + // If D is fully undefined and no reset signal and Q has an initial value if (sig_d.is_fully_undef() && !sig_r.size() && has_init) { + // Q is permanently initial value mod->connect(sig_q, val_init); goto delete_dff; } + // If D is fully constant and (i) no reset signal + // (ii) reset value is same as constant D + // and (a) has no initial value + // (b) initial value same as constant D if (sig_d.is_fully_const() && (!sig_r.size() || val_rv == sig_d.as_const()) && (!has_init || val_init == sig_d.as_const())) { + // Q is permanently D mod->connect(sig_q, sig_d); goto delete_dff; } + // If D input is same as Q output and (i) no reset signal + // (ii) no initial signal + // (iii) initial value is same as reset value if (sig_d == sig_q && (sig_r.empty() || !has_init || val_init == val_rv)) { + // Q is permanently reset value or initial value if (sig_r.size()) mod->connect(sig_q, val_rv); - if (has_init) + else if (has_init) mod->connect(sig_q, val_init); goto delete_dff; } + // If reset signal is present, and is fully constant if (!sig_r.empty() && sig_r.is_fully_const()) { + // If reset value is permanently active or if reset is undefined if (sig_r == val_rp || sig_r.is_fully_undef()) { + // Q is permanently reset value mod->connect(sig_q, val_rv); goto delete_dff; } @@ -417,6 +428,30 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) dff->unsetPort("\\R"); } + // If enable signal is present, and is fully constant + if (!sig_e.empty() && sig_e.is_fully_const()) + { + // If enable value is permanently inactive + if (sig_e != val_ep) { + // Q is permanently initial value + mod->connect(sig_q, val_init); + goto delete_dff; + } + + log("Removing unused enable from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); + + if (dff->type == "$dffe") { + dff->type = "$dff"; + dff->unsetPort("\\EN"); + dff->unsetParam("\\EN_POLARITY"); + return true; + } + + log_assert(dff->type.substr(0,7) == "$_DFFE_"); + dff->type = stringf("$_DFF_%c_", + dff->type[7]); + dff->unsetPort("\\E"); + } + return false; delete_dff: |