mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge pull request #768 from whitequark/opt_lut_elim
opt_lut: eliminate LUTs evaluating to constants or inputs
This commit is contained in:
		
						commit
						4b9f619349
					
				
					 4 changed files with 104 additions and 0 deletions
				
			
		|  | @ -187,6 +187,87 @@ struct OptLutWorker | |||
| 		} | ||||
| 		show_stats_by_arity(); | ||||
| 
 | ||||
| 		log("\n"); | ||||
| 		log("Eliminating LUTs.\n"); | ||||
| 		for (auto lut : luts) | ||||
| 		{ | ||||
| 			SigSpec lut_input = sigmap(lut->getPort("\\A")); | ||||
| 			pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut]; | ||||
| 
 | ||||
| 			vector<SigBit> lut_inputs; | ||||
| 			for (auto &bit : lut_input) | ||||
| 			{ | ||||
| 				if (bit.wire) | ||||
| 					lut_inputs.push_back(sigmap(bit)); | ||||
| 			} | ||||
| 
 | ||||
| 			bool const0_match = true; | ||||
| 			bool const1_match = true; | ||||
| 			vector<bool> input_matches; | ||||
| 			for (size_t i = 0; i < lut_inputs.size(); i++) | ||||
| 				input_matches.push_back(true); | ||||
| 
 | ||||
| 			for (int eval = 0; eval < 1 << lut_inputs.size(); eval++) | ||||
| 			{ | ||||
| 				dict<SigBit, bool> eval_inputs; | ||||
| 				for (size_t i = 0; i < lut_inputs.size(); i++) | ||||
| 					eval_inputs[lut_inputs[i]] = (eval >> i) & 1; | ||||
| 				bool value = evaluate_lut(lut, eval_inputs); | ||||
| 				if (value != 0) | ||||
| 					const0_match = false; | ||||
| 				if (value != 1) | ||||
| 					const1_match = false; | ||||
| 				for (size_t i = 0; i < lut_inputs.size(); i++) | ||||
| 				{ | ||||
| 					if (value != eval_inputs[lut_inputs[i]]) | ||||
| 						input_matches[i] = false; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			int input_match = -1; | ||||
| 			for (size_t i = 0; i < lut_inputs.size(); i++) | ||||
| 				if (input_matches[i]) | ||||
| 					input_match = i; | ||||
| 
 | ||||
| 			if (const0_match || const1_match || input_match != -1) | ||||
| 			{ | ||||
| 				log("Found redundant cell %s.%s.\n", log_id(module), log_id(lut)); | ||||
| 
 | ||||
| 				SigBit value; | ||||
| 				if (const0_match) | ||||
| 				{ | ||||
| 					log("  Cell evaluates constant 0.\n"); | ||||
| 					value = State::S0; | ||||
| 				} | ||||
| 				if (const1_match) | ||||
| 				{ | ||||
| 					log("  Cell evaluates constant 1.\n"); | ||||
| 					value = State::S1; | ||||
| 				} | ||||
| 				if (input_match != -1) { | ||||
| 					log("  Cell evaluates signal %s.\n", log_signal(lut_inputs[input_match])); | ||||
| 					value = lut_inputs[input_match]; | ||||
| 				} | ||||
| 
 | ||||
| 				if (lut_dlogic_inputs.size()) | ||||
| 				{ | ||||
| 					log("  Not eliminating cell (connected to dedicated logic).\n"); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					SigSpec lut_output = lut->getPort("\\Y"); | ||||
| 					module->connect(lut_output, value); | ||||
| 
 | ||||
| 					module->remove(lut); | ||||
| 					luts.erase(lut); | ||||
| 					luts_arity.erase(lut); | ||||
| 					luts_dlogics.erase(lut); | ||||
| 					luts_dlogic_inputs.erase(lut); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		show_stats_by_arity(); | ||||
| 
 | ||||
| 		log("\n"); | ||||
| 		log("Combining LUTs.\n"); | ||||
| 		pool<RTLIL::Cell*> worklist = luts; | ||||
|  |  | |||
							
								
								
									
										19
									
								
								tests/opt/opt_lut_elim.il
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/opt/opt_lut_elim.il
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| module \test | ||||
|   wire input 1 \i | ||||
| 
 | ||||
|   wire output 2 \o1 | ||||
|   cell $lut $1 | ||||
|     parameter \LUT 16'0110100110010110 | ||||
|     parameter \WIDTH 4 | ||||
|     connect \A { \i 3'000 } | ||||
|     connect \Y \o1 | ||||
|   end | ||||
| 
 | ||||
|   wire output 2 \o2 | ||||
|   cell $lut $2 | ||||
|     parameter \LUT 16'0110100010010110 | ||||
|     parameter \WIDTH 4 | ||||
|     connect \A { \i 3'000 } | ||||
|     connect \Y \o2 | ||||
|   end | ||||
| end | ||||
							
								
								
									
										3
									
								
								tests/opt/opt_lut_elim.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/opt/opt_lut_elim.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| read_ilang opt_lut_elim.il | ||||
| opt_lut | ||||
| select -assert-count 0 t:$lut | ||||
|  | @ -1,2 +1,3 @@ | |||
| read_ilang opt_lut_port.il | ||||
| opt_lut | ||||
| select -assert-count 2 t:$lut | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue