aboutsummaryrefslogtreecommitdiffstats
path: root/passes/cmds/scc.cc
diff options
context:
space:
mode:
authorDan Ravensloft <dan.ravensloft@gmail.com>2021-01-11 18:37:27 +0000
committerDan Ravensloft <dan.ravensloft@gmail.com>2021-01-26 16:23:08 +0000
commit74dad5afe72ff1afa777352e9ca078cd80878a52 (patch)
treed5d43c4032819ca42a5685ad158c5a1603d5c016 /passes/cmds/scc.cc
parentb0004911ca15ec41db56c76c83461061fedc742e (diff)
downloadyosys-74dad5afe72ff1afa777352e9ca078cd80878a52.tar.gz
yosys-74dad5afe72ff1afa777352e9ca078cd80878a52.tar.bz2
yosys-74dad5afe72ff1afa777352e9ca078cd80878a52.zip
scc: Add -specify option to find loops in boxes
Diffstat (limited to 'passes/cmds/scc.cc')
-rw-r--r--passes/cmds/scc.cc77
1 files changed, 60 insertions, 17 deletions
diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc
index 8e7f3f990..7aa9a484f 100644
--- a/passes/cmds/scc.cc
+++ b/passes/cmds/scc.cc
@@ -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,29 +141,52 @@ 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;
- for (auto &conn : cell->connections())
- {
- bool isInput = true, isOutput = true;
+ 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;
- if (ct.cell_known(cell->type)) {
- isInput = ct.cell_input(cell->type, conn.first);
- isOutput = ct.cell_output(cell->type, conn.first);
+ 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;
+
+ if (ct.cell_known(cell->type)) {
+ isInput = ct.cell_input(cell->type, conn.first);
+ isOutput = ct.cell_output(cell->type, conn.first);
+ }
- RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));
- sig.sort_and_unify();
+ RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));
+ sig.sort_and_unify();
- if (isInput)
- inputSignals.append(sig);
- if (isOutput)
- outputSignals.append(sig);
+ if (isInput)
+ inputSignals.append(sig);
+ if (isOutput)
+ outputSignals.append(sig);
+ }
}
inputSignals.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())
{