Skip to content

Commit 8fc9e71

Browse files
committed
proc_dff: refactor shrinking logic in optimizers
1 parent b690130 commit 8fc9e71

File tree

1 file changed

+25
-34
lines changed

1 file changed

+25
-34
lines changed

passes/proc/proc_dff.cc

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <stdlib.h>
2626
#include <stdio.h>
2727
#include <algorithm>
28+
#include <type_traits>
2829

2930
USING_YOSYS_NAMESPACE
3031
PRIVATE_NAMESPACE_BEGIN
@@ -159,17 +160,9 @@ class Dff {
159160
// higher bits cannot be optimized in the same way.
160161
void optimize_same_value(ConstEval& ce) {
161162
for (size_t i = 0; i + 1 < async_rules.size();) {
162-
const auto bit_optimizable = [&](const size_t bit) {
163+
const bool lsb_optimizable = shrink_while_matching_values([&](const size_t bit) {
163164
return async_rules[i].value[bit] == async_rules[i + 1].value[bit];
164-
};
165-
166-
const bool lsb_optimizable = bit_optimizable(0);
167-
168-
size_t new_size;
169-
for (new_size = 1; new_size < size(); new_size++)
170-
if (bit_optimizable(new_size) != lsb_optimizable)
171-
break;
172-
resize(new_size);
165+
});
173166

174167
if (!lsb_optimizable) {
175168
i++;
@@ -202,26 +195,15 @@ class Dff {
202195

203196
// Calculate the number of low priority rules that can be folded into
204197
// the input signal for a given bit position
205-
const auto foldable_rules = [&](const size_t i) {
198+
const size_t lsb_foldable_rules = shrink_while_matching_values([&](const size_t i) {
206199
size_t foldable = 0;
207200
for (auto it = async_rules.crbegin(); it != async_rules.crend(); it++, foldable++) {
208201
const auto& [value, trigger] = *it;
209202
if (value[i] != sig_out_mapped[i])
210203
break;
211204
}
212205
return foldable;
213-
};
214-
215-
// Work out how many bits from the lsb can be folded into the same
216-
// number of rules
217-
const size_t lsb_foldable_rules = foldable_rules(0);
218-
219-
size_t new_size;
220-
for (new_size = 1; new_size < size(); new_size++)
221-
if (foldable_rules(new_size) != lsb_foldable_rules)
222-
break;
223-
224-
resize(new_size);
206+
});
225207

226208
if (lsb_foldable_rules == 0)
227209
return;
@@ -250,17 +232,9 @@ class Dff {
250232
if (async_rules.size() != 1)
251233
return;
252234

253-
const auto& [val, trigger] = async_rules.front();
254-
log_assert(GetSize(val) > 0);
255-
256-
const bool lsb_wire = val[0].is_wire();
257-
258-
size_t new_size;
259-
for (new_size = 1; new_size < size(); new_size++)
260-
if (val[new_size].is_wire() != lsb_wire)
261-
break;
262-
263-
resize(new_size);
235+
shrink_while_matching_values([&](const size_t i) {
236+
return async_rules.front().value[i].is_wire();
237+
});
264238
}
265239

266240
void generate() {
@@ -432,6 +406,23 @@ class Dff {
432406
value = value.extract(0, new_size);
433407
}
434408

409+
// Given some function that maps from an index to a value, this resizes
410+
// the dff to a range starting at the LSB that all return the same value
411+
// from the function as the LSB. This function also returns the value
412+
// calculated for the LSB.
413+
template <typename F>
414+
typename std::result_of<F(size_t)>::type shrink_while_matching_values(F f) {
415+
const auto base_val = f(0);
416+
417+
size_t new_size;
418+
for (new_size = 1; new_size < size(); new_size++)
419+
if (f(new_size) != base_val)
420+
break;
421+
422+
resize(new_size);
423+
return base_val;
424+
}
425+
435426
RTLIL::Process& proc;
436427
RTLIL::Module& mod;
437428

0 commit comments

Comments
 (0)