3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-02-14 04:41:48 +00:00

kernel/celledges: cover more cell types

This commit is contained in:
Rowan Goemans 2026-02-09 14:13:40 +01:00
parent 1717fa0180
commit b8ee50d77f

View file

@ -112,6 +112,41 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
}
void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
}
void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, ID::B, i, ID::Y, a_width + i, -1);
}
void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int offset = cell->getParam(ID::OFFSET).as_int();
int a_width = GetSize(cell->getPort(ID::A));
int y_width = GetSize(cell->getPort(ID::Y));
for (int i = 0; i < y_width; i++) {
int a_bit = offset + i;
if (a_bit >= 0 && a_bit < a_width)
db->add_edge(cell, ID::A, a_bit, ID::Y, i, -1);
}
}
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int a_width = GetSize(cell->getPort(ID::A));
@ -254,7 +289,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int skip = 1 << (k + 1);
int base = skip -1;
if (i % skip != base && i - a_width + 2 < 1 << b_width_capped)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
} else if (is_signed) {
if (i - a_width + 2 < 1 << b_width_capped)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
@ -388,6 +423,64 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1);
}
void full_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
std::vector<RTLIL::IdString> input_ports;
std::vector<RTLIL::IdString> output_ports;
for (auto &conn : cell->connections())
{
RTLIL::IdString port = conn.first;
RTLIL::PortDir dir = cell->port_dir(port);
if (cell->input(port) || dir == RTLIL::PortDir::PD_INOUT)
input_ports.push_back(port);
if (cell->output(port) || dir == RTLIL::PortDir::PD_INOUT)
output_ports.push_back(port);
}
for (auto out_port : output_ports)
{
int out_width = GetSize(cell->getPort(out_port));
for (int out_bit = 0; out_bit < out_width; out_bit++)
{
for (auto in_port : input_ports)
{
int in_width = GetSize(cell->getPort(in_port));
for (int in_bit = 0; in_bit < in_width; in_bit++)
db->add_edge(cell, in_port, in_bit, out_port, out_bit, -1);
}
}
}
}
void bweqx_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int width = GetSize(cell->getPort(ID::Y));
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
int max_width = std::min(width, std::min(a_width, b_width));
for (int i = 0; i < max_width; i++) {
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
}
}
void bwmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int width = GetSize(cell->getPort(ID::Y));
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
int s_width = GetSize(cell->getPort(ID::S));
int max_width = std::min(width, std::min(a_width, std::min(b_width, s_width)));
for (int i = 0; i < max_width; i++) {
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
db->add_edge(cell, ID::S, i, ID::Y, i, -1);
}
}
PRIVATE_NAMESPACE_END
bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)
@ -417,6 +510,21 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true;
}
if (cell->type.in(ID($logic_and), ID($logic_or))) {
logic_op(this, cell);
return true;
}
if (cell->type == ID($slice)) {
slice_op(this, cell);
return true;
}
if (cell->type == ID($concat)) {
concat_op(this, cell);
return true;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
shift_op(this, cell);
return true;
@ -442,6 +550,16 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true;
}
if (cell->type == ID($bweqx)) {
bweqx_op(this, cell);
return true;
}
if (cell->type == ID($bwmux)) {
bwmux_op(this, cell);
return true;
}
if (cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit))) {
mem_op(this, cell);
return true;
@ -452,13 +570,24 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true;
}
// FIXME: $mul $div $mod $divfloor $modfloor $slice $concat
// 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
if (cell->type.in(ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) {
full_op(this, cell);
return true;
}
// FIXME: $_BUF_ $_NOT_ $_AND_ $_NAND_ $_OR_ $_NOR_ $_XOR_ $_XNOR_ $_ANDNOT_ $_ORNOT_
// FIXME: $_MUX_ $_NMUX_ $_MUX4_ $_MUX8_ $_MUX16_ $_AOI3_ $_OAI3_ $_AOI4_ $_OAI4_
if (cell->type.in(ID($lut), ID($sop), ID($alu), ID($lcu), ID($macc), ID($macc_v2))) {
full_op(this, cell);
return true;
}
if (cell->type.in(
ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_),
ID($_OAI4_), ID($_TBUF_))) {
full_op(this, cell);
return true;
}
// FIXME: $specify2 $specify3 $specrule ???
// FIXME: $equiv $set_tag $get_tag $overwrite_tag $original_tag
@ -468,4 +597,3 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return false;
}