3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-24 01:25:33 +00:00

Merge remote-tracking branch 'upstream/main'

This commit is contained in:
Akash Levy 2025-03-12 19:21:32 -07:00
commit e4066b784d
23 changed files with 425 additions and 60 deletions

View file

@ -453,7 +453,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
}
// FIXME: $mul $div $mod $divfloor $modfloor $slice $concat
// FIXME: $lut $sop $alu $lcu $macc $fa
// FIXME: $lut $sop $alu $lcu $macc $macc_v2 $fa
// FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx
// FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux

View file

@ -144,6 +144,7 @@ struct CellTypes
setup_type(ID($lcu), {ID::P, ID::G, ID::CI}, {ID::CO}, true);
setup_type(ID($alu), {ID::A, ID::B, ID::CI, ID::BI}, {ID::X, ID::Y, ID::CO}, true);
setup_type(ID($macc_v2), {ID::A, ID::B, ID::C}, {ID::Y}, true);
setup_type(ID($fa), {ID::A, ID::B, ID::C}, {ID::X, ID::Y}, true);
}

View file

@ -310,7 +310,7 @@ struct ConstEval
}
}
}
else if (cell->type == ID($macc))
else if (cell->type.in(ID($macc), ID($macc_v2)))
{
Macc macc;
macc.from_cell(cell);

View file

@ -276,3 +276,11 @@ X(Y)
X(Y_WIDTH)
X(area)
X(capacitance)
X(NPRODUCTS)
X(NADDENDS)
X(PRODUCT_NEGATED)
X(ADDEND_NEGATED)
X(A_WIDTHS)
X(B_WIDTHS)
X(C_WIDTHS)
X(C_SIGNED)

View file

@ -82,7 +82,7 @@ struct Macc
new_ports.swap(ports);
}
void from_cell(RTLIL::Cell *cell)
void from_cell_v1(RTLIL::Cell *cell)
{
RTLIL::SigSpec port_a = cell->getPort(ID::A);
@ -136,52 +136,128 @@ struct Macc
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;
if (cell->type == ID($macc)) {
from_cell_v1(cell);
return;
}
log_assert(cell->type == ID($macc_v2));
for (auto &port : ports) {
max_size = max(max_size, GetSize(port.in_a));
max_size = max(max_size, GetSize(port.in_b));
RTLIL::SigSpec port_a = cell->getPort(ID::A);
RTLIL::SigSpec port_b = cell->getPort(ID::B);
RTLIL::SigSpec port_c = cell->getPort(ID::C);
ports.clear();
int nproducts = cell->getParam(ID::NPRODUCTS).as_int();
const Const &product_neg = cell->getParam(ID::PRODUCT_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 < nproducts; 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 = (product_neg[i] == State::S1);
ports.push_back(term);
}
log_assert(port_a.size() == ai);
log_assert(port_b.size() == bi);
int naddends = cell->getParam(ID::NADDENDS).as_int();
const Const &addend_neg = cell->getParam(ID::ADDEND_NEGATED);
const Const &c_widths = cell->getParam(ID::C_WIDTHS);
const Const &c_signed = cell->getParam(ID::C_SIGNED);
int ci = 0;
for (int i = 0; i < naddends; i++) {
port_t term;
term.is_signed = (c_signed[i] == State::S1);
int c_width = c_widths.extract(16 * i, 16).as_int(false);
term.in_a = port_c.extract(ci, c_width);
ci += c_width;
term.do_subtract = (addend_neg[i] == State::S1);
ports.push_back(term);
}
log_assert(port_c.size() == ci);
}
void to_cell(RTLIL::Cell *cell)
{
cell->type = ID($macc_v2);
int nproducts = 0, naddends = 0;
Const a_signed, b_signed, a_widths, b_widths, product_negated;
Const c_signed, c_widths, addend_negated;
SigSpec a, b, c;
for (int i = 0; i < (int) ports.size(); i++) {
SigSpec term_a = ports[i].in_a, term_b = ports[i].in_b;
if (term_b.empty()) {
// addend
c_widths.append(Const(term_a.size(), 16));
c_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
addend_negated.append(ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0);
c.append(term_a);
naddends++;
} else {
// product
a_widths.append(Const(term_a.size(), 16));
b_widths.append(Const(term_b.size(), 16));
a_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
b_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
product_negated.append(ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0);
a.append(term_a);
b.append(term_b);
nproducts++;
}
}
while (max_size)
num_bits++, max_size /= 2;
if (a_signed.empty())
a_signed = {RTLIL::Sx};
if (b_signed.empty())
b_signed = {RTLIL::Sx};
if (c_signed.empty())
c_signed = {RTLIL::Sx};
if (a_widths.empty())
a_widths = {RTLIL::Sx};
if (b_widths.empty())
b_widths = {RTLIL::Sx};
if (c_widths.empty())
c_widths = {RTLIL::Sx};
if (product_negated.empty())
product_negated = {RTLIL::Sx};
if (addend_negated.empty())
addend_negated = {RTLIL::Sx};
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);
for (auto &port : ports)
{
if (GetSize(port.in_a) == 0)
continue;
config_bits.push_back(port.is_signed ? State::S1 : State::S0);
config_bits.push_back(port.do_subtract ? State::S1 : State::S0);
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 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);
port_a.append(port.in_a);
port_a.append(port.in_b);
}
cell->setPort(ID::A, port_a);
cell->setPort(ID::B, {});
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, 0);
cell->setParam(ID::NPRODUCTS, nproducts);
cell->setParam(ID::PRODUCT_NEGATED, product_negated);
cell->setParam(ID::NADDENDS, naddends);
cell->setParam(ID::ADDEND_NEGATED, addend_negated);
cell->setParam(ID::A_SIGNED, a_signed);
cell->setParam(ID::B_SIGNED, b_signed);
cell->setParam(ID::C_SIGNED, c_signed);
cell->setParam(ID::A_WIDTHS, a_widths);
cell->setParam(ID::B_WIDTHS, b_widths);
cell->setParam(ID::C_WIDTHS, c_widths);
cell->setPort(ID::A, a);
cell->setPort(ID::B, b);
cell->setPort(ID::C, c);
}
bool eval(RTLIL::Const &result) const

View file

@ -542,6 +542,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];
@ -1471,6 +1477,40 @@ namespace {
return;
}
if (cell->type == ID($macc_v2)) {
if (param(ID::NPRODUCTS) < 0)
error(__LINE__);
if (param(ID::NADDENDS) < 0)
error(__LINE__);
param_bits(ID::PRODUCT_NEGATED, max(param(ID::NPRODUCTS), 1));
param_bits(ID::ADDEND_NEGATED, max(param(ID::NADDENDS), 1));
param_bits(ID::A_SIGNED, max(param(ID::NPRODUCTS), 1));
param_bits(ID::B_SIGNED, max(param(ID::NPRODUCTS), 1));
param_bits(ID::C_SIGNED, max(param(ID::NADDENDS), 1));
if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED))
error(__LINE__);
param_bits(ID::A_WIDTHS, max(param(ID::NPRODUCTS) * 16, 1));
param_bits(ID::B_WIDTHS, max(param(ID::NPRODUCTS) * 16, 1));
param_bits(ID::C_WIDTHS, max(param(ID::NADDENDS) * 16, 1));
const Const &a_width = cell->getParam(ID::A_WIDTHS);
const Const &b_width = cell->getParam(ID::B_WIDTHS);
const Const &c_width = cell->getParam(ID::C_WIDTHS);
int a_width_sum = 0, b_width_sum = 0, c_width_sum = 0;
for (int i = 0; i < param(ID::NPRODUCTS); 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);
}
for (int i = 0; i < param(ID::NADDENDS); i++) {
c_width_sum += c_width.extract(16 * i, 16).as_int(false);
}
port(ID::A, a_width_sum);
port(ID::B, b_width_sum);
port(ID::C, c_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));
@ -4146,6 +4186,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)) {

View file

@ -744,6 +744,8 @@ public:
bool empty() const;
void bitvectorize() const;
void append(const RTLIL::Const &other);
class const_iterator {
private:
const Const& parent;

View file

@ -740,7 +740,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($macc))
if (cell->type.in(ID($macc), ID($macc_v2)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);