3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-06 17:44:09 +00:00

Improvements in "bufnorm" pass

Signed-off-by: Claire Xenia Wolf <claire@clairexen.net>
This commit is contained in:
Claire Xenia Wolf 2023-09-29 10:03:36 +02:00 committed by Martin Povišer
parent d027ead4b5
commit 8bb70bac8d

View file

@ -172,6 +172,12 @@ struct BufnormPass : public Pass {
if (pos_mode && conn_mode) if (pos_mode && conn_mode)
log_cmd_error("Options -pos and -conn are exclusive.\n"); log_cmd_error("Options -pos and -conn are exclusive.\n");
int count_removed_buffers = 0;
int count_updated_buffers = 0;
int count_kept_buffers = 0;
int count_created_buffers = 0;
int count_updated_cellports = 0;
for (auto module : design->selected_modules()) for (auto module : design->selected_modules())
{ {
log("Buffer-normalizing module %s.\n", log_id(module)); log("Buffer-normalizing module %s.\n", log_id(module));
@ -179,21 +185,29 @@ struct BufnormPass : public Pass {
SigMap sigmap(module); SigMap sigmap(module);
module->new_connections({}); module->new_connections({});
dict<pair<IdString, SigSpec>, Cell*> old_buffers;
{ {
vector<Cell*> old_buffers; vector<Cell*> old_dup_buffers;
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (!cell->type.in(ID($buf), ID($_BUF_))) if (!cell->type.in(ID($buf), ID($_BUF_)))
continue; continue;
SigSpec insig = sigmap(cell->getPort(ID::A)); SigSpec insig = cell->getPort(ID::A);
SigSpec outsig = sigmap(cell->getPort(ID::Y)); SigSpec outsig = cell->getPort(ID::Y);
for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++) for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++)
sigmap.add(insig[i], outsig[i]); sigmap.add(insig[i], outsig[i]);
old_buffers.push_back(cell);
pair<IdString,Wire*> key(cell->type, outsig.as_wire());
if (old_buffers.count(key))
old_dup_buffers.push_back(cell);
else
old_buffers[key] = cell;
} }
for (auto cell : old_buffers) for (auto cell : old_dup_buffers)
module->remove(cell); module->remove(cell);
count_removed_buffers += GetSize(old_dup_buffers);
} }
dict<SigBit, pool<Wire*>> bit2wires; dict<SigBit, pool<Wire*>> bit2wires;
@ -280,6 +294,9 @@ struct BufnormPass : public Pass {
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($buf), ID($_BUF_)))
continue;
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
{ {
if (!cell->output(conn.first)) if (!cell->output(conn.first))
@ -318,6 +335,34 @@ struct BufnormPass : public Pass {
pool<Cell*> added_buffers; pool<Cell*> added_buffers;
auto make_buffer_f = [&](const IdString &type, const SigSpec &src, const SigSpec &dst)
{
auto it = old_buffers.find(pair<IdString, SigSpec>(type, dst));
if (it != old_buffers.end())
{
Cell *cell = it->second;
old_buffers.erase(it);
added_buffers.insert(cell);
if (cell->getPort(ID::A) == src) {
count_kept_buffers++;
} else {
cell->setPort(ID::A, src);
count_updated_buffers++;
}
return;
}
Cell *cell = module->addCell(NEW_ID, type);
added_buffers.insert(cell);
cell->setPort(ID::A, src);
cell->setPort(ID::Y, dst);
cell->fixup_parameters();
count_created_buffers++;
};
unmapped_wires.sort(compare_wires_f); unmapped_wires.sort(compare_wires_f);
for (auto wire : unmapped_wires) for (auto wire : unmapped_wires)
{ {
@ -346,25 +391,20 @@ struct BufnormPass : public Pass {
} else { } else {
if (bits_mode) { if (bits_mode) {
IdString celltype = pos_mode ? ID($pos) : buf_mode ? ID($buf) : ID($_BUF_); IdString celltype = pos_mode ? ID($pos) : buf_mode ? ID($buf) : ID($_BUF_);
for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++) { for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++)
Cell *c = module->addCell(NEW_ID, celltype); make_buffer_f(celltype, insig[i], outsig[i]);
c->setPort(ID::A, insig[i]);
c->setPort(ID::Y, outsig[i]);
c->fixup_parameters();
added_buffers.insert(c);
}
} else { } else {
IdString celltype = pos_mode ? ID($pos) : buf_mode ? ID($buf) : IdString celltype = pos_mode ? ID($pos) : buf_mode ? ID($buf) :
GetSize(outsig) == 1 ? ID($_BUF_) : ID($buf); GetSize(outsig) == 1 ? ID($_BUF_) : ID($buf);
Cell *c = module->addCell(NEW_ID, celltype); make_buffer_f(celltype, insig, outsig);
c->setPort(ID::A, insig);
c->setPort(ID::Y, outsig);
c->fixup_parameters();
added_buffers.insert(c);
} }
} }
} }
for (auto &it : old_buffers)
module->remove(it.second);
count_removed_buffers += GetSize(old_buffers);
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (added_buffers.count(cell)) if (added_buffers.count(cell))
@ -383,10 +423,15 @@ struct BufnormPass : public Pass {
log(" fixing input signal on cell %s port %s: %s\n", log(" fixing input signal on cell %s port %s: %s\n",
log_id(cell), log_id(conn.first), log_signal(newsig)); log_id(cell), log_id(conn.first), log_signal(newsig));
cell->setPort(conn.first, newsig); cell->setPort(conn.first, newsig);
count_updated_cellports++;
} }
} }
} }
} }
log("Summary: removed %d, updated %d, kept %d, and created %d buffers, and updated %d cell ports.\n",
count_removed_buffers, count_updated_buffers, count_kept_buffers,
count_created_buffers, count_updated_cellports);
} }
} BufnormPass; } BufnormPass;