Skip to content

Commit 14ee5ce

Browse files
authored
Merge pull request #4787 from povik/booth-macc
booth: Map simple `$macc` instances too
2 parents 3b8e8ee + 1ded817 commit 14ee5ce

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

kernel/macc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,14 @@ struct Macc
228228
return true;
229229
}
230230

231+
bool is_simple_product()
232+
{
233+
return bit_ports.empty() &&
234+
ports.size() == 1 &&
235+
!ports[0].in_b.empty() &&
236+
!ports[0].do_subtract;
237+
}
238+
231239
Macc(RTLIL::Cell *cell = nullptr)
232240
{
233241
if (cell != nullptr)

passes/techmap/booth.cc

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ synth -top my_design -booth
5757

5858
#include "kernel/sigtools.h"
5959
#include "kernel/yosys.h"
60+
#include "kernel/macc.h"
6061

6162
USING_YOSYS_NAMESPACE
6263
PRIVATE_NAMESPACE_BEGIN
@@ -207,12 +208,33 @@ struct BoothPassWorker {
207208
void run()
208209
{
209210
for (auto cell : module->selected_cells()) {
210-
if (cell->type != ID($mul))
211+
SigSpec A, B, Y;
212+
bool is_signed;
213+
214+
if (cell->type == ID($mul)) {
215+
A = cell->getPort(ID::A);
216+
B = cell->getPort(ID::B);
217+
Y = cell->getPort(ID::Y);
218+
219+
log_assert(cell->getParam(ID::A_SIGNED).as_bool() == cell->getParam(ID::B_SIGNED).as_bool());
220+
is_signed = cell->getParam(ID::A_SIGNED).as_bool();
221+
} else if (cell->type == ID($macc)) {
222+
Macc macc;
223+
macc.from_cell(cell);
224+
225+
if (!macc.is_simple_product()) {
226+
log_debug("Not mapping cell %s: not a simple macc cell\n", log_id(cell));
227+
continue;
228+
}
229+
230+
A = macc.ports[0].in_a;
231+
B = macc.ports[0].in_b;
232+
is_signed = macc.ports[0].is_signed;
233+
Y = cell->getPort(ID::Y);
234+
} else {
211235
continue;
236+
}
212237

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

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

224-
log_assert(cell->getParam(ID::A_SIGNED).as_bool() == cell->getParam(ID::B_SIGNED).as_bool());
225-
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
226-
227246
log("Mapping cell %s to %s Booth multiplier\n", log_id(cell), is_signed ? "signed" : "unsigned");
228247

229248
// To simplify the generator size the arguments

tests/techmap/booth.ys

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ endmodule
1010
EOF
1111
booth
1212
sat -verify -set a 0 -set b 0 -prove y 0
13+
1314
design -reset
15+
test_cell -s 1694091355 -n 100 -script booth_map_script.ys_ $mul
1416

15-
test_cell -s 1694091355 -n 100 -script booth_map_script.ys_ $mul
17+
design -reset
18+
read_verilog <<EOF
19+
module top(a,b,y);
20+
input wire [4:0] a;
21+
input wire [5:0] b;
22+
output wire [6:0] y;
23+
assign y = a * b;
24+
endmodule
25+
EOF
26+
synth -run :fine
27+
# test compatibility with alumacc
28+
equiv_opt -assert booth

0 commit comments

Comments
 (0)