Skip to content

Commit

Permalink
proc_dff: refactor shrinking logic in optimizers
Browse files Browse the repository at this point in the history
  • Loading branch information
georgerennie committed Nov 28, 2024
1 parent b690130 commit 673b024
Showing 1 changed file with 24 additions and 28 deletions.
52 changes: 24 additions & 28 deletions passes/proc/proc_dff.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <type_traits>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -250,17 +236,10 @@ class Dff {
if (async_rules.size() != 1)
return;

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 async_rules.front().value[i].is_wire();
};
shrink_while_matching_values(bit_is_wire);
}

void generate() {
Expand Down Expand Up @@ -432,6 +411,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 F>
typename std::result_of<F(size_t)>::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;

Expand Down

0 comments on commit 673b024

Please sign in to comment.