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

inputs option

This commit is contained in:
Alain Dargelas 2025-03-04 11:43:12 -08:00
parent 864850ab51
commit 1027a96860

View file

@ -17,7 +17,8 @@ std::string substringuntil(const std::string &str, char delimiter)
} }
// Generate a human readable name for a sigspec, uniquify if necessary // Generate a human readable name for a sigspec, uniquify if necessary
RTLIL::IdString generateSigSpecName(Module* module, const RTLIL::SigSpec &sigspec, bool makeUnique = false, std::string postfix = "", bool cellName = false) RTLIL::IdString generateSigSpecName(Module *module, const RTLIL::SigSpec &sigspec, bool makeUnique = false, std::string postfix = "",
bool cellName = false)
{ {
if (sigspec.empty()) { if (sigspec.empty()) {
return RTLIL::IdString(); // Empty SigSpec, return empty IdString return RTLIL::IdString(); // Empty SigSpec, return empty IdString
@ -241,11 +242,10 @@ RTLIL::SigSpec getCellOutputSigSpec(Cell *cell, SigMap &sigmap)
} }
// Get new output signal for a given signal, used all datastructures with change to buffer // Get new output signal for a given signal, used all datastructures with change to buffer
SigSpec updateToBuffer(Module* module, std::map<SigSpec, int> &bufferIndexes, SigSpec updateToBuffer(Module *module, std::map<SigSpec, int> &bufferIndexes,
std::map<RTLIL::SigSpec, std::vector<std::pair<RTLIL::SigSpec, Cell *>>> &buffer_outputs, std::map<RTLIL::SigSpec, std::vector<std::pair<RTLIL::SigSpec, Cell *>>> &buffer_outputs,
dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout, std::map<Cell *, int> &bufferActualFanout, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout, std::map<Cell *, int> &bufferActualFanout,
std::map<SigSpec, SigSpec> &usedBuffers, int max_output_per_buffer, Cell *fanoutcell, SigSpec sigToReplace, std::map<SigSpec, SigSpec> &usedBuffers, int max_output_per_buffer, Cell *fanoutcell, SigSpec sigToReplace, bool debug)
bool debug)
{ {
if (debug) if (debug)
std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[sigToReplace] << " buffer_outputs " std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[sigToReplace] << " buffer_outputs "
@ -255,7 +255,7 @@ SigSpec updateToBuffer(Module* module, std::map<SigSpec, int> &bufferIndexes,
if (itrBuffer != usedBuffers.end()) { if (itrBuffer != usedBuffers.end()) {
if (debug) if (debug)
std::cout << "REUSE CACHE:" << fanoutcell->name.c_str() << " SIG: " << generateSigSpecName(module, sigToReplace).c_str() std::cout << "REUSE CACHE:" << fanoutcell->name.c_str() << " SIG: " << generateSigSpecName(module, sigToReplace).c_str()
<< std::endl; << std::endl;
return itrBuffer->second; return itrBuffer->second;
} }
@ -299,7 +299,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, int limit, bool debug) void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout, SigSpec sigToBuffer, int fanout,
int limit, bool debug)
{ {
if (sigToBuffer.is_fully_const()) { if (sigToBuffer.is_fully_const()) {
return; return;
@ -386,8 +387,9 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::
if (debug) if (debug)
std::cout << " MATCH" << std::endl; std::cout << " MATCH" << std::endl;
// Input is one of the cell's outputs, its a match // Input is one of the cell's outputs, its a match
SigSpec newSig = updateToBuffer(module, bufferIndexes, buffer_outputs, sig2CellsInFanout, bufferActualFanout, SigSpec newSig =
usedBuffers, max_output_per_buffer, fanoutcell, actual, debug); updateToBuffer(module, bufferIndexes, buffer_outputs, sig2CellsInFanout, bufferActualFanout,
usedBuffers, max_output_per_buffer, fanoutcell, actual, debug);
// Override the fanout cell's input with the buffer output // Override the fanout cell's input with the buffer output
fanoutcell->setPort(portName, newSig); fanoutcell->setPort(portName, newSig);
} }
@ -402,9 +404,9 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::
if (buffer_outputs.find(chunk) != buffer_outputs.end()) { if (buffer_outputs.find(chunk) != buffer_outputs.end()) {
if (debug) if (debug)
std::cout << " MATCH" << std::endl; std::cout << " MATCH" << std::endl;
SigSpec newSig = SigSpec newSig = updateToBuffer(module, bufferIndexes, buffer_outputs,
updateToBuffer(module, bufferIndexes, buffer_outputs, sig2CellsInFanout, bufferActualFanout, sig2CellsInFanout, bufferActualFanout, usedBuffers,
usedBuffers, max_output_per_buffer, fanoutcell, chunk, debug); max_output_per_buffer, fanoutcell, chunk, debug);
// Append the buffer's output in the chunk vector // Append the buffer's output in the chunk vector
newChunks.push_back(newSig.as_chunk()); newChunks.push_back(newSig.as_chunk());
} else { } else {
@ -489,6 +491,7 @@ void calculateFanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec,
cellFanout[cell] = 1; cellFanout[cell] = 1;
} }
// Correct input pin fanout
for (Wire *wire : module->wires()) { for (Wire *wire : module->wires()) {
if (wire->port_input) { if (wire->port_input) {
SigSpec inp = sigmap(wire); SigSpec inp = sigmap(wire);
@ -504,8 +507,6 @@ void calculateFanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec,
} }
} }
} }
} }
void splitNet(Design *design, std::set<std::string> &netsToSplitS, RTLIL::SigSpec &sigToSplit, bool formalFriendly, bool inputPort = false) void splitNet(Design *design, std::set<std::string> &netsToSplitS, RTLIL::SigSpec &sigToSplit, bool formalFriendly, bool inputPort = false)
@ -552,6 +553,8 @@ struct AnnotateCellFanout : public ScriptPass {
log(" Limits the fanout by inserting balanced buffer trees.\n"); log(" Limits the fanout by inserting balanced buffer trees.\n");
log(" -formal\n"); log(" -formal\n");
log(" For formal verification to pass, will prevent splitnets passes on ports, even if they have large fanout.\n"); log(" For formal verification to pass, will prevent splitnets passes on ports, even if they have large fanout.\n");
log(" -inputs\n");
log(" Fix module inputs fanout.\n");
log(" -debug\n"); log(" -debug\n");
log(" Debug trace.\n"); log(" Debug trace.\n");
log("\n"); log("\n");
@ -560,6 +563,7 @@ struct AnnotateCellFanout : public ScriptPass {
{ {
int limit = -1; int limit = -1;
bool formalFriendly = false; bool formalFriendly = false;
bool inputs = false;
bool debug = false; bool debug = false;
if (design == nullptr) { if (design == nullptr) {
log_error("No design object\n"); log_error("No design object\n");
@ -582,6 +586,10 @@ struct AnnotateCellFanout : public ScriptPass {
formalFriendly = true; formalFriendly = true;
continue; continue;
} }
if (args[argidx] == "-inputs") {
inputs = true;
continue;
}
break; break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -611,32 +619,33 @@ 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);
splitNet(design, netsToSplitS, cellOutSig, formalFriendly); splitNet(design, netsToSplitS, cellOutSig, formalFriendly);
} }
} }
} }
} }
// Split module input nets with high fanout if (inputs) {
std::set<Wire *> wiresToSplit; // Split module input nets with high fanout
for (Wire *wire : module->wires()) { std::set<Wire *> wiresToSplit;
if (wire->port_input) { for (Wire *wire : module->wires()) {
SigSpec inp = sigmap(wire); if (wire->port_input) {
int fanout = sigFanout[inp]; SigSpec inp = sigmap(wire);
if (limit > 0 && (fanout > limit)) { int fanout = sigFanout[inp];
wiresToSplit.insert(wire); if (limit > 0 && (fanout > limit)) {
wiresToSplit.insert(wire);
}
} }
} }
} for (Wire *wire : wiresToSplit) {
for (Wire *wire : wiresToSplit) { SigSpec inp = sigmap(wire);
SigSpec inp = sigmap(wire); splitNet(design, netsToSplitS, inp, formalFriendly, true);
splitNet(design, netsToSplitS, inp, formalFriendly, true); }
} }
} }
{ {
// Fix high fanout // Fix high fanout
SigMap sigmap(module); SigMap sigmap(module);
dict<Cell *, int> cellFanout; dict<Cell *, int> cellFanout;
dict<SigSpec, int> sigFanout; dict<SigSpec, int> sigFanout;
@ -670,7 +679,11 @@ struct AnnotateCellFanout : public ScriptPass {
SigSpec inp = sigmap(wire); SigSpec inp = sigmap(wire);
int fanout = sigFanout[inp]; int fanout = sigFanout[inp];
if (limit > 0 && (fanout > limit)) { if (limit > 0 && (fanout > limit)) {
sigsToFix.emplace(inp, fanout); if (inputs) {
sigsToFix.emplace(inp, fanout);
} else {
wire->set_string_attribute("$FANOUT", std::to_string(fanout));
}
} else { } else {
wire->set_string_attribute("$FANOUT", std::to_string(fanout)); wire->set_string_attribute("$FANOUT", std::to_string(fanout));
} }