mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-23 06:13:41 +00:00
inputs option
This commit is contained in:
parent
864850ab51
commit
1027a96860
1 changed files with 45 additions and 32 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue