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::Design *design; | ||||||
| 	RTLIL::Module *module; | 	RTLIL::Module *module; | ||||||
| 	SigMap sigmap; | 	SigMap sigmap; | ||||||
| 	CellTypes ct; | 	CellTypes ct, specifyCells; | ||||||
| 
 | 
 | ||||||
| 	std::set<RTLIL::Cell*> workQueue; | 	std::set<RTLIL::Cell*> workQueue; | ||||||
| 	std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell; | 	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) | 			design(design), module(module), sigmap(module) | ||||||
| 	{ | 	{ | ||||||
| 		if (module->processes.size() > 0) { | 		if (module->processes.size() > 0) { | ||||||
|  | @ -115,6 +115,18 @@ struct SccWorker | ||||||
| 			ct.setup_stdcells(); | 			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; | 		SigPool selectedSignals; | ||||||
| 		SigSet<RTLIL::Cell*> sigToNextCells; | 		SigSet<RTLIL::Cell*> sigToNextCells; | ||||||
| 
 | 
 | ||||||
|  | @ -129,29 +141,52 @@ struct SccWorker | ||||||
| 			if (!design->selected(module, cell)) | 			if (!design->selected(module, cell)) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
| 			if (!allCellTypes && !ct.cell_known(cell->type)) | 			if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type)) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
| 			workQueue.insert(cell); | 			workQueue.insert(cell); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec inputSignals, outputSignals; | 			RTLIL::SigSpec inputSignals, outputSignals; | ||||||
| 
 | 
 | ||||||
| 			for (auto &conn : cell->connections()) | 			if (specifyCells.cell_known(cell->type)) { | ||||||
| 			{ | 				// Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes.
 | ||||||
| 				bool isInput = true, isOutput = true; | 				for (auto subcell : design->module(cell->type)->cells()) | ||||||
|  | 				{ | ||||||
|  | 					if (subcell->type != ID($specify2)) | ||||||
|  | 						continue; | ||||||
| 
 | 
 | ||||||
| 				if (ct.cell_known(cell->type)) { | 					for (auto bit : subcell->getPort(ID::SRC)) | ||||||
| 					isInput = ct.cell_input(cell->type, conn.first); | 					{ | ||||||
| 					isOutput = ct.cell_output(cell->type, conn.first); | 						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; | ||||||
| 
 | 
 | ||||||
| 				RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); | 					if (ct.cell_known(cell->type)) { | ||||||
| 				sig.sort_and_unify(); | 						isInput = ct.cell_input(cell->type, conn.first); | ||||||
|  | 						isOutput = ct.cell_output(cell->type, conn.first); | ||||||
|  | 					} | ||||||
| 
 | 
 | ||||||
| 				if (isInput) | 					RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); | ||||||
| 					inputSignals.append(sig); | 					sig.sort_and_unify(); | ||||||
| 				if (isOutput) | 
 | ||||||
| 					outputSignals.append(sig); | 					if (isInput) | ||||||
|  | 						inputSignals.append(sig); | ||||||
|  | 					if (isOutput) | ||||||
|  | 						outputSignals.append(sig); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			inputSignals.sort_and_unify(); | 			inputSignals.sort_and_unify(); | ||||||
|  | @ -228,7 +263,7 @@ struct SccPass : public Pass { | ||||||
| 		log("design.\n"); | 		log("design.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -expect <num>\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("        produce an error.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -max_depth <num>\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("        replace the current selection with a selection of all cells and wires\n"); | ||||||
| 		log("        that are part of a found logic loop\n"); | 		log("        that are part of a found logic loop\n"); | ||||||
| 		log("\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 | 	void execute(std::vector<std::string> args, RTLIL::Design *design) override | ||||||
| 	{ | 	{ | ||||||
|  | @ -261,6 +299,7 @@ struct SccPass : public Pass { | ||||||
| 		bool allCellTypes = false; | 		bool allCellTypes = false; | ||||||
| 		bool selectMode = false; | 		bool selectMode = false; | ||||||
| 		bool nofeedbackMode = false; | 		bool nofeedbackMode = false; | ||||||
|  | 		bool specifyMode = false; | ||||||
| 		int maxDepth = -1; | 		int maxDepth = -1; | ||||||
| 		int expect = -1; | 		int expect = -1; | ||||||
| 
 | 
 | ||||||
|  | @ -293,6 +332,10 @@ struct SccPass : public Pass { | ||||||
| 				selectMode = true; | 				selectMode = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (args[argidx] == "-specify") { | ||||||
|  | 				specifyMode = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		int origSelectPos = design->selection_stack.size() - 1; | 		int origSelectPos = design->selection_stack.size() - 1; | ||||||
|  | @ -303,7 +346,7 @@ struct SccPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 		for (auto mod : design->selected_modules()) | 		for (auto mod : design->selected_modules()) | ||||||
| 		{ | 		{ | ||||||
| 			SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); | 			SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth); | ||||||
| 
 | 
 | ||||||
| 			if (!setAttr.empty()) | 			if (!setAttr.empty()) | ||||||
| 			{ | 			{ | ||||||
|  |  | ||||||
|  | @ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass | ||||||
| 
 | 
 | ||||||
| 		if (check_label("pre")) { | 		if (check_label("pre")) { | ||||||
| 			run("read_verilog -icells -lib -specify +/abc9_model.v"); | 			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) | 			if (help_mode) | ||||||
| 				run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); | 				run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); | ||||||
| 			else | 			else | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue