diff options
author | Clifford Wolf <clifford@clifford.at> | 2014-09-08 13:28:23 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2014-09-08 13:31:04 +0200 |
commit | af0c8873bbc13eea10b3d705061b4cf68fe27c17 (patch) | |
tree | a295ce024870762e0388cd9fcd28c458d86fa0d3 /kernel/consteval.h | |
parent | 48b00dcceab8bb046258cd6f0912636a6e5b232c (diff) | |
download | yosys-af0c8873bbc13eea10b3d705061b4cf68fe27c17.tar.gz yosys-af0c8873bbc13eea10b3d705061b4cf68fe27c17.tar.bz2 yosys-af0c8873bbc13eea10b3d705061b4cf68fe27c17.zip |
Added $lcu cell type
Diffstat (limited to 'kernel/consteval.h')
-rw-r--r-- | kernel/consteval.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/kernel/consteval.h b/kernel/consteval.h index 7423f950f..6e507bd51 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -86,6 +86,43 @@ struct ConstEval bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) { + if (cell->type == "$lcu") + { + RTLIL::SigSpec sig_p = cell->getPort("\\P"); + RTLIL::SigSpec sig_g = cell->getPort("\\G"); + RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO"))); + + if (sig_co.is_fully_const()) + return true; + + if (!eval(sig_p, undef, cell)) + return false; + + if (!eval(sig_g, undef, cell)) + return false; + + if (!eval(sig_ci, undef, cell)) + return false; + + if (sig_p.is_fully_def() && sig_g.is_fully_def() && sig_ci.is_fully_def()) + { + RTLIL::Const coval(RTLIL::Sx, SIZE(sig_co)); + bool carry = sig_ci.as_bool(); + + for (int i = 0; i < SIZE(coval); i++) { + carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); + coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; + } + + set(sig_co, coval); + } + else + set(sig_co, RTLIL::Const(RTLIL::Sx, SIZE(sig_co))); + + return true; + } + RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; log_assert(cell->hasPort("\\Y")); |