From 1ded817bebe0ef8bbade7bc0d17a3ffb8b39a4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sun, 1 Dec 2024 15:58:01 +0100 Subject: [PATCH] booth: Map simple `$macc` instances too --- kernel/macc.h | 8 ++++++++ passes/techmap/booth.cc | 35 +++++++++++++++++++++++++++-------- tests/techmap/booth.ys | 17 +++++++++++++++-- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/kernel/macc.h b/kernel/macc.h index 6bcd4cc3b..4af08cfd8 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -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) diff --git a/passes/techmap/booth.cc b/passes/techmap/booth.cc index 09c20b507..dce7da486 100644 --- a/passes/techmap/booth.cc +++ b/passes/techmap/booth.cc @@ -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 @@ -207,12 +208,33 @@ struct BoothPassWorker { void run() { for (auto cell : module->selected_cells()) { - if (cell->type != ID($mul)) - continue; + 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) { @@ -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 diff --git a/tests/techmap/booth.ys b/tests/techmap/booth.ys index 55dfdb8e9..814a65d9e 100644 --- a/tests/techmap/booth.ys +++ b/tests/techmap/booth.ys @@ -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 \ No newline at end of file +design -reset +test_cell -s 1694091355 -n 100 -script booth_map_script.ys_ $mul + +design -reset +read_verilog <