Skip to content

Commit

Permalink
Merge pull request YosysHQ#4455 from phsauter/shiftadd-limit-padding
Browse files Browse the repository at this point in the history
peepopt: limit padding from shiftadd
  • Loading branch information
nakengelhardt authored Jul 6, 2024
2 parents a739e21 + 2f0f10c commit dac5bd1
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 dac5bd1

Please sign in to comment.