Skip to content

Commit

Permalink
peepopt: limit padding from shiftadd
Browse files Browse the repository at this point in the history
The input to a shift operation is padded.
This reduced the final number of MUX cells
but during techmap it can create huge
temporary multiplexers in the log shifter.
This significantly increases runtime and resources.

A limit is added with a warning when it is used.
  • Loading branch information
phsauter committed Jun 14, 2024
1 parent 62bff3a commit 2f0f10c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
11 changes: 11 additions & 0 deletions passes/pmgen/peepopt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ PRIVATE_NAMESPACE_BEGIN

bool did_something;

// scratchpad configurations for pmgen
int shiftadd_max_ratio;

#include "passes/pmgen/peepopt_pm.h"

struct PeepoptPass : public Pass {
Expand All @@ -50,6 +53,9 @@ struct PeepoptPass : public Pass {
log("\n");
log(" * shiftadd - Replace A>>(B+D) with (A'>>D)>>(B) where D is constant and\n");
log(" A' is derived from A by padding or cutting inaccessible bits.\n");
log(" Scratchpad: 'peepopt.shiftadd.max_data_multiple' (default: 2)\n");
log(" limits the amount of padding to a multiple of the data, \n");
log(" to avoid high resource usage from large temporary MUX trees.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
Expand All @@ -63,6 +69,11 @@ struct PeepoptPass : public Pass {
}
extra_args(args, argidx, design);

// limit the padding from shiftadd to a multiple of the input data
// during techmap it creates (#data + #padding) * log(shift) $_MUX_ cells
// 2x implies there is a constant shift larger than the input-data which should be extremely rare
shiftadd_max_ratio = design->scratchpad_get_int("peepopt.shiftadd.max_data_multiple", 2);

for (auto module : design->selected_modules())
{
did_something = true;
Expand Down
15 changes: 12 additions & 3 deletions passes/pmgen/peepopt_shiftadd.pmg
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,21 @@ code
// it should only differ if previous passes create invalid data
log_assert(!(offset>0 && var_signed));

SigSpec old_a = port(shift, \A); // data
std::string location = shift->get_src_attribute();

if(shiftadd_max_ratio>0 && offset<0 && -offset*shiftadd_max_ratio > old_a.size()) {
log_warning("at %s: candiate for shiftadd optimization (shifting '%s' by '%s - %d' bits) "
"was ignored to avoid high resource usage, see help peepopt\n",
location.c_str(), log_signal(old_a), log_signal(var_signal), -offset);
reject;
}

did_something = true;
log("shiftadd pattern in %s: shift=%s, add/sub=%s, offset: %d\n", \
log_id(module), log_id(shift), log_id(add), offset);

SigSpec old_a = port(shift, \A), new_a;
SigSpec new_a;
if(offset<0) {
// data >> (...-c) transformed to {data, c'X} >> (...)
SigSpec padding( (shift->type.in($shiftx) ? State::Sx : State::S0), -offset );
Expand All @@ -107,14 +117,13 @@ code
new_a.append(old_a.extract_end(offset));
} else {
// warn user in case data is empty (no bits left)
std::string location = shift->get_src_attribute();
if (location.empty())
location = shift->name.str();
if(shift->type.in($shiftx))
log_warning("at %s: result of indexed part-selection is always constant (selecting from '%s' with index '%s + %d')\n", \
location.c_str(), log_signal(old_a), log_signal(var_signal), offset);
else
log_warning("at %s: result of shift operation is always constant (shifting '%s' by '%s + %d'-bits)\n", \
log_warning("at %s: result of shift operation is always constant (shifting '%s' by '%s + %d' bits)\n", \
location.c_str(), log_signal(old_a), log_signal(var_signal), offset);
}
}
Expand Down

0 comments on commit 2f0f10c

Please sign in to comment.