mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #4787 from povik/booth-macc
booth: Map simple `$macc` instances too
This commit is contained in:
commit
14ee5ce800
|
@ -228,6 +228,14 @@ struct Macc
|
||||||
return true;
|
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)
|
Macc(RTLIL::Cell *cell = nullptr)
|
||||||
{
|
{
|
||||||
if (cell != nullptr)
|
if (cell != nullptr)
|
||||||
|
|
|
@ -57,6 +57,7 @@ synth -top my_design -booth
|
||||||
|
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
|
#include "kernel/macc.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -207,12 +208,33 @@ struct BoothPassWorker {
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
for (auto cell : module->selected_cells()) {
|
for (auto cell : module->selected_cells()) {
|
||||||
if (cell->type != ID($mul))
|
SigSpec A, B, Y;
|
||||||
continue;
|
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);
|
int x_sz = GetSize(A), y_sz = GetSize(B), z_sz = GetSize(Y);
|
||||||
|
|
||||||
if (x_sz < 4 || y_sz < 4 || z_sz < 8) {
|
if (x_sz < 4 || y_sz < 4 || z_sz < 8) {
|
||||||
|
@ -221,9 +243,6 @@ struct BoothPassWorker {
|
||||||
continue;
|
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");
|
log("Mapping cell %s to %s Booth multiplier\n", log_id(cell), is_signed ? "signed" : "unsigned");
|
||||||
|
|
||||||
// To simplify the generator size the arguments
|
// To simplify the generator size the arguments
|
||||||
|
|
|
@ -10,6 +10,19 @@ endmodule
|
||||||
EOF
|
EOF
|
||||||
booth
|
booth
|
||||||
sat -verify -set a 0 -set b 0 -prove y 0
|
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
|
design -reset
|
||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue