mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge pull request #2535 from Ravenslofty/scc-specify
scc: Add -specify option to find loops in boxes
This commit is contained in:
		
						commit
						d0d7a360ed
					
				
					 2 changed files with 61 additions and 18 deletions
				
			
		|  | @ -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,13 +141,35 @@ 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; | ||||
| 
 | ||||
| 			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; | ||||
| 
 | ||||
| 					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; | ||||
|  | @ -153,6 +187,7 @@ struct SccWorker | |||
| 					if (isOutput) | ||||
| 						outputSignals.append(sig); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			inputSignals.sort_and_unify(); | ||||
| 			outputSignals.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()) | ||||
| 			{ | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue