diff options
author | Clifford Wolf <clifford@clifford.at> | 2017-02-11 10:01:17 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2017-02-11 10:05:00 +0100 |
commit | a5bfeb9e07e7d160c55c6223c203d6ec124911f0 (patch) | |
tree | 7a97bfcb8f80f07fb648c8316ead3bee6f321ac4 /passes | |
parent | 9c1a7be636b9e0eca2a62173b8ed069d2db8535c (diff) | |
download | yosys-a5bfeb9e07e7d160c55c6223c203d6ec124911f0.tar.gz yosys-a5bfeb9e07e7d160c55c6223c203d6ec124911f0.tar.bz2 yosys-a5bfeb9e07e7d160c55c6223c203d6ec124911f0.zip |
Add optimization of (a && 1'b1) and (a || 1'b0)
Diffstat (limited to 'passes')
-rw-r--r-- | passes/opt/opt_expr.cc | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 7afb380a2..9ccc230e8 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -383,7 +383,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (detect_const_and || detect_const_or) { pool<SigBit> input_bits = assign_map(cell->getPort("\\A")).to_sigbit_pool(); - bool found_zero = false, found_one = false, found_inv = false; + bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false; + SigBit non_const_input = State::Sm; if (cell->hasPort("\\B")) { vector<SigBit> more_bits = assign_map(cell->getPort("\\B")).to_sigbit_vector(); @@ -391,12 +392,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } for (auto bit : input_bits) { - if (bit == State::S0) - found_zero = true; - if (bit == State::S1) - found_one = true; - if (invert_map.count(bit) && input_bits.count(invert_map.at(bit))) - found_inv = true; + if (bit.wire) { + if (invert_map.count(bit) && input_bits.count(invert_map.at(bit))) + found_inv = true; + if (non_const_input != State::Sm) + many_conconst = true; + non_const_input = many_conconst ? State::Sm : bit; + } else { + if (bit == State::S0) + found_zero = true; + else if (bit == State::S1) + found_one = true; + else + found_undef = true; + } } if (detect_const_and && (found_zero || found_inv)) { @@ -410,6 +419,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons replace_cell(assign_map, module, cell, "const_or", "\\Y", RTLIL::State::S1); goto next_cell; } + + if (non_const_input != State::Sm && !found_undef) { + cover("opt.opt_expr.and_or_buffer"); + replace_cell(assign_map, module, cell, "and_or_buffer", "\\Y", non_const_input); + goto next_cell; + } } if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor", "$neg") && |