diff --git a/passes/silimate/annotate_cell_fanout.cc b/passes/silimate/annotate_cell_fanout.cc index 3b9875d39..c73bf28f6 100644 --- a/passes/silimate/annotate_cell_fanout.cc +++ b/passes/silimate/annotate_cell_fanout.cc @@ -17,7 +17,8 @@ std::string substringuntil(const std::string &str, char delimiter) } // 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()) { return RTLIL::IdString(); // Empty SigSpec, return empty IdString @@ -55,7 +56,7 @@ RTLIL::IdString generateSigSpecName(Module* module, const RTLIL::SigSpec &sigspe } else { ss << "\\sigspec_[" << max << ":" << min << "]"; } - } + } ss << postfix; if (makeUnique) { RTLIL::IdString base_name = RTLIL::IdString(ss.str()); @@ -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 -SigSpec updateToBuffer(Module* module, std::map &bufferIndexes, +SigSpec updateToBuffer(Module *module, std::map &bufferIndexes, std::map>> &buffer_outputs, dict> &sig2CellsInFanout, std::map &bufferActualFanout, - std::map &usedBuffers, int max_output_per_buffer, Cell *fanoutcell, SigSpec sigToReplace, - bool debug) + std::map &usedBuffers, int max_output_per_buffer, Cell *fanoutcell, SigSpec sigToReplace, bool debug) { if (debug) std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[sigToReplace] << " buffer_outputs " @@ -255,10 +255,10 @@ SigSpec updateToBuffer(Module* module, std::map &bufferIndexes, if (itrBuffer != usedBuffers.end()) { if (debug) std::cout << "REUSE CACHE:" << fanoutcell->name.c_str() << " SIG: " << generateSigSpecName(module, sigToReplace).c_str() - << std::endl; + << std::endl; return itrBuffer->second; } - + // Retrieve the buffer information for that cell's chunk std::vector> &buf_info_vec = buffer_outputs[sigToReplace]; // Retrieve which buffer is getting filled @@ -285,9 +285,9 @@ SigSpec updateToBuffer(Module* module, std::map &bufferIndexes, // Cache result if (debug) std::cout << "CACHE:" << fanoutcell->name.c_str() << " SIG: " << generateSigSpecName(module, sigToReplace).c_str() << " BY " - << generateSigSpecName(module, newSig).c_str() << std::endl; + << generateSigSpecName(module, newSig).c_str() << std::endl; usedBuffers.emplace(sigToReplace, newSig); - + // Return buffer's output return newSig; } @@ -299,7 +299,8 @@ SigSpec updateToBuffer(Module* module, std::map &bufferIndexes, // - 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, // Recursion is used until all buffers capacity is under or at the limit. -void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict> &sig2CellsInFanout, SigSpec sigToBuffer, int fanout, int limit, bool debug) +void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict> &sig2CellsInFanout, SigSpec sigToBuffer, int fanout, + int limit, bool debug) { if (sigToBuffer.is_fully_const()) { return; @@ -386,8 +387,9 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dictsetPort(portName, newSig); } @@ -402,9 +404,9 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dictwires()) { if (wire->port_input) { SigSpec inp = sigmap(wire); @@ -504,8 +507,6 @@ void calculateFanout(RTLIL::Module *module, SigMap &sigmap, dict &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(" -formal\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 trace.\n"); log("\n"); @@ -560,6 +563,7 @@ struct AnnotateCellFanout : public ScriptPass { { int limit = -1; bool formalFriendly = false; + bool inputs = false; bool debug = false; if (design == nullptr) { log_error("No design object\n"); @@ -582,6 +586,10 @@ struct AnnotateCellFanout : public ScriptPass { formalFriendly = true; continue; } + if (args[argidx] == "-inputs") { + inputs = true; + continue; + } break; } extra_args(args, argidx, design); @@ -611,32 +619,33 @@ struct AnnotateCellFanout : public ScriptPass { RTLIL::SigSpec actual = conn.second; if (cell->output(portName)) { RTLIL::SigSpec cellOutSig = sigmap(actual); - splitNet(design, netsToSplitS, cellOutSig, formalFriendly); + splitNet(design, netsToSplitS, cellOutSig, formalFriendly); } } } } - // Split module input nets with high fanout - std::set wiresToSplit; - for (Wire *wire : module->wires()) { - if (wire->port_input) { - SigSpec inp = sigmap(wire); - int fanout = sigFanout[inp]; - if (limit > 0 && (fanout > limit)) { - wiresToSplit.insert(wire); + if (inputs) { + // Split module input nets with high fanout + std::set wiresToSplit; + for (Wire *wire : module->wires()) { + if (wire->port_input) { + SigSpec inp = sigmap(wire); + int fanout = sigFanout[inp]; + if (limit > 0 && (fanout > limit)) { + wiresToSplit.insert(wire); + } } } - } - for (Wire *wire : wiresToSplit) { - SigSpec inp = sigmap(wire); - splitNet(design, netsToSplitS, inp, formalFriendly, true); + for (Wire *wire : wiresToSplit) { + SigSpec inp = sigmap(wire); + splitNet(design, netsToSplitS, inp, formalFriendly, true); + } } } { // Fix high fanout - SigMap sigmap(module); dict cellFanout; dict sigFanout; @@ -670,7 +679,11 @@ struct AnnotateCellFanout : public ScriptPass { SigSpec inp = sigmap(wire); int fanout = sigFanout[inp]; 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 { wire->set_string_attribute("$FANOUT", std::to_string(fanout)); }