aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/scc.cc77
-rw-r--r--passes/techmap/abc9.cc2
-rw-r--r--passes/techmap/flatten.cc2
3 files changed, 62 insertions, 19 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())
{
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 7d017ac40..56bb15495 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -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
diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc
index ec5f83fb0..f35b7ff60 100644
--- a/passes/techmap/flatten.cc
+++ b/passes/techmap/flatten.cc
@@ -211,7 +211,7 @@ struct FlattenWorker
log_assert(new_conn.first.size() == new_conn.second.size());
if (sigmap(new_conn.first).has_const())
- log_error("Mismatch in directionality for cell port %s.%s.%s: %s <= %s\n",
+ log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n",
log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second));
module->connect(new_conn);