From 56509d7938d2451f1503c266c2f18a2d0cafe608 Mon Sep 17 00:00:00 2001 From: George Rennie Date: Thu, 28 Nov 2024 23:55:52 +0100 Subject: [PATCH] proc_dff: refactor shrinking logic in optimizers --- passes/proc/proc_dff.cc | 47 +++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 0a6ae1140f4..91a13a2189f 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -25,6 +25,7 @@ #include #include #include +#include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -163,13 +164,7 @@ class Dff { return async_rules[i].value[bit] == async_rules[i + 1].value[bit]; }; - const bool lsb_optimizable = bit_optimizable(0); - - size_t new_size; - for (new_size = 1; new_size < size(); new_size++) - if (bit_optimizable(new_size) != lsb_optimizable) - break; - resize(new_size); + const bool lsb_optimizable = shrink_while_matching_values(bit_optimizable); if (!lsb_optimizable) { i++; @@ -212,16 +207,7 @@ class Dff { return foldable; }; - // Work out how many bits from the lsb can be folded into the same - // number of rules - const size_t lsb_foldable_rules = foldable_rules(0); - - size_t new_size; - for (new_size = 1; new_size < size(); new_size++) - if (foldable_rules(new_size) != lsb_foldable_rules) - break; - - resize(new_size); + const size_t lsb_foldable_rules = shrink_while_matching_values(foldable_rules); if (lsb_foldable_rules == 0) return; @@ -253,14 +239,8 @@ class Dff { const auto& [val, trigger] = async_rules.front(); log_assert(GetSize(val) > 0); - const bool lsb_wire = val[0].is_wire(); - - size_t new_size; - for (new_size = 1; new_size < size(); new_size++) - if (val[new_size].is_wire() != lsb_wire) - break; - - resize(new_size); + const auto bit_is_wire = [&](const size_t i) { return val[i].is_wire(); }; + shrink_while_matching_values(bit_is_wire); } void generate() { @@ -432,6 +412,23 @@ class Dff { value = value.extract(0, new_size); } + // Given some function that maps from an index to a value, this resizes + // the dff to a range starting at the LSB that all return the same value + // from the function as the LSB. This function also returns the value + // calculated for the LSB. + template + typename std::result_of::type shrink_while_matching_values(F f) { + const auto base_val = f(0); + + size_t new_size; + for (new_size = 1; new_size < size(); new_size++) + if (f(new_size) != base_val) + break; + + resize(new_size); + return base_val; + } + RTLIL::Process& proc; RTLIL::Module& mod;