mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-23 06:13:41 +00:00
Fix splitfanout
This commit is contained in:
parent
63a421aed8
commit
83dfdd9dd5
1 changed files with 23 additions and 30 deletions
|
@ -71,22 +71,23 @@ struct SplitfanoutWorker
|
||||||
// Get output signal/port
|
// Get output signal/port
|
||||||
SigSpec outsig;
|
SigSpec outsig;
|
||||||
IdString outport;
|
IdString outport;
|
||||||
if (cell->hasPort(ID::Y)) {
|
int output_count = 0;
|
||||||
outsig = sigmap(cell->getPort(ID::Y));
|
for (auto conn : cell->connections())
|
||||||
outport = ID::Y;
|
if (cell->output(conn.first)) {
|
||||||
}
|
output_count++;
|
||||||
else if (cell->hasPort(ID::Q)) {
|
outport = conn.first;
|
||||||
outsig = sigmap(cell->getPort(ID::Q));
|
outsig = conn.second;
|
||||||
outport = ID::Q;
|
}
|
||||||
}
|
if (output_count != 1) {
|
||||||
else
|
log("Skipping %s cell %s/%s with %d output ports.\n", log_id(cell->type), log_id(module), log_id(cell), output_count);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if output signal is "bit-split", skip if so
|
// Check if output signal is "bit-split", skip if so
|
||||||
pool<tuple<IdString,IdString,int>> bit_users = bit_users_db[outsig[0]];
|
auto bit_users = bit_users_db[outsig[0]];
|
||||||
for (int i = 0; i < GetSize(outsig); i++) {
|
for (int i = 0; i < GetSize(outsig); i++) {
|
||||||
if (bit_users_db[outsig[i]] != bit_users) {
|
if (bit_users_db[outsig[i]] != bit_users) {
|
||||||
log(" Skipping %s cell %s/%s with bit-split output.\n", log_id(cell->type), log_id(module), log_id(cell));
|
log("Skipping %s cell %s/%s with bit-split output.\n", log_id(cell->type), log_id(module), log_id(cell));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,37 +99,29 @@ struct SplitfanoutWorker
|
||||||
// Iterate over bit users and create a new cell for each one
|
// Iterate over bit users and create a new cell for each one
|
||||||
log("Splitting %s cell %s/%s into %d copies based on fanout:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(bit_users)-1);
|
log("Splitting %s cell %s/%s into %d copies based on fanout:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(bit_users)-1);
|
||||||
int foi = 0;
|
int foi = 0;
|
||||||
cell->setPort(outport, module->addWire(NEW_ID, GetSize(outsig))); // disconnect the original cell (to be deleted)
|
cell->unsetPort(outport);
|
||||||
for (auto user : bit_users)
|
for (auto bit_user : bit_users)
|
||||||
{
|
{
|
||||||
// Create a new cell
|
// Create a new cell
|
||||||
IdString new_name = module->uniquify(cell->name.str());
|
IdString new_name = module->uniquify(cell->name.str());
|
||||||
Cell *new_cell = module->addCell(new_name, cell);
|
Cell *new_cell = module->addCell(new_name, cell);
|
||||||
|
|
||||||
// Connect the new cell to the user
|
// Connect the new cell to the user
|
||||||
if (std::get<1>(user) == IdString()) {
|
if (std::get<1>(bit_user) == IdString()) { // is wire
|
||||||
IdString old_name = std::get<0>(user);
|
Wire *wire = module->wire(std::get<0>(bit_user));
|
||||||
IdString new_name = module->uniquify(old_name.str());
|
SigSpec spec(wire, std::get<2>(bit_user), GetSize(outsig));
|
||||||
Wire *old_wire = module->wire(old_name);
|
new_cell->setPort(outport, spec);
|
||||||
Wire *new_wire = module->addWire(new_name, old_wire);
|
|
||||||
module->swap_names(old_wire, new_wire);
|
|
||||||
old_wire->port_input = false;
|
|
||||||
old_wire->port_output = false;
|
|
||||||
new_cell->setPort(outport, new_wire);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Wire *new_wire = module->addWire(NEW_ID, GetSize(outsig));
|
Wire *new_wire = module->addWire(NEW_ID, GetSize(outsig));
|
||||||
SigSpec sig = module->cell(std::get<0>(user))->getPort(std::get<1>(user));
|
SigSpec sig = module->cell(std::get<0>(bit_user))->getPort(std::get<1>(bit_user));
|
||||||
sig.replace(std::get<2>(user), new_wire);
|
sig.replace(std::get<2>(bit_user), new_wire);
|
||||||
module->cell(std::get<0>(user))->setPort(std::get<1>(user), sig);
|
module->cell(std::get<0>(bit_user))->setPort(std::get<1>(bit_user), sig);
|
||||||
new_cell->setPort(outport, new_wire);
|
new_cell->setPort(outport, new_wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the new cell
|
// Log the new cell
|
||||||
log(" slice %d: %s => %s\n", foi, log_id(new_name), log_signal(new_cell->getPort(outport)));
|
log(" slice %d: %s => %s\n", foi++, log_id(new_name), log_signal(new_cell->getPort(outport)));
|
||||||
|
|
||||||
// Increment the fanout index
|
|
||||||
foi++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the original cell
|
// Remove the original cell
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue