53 std::vector<std::set<RTLIL::Cell*>>
sccList;
71 run(nextCell, depth+1, maxDepth);
74 if (
cellsOnStack.count(nextCell) > 0 && (maxDepth < 0 || cellDepth[nextCell] + maxDepth > depth)) {
88 std::set<RTLIL::Cell*> scc;
106 log(
"Skipping module %s as it contains processes (run 'proc' pass first).\n", module->
name.
c_str());
120 for (
auto &it : module->
wires_)
121 if (design->
selected(module, it.second))
124 for (
auto &it : module->
cells_)
128 if (!design->
selected(module, cell))
140 bool isInput =
true, isOutput =
true;
153 outputSignals.
append(sig);
161 sigToNextCells.
insert(inputSignals, cell);
170 while (workQueue.size() > 0) {
174 run(cell, 0, maxDepth);
182 for (
int i = 0; i < int(
sccList.size()); i++)
184 std::set<RTLIL::Cell*> &cells =
sccList[i];
187 for (
auto cell : cells) {
195 sig = prevsig.
extract(nextsig);
197 for (
auto &chunk : sig.
chunks())
198 if (chunk.wire !=
NULL)
205 SccPass() :
Pass(
"scc",
"detect strongly connected components (logic loops)") { }
210 log(
" scc [options] [selection]\n");
212 log(
"This command identifies strongly connected components (aka logic loops) in the\n");
215 log(
" -max_depth <num>\n");
216 log(
" limit to loops not longer than the specified number of cells. This can\n");
217 log(
" e.g. be useful in identifying local loops in a module that turns out\n");
218 log(
" to be one gigantic SCC.\n");
220 log(
" -all_cell_types\n");
221 log(
" Usually this command only considers internal non-memory cells. With\n");
222 log(
" this option set, all cells are considered. For unknown cells all ports\n");
223 log(
" are assumed to be bidirectional 'inout' ports.\n");
225 log(
" -set_attr <name> <value>\n");
226 log(
" -set_cell_attr <name> <value>\n");
227 log(
" -set_wire_attr <name> <value>\n");
228 log(
" set the specified attribute on all cells and/or wires that are part of\n");
229 log(
" a logic loop. the special token {} in the value is replaced with a\n");
230 log(
" unique identifier for the logic loop.\n");
233 log(
" replace the current selection with a selection of all cells and wires\n");
234 log(
" that are part of a found logic loop\n");
239 std::map<std::string, std::string> setCellAttr, setWireAttr;
240 bool allCellTypes =
false;
241 bool selectMode =
false;
244 log_header(
"Executing SCC pass (detecting logic loops).\n");
247 for (argidx = 1; argidx < args.size(); argidx++) {
248 if (args[argidx] ==
"-max_depth" && argidx+1 < args.size()) {
249 maxDepth = atoi(args[++argidx].c_str());
252 if (args[argidx] ==
"-all_cell_types") {
256 if (args[argidx] ==
"-set_attr" && argidx+2 < args.size()) {
257 setCellAttr[args[argidx+1]] = args[argidx+2];
258 setWireAttr[args[argidx+1]] = args[argidx+2];
262 if (args[argidx] ==
"-set_cell_attr" && argidx+2 < args.size()) {
263 setCellAttr[args[argidx+1]] = args[argidx+2];
267 if (args[argidx] ==
"-set_wire_attr" && argidx+2 < args.size()) {
268 setWireAttr[args[argidx+1]] = args[argidx+2];
272 if (args[argidx] ==
"-select") {
281 if (setCellAttr.size() > 0 || setWireAttr.size() > 0)
282 log_cmd_error(
"The -set*_attr options are not implemented at the moment!\n");
286 for (
auto &mod_it : design->
modules_)
287 if (design->
selected(mod_it.second))
289 SccWorker worker(design, mod_it.second, allCellTypes, maxDepth);
292 worker.
select(newSelection);
const char * c_str() const
bool selected(T1 *module) const
RTLIL::SigSpec extract(RTLIL::SigSpec sig)
std::vector< RTLIL::Selection > selection_stack
void run(RTLIL::Cell *cell, int depth, int maxDepth)
void log_header(const char *format,...)
void setup(RTLIL::Design *design=NULL)
std::map< RTLIL::Cell *, int > cell2scc
std::map< RTLIL::IdString, std::set< RTLIL::IdString > > selected_members
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
std::map< RTLIL::Cell *, int > cellDepth
std::map< RTLIL::Cell *, std::pair< int, int > > cellLabels
bool cell_known(RTLIL::IdString type)
#define PRIVATE_NAMESPACE_BEGIN
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
#define log_assert(_assert_expr_)
std::map< RTLIL::Cell *, std::set< RTLIL::Cell * > > cellToNextCell
#define PRIVATE_NAMESPACE_END
static const char * id2cstr(const RTLIL::IdString &str)
void log_cmd_error(const char *format,...)
SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool allCellTypes, int maxDepth)
std::map< RTLIL::IdString, RTLIL::Process * > processes
void add(RTLIL::SigSpec sig)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::vector< std::set< RTLIL::Cell * > > sccList
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void log(const char *format,...)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
std::vector< RTLIL::Cell * > cellStack
void append(const RTLIL::SigSpec &signal)
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::map< RTLIL::Cell *, RTLIL::SigSpec > cellToNextSig
std::set< RTLIL::Cell * > workQueue
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
void find(RTLIL::SigSpec sig, std::set< T > &result)
void insert(RTLIL::SigSpec sig, T data)
std::map< RTLIL::Cell *, RTLIL::SigSpec > cellToPrevSig
const std::vector< RTLIL::SigChunk > & chunks() const
std::set< RTLIL::Cell * > cellsOnStack
void select(RTLIL::Selection &sel)