diff options
Diffstat (limited to 'passes')
| -rw-r--r-- | passes/cmds/scc.cc | 77 | ||||
| -rw-r--r-- | 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<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,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 <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())  			{ 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 | 
