3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-23 06:13:41 +00:00

fanout per buffer

This commit is contained in:
Alain Dargelas 2025-02-28 20:38:36 -08:00
parent 2741989158
commit 0d854120a7

View file

@ -108,22 +108,22 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
} }
// Create buffers and new wires // Create buffers and new wires
std::vector<std::vector<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>>> buffer_outputs; std::map<Cell *, int> bufferActualFanout;
std::vector<std::vector<RTLIL::Cell *>> buffers; std::map<RTLIL::SigSpec, std::vector<std::tuple<RTLIL::SigSpec, Cell*>>> buffer_outputs;
for (int i = 0; i < num_buffers; ++i) { std::map<SigSpec, int> bufferIndexes;
std::vector<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>> buffer_chunk_outputs;
std::vector<RTLIL::Cell *> buffer_chunks;
for (SigChunk chunk : cellOutSig.chunks()) { for (SigChunk chunk : cellOutSig.chunks()) {
std::vector<std::tuple<RTLIL::SigSpec, Cell*>> buffer_chunk_outputs;
for (int i = 0; i < num_buffers; ++i) {
RTLIL::Cell *buffer = module->addCell(NEW_ID2_SUFFIX("fbuf"), ID($pos)); RTLIL::Cell *buffer = module->addCell(NEW_ID2_SUFFIX("fbuf"), ID($pos));
bufferActualFanout[buffer] = 0;
RTLIL::SigSpec buffer_output = module->addWire(NEW_ID2_SUFFIX("fbuf"), chunk.size()); RTLIL::SigSpec buffer_output = module->addWire(NEW_ID2_SUFFIX("fbuf"), chunk.size());
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();
buffer_chunk_outputs.push_back(std::make_pair(chunk, buffer_output)); // Old - New buffer_chunk_outputs.push_back(std::make_tuple(buffer_output, buffer)); // Old - New
buffer_chunks.push_back(buffer); bufferIndexes[chunk] = 0;
} }
buffer_outputs.push_back(buffer_chunk_outputs); buffer_outputs.emplace(sigmap(SigSpec(chunk)), buffer_chunk_outputs);
buffers.push_back(buffer_chunks);
} }
// Cumulate all cells in the fanout of this cell // Cumulate all cells in the fanout of this cell
@ -136,38 +136,34 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
} }
// Fix input connections to cells in fanout of buffer to point to the inserted buffer // Fix input connections to cells in fanout of buffer to point to the inserted buffer
int indexCurrentBuffer = 0;
int indexFanout = 0;
std::map<Cell *, int> bufferActualFanout;
for (Cell *c : cells) { for (Cell *c : cells) {
std::cout << " CELL in fanout: " << c->name.c_str() << "\n" << std::flush; std::cout << "\n CELL in fanout: " << c->name.c_str() << "\n" << std::flush;
for (auto &conn : c->connections()) { for (auto &conn : c->connections()) {
IdString portName = conn.first; IdString portName = conn.first;
RTLIL::SigSpec actual = conn.second; RTLIL::SigSpec actual = sigmap(conn.second);
if (c->input(portName)) { if (c->input(portName)) {
if (actual.is_chunk()) { if (actual.is_chunk()) {
std::cout << " CHUNK, indexCurrentBuffer: " << indexCurrentBuffer << " buffer_outputs " << buffer_outputs.size() << std::endl; if (buffer_outputs.find(actual) != buffer_outputs.end()) {
for (std::pair<RTLIL::SigSpec, RTLIL::SigSpec>& old_new : buffer_outputs[indexCurrentBuffer]) { std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[actual] << " buffer_outputs " << buffer_outputs[actual].size() << std::endl;
if (sigmap(old_new.first) == sigmap(actual)) { std::vector<std::tuple<RTLIL::SigSpec, Cell*>>& buf_info_vec = buffer_outputs[actual];
int bufferIndex = bufferIndexes[actual];
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
std::cout << " VEC SIZE: " << buf_info_vec.size() << std::endl;
std::tuple<RTLIL::SigSpec, Cell*>& buf_info = buf_info_vec[bufferIndex];
SigSpec newSig = std::get<0>(buf_info);
Cell* newBuf = std::get<1>(buf_info);
std::cout << " MATCH" << std::endl; std::cout << " MATCH" << std::endl;
c->setPort(portName, old_new.second); c->setPort(portName, newSig);
sig2CellsInFanout[sigmap(old_new.second)].insert(c); sig2CellsInFanout[newSig].insert(c);
indexFanout++; bufferActualFanout[newBuf]++;
for (Cell* c : buffers[indexCurrentBuffer]) { std::cout << " b: " << newBuf->name.c_str() << " fanout: " << bufferActualFanout[newBuf] << std::endl;
if (bufferActualFanout.find(c) != bufferActualFanout.end()) { if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
bufferActualFanout[c] = std::max(indexFanout, bufferActualFanout[c]); std::cout << " REACHED MAX" << std::endl;
} else { if (buffer_outputs[actual].size() - 1 > bufferIndex) {
bufferActualFanout[c] = indexFanout; bufferIndexes[actual]++;
std::cout << " NEXT BUFFER" << std::endl;
} }
} }
break;
}
}
if (indexFanout >= max_output_per_buffer) {
if (buffer_outputs.size()-1 > indexCurrentBuffer) {
indexFanout = 0;
indexCurrentBuffer++;
}
} }
} else { } else {
std::cout << " NOT CHUNK" << std::endl; std::cout << " NOT CHUNK" << std::endl;
@ -187,35 +183,34 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
break; break;
} }
if (match) { if (match) {
std::cout << " MATCH" << std::endl; std::cout << " MATCH" << std::endl;
std::vector<RTLIL::SigChunk> newChunks; std::vector<RTLIL::SigChunk> newChunks;
bool missed = true; bool missed = true;
for (SigChunk chunk : actual.chunks()) { for (SigChunk chunk : actual.chunks()) {
bool replaced = false; bool replaced = false;
for (std::pair<RTLIL::SigSpec, RTLIL::SigSpec>& old_new : buffer_outputs[indexCurrentBuffer]) { if (buffer_outputs.find(chunk) != buffer_outputs.end()) {
if (sigmap(old_new.first) == sigmap(SigSpec(chunk))) { std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[chunk] << " buffer_outputs " << buffer_outputs[chunk].size() << std::endl;
std::vector<std::tuple<RTLIL::SigSpec, Cell*>>& buf_info_vec = buffer_outputs[chunk];
int bufferIndex = bufferIndexes[chunk];
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
std::cout << " VEC SIZE: " << buf_info_vec.size() << std::endl;
std::tuple<RTLIL::SigSpec, Cell*>& buf_info = buf_info_vec[bufferIndex];
SigSpec newSig = std::get<0>(buf_info);
Cell* newBuf = std::get<1>(buf_info);
missed = false; missed = false;
newChunks.push_back(old_new.second.as_chunk()); newChunks.push_back(newSig.as_chunk());
sig2CellsInFanout[sigmap(old_new.second)].insert(c); sig2CellsInFanout[newSig].insert(c);
replaced = true; replaced = true;
indexFanout++; bufferActualFanout[newBuf]++;
std::cout << " b: " << newBuf->name.c_str() << " fanout: " << bufferActualFanout[newBuf] << std::endl;
for (Cell *c : buffers[indexCurrentBuffer]) { if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
if (bufferActualFanout.find(c) != bufferActualFanout.end()) { std::cout << " REACHED MAX" << std::endl;
bufferActualFanout[c] = std::max(indexFanout, bufferActualFanout[c]); if (buffer_outputs[chunk].size() - 1 > bufferIndex) {
} else { bufferIndexes[chunk]++;
bufferActualFanout[c] = indexFanout; std::cout << " NEXT BUFFER" << std::endl;
} }
} }
if (indexFanout >= max_output_per_buffer) {
if (buffer_outputs.size() - 1 > indexCurrentBuffer) {
indexFanout = 0;
indexCurrentBuffer++;
}
}
break;
}
} }
if (!replaced) { if (!replaced) {
newChunks.push_back(chunk); newChunks.push_back(chunk);
@ -226,6 +221,7 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
} }
c->setPort(portName, newChunks); c->setPort(portName, newChunks);
break; break;
} }
} }
} }
@ -267,8 +263,8 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
} }
} }
} }
//module->remove(itr->first); module->remove(itr->first);
//module->remove({bufferOutSig.as_wire()}); module->remove({bufferOutSig.as_wire()});
} else { } else {
fixfanout(design, module, sigmap, sig2CellsInFanout, itr->first, itr->second, limit); fixfanout(design, module, sigmap, sig2CellsInFanout, itr->first, itr->second, limit);
} }
@ -389,8 +385,9 @@ struct AnnotateCellFanout : public ScriptPass {
} }
} }
netsToSplit += std::string(" w:") + getParentWire(cellOutSig)->name.c_str(); netsToSplit += std::string(" w:") + getParentWire(cellOutSig)->name.c_str();
netsToSplit += std::string(" x:") + getParentWire(cellOutSig)->name.c_str();
} }
std::string splitnets = std::string("splitnets -ports ") + netsToSplit; std::string splitnets = std::string("splitnets ") + netsToSplit;
Pass::call(design, splitnets); Pass::call(design, splitnets);
} }