Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add $macc_v2 #4818

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ endif
+cd tests/blif && bash run-test.sh
+cd tests/opt && bash run-test.sh
+cd tests/aiger && bash run-test.sh $(ABCOPT)
+cd tests/alumacc && bash run-test.sh $(ABCOPT)
+cd tests/arch && bash run-test.sh
+cd tests/arch/ice40 && bash run-test.sh $(SEEDOPT)
+cd tests/arch/xilinx && bash run-test.sh $(SEEDOPT)
Expand Down
3 changes: 0 additions & 3 deletions kernel/consteval.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,6 @@ struct ConstEval
Macc macc;
macc.from_cell(cell);

if (!eval(macc.bit_ports, undef, cell))
return false;

for (auto &port : macc.ports) {
if (!eval(port.in_a, undef, cell))
return false;
Expand Down
4 changes: 4 additions & 0 deletions kernel/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,7 @@ X(Y)
X(Y_WIDTH)
X(area)
X(capacitance)
X(NTERMS)
X(TERM_NEGATED)
X(A_WIDTHS)
X(B_WIDTHS)
132 changes: 71 additions & 61 deletions kernel/macc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ struct Macc
RTLIL::SigSpec in_a, in_b;
bool is_signed, do_subtract;
};

std::vector<port_t> ports;
RTLIL::SigSpec bit_ports;

void optimize(int width)
{
std::vector<port_t> new_ports;
RTLIL::SigSpec new_bit_ports;
RTLIL::Const off(0, width);

for (auto &port : ports)
Expand All @@ -48,11 +45,6 @@ struct Macc
if (GetSize(port.in_a) < GetSize(port.in_b))
std::swap(port.in_a, port.in_b);

if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) {
bit_ports.append(port.in_a);
continue;
}

if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) {
RTLIL::Const v = port.in_a.as_const();
if (GetSize(port.in_b))
Expand All @@ -79,12 +71,6 @@ struct Macc
new_ports.push_back(port);
}

for (auto &bit : bit_ports)
if (bit == State::S1)
off = const_add(off, RTLIL::Const(1, width), false, false, width);
else if (bit != State::S0)
new_bit_ports.append(bit);

if (off.as_bool()) {
port_t port;
port.in_a = off;
Expand All @@ -94,15 +80,13 @@ struct Macc
}

new_ports.swap(ports);
bit_ports = new_bit_ports;
}

void from_cell(RTLIL::Cell *cell)
void from_cell_v1(RTLIL::Cell *cell)
{
RTLIL::SigSpec port_a = cell->getPort(ID::A);

ports.clear();
bit_ports = cell->getPort(ID::B);

auto config_bits = cell->getParam(ID::CONFIG);
int config_cursor = 0;
Expand Down Expand Up @@ -145,56 +129,89 @@ struct Macc
ports.push_back(this_port);
}

for (auto bit : cell->getPort(ID::B))
ports.push_back(port_t{{bit}, {}, false, false});

log_assert(config_cursor == config_width);
log_assert(port_a_cursor == GetSize(port_a));
}

void to_cell(RTLIL::Cell *cell) const
void from_cell(RTLIL::Cell *cell)
{
RTLIL::SigSpec port_a;
std::vector<RTLIL::State> config_bits;
int max_size = 0, num_bits = 0;

for (auto &port : ports) {
max_size = max(max_size, GetSize(port.in_a));
max_size = max(max_size, GetSize(port.in_b));
if (cell->type == ID($macc)) {
from_cell_v1(cell);
return;
}
log_assert(cell->type == ID($macc_v2));

while (max_size)
num_bits++, max_size /= 2;
RTLIL::SigSpec port_a = cell->getPort(ID::A);
RTLIL::SigSpec port_b = cell->getPort(ID::B);

log_assert(num_bits < 16);
config_bits.push_back(num_bits & 1 ? State::S1 : State::S0);
config_bits.push_back(num_bits & 2 ? State::S1 : State::S0);
config_bits.push_back(num_bits & 4 ? State::S1 : State::S0);
config_bits.push_back(num_bits & 8 ? State::S1 : State::S0);
ports.clear();

for (auto &port : ports)
{
if (GetSize(port.in_a) == 0)
continue;
int nterms = cell->getParam(ID::NTERMS).as_int();
const Const &neg = cell->getParam(ID::TERM_NEGATED);
const Const &a_widths = cell->getParam(ID::A_WIDTHS);
const Const &b_widths = cell->getParam(ID::B_WIDTHS);
const Const &a_signed = cell->getParam(ID::A_SIGNED);
const Const &b_signed = cell->getParam(ID::B_SIGNED);

int ai = 0, bi = 0;
for (int i = 0; i < nterms; i++) {
port_t term;

log_assert(a_signed[i] == b_signed[i]);
term.is_signed = (a_signed[i] == State::S1);
int a_width = a_widths.extract(16 * i, 16).as_int(false);
int b_width = b_widths.extract(16 * i, 16).as_int(false);

term.in_a = port_a.extract(ai, a_width);
ai += a_width;
term.in_b = port_b.extract(bi, b_width);
bi += b_width;
term.do_subtract = (neg[i] == State::S1);

ports.push_back(term);
}
log_assert(port_a.size() == ai);
log_assert(port_b.size() == bi);
}

config_bits.push_back(port.is_signed ? State::S1 : State::S0);
config_bits.push_back(port.do_subtract ? State::S1 : State::S0);
void to_cell(RTLIL::Cell *cell)
{
cell->type = ID($macc_v2);

int size_a = GetSize(port.in_a);
for (int i = 0; i < num_bits; i++)
config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0);
int nterms = ports.size();
const auto Sx = State::Sx;
Const a_signed(Sx, nterms), b_signed(Sx, nterms), negated(Sx, nterms);
Const a_widths, b_widths;
SigSpec a, b;

int size_b = GetSize(port.in_b);
for (int i = 0; i < num_bits; i++)
config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0);
for (int i = 0; i < nterms; i++) {
SigSpec term_a = ports[i].in_a, term_b = ports[i].in_b;

port_a.append(port.in_a);
port_a.append(port.in_b);
}
a_widths.append(Const(term_a.size(), 16));
b_widths.append(Const(term_b.size(), 16));

a_signed.bits()[i] = b_signed.bits()[i] =
(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
negated.bits()[i] = (ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0);

cell->setPort(ID::A, port_a);
cell->setPort(ID::B, bit_ports);
cell->setParam(ID::CONFIG, config_bits);
cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits));
cell->setParam(ID::A_WIDTH, GetSize(port_a));
cell->setParam(ID::B_WIDTH, GetSize(bit_ports));
a.append(term_a);
b.append(term_b);
}
negated.is_fully_def();
a_signed.is_fully_def();
b_signed.is_fully_def();

