mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	More "freduce" related fixes and improvements
This commit is contained in:
		
							parent
							
								
									ced4d7b321
								
							
						
					
					
						commit
						0759c97748
					
				
					 1 changed files with 67 additions and 19 deletions
				
			
		|  | @ -38,6 +38,7 @@ struct equiv_bit_t | ||||||
| { | { | ||||||
| 	int depth; | 	int depth; | ||||||
| 	bool inverted; | 	bool inverted; | ||||||
|  | 	RTLIL::Cell *drv; | ||||||
| 	RTLIL::SigBit bit; | 	RTLIL::SigBit bit; | ||||||
| 
 | 
 | ||||||
| 	bool operator<(const equiv_bit_t &other) const { | 	bool operator<(const equiv_bit_t &other) const { | ||||||
|  | @ -45,6 +46,8 @@ struct equiv_bit_t | ||||||
| 			return depth < other.depth; | 			return depth < other.depth; | ||||||
| 		if (inverted != other.inverted) | 		if (inverted != other.inverted) | ||||||
| 			return inverted < other.inverted; | 			return inverted < other.inverted; | ||||||
|  | 		if (drv != other.drv) | ||||||
|  | 			return drv < other.drv; | ||||||
| 		return bit < other.bit; | 		return bit < other.bit; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  | @ -216,7 +219,7 @@ struct PerformReduction | ||||||
| 			out_inverted = std::vector<bool>(sat_out.size(), false); | 			out_inverted = std::vector<bool>(sat_out.size(), false); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void analyze(std::vector<std::vector<equiv_bit_t>> &results, std::vector<int> &bucket, int level) | 	void analyze(std::vector<std::set<int>> &results, std::map<int, int> &results_map, std::vector<int> &bucket, int level) | ||||||
| 	{ | 	{ | ||||||
| 		if (bucket.size() <= 1) | 		if (bucket.size() <= 1) | ||||||
| 			return; | 			return; | ||||||
|  | @ -233,10 +236,9 @@ struct PerformReduction | ||||||
| 		std::vector<int> modelVars = sat_out; | 		std::vector<int> modelVars = sat_out; | ||||||
| 		std::vector<bool> model; | 		std::vector<bool> model; | ||||||
| 
 | 
 | ||||||
| 		if (verbose_level >= 2) { | 		modelVars.insert(modelVars.end(), sat_def.begin(), sat_def.end()); | ||||||
| 			modelVars.insert(modelVars.end(), sat_def.begin(), sat_def.end()); | 		if (verbose_level >= 2) | ||||||
| 			modelVars.insert(modelVars.end(), sat_pi.begin(), sat_pi.end()); | 			modelVars.insert(modelVars.end(), sat_pi.begin(), sat_pi.end()); | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_list), ez.expression(ezSAT::OpOr, sat_inv_list))) | 		if (ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_list), ez.expression(ezSAT::OpOr, sat_inv_list))) | ||||||
| 		{ | 		{ | ||||||
|  | @ -248,11 +250,17 @@ struct PerformReduction | ||||||
| 							out_inverted.at(idx) ? "~" : "", log_signal(out_bits[idx])); | 							out_inverted.at(idx) ? "~" : "", log_signal(out_bits[idx])); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			std::vector<int> buckets[2]; | 			std::vector<int> buckets_a; | ||||||
| 			for (int idx : bucket) | 			std::vector<int> buckets_b; | ||||||
| 				buckets[model[idx] ? 1 : 0].push_back(idx); | 
 | ||||||
| 			analyze(results, buckets[0], level+1); | 			for (int idx : bucket) { | ||||||
| 			analyze(results, buckets[1], level+1); | 				if (!model[sat_out.size() + idx] || model[idx]) | ||||||
|  | 					buckets_a.push_back(idx); | ||||||
|  | 				if (!model[sat_out.size() + idx] || !model[idx]) | ||||||
|  | 					buckets_b.push_back(idx); | ||||||
|  | 			} | ||||||
|  | 			analyze(results, results_map, buckets_a, level+1); | ||||||
|  | 			analyze(results, results_map, buckets_b, level+1); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | @ -263,16 +271,58 @@ struct PerformReduction | ||||||
| 				log("\n"); | 				log("\n"); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			std::vector<equiv_bit_t> result; | 			int result_idx = -1; | ||||||
| 			for (int idx : bucket) { | 			for (int idx : bucket) { | ||||||
|  | 				if (results_map.count(idx) == 0) | ||||||
|  | 					continue; | ||||||
|  | 				if (result_idx == -1) { | ||||||
|  | 					result_idx = results_map.at(idx); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				int result_idx2 = results_map.at(idx); | ||||||
|  | 				results[result_idx].insert(results[result_idx2].begin(), results[result_idx2].end()); | ||||||
|  | 				for (int idx2 : results[result_idx2]) | ||||||
|  | 					results_map[idx2] = result_idx; | ||||||
|  | 				results[result_idx2].clear(); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (result_idx == -1) { | ||||||
|  | 				result_idx = results.size(); | ||||||
|  | 				results.push_back(std::set<int>()); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			results[result_idx].insert(bucket.begin(), bucket.end()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void analyze(std::vector<std::vector<equiv_bit_t>> &results) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<int> bucket; | ||||||
|  | 		for (size_t i = 0; i < sat_out.size(); i++) | ||||||
|  | 			bucket.push_back(i); | ||||||
|  | 
 | ||||||
|  | 		std::vector<std::set<int>> results_buf; | ||||||
|  | 		std::map<int, int> results_map; | ||||||
|  | 		analyze(results_buf, results_map, bucket, 1); | ||||||
|  | 
 | ||||||
|  | 		for (auto &r : results_buf) | ||||||
|  | 		{ | ||||||
|  | 			if (r.size() <= 1) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			std::vector<equiv_bit_t> result; | ||||||
|  | 
 | ||||||
|  | 			for (int idx : r) { | ||||||
| 				equiv_bit_t bit; | 				equiv_bit_t bit; | ||||||
| 				bit.depth = out_depth[idx]; | 				bit.depth = out_depth[idx]; | ||||||
| 				bit.inverted = out_inverted[idx]; | 				bit.inverted = out_inverted[idx]; | ||||||
|  | 				bit.drv = drivers.count(out_bits[idx]) ? drivers.at(out_bits[idx]).first : NULL; | ||||||
| 				bit.bit = out_bits[idx]; | 				bit.bit = out_bits[idx]; | ||||||
| 				result.push_back(bit); | 				result.push_back(bit); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			std::sort(result.begin(), result.end()); | 			std::sort(result.begin(), result.end()); | ||||||
|  | 
 | ||||||
| 			if (result.front().inverted) | 			if (result.front().inverted) | ||||||
| 				for (auto &bit : result) | 				for (auto &bit : result) | ||||||
| 					bit.inverted = !bit.inverted; | 					bit.inverted = !bit.inverted; | ||||||
|  | @ -287,14 +337,6 @@ struct PerformReduction | ||||||
| 				results.push_back(result); | 				results.push_back(result); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	void analyze(std::vector<std::vector<equiv_bit_t>> &results) |  | ||||||
| 	{ |  | ||||||
| 		std::vector<int> bucket; |  | ||||||
| 		for (size_t i = 0; i < sat_out.size(); i++) |  | ||||||
| 			bucket.push_back(i); |  | ||||||
| 		analyze(results, bucket, 1); |  | ||||||
| 	} |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct FreduceHelper | struct FreduceHelper | ||||||
|  | @ -318,6 +360,9 @@ struct FreduceHelper | ||||||
| 		ct.setup_stdcells(); | 		ct.setup_stdcells(); | ||||||
| 
 | 
 | ||||||
| 		std::vector<std::set<RTLIL::SigBit>> batches; | 		std::vector<std::set<RTLIL::SigBit>> batches; | ||||||
|  | 		for (auto &it : module->wires) | ||||||
|  | 			if (it.second->port_input) | ||||||
|  | 				batches.push_back(sigmap(it.second).to_sigbit_set()); | ||||||
| 		for (auto &it : module->cells) { | 		for (auto &it : module->cells) { | ||||||
| 			if (ct.cell_known(it.second->type)) { | 			if (ct.cell_known(it.second->type)) { | ||||||
| 				std::set<RTLIL::SigBit> inputs, outputs; | 				std::set<RTLIL::SigBit> inputs, outputs; | ||||||
|  | @ -426,7 +471,10 @@ struct FreducePass : public Pass { | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("This pass performs functional reduction in the circuit. I.e. if two nodes are\n"); | 		log("This pass performs functional reduction in the circuit. I.e. if two nodes are\n"); | ||||||
| 		log("equivialent, they are merged to one node and one of the redundant drivers is\n"); | 		log("equivialent, they are merged to one node and one of the redundant drivers is\n"); | ||||||
| 		log("removed.\n"); | 		log("unconnected. A subsequent call to 'clean' will remove the redundant drivers.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("This pass is undef-aware, i.e. it considers don't-care values for detecting\n"); | ||||||
|  | 		log("equivialent nodes.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -v, -vv\n"); | 		log("    -v, -vv\n"); | ||||||
| 		log("        enable verbose or very verbose output\n"); | 		log("        enable verbose or very verbose output\n"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue