mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Improved performance of opt_const on large modules
This commit is contained in:
		
							parent
							
								
									4be645860b
								
							
						
					
					
						commit
						d07a871d35
					
				
					 2 changed files with 157 additions and 29 deletions
				
			
		
							
								
								
									
										103
									
								
								kernel/toposort.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								kernel/toposort.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | ||||||
|  | /*
 | ||||||
|  |  *  yosys -- Yosys Open SYnthesis Suite | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||||
|  |  *   | ||||||
|  |  *  Permission to use, copy, modify, and/or distribute this software for any | ||||||
|  |  *  purpose with or without fee is hereby granted, provided that the above | ||||||
|  |  *  copyright notice and this permission notice appear in all copies. | ||||||
|  |  *   | ||||||
|  |  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||||
|  |  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||||
|  |  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||||
|  |  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  |  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||||
|  |  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||||
|  |  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef TOPOSORT_H | ||||||
|  | #define TOPOSORT_H | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | struct TopoSort | ||||||
|  | { | ||||||
|  | 	bool analyze_loops, found_loops; | ||||||
|  | 	std::map<T, std::set<T>> database; | ||||||
|  | 	std::set<std::set<T>> loops; | ||||||
|  | 	std::vector<T> sorted; | ||||||
|  | 
 | ||||||
|  | 	TopoSort() | ||||||
|  | 	{ | ||||||
|  | 		analyze_loops = true; | ||||||
|  | 		found_loops = false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void node(T n) | ||||||
|  | 	{ | ||||||
|  | 		if (database.count(n) == 0) | ||||||
|  | 			database[n] = std::set<T>(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void edge(T left, T right) | ||||||
|  | 	{ | ||||||
|  | 		node(left); | ||||||
|  | 		database[right].insert(left); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void sort_worker(T n, std::set<T> &marked_cells, std::set<T> &active_cells, std::vector<T> active_stack) | ||||||
|  | 	{ | ||||||
|  | 		if (active_cells.count(n)) { | ||||||
|  | 			found_loops = false; | ||||||
|  | 			if (analyze_loops) { | ||||||
|  | 				std::set<T> loop; | ||||||
|  | 				for (int i = SIZE(active_stack)-1; i >= 0; i--) { | ||||||
|  | 					loop.insert(active_stack[i]); | ||||||
|  | 					if (active_stack[i] == n) | ||||||
|  | 						break; | ||||||
|  | 				} | ||||||
|  | 				loops.insert(loop); | ||||||
|  | 			} | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (marked_cells.count(n)) | ||||||
|  | 			return; | ||||||
|  | 
 | ||||||
|  | 		if (!database.at(n).empty()) | ||||||
|  | 		{ | ||||||
|  | 			if (analyze_loops) | ||||||
|  | 				active_stack.push_back(n); | ||||||
|  | 			active_cells.insert(n); | ||||||
|  | 
 | ||||||
|  | 			for (auto &left_n : database.at(n)) | ||||||
|  | 				sort_worker(left_n, marked_cells, active_cells, active_stack); | ||||||
|  | 
 | ||||||
|  | 			if (analyze_loops) | ||||||
|  | 				active_stack.pop_back(); | ||||||
|  | 			active_cells.erase(n); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		marked_cells.insert(n); | ||||||
|  | 		sorted.push_back(n); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bool sort() | ||||||
|  | 	{ | ||||||
|  | 		loops.clear(); | ||||||
|  | 		sorted.clear(); | ||||||
|  | 		found_loops = false; | ||||||
|  | 
 | ||||||
|  | 		std::set<T> marked_cells; | ||||||
|  | 		std::set<T> active_cells; | ||||||
|  | 		std::vector<T> active_stack; | ||||||
|  | 
 | ||||||
|  | 		for (auto &it : database) | ||||||
|  | 			sort_worker(it.first, marked_cells, active_cells, active_stack); | ||||||
|  | 
 | ||||||
|  | 		return !found_loops; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include "kernel/register.h" | #include "kernel/register.h" | ||||||
| #include "kernel/sigtools.h" | #include "kernel/sigtools.h" | ||||||
| #include "kernel/celltypes.h" | #include "kernel/celltypes.h" | ||||||
|  | #include "kernel/toposort.h" | ||||||
| #include "kernel/log.h" | #include "kernel/log.h" | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  | @ -71,7 +72,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) | static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) | ||||||
| { | { | ||||||
| 	RTLIL::SigSpec Y = cell->get(out_port); | 	RTLIL::SigSpec Y = cell->get(out_port); | ||||||
| 	out_val.extend_u0(Y.size(), false); | 	out_val.extend_u0(Y.size(), false); | ||||||
|  | @ -80,7 +81,8 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i | ||||||
| 			cell->type.c_str(), cell->name.c_str(), info.c_str(), | 			cell->type.c_str(), cell->name.c_str(), info.c_str(), | ||||||
| 			module->name.c_str(), log_signal(Y), log_signal(out_val)); | 			module->name.c_str(), log_signal(Y), log_signal(out_val)); | ||||||
| 	// ILANG_BACKEND::dump_cell(stderr, "--> ", cell);
 | 	// ILANG_BACKEND::dump_cell(stderr, "--> ", cell);
 | ||||||
| 	module->connect(RTLIL::SigSig(Y, out_val)); | 	assign_map.add(Y, out_val); | ||||||
|  | 	module->connect(Y, out_val); | ||||||
| 	module->remove(cell); | 	module->remove(cell); | ||||||
| 	OPT_DID_SOMETHING = true; | 	OPT_DID_SOMETHING = true; | ||||||
| 	did_something = true; | 	did_something = true; | ||||||
|  | @ -195,22 +197,45 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 	if (!design->selected(module)) | 	if (!design->selected(module)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	CellTypes ct_combinational; | ||||||
|  | 	ct_combinational.setup_internals(); | ||||||
|  | 	ct_combinational.setup_stdcells(); | ||||||
|  | 
 | ||||||
| 	SigMap assign_map(module); | 	SigMap assign_map(module); | ||||||
| 	std::map<RTLIL::SigSpec, RTLIL::SigSpec> invert_map; | 	std::map<RTLIL::SigSpec, RTLIL::SigSpec> invert_map; | ||||||
| 
 | 
 | ||||||
| 	std::vector<RTLIL::Cell*> cells; | 	TopoSort<RTLIL::Cell*> cells; | ||||||
| 	cells.reserve(module->cells_.size()); | 	std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit; | ||||||
| 	for (auto &cell_it : module->cells_) | 	std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell; | ||||||
| 		if (design->selected(module, cell_it.second)) { | 
 | ||||||
| 			if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && | 	for (auto cell : module->cells()) | ||||||
| 					cell_it.second->get("\\A").size() == 1 && cell_it.second->get("\\Y").size() == 1) | 		if (design->selected(module, cell) && cell->type[0] == '$') { | ||||||
| 				invert_map[assign_map(cell_it.second->get("\\Y"))] = assign_map(cell_it.second->get("\\A")); | 			if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && | ||||||
| 			cells.push_back(cell_it.second); | 					cell->get("\\A").size() == 1 && cell->get("\\Y").size() == 1) | ||||||
|  | 				invert_map[assign_map(cell->get("\\Y"))] = assign_map(cell->get("\\A")); | ||||||
|  | 			if (ct_combinational.cell_known(cell->type)) | ||||||
|  | 				for (auto &conn : cell->connections()) { | ||||||
|  | 					RTLIL::SigSpec sig = assign_map(conn.second); | ||||||
|  | 					sig.remove_const(); | ||||||
|  | 					if (ct_combinational.cell_input(cell->type, conn.first)) | ||||||
|  | 						cell_to_inbit[cell].insert(sig.begin(), sig.end()); | ||||||
|  | 					if (ct_combinational.cell_output(cell->type, conn.first)) | ||||||
|  | 						for (auto &bit : sig) | ||||||
|  | 							outbit_to_cell[bit].insert(cell); | ||||||
|  | 				} | ||||||
|  | 			cells.node(cell); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	for (auto cell : cells) | 	for (auto &it_right : cell_to_inbit) | ||||||
|  | 	for (auto &it_sigbit : it_right.second) | ||||||
|  | 	for (auto &it_left : outbit_to_cell[it_sigbit]) | ||||||
|  | 		cells.edge(it_left, it_right.first); | ||||||
|  | 
 | ||||||
|  | 	cells.sort(); | ||||||
|  | 
 | ||||||
|  | 	for (auto cell : cells.sorted) | ||||||
| 	{ | 	{ | ||||||
| #define ACTION_DO(_p_, _s_) do { cover("opt.opt_const.action_" S__LINE__); replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) | #define ACTION_DO(_p_, _s_) do { cover("opt.opt_const.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) | ||||||
| #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) | #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) | ||||||
| 
 | 
 | ||||||
| 		if (do_fine) | 		if (do_fine) | ||||||
|  | @ -304,13 +329,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$logic_or" && (assign_map(cell->get("\\A")) == RTLIL::State::S1 || assign_map(cell->get("\\B")) == RTLIL::State::S1)) { | 		if (cell->type == "$logic_or" && (assign_map(cell->get("\\A")) == RTLIL::State::S1 || assign_map(cell->get("\\B")) == RTLIL::State::S1)) { | ||||||
| 			cover("opt.opt_const.one_high"); | 			cover("opt.opt_const.one_high"); | ||||||
| 			replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); | 			replace_cell(assign_map, module, cell, "one high", "\\Y", RTLIL::State::S1); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$logic_and" && (assign_map(cell->get("\\A")) == RTLIL::State::S0 || assign_map(cell->get("\\B")) == RTLIL::State::S0)) { | 		if (cell->type == "$logic_and" && (assign_map(cell->get("\\A")) == RTLIL::State::S0 || assign_map(cell->get("\\B")) == RTLIL::State::S0)) { | ||||||
| 			cover("opt.opt_const.one_low"); | 			cover("opt.opt_const.one_low"); | ||||||
| 			replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); | 			replace_cell(assign_map, module, cell, "one low", "\\Y", RTLIL::State::S0); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -340,9 +365,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 						"$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); | 						"$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); | ||||||
| 				if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || | 				if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || | ||||||
| 						cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") | 						cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") | ||||||
| 					replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); | 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); | ||||||
| 				else | 				else | ||||||
| 					replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); | 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -350,7 +375,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 		if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->get("\\Y").size() == 1 && | 		if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->get("\\Y").size() == 1 && | ||||||
| 				invert_map.count(assign_map(cell->get("\\A"))) != 0) { | 				invert_map.count(assign_map(cell->get("\\A"))) != 0) { | ||||||
| 			cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); | 			cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); | ||||||
| 			replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); | 			replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -476,7 +501,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 					cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); | 					cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); | ||||||
| 					RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S0 : RTLIL::State::S1); | 					RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S0 : RTLIL::State::S1); | ||||||
| 					new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); | 					new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); | ||||||
| 					replace_cell(module, cell, "isneq", "\\Y", new_y); | 					replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); | ||||||
| 					goto next_cell; | 					goto next_cell; | ||||||
| 				} | 				} | ||||||
| 				if (a[i] == b[i]) | 				if (a[i] == b[i]) | ||||||
|  | @ -489,7 +514,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 				cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type); | 				cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type); | ||||||
| 				RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S1 : RTLIL::State::S0); | 				RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S1 : RTLIL::State::S0); | ||||||
| 				new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); | 				new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); | ||||||
| 				replace_cell(module, cell, "empty", "\\Y", new_y); | 				replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -607,7 +632,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 		if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && | 		if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && | ||||||
| 				cell->get("\\A") == RTLIL::SigSpec(0, 1) && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { | 				cell->get("\\A") == RTLIL::SigSpec(0, 1) && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { | ||||||
| 			cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); | 			cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); | ||||||
| 			replace_cell(module, cell, "mux_bool", "\\Y", cell->get("\\S")); | 			replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->get("\\S")); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -674,7 +699,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 			if ((cell->get("\\A").is_fully_undef() && cell->get("\\B").is_fully_undef()) || | 			if ((cell->get("\\A").is_fully_undef() && cell->get("\\B").is_fully_undef()) || | ||||||
| 					cell->get("\\S").is_fully_undef()) { | 					cell->get("\\S").is_fully_undef()) { | ||||||
| 				cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); | 				cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); | ||||||
| 				replace_cell(module, cell, "mux_undef", "\\Y", cell->get("\\A")); | 				replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->get("\\A")); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
| 			} | 			} | ||||||
| 			for (int i = 0; i < cell->get("\\S").size(); i++) { | 			for (int i = 0; i < cell->get("\\S").size(); i++) { | ||||||
|  | @ -693,12 +718,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 			} | 			} | ||||||
| 			if (new_s.size() == 0) { | 			if (new_s.size() == 0) { | ||||||
| 				cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type); | 				cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type); | ||||||
| 				replace_cell(module, cell, "mux_empty", "\\Y", new_a); | 				replace_cell(assign_map, module, cell, "mux_empty", "\\Y", new_a); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
| 			} | 			} | ||||||
| 			if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { | 			if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { | ||||||
| 				cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type); | 				cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type); | ||||||
| 				replace_cell(module, cell, "mux_sel01", "\\Y", new_s); | 				replace_cell(assign_map, module, cell, "mux_sel01", "\\Y", new_s); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
| 			} | 			} | ||||||
| 			if (cell->get("\\S").size() != new_s.size()) { | 			if (cell->get("\\S").size() != new_s.size()) { | ||||||
|  | @ -728,7 +753,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 						cell->parameters["\\A_SIGNED"].as_bool(), false, \ | 						cell->parameters["\\A_SIGNED"].as_bool(), false, \ | ||||||
| 						cell->parameters["\\Y_WIDTH"].as_int())); \ | 						cell->parameters["\\Y_WIDTH"].as_int())); \ | ||||||
| 				cover("opt.opt_const.const.$" #_t); \ | 				cover("opt.opt_const.const.$" #_t); \ | ||||||
| 				replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ | 				replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ | ||||||
| 				goto next_cell; \ | 				goto next_cell; \ | ||||||
| 			} \ | 			} \ | ||||||
| 		} | 		} | ||||||
|  | @ -743,7 +768,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo | ||||||
| 						cell->parameters["\\B_SIGNED"].as_bool(), \ | 						cell->parameters["\\B_SIGNED"].as_bool(), \ | ||||||
| 						cell->parameters["\\Y_WIDTH"].as_int())); \ | 						cell->parameters["\\Y_WIDTH"].as_int())); \ | ||||||
| 				cover("opt.opt_const.const.$" #_t); \ | 				cover("opt.opt_const.const.$" #_t); \ | ||||||
| 				replace_cell(module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ | 				replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ | ||||||
| 				goto next_cell; \ | 				goto next_cell; \ | ||||||
| 			} \ | 			} \ | ||||||
| 		} | 		} | ||||||
|  | @ -939,17 +964,17 @@ struct OptConstPass : public Pass { | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
| 		for (auto &mod_it : design->modules_) | 		for (auto module : design->modules()) | ||||||
| 		{ | 		{ | ||||||
| 			if (undriven) | 			if (undriven) | ||||||
| 				replace_undriven(design, mod_it.second); | 				replace_undriven(design, module); | ||||||
| 
 | 
 | ||||||
| 			do { | 			do { | ||||||
| 				do { | 				do { | ||||||
| 					did_something = false; | 					did_something = false; | ||||||
| 					replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool, do_fine, keepdc); | 					replace_const_cells(design, module, false, mux_undef, mux_bool, do_fine, keepdc); | ||||||
| 				} while (did_something); | 				} while (did_something); | ||||||
| 				replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool, do_fine, keepdc); | 				replace_const_cells(design, module, true, mux_undef, mux_bool, do_fine, keepdc); | ||||||
| 			} while (did_something); | 			} while (did_something); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue