mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 06:03:23 +00:00
cleanup dangling buffers
This commit is contained in:
parent
7d46ab08d5
commit
f65d822935
1 changed files with 25 additions and 8 deletions
|
@ -171,7 +171,7 @@ bool isSigSpecUsedIn(SigSpec &haystack, SigMap &sigmap, SigSpec &needle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a buffer and fix the fanout connections to use the buffer's input
|
// Remove a buffer and fix the fanout connections to use the buffer's input
|
||||||
void removeBuffer(Module *module, SigMap &sigmap, std::set<Cell *> &fanoutcells, Cell *buffer, bool debug)
|
void removeBuffer(Module *module, SigMap &sigmap, std::set<Cell *> &fanoutcells, std::map<Cell *, Wire *> &insertedBuffers, Cell *buffer, bool debug)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
std::cout << "Buffer with fanout 1: " << buffer->name.c_str() << std::endl;
|
std::cout << "Buffer with fanout 1: " << buffer->name.c_str() << std::endl;
|
||||||
|
@ -223,6 +223,8 @@ void removeBuffer(Module *module, SigMap &sigmap, std::set<Cell *> &fanoutcells,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Delete the now unsused buffer and it's output signal
|
// Delete the now unsused buffer and it's output signal
|
||||||
|
auto itr = insertedBuffers.find(buffer);
|
||||||
|
insertedBuffers.erase(itr);
|
||||||
module->remove(buffer);
|
module->remove(buffer);
|
||||||
module->remove({bufferOutSig.as_wire()});
|
module->remove({bufferOutSig.as_wire()});
|
||||||
}
|
}
|
||||||
|
@ -300,8 +302,8 @@ SigSpec updateToBuffer(Module *module, std::map<SigSpec, int> &bufferIndexes,
|
||||||
// - when a buffer reaches capacity, switch to the next buffer
|
// - when a buffer reaches capacity, switch to the next buffer
|
||||||
// The capacity of the buffers might be larger than the limit in a given pass,
|
// The capacity of the buffers might be larger than the limit in a given pass,
|
||||||
// Recursion is used until all buffers capacity is under or at the limit.
|
// Recursion is used until all buffers capacity is under or at the limit.
|
||||||
void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout, SigSpec sigToBuffer, int fanout,
|
void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout,
|
||||||
int limit, bool debug)
|
std::map<Cell *, Wire *> &insertedBuffers, SigSpec sigToBuffer, int fanout, int limit, bool debug)
|
||||||
{
|
{
|
||||||
if (sigToBuffer.is_fully_const()) {
|
if (sigToBuffer.is_fully_const()) {
|
||||||
return;
|
return;
|
||||||
|
@ -350,6 +352,7 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::
|
||||||
RTLIL::Cell *buffer = module->addCell(cellName, ID($buf));
|
RTLIL::Cell *buffer = module->addCell(cellName, ID($buf));
|
||||||
bufferActualFanout[buffer] = 0;
|
bufferActualFanout[buffer] = 0;
|
||||||
RTLIL::SigSpec buffer_output = module->addWire(wireName, chunk.size());
|
RTLIL::SigSpec buffer_output = module->addWire(wireName, chunk.size());
|
||||||
|
insertedBuffers.emplace(buffer, buffer_output.as_wire());
|
||||||
buffer->setPort(ID(A), chunk);
|
buffer->setPort(ID(A), chunk);
|
||||||
buffer->setPort(ID(Y), sigmap(buffer_output));
|
buffer->setPort(ID(Y), sigmap(buffer_output));
|
||||||
buffer->fixup_parameters();
|
buffer->fixup_parameters();
|
||||||
|
@ -427,11 +430,11 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::
|
||||||
for (std::map<Cell *, int>::iterator itr = bufferActualFanout.begin(); itr != bufferActualFanout.end(); itr++) {
|
for (std::map<Cell *, int>::iterator itr = bufferActualFanout.begin(); itr != bufferActualFanout.end(); itr++) {
|
||||||
if (itr->second == 1) {
|
if (itr->second == 1) {
|
||||||
// Remove previously inserted buffers with fanout of 1 (Hard to predict the last buffer usage in above step)
|
// Remove previously inserted buffers with fanout of 1 (Hard to predict the last buffer usage in above step)
|
||||||
removeBuffer(module, sigmap, fanoutcells, itr->first, debug);
|
removeBuffer(module, sigmap, fanoutcells, insertedBuffers, itr->first, debug);
|
||||||
} else {
|
} else {
|
||||||
// Recursively fix the fanout of the newly created buffers
|
// Recursively fix the fanout of the newly created buffers
|
||||||
RTLIL::SigSpec sig = getCellOutputSigSpec(itr->first, sigmap);
|
RTLIL::SigSpec sig = getCellOutputSigSpec(itr->first, sigmap);
|
||||||
fixfanout(module, sigmap, sig2CellsInFanout, sig, itr->second, limit, debug);
|
fixfanout(module, sigmap, sig2CellsInFanout, insertedBuffers, sig, itr->second, limit, debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -632,7 +635,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
}
|
}
|
||||||
for (auto module : design->selected_modules()) {
|
for (auto module : design->selected_modules()) {
|
||||||
bool fixedFanout = false;
|
bool fixedFanout = false;
|
||||||
|
std::map<Cell*, Wire*> insertedBuffers;
|
||||||
{
|
{
|
||||||
// Calculate fanout
|
// Calculate fanout
|
||||||
SigMap sigmap(module);
|
SigMap sigmap(module);
|
||||||
|
@ -694,7 +697,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
RTLIL::SigSpec actual = conn.second;
|
RTLIL::SigSpec actual = conn.second;
|
||||||
if (cell->output(portName)) {
|
if (cell->output(portName)) {
|
||||||
RTLIL::SigSpec cellOutSig = sigmap(actual);
|
RTLIL::SigSpec cellOutSig = sigmap(actual);
|
||||||
fixfanout(module, sigmap, sig2CellsInFanout, cellOutSig, fanout, limit, debug);
|
fixfanout(module, sigmap, sig2CellsInFanout, insertedBuffers, cellOutSig, fanout, limit, debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fixedFanout = true;
|
fixedFanout = true;
|
||||||
|
@ -748,7 +751,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto sig : sigsToFix) {
|
for (auto sig : sigsToFix) {
|
||||||
fixfanout(module, sigmap, sig2CellsInFanout, sig.first, sig.second, limit, debug);
|
fixfanout(module, sigmap, sig2CellsInFanout, insertedBuffers, sig.first, sig.second, limit, debug);
|
||||||
fixedFanout = true;
|
fixedFanout = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,6 +766,19 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
for (auto itrCell : cellFanout) {
|
for (auto itrCell : cellFanout) {
|
||||||
Cell *cell = itrCell.first;
|
Cell *cell = itrCell.first;
|
||||||
int fanout = itrCell.second;
|
int fanout = itrCell.second;
|
||||||
|
// Final cleanup, remove buffers of 1
|
||||||
|
if ((fanout == 1) && insertedBuffers.find(cell) != insertedBuffers.end()) {
|
||||||
|
SigSpec bufferOut = insertedBuffers.find(cell)->second;
|
||||||
|
std::set<Cell *> fanoutcells = sig2CellsInFanout[bufferOut];
|
||||||
|
for (int i = 0; i < bufferOut.size(); i++) {
|
||||||
|
SigSpec bit_sig = bufferOut.extract(i, 1);
|
||||||
|
for (Cell *c : sig2CellsInFanout[sigmap(bit_sig)]) {
|
||||||
|
fanoutcells.insert(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeBuffer(module, sigmap, fanoutcells, insertedBuffers, cell, debug);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Add attribute with fanout info to every cell
|
// Add attribute with fanout info to every cell
|
||||||
cell->set_string_attribute("$FANOUT", std::to_string(fanout));
|
cell->set_string_attribute("$FANOUT", std::to_string(fanout));
|
||||||
}
|
}
|
||||||
|
@ -774,6 +790,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
wire->set_string_attribute("$FANOUT", std::to_string(fanout));
|
wire->set_string_attribute("$FANOUT", std::to_string(fanout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log("Added %ld buffers in module %s\n", insertedBuffers.size(), module->name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue