From 74dad5afe72ff1afa777352e9ca078cd80878a52 Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Mon, 11 Jan 2021 18:37:27 +0000 Subject: [PATCH] scc: Add -specify option to find loops in boxes --- passes/cmds/scc.cc | 77 ++++++++++++++++++++++++++++++++---------- passes/techmap/abc9.cc | 2 +- 2 files changed, 61 insertions(+), 18 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 workQueue; std::map> 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 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 \n"); - log(" expect to find exactly SSCs. A different number of SSCs will\n"); + log(" expect to find exactly SCCs. A different number of SCCs will\n"); log(" produce an error.\n"); log("\n"); log(" -max_depth \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 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 -- 2.30.2