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::Design *design;
|
||||||
RTLIL::Module *module;
|
RTLIL::Module *module;
|
||||||
SigMap sigmap;
|
SigMap sigmap;
|
||||||
CellTypes ct;
|
CellTypes ct, specifyCells;
|
||||||
|
|
||||||
std::set<RTLIL::Cell*> workQueue;
|
std::set<RTLIL::Cell*> workQueue;
|
||||||
std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell;
|
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)
|
design(design), module(module), sigmap(module)
|
||||||
{
|
{
|
||||||
if (module->processes.size() > 0) {
|
if (module->processes.size() > 0) {
|
||||||
|
@ -115,6 +115,18 @@ struct SccWorker
|
||||||
ct.setup_stdcells();
|
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;
|
SigPool selectedSignals;
|
||||||
SigSet<RTLIL::Cell*> sigToNextCells;
|
SigSet<RTLIL::Cell*> sigToNextCells;
|
||||||
|
|
||||||
|
@ -129,29 +141,52 @@ struct SccWorker
|
||||||
if (!design->selected(module, cell))
|
if (!design->selected(module, cell))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!allCellTypes && !ct.cell_known(cell->type))
|
if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
workQueue.insert(cell);
|
workQueue.insert(cell);
|
||||||
|
|
||||||
RTLIL::SigSpec inputSignals, outputSignals;
|
RTLIL::SigSpec inputSignals, outputSignals;
|
||||||
|
|
||||||
for (auto &conn : cell->connections())
|
if (specifyCells.cell_known(cell->type)) {
|
||||||
{
|
// Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes.
|
||||||
bool isInput = true, isOutput = true;
|
for (auto subcell : design->module(cell->type)->cells())
|
||||||
|
{
|
||||||
|
if (subcell->type != ID($specify2))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ct.cell_known(cell->type)) {
|
for (auto bit : subcell->getPort(ID::SRC))
|
||||||
isInput = ct.cell_input(cell->type, conn.first);
|
{
|
||||||
isOutput = ct.cell_output(cell->type, conn.first);
|
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;
|
||||||
|
|
||||||
RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));
|
if (ct.cell_known(cell->type)) {
|
||||||
sig.sort_and_unify();
|
isInput = ct.cell_input(cell->type, conn.first);
|
||||||
|
isOutput = ct.cell_output(cell->type, conn.first);
|
||||||
|
}
|
||||||
|
|
||||||
if (isInput)
|
RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second));
|
||||||
inputSignals.append(sig);
|
sig.sort_and_unify();
|
||||||
if (isOutput)
|
|
||||||
outputSignals.append(sig);
|
if (isInput)
|
||||||
|
inputSignals.append(sig);
|
||||||
|
if (isOutput)
|
||||||
|
outputSignals.append(sig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputSignals.sort_and_unify();
|
inputSignals.sort_and_unify();
|
||||||
|
@ -228,7 +263,7 @@ struct SccPass : public Pass {
|
||||||
log("design.\n");
|
log("design.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -expect <num>\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(" produce an error.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -max_depth <num>\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(" replace the current selection with a selection of all cells and wires\n");
|
||||||
log(" that are part of a found logic loop\n");
|
log(" that are part of a found logic loop\n");
|
||||||
log("\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
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
|
@ -261,6 +299,7 @@ struct SccPass : public Pass {
|
||||||
bool allCellTypes = false;
|
bool allCellTypes = false;
|
||||||
bool selectMode = false;
|
bool selectMode = false;
|
||||||
bool nofeedbackMode = false;
|
bool nofeedbackMode = false;
|
||||||
|
bool specifyMode = false;
|
||||||
int maxDepth = -1;
|
int maxDepth = -1;
|
||||||
int expect = -1;
|
int expect = -1;
|
||||||
|
|
||||||
|
@ -293,6 +332,10 @@ struct SccPass : public Pass {
|
||||||
selectMode = true;
|
selectMode = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-specify") {
|
||||||
|
specifyMode = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int origSelectPos = design->selection_stack.size() - 1;
|
int origSelectPos = design->selection_stack.size() - 1;
|
||||||
|
@ -303,7 +346,7 @@ struct SccPass : public Pass {
|
||||||
|
|
||||||
for (auto mod : design->selected_modules())
|
for (auto mod : design->selected_modules())
|
||||||
{
|
{
|
||||||
SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth);
|
SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth);
|
||||||
|
|
||||||
if (!setAttr.empty())
|
if (!setAttr.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("pre")) {
|
if (check_label("pre")) {
|
||||||
run("read_verilog -icells -lib -specify +/abc9_model.v");
|
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)
|
if (help_mode)
|
||||||
run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
|
run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue