Skip to content

Commit

Permalink
Merge pull request #4787 from povik/booth-macc
Browse files Browse the repository at this point in the history
booth: Map simple `$macc` instances too
  • Loading branch information
povik authored Dec 4, 2024
2 parents 3b8e8ee + 1ded817 commit 14ee5ce
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
8 changes: 8 additions & 0 deletions kernel/macc.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ struct Macc
return true;
}

bool is_simple_product()
{
return bit_ports.empty() &&
ports.size() == 1 &&
!ports[0].in_b.empty() &&
!ports[0].do_subtract;
}

Macc(RTLIL::Cell *cell = nullptr)
{
if (cell != nullptr)
Expand Down
33 changes: 26 additions & 7 deletions passes/techmap/booth.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ synth -top my_design -booth

#include "kernel/sigtools.h"
#include "kernel/yosys.h"
#include "kernel/macc.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
Expand Down Expand Up @@ -207,12 +208,33 @@ struct BoothPassWorker {
void run()
{
for (auto cell : module->selected_cells()) {
if (cell->type != ID($mul))
SigSpec A, B, Y;
bool is_signed;

if (cell->type == ID($mul)) {
A = cell->getPort(ID::A);
B = cell->getPort(ID::B);
Y = cell->getPort(ID::Y);

log_assert(cell->getParam(ID::A_SIGNED).as_bool() == cell->getParam(ID::B_SIGNED).as_bool());
is_signed = cell->getParam(ID::A_SIGNED).as_bool();
} else if (cell->type == ID($macc)) {
Macc macc;
macc.from_cell(cell);

if (!macc.is_simple_product()) {
log_debug("Not mapping cell %s: not a simple macc cell\n", log_id(cell));
continue;
}

A = macc.ports[0].in_a;
B = macc.ports[0].in_b;
is_signed = macc.ports[0].is_signed;
Y = cell->getPort(ID::Y);
} else {
continue;
}

SigSpec A = cell->getPort(ID::A);
SigSpec B = cell->getPort(ID::B);
SigSpec Y = cell->getPort(ID::Y);
int x_sz = GetSize(A), y_sz = GetSize(B), z_sz = GetSize(Y);

if (x_sz < 4 || y_sz < 4 || z_sz < 8) {
Expand All @@ -221,9 +243,6 @@ struct BoothPassWorker {
continue;
}

log_assert(cell->getParam(ID::A_SIGNED).as_bool() == cell->getParam(ID::B_SIGNED).as_bool());
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();

log("Mapping cell %s to %s Booth multiplier\n", log_id(cell), is_signed ? "signed" : "unsigned");

// To simplify the generator size the arguments
Expand Down
15 changes: 14 additions & 1 deletion tests/techmap/booth.ys
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ endmodule
EOF
booth
sat -verify -set a 0 -set b 0 -prove y 0

design -reset
test_cell -s 1694091355 -n 100 -script booth_map_script.ys_ $mul

test_cell -s 1694091355 -n 100 -script booth_map_script.ys_ $mul
design -reset
read_verilog <<EOF
module top(a,b,y);
input wire [4:0] a;
input wire [5:0] b;
output wire [6:0] y;
assign y = a * b;
endmodule
EOF
synth -run :fine
# test compatibility with alumacc
equiv_opt -assert booth

0 comments on commit 14ee5ce

Please sign in to comment.