mirror of https://github.com/YosysHQ/yosys.git
scc: Add -specify option to find loops in boxes
This commit is contained in:
parent
b0004911ca
commit
74dad5afe7
|
@ -37,7 +37,7 @@ struct SccWorker
|
|||
RTLIL::Design *design;
|
||||
RTLIL::Module *module;
|
||||
SigMap sigmap;
|
||||
CellTypes ct;
|
||||
CellTypes ct, specifyCells;
|
||||
|
||||
std::set<RTLIL::Cell*> workQueue;
|
||||
std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell;
|
||||
|
@ -100,7 +100,7 @@ struct SccWorker
|
|||
}
|
||||
}
|
||||
|
||||
SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) :
|
||||
SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, bool specifyMode, int maxDepth) :
|
||||
design(design), module(module), sigmap(module)
|
||||
{
|
||||
if (module->processes.size() > 0) {
|
||||
|
@ -115,6 +115,18 @@ struct SccWorker
|
|||
ct.setup_stdcells();
|
||||
}
|
||||
|
||||
// Discover boxes with specify rules in them, for special handling.
|
||||
if (specifyMode) {
|
||||
for (auto mod : design->modules())
|
||||
if (mod->get_blackbox_attribute(false))
|
||||
for (auto cell : mod->cells())
|
||||
if (cell->type == ID($specify2))
|
||||
{
|
||||
specifyCells.setup_module(mod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SigPool selectedSignals;
|
||||
SigSet<RTLIL::Cell*> sigToNextCells;
|
||||
|
||||
|
@ -129,13 +141,35 @@ struct SccWorker
|
|||
if (!design->selected(module, cell))
|
||||
continue;
|
||||
|
||||
if (!allCellTypes && !ct.cell_known(cell->type))
|
||||
if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type))
|
||||
continue;
|
||||
|
||||
workQueue.insert(cell);
|
||||
|
||||
RTLIL::SigSpec inputSignals, outputSignals;
|
||||
|
||||
if (specifyCells.cell_known(cell->type)) {
|
||||
// Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes.
|
||||
for (auto subcell : design->module(cell->type)->cells())
|
||||
{
|
||||
if (subcell->type != ID($specify2))
|
||||
continue;
|
||||
|
||||
for (auto bit : subcell->getPort(ID::SRC))
|
||||
{
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->name))
|
||||
continue;
|
||||
inputSignals.append(sigmap(cell->getPort(bit.wire->name)));
|
||||
}
|
||||
|
||||
for (auto bit : subcell->getPort(ID::DST))
|
||||
{
|
||||
if (!bit.wire || !cell->hasPort(bit.wire->name))
|
||||
continue;
|
||||
outputSignals.append(sigmap(cell->getPort(bit.wire->name)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
bool isInput = true, isOutput = true;
|
||||
|
@ -153,6 +187,7 @@ struct SccWorker
|
|||
if (isOutput)
|
||||
outputSignals.append(sig);
|
||||
}
|
||||
}
|
||||
|
||||
inputSignals.sort_and_unify();
|
||||
outputSignals.sort_and_unify();
|
||||
|
@ -228,7 +263,7 @@ struct SccPass : public Pass {
|
|||
log("design.\n");
|
||||
log("\n");
|
||||
log(" -expect <num>\n");
|
||||
log(" expect to find exactly <num> SSCs. A different number of SSCs will\n");
|
||||
log(" expect to find exactly <num> SCCs. A different number of SCCs will\n");
|
||||
log(" produce an error.\n");
|
||||
log("\n");
|
||||
log(" -max_depth <num>\n");
|
||||
|
@ -254,6 +289,9 @@ struct SccPass : public Pass {
|
|||
log(" replace the current selection with a selection of all cells and wires\n");
|
||||
log(" that are part of a found logic loop\n");
|
||||
log("\n");
|
||||
log(" -specify\n");
|
||||
log(" examine specify rules to detect logic loops in whitebox/blackbox cells\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
|
@ -261,6 +299,7 @@ struct SccPass : public Pass {
|
|||
bool allCellTypes = false;
|
||||
bool selectMode = false;
|
||||
bool nofeedbackMode = false;
|
||||
bool specifyMode = false;
|
||||
int maxDepth = -1;
|
||||
int expect = -1;
|
||||
|
||||
|
@ -293,6 +332,10 @@ struct SccPass : public Pass {
|
|||
selectMode = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-specify") {
|
||||
specifyMode = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
int origSelectPos = design->selection_stack.size() - 1;
|
||||
|
@ -303,7 +346,7 @@ struct SccPass : public Pass {
|
|||
|
||||
for (auto mod : design->selected_modules())
|
||||
{
|
||||
SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth);
|
||||
SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth);
|
||||
|
||||
if (!setAttr.empty())
|
||||
{
|
||||
|
|
|
@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass
|
|||
|
||||
if (check_label("pre")) {
|
||||
run("read_verilog -icells -lib -specify +/abc9_model.v");
|
||||
run("scc -set_attr abc9_scc_id {}");
|
||||
run("scc -specify -set_attr abc9_scc_id {}");
|
||||
if (help_mode)
|
||||
run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue