booth: Expose `-lowpower` option

This commit is contained in:
Martin Povišer 2023-11-22 14:57:13 +01:00
parent 7005ea9411
commit beb5cb55a5
1 changed files with 26 additions and 8 deletions

View File

@ -66,6 +66,7 @@ struct BoothPassWorker {
RTLIL::Module *module; RTLIL::Module *module;
SigMap sigmap; SigMap sigmap;
int booth_counter; int booth_counter;
bool lowpower = false;
BoothPassWorker(RTLIL::Module *module) : module(module), sigmap(module) { booth_counter = 0; } BoothPassWorker(RTLIL::Module *module) : module(module), sigmap(module) { booth_counter = 0; }
@ -276,12 +277,20 @@ struct BoothPassWorker {
} }
log_assert(GetSize(Y) == required_op_size); log_assert(GetSize(Y) == required_op_size);
if (!lowpower)
CreateBoothMult(module, CreateBoothMult(module,
A, // multiplicand A, // multiplicand
B, // multiplier(scanned) B, // multiplier(scanned)
Y, // result Y, // result
is_signed is_signed
); );
else
CreateBoothLowpowerMult(module,
A, // multiplicand
B, // multiplier(scanned)
Y, // result
is_signed
);
module->remove(cell); module->remove(cell);
booth_counter++; booth_counter++;
@ -904,12 +913,15 @@ struct BoothPassWorker {
} }
/* /*
Signed Multiplier Low-power Multiplier
*/ */
void CreateBoothSMult(RTLIL::Module *module, SigSpec X, SigSpec Y, SigSpec Z) void CreateBoothLowpowerMult(RTLIL::Module *module, SigSpec X, SigSpec Y, SigSpec Z, bool is_signed)
{ // product { // product
int x_sz = X.size(), y_sz = Y.size(), z_sz = Z.size(); int x_sz = X.size(), y_sz = Y.size(), z_sz = Z.size();
if (!is_signed)
log_error("Low-power Booth architecture is only supported on signed multipliers.\n");
unsigned enc_count = (y_sz / 2) + (((y_sz % 2) != 0) ? 1 : 0); unsigned enc_count = (y_sz / 2) + (((y_sz % 2) != 0) ? 1 : 0);
int dec_count = x_sz + 1; int dec_count = x_sz + 1;
@ -1118,8 +1130,13 @@ struct BoothPass : public Pass {
log_header(design, "Executing BOOTH pass (map to Booth multipliers).\n"); log_header(design, "Executing BOOTH pass (map to Booth multipliers).\n");
size_t argidx; size_t argidx;
bool lowpower = false;
for (argidx = 1; argidx < args.size(); argidx++) { for (argidx = 1; argidx < args.size(); argidx++) {
break; break;
if (args[argidx] == "-lowpower")
lowpower = true;
else
break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -1128,6 +1145,7 @@ struct BoothPass : public Pass {
for (auto mod : design->selected_modules()) { for (auto mod : design->selected_modules()) {
if (!mod->has_processes_warn()) { if (!mod->has_processes_warn()) {
BoothPassWorker worker(mod); BoothPassWorker worker(mod);
worker.lowpower = lowpower;
worker.run(); worker.run();
total += worker.booth_counter; total += worker.booth_counter;
} }