cell->setParam(ID::NTERMS, nterms);
cell->setParam(ID::TERM_NEGATED, negated);
cell->setParam(ID::A_SIGNED, a_signed);
cell->setParam(ID::B_SIGNED, b_signed);
cell->setParam(ID::A_WIDTHS, a_widths);
cell->setParam(ID::B_WIDTHS, b_widths);
cell->setPort(ID::A, a);
cell->setPort(ID::B, b);
}

bool eval(RTLIL::Const &result) const
Expand All @@ -219,19 +236,12 @@ struct Macc
result = const_add(result, summand, port.is_signed, port.is_signed, GetSize(result));
}

for (auto bit : bit_ports) {
if (bit.wire)
return false;
result = const_add(result, bit.data, false, false, GetSize(result));
}

return true;
}

bool is_simple_product()
{
return bit_ports.empty() &&
ports.size() == 1 &&
return ports.size() == 1 &&
!ports[0].in_b.empty() &&
!ports[0].do_subtract;
}
Expand Down
35 changes: 35 additions & 0 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,12 @@ void RTLIL::Const::bitvectorize() const {
}
}

void RTLIL::Const::append(const RTLIL::Const &other) {
bitvectorize();
bitvectype& bv = get_bits();
bv.insert(bv.end(), other.begin(), other.end());
}

RTLIL::State RTLIL::Const::const_iterator::operator*() const {
if (auto bv = parent.get_if_bits())
return (*bv)[idx];
Expand Down Expand Up @@ -1461,6 +1467,30 @@ namespace {
return;
}

if (cell->type == ID($macc_v2)) {
if (param(ID::NTERMS) <= 0)
error(__LINE__);
param_bits(ID::TERM_NEGATED, param(ID::NTERMS));
param_bits(ID::A_SIGNED, param(ID::NTERMS));
param_bits(ID::B_SIGNED, param(ID::NTERMS));
if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED))
error(__LINE__);
param_bits(ID::A_WIDTHS, param(ID::NTERMS) * 16);
param_bits(ID::B_WIDTHS, param(ID::NTERMS) * 16);
const Const &a_width = cell->getParam(ID::A_WIDTHS);
const Const &b_width = cell->getParam(ID::B_WIDTHS);
int a_width_sum = 0, b_width_sum = 0;
for (int i = 0; i < param(ID::NTERMS); i++) {
a_width_sum += a_width.extract(16 * i, 16).as_int(false);
b_width_sum += b_width.extract(16 * i, 16).as_int(false);
}
port(ID::A, a_width_sum);
port(ID::B, b_width_sum);
port(ID::Y, param(ID::Y_WIDTH));
check_expected();
return;
}

if (cell->type == ID($logic_not)) {
param_bool(ID::A_SIGNED);
port(ID::A, param(ID::A_WIDTH));
Expand Down Expand Up @@ -4093,6 +4123,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
return;
}

if (type == ID($macc_v2)) {
parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]);
return;
}

bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc));

if (connections_.count(ID::A)) {
Expand Down
2 changes: 2 additions & 0 deletions kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@ struct RTLIL::Const
bool empty() const;
void bitvectorize() const;

void append(const RTLIL::Const &other);

class const_iterator {
private:
const Const& parent;
Expand Down
7 changes: 0 additions & 7 deletions kernel/satgen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,6 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
if (cell->type == ID($macc))
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);

Macc macc;
Expand Down Expand Up @@ -785,12 +784,6 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
}
}

for (int i = 0; i < GetSize(b); i++) {
std::vector<int> val(GetSize(y), ez->CONST_FALSE);
val.at(0) = b.at(i);
tmp = ez->vec_add(tmp, val);
}

if (model_undef)
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
Expand Down
2 changes: 1 addition & 1 deletion passes/opt/share.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct ShareWorker

static int bits_macc(const Macc &m, int width)
{
int bits = GetSize(m.bit_ports);
int bits = 0;
for (auto &p : m.ports)
bits += bits_macc_port(p, width);
return bits;
Expand Down
2 changes: 1 addition & 1 deletion passes/techmap/alumacc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ struct AlumaccWorker
for (auto &it : sig_macc)
{
auto n = it.second;
RTLIL::SigSpec A, B, C = n->macc.bit_ports;
RTLIL::SigSpec A, B, C;
bool a_signed = false, b_signed = false;
bool subtract_b = false;
alunode_t *alunode;
Expand Down
Loading
Loading