mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-26 09:24:37 +00:00 
			
		
		
		
	Added "scc -expect <N> -nofeedback"
This commit is contained in:
		
							parent
							
								
									adf4ecbc1f
								
							
						
					
					
						commit
						510deb3577
					
				
					 1 changed files with 48 additions and 7 deletions
				
			
		|  | @ -100,7 +100,8 @@ struct SccWorker | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool allCellTypes, int maxDepth) : design(design), module(module), sigmap(module) | ||||
| 	SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) : | ||||
| 			design(design), module(module), sigmap(module) | ||||
| 	{ | ||||
| 		if (module->processes.size() > 0) { | ||||
| 			log("Skipping module %s as it contains processes (run 'proc' pass first).\n", module->name.c_str()); | ||||
|  | @ -167,11 +168,23 @@ struct SccWorker | |||
| 		labelCounter = 0; | ||||
| 		cellLabels.clear(); | ||||
| 
 | ||||
| 		while (workQueue.size() > 0) { | ||||
| 		while (workQueue.size() > 0) | ||||
| 		{ | ||||
| 			RTLIL::Cell *cell = *workQueue.begin(); | ||||
| 			log_assert(cellStack.size() == 0); | ||||
| 			cellDepth.clear(); | ||||
| 			run(cell, 0, maxDepth); | ||||
| 
 | ||||
| 			if (!nofeedbackMode && cellToNextCell[cell].count(cell)) { | ||||
| 				log("Found an SCC:"); | ||||
| 				std::set<RTLIL::Cell*> scc; | ||||
| 				log(" %s", RTLIL::id2cstr(cell->name)); | ||||
| 				cell2scc[cell] = sccList.size(); | ||||
| 				scc.insert(cell); | ||||
| 				sccList.push_back(scc); | ||||
| 				workQueue.erase(cell); | ||||
| 				log("\n"); | ||||
| 			} else | ||||
| 				run(cell, 0, maxDepth); | ||||
| 		} | ||||
| 
 | ||||
| 		log("Found %d SCCs in module %s.\n", int(sccList.size()), RTLIL::id2cstr(module->name)); | ||||
|  | @ -212,10 +225,18 @@ struct SccPass : public Pass { | |||
| 		log("This command identifies strongly connected components (aka logic loops) in the\n"); | ||||
| 		log("design.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -expect <num>\n"); | ||||
| 		log("        expect to find exactly <num> SSCs. A different number of SSCs will\n"); | ||||
| 		log("        produce an error.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -max_depth <num>\n"); | ||||
| 		log("        limit to loops not longer than the specified number of cells. This can\n"); | ||||
| 		log("        e.g. be useful in identifying local loops in a module that turns out\n"); | ||||
| 		log("        to be one gigantic SCC.\n"); | ||||
| 		log("        limit to loops not longer than the specified number of cells. This\n"); | ||||
| 		log("        can e.g. be useful in identifying small local loops in a module that\n"); | ||||
| 		log("        implements one large SCC.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -nofeedback\n"); | ||||
| 		log("        do not count cells that have their output fed back into one of their\n"); | ||||
| 		log("        inputs as single-cell scc.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -all_cell_types\n"); | ||||
| 		log("        Usually this command only considers internal non-memory cells. With\n"); | ||||
|  | @ -239,7 +260,9 @@ struct SccPass : public Pass { | |||
| 		std::map<std::string, std::string> setCellAttr, setWireAttr; | ||||
| 		bool allCellTypes = false; | ||||
| 		bool selectMode = false; | ||||
| 		bool nofeedbackMode = false; | ||||
| 		int maxDepth = -1; | ||||
| 		int expect = -1; | ||||
| 
 | ||||
| 		log_header("Executing SCC pass (detecting logic loops).\n"); | ||||
| 
 | ||||
|  | @ -249,6 +272,14 @@ struct SccPass : public Pass { | |||
| 				maxDepth = atoi(args[++argidx].c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-expect" && argidx+1 < args.size()) { | ||||
| 				expect = atoi(args[++argidx].c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-nofeedback") { | ||||
| 				nofeedbackMode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-all_cell_types") { | ||||
| 				allCellTypes = true; | ||||
| 				continue; | ||||
|  | @ -282,16 +313,26 @@ struct SccPass : public Pass { | |||
| 			log_cmd_error("The -set*_attr options are not implemented at the moment!\n"); | ||||
| 
 | ||||
| 		RTLIL::Selection newSelection(false); | ||||
| 		int scc_counter = 0; | ||||
| 
 | ||||
| 		for (auto &mod_it : design->modules_) | ||||
| 			if (design->selected(mod_it.second)) | ||||
| 			{ | ||||
| 				SccWorker worker(design, mod_it.second, allCellTypes, maxDepth); | ||||
| 				SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth); | ||||
| 				scc_counter += GetSize(worker.sccList); | ||||
| 
 | ||||
| 				if (selectMode) | ||||
| 					worker.select(newSelection); | ||||
| 			} | ||||
| 
 | ||||
| 		if (expect >= 0) { | ||||
| 			if (scc_counter == expect) | ||||
| 				log("Found and expected %d SCCs.\n", scc_counter); | ||||
| 			else | ||||
| 				log_error("Found %d SCCs but expected %d.\n", scc_counter, expect); | ||||
| 		} else | ||||
| 			log("Found %d SCCs.\n", scc_counter); | ||||
| 
 | ||||
| 		if (selectMode) { | ||||
| 			log_assert(origSelectPos >= 0); | ||||
| 			design->selection_stack[origSelectPos] = newSelection; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue