mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge pull request #1213 from YosysHQ/eddie/wreduce_add
wreduce/opt_expr: improve width reduction for $add and $sub cells
This commit is contained in:
		
						commit
						e9a756aa7a
					
				
					 5 changed files with 226 additions and 3 deletions
				
			
		|  | @ -788,6 +788,7 @@ public: | |||
| 	RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||
| 	RTLIL::SigSpec extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||
| 	RTLIL::SigSpec extract(int offset, int length = 1) const; | ||||
| 	RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); } | ||||
| 
 | ||||
| 	void append(const RTLIL::SigSpec &signal); | ||||
| 	void append_bit(const RTLIL::SigBit &bit); | ||||
|  | @ -834,6 +835,7 @@ public: | |||
| 
 | ||||
| 	operator std::vector<RTLIL::SigChunk>() const { return chunks(); } | ||||
| 	operator std::vector<RTLIL::SigBit>() const { return bits(); } | ||||
| 	RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; } | ||||
| 
 | ||||
| 	unsigned int hash() const { if (!hash_) updhash(); return hash_; }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -641,6 +641,31 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | |||
| 					did_something = true; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (cell->type.in("$add", "$sub")) { | ||||
| 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | ||||
| 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | ||||
| 				RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||
| 				bool sub = cell->type == "$sub"; | ||||
| 
 | ||||
| 				int i; | ||||
| 				for (i = 0; i < GetSize(sig_y); i++) { | ||||
| 					if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) | ||||
| 						module->connect(sig_y[i], sig_a[i]); | ||||
| 					else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) | ||||
| 						module->connect(sig_y[i], sig_b[i]); | ||||
| 					else | ||||
| 						break; | ||||
| 				} | ||||
| 				if (i > 0) { | ||||
| 					cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str()); | ||||
| 					cell->setPort("\\A", sig_a.extract_end(i)); | ||||
| 					cell->setPort("\\B", sig_b.extract_end(i)); | ||||
| 					cell->setPort("\\Y", sig_y.extract_end(i)); | ||||
| 					cell->fixup_parameters(); | ||||
| 					did_something = true; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" || | ||||
|  |  | |||
|  | @ -342,9 +342,9 @@ struct WreduceWorker | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor")) | ||||
| 		if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor", "$sub")) | ||||
| 		{ | ||||
| 			bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); | ||||
| 			bool is_signed = cell->getParam("\\A_SIGNED").as_bool() || cell->type == "$sub"; | ||||
| 
 | ||||
| 			int a_size = 0, b_size = 0; | ||||
| 			if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A")); | ||||
|  | @ -352,7 +352,7 @@ struct WreduceWorker | |||
| 
 | ||||
| 			int max_y_size = max(a_size, b_size); | ||||
| 
 | ||||
| 			if (cell->type == "$add") | ||||
| 			if (cell->type.in("$add", "$sub")) | ||||
| 				max_y_size++; | ||||
| 
 | ||||
| 			if (cell->type == "$mul") | ||||
|  |  | |||
							
								
								
									
										148
									
								
								tests/various/opt_expr.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								tests/various/opt_expr.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,148 @@ | |||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o); | ||||
|     assign o = (i << 4) + j; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||
|     assign o = (i << 4) + j; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o); | ||||
|     assign o = j - (i << 4); | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||
|     assign o = j - (i << 4); | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o); | ||||
|     assign o = (i << 4) - j; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module opt_expr_sub_test4(input [3:0] i, output [8:0] o); | ||||
|     assign o = 5'b00010 - i; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr -fine | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
							
								
								
									
										48
									
								
								tests/various/wreduce.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/various/wreduce.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| read_verilog <<EOT | ||||
| module wreduce_sub_test(input [3:0] i, input [7:0] j, output [8:0] o); | ||||
|     assign o = (j >> 4) - i; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr | ||||
| wreduce | ||||
| 
 | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
| 
 | ||||
| ########## | ||||
| 
 | ||||
| read_verilog <<EOT | ||||
| module wreduce_sub_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||
|     assign o = (j >>> 4) - i; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| hierarchy -auto-top | ||||
| proc | ||||
| design -save gold | ||||
| 
 | ||||
| opt_expr | ||||
| wreduce | ||||
| 
 | ||||
| dump | ||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||
| 
 | ||||
| design -stash gate | ||||
| 
 | ||||
| design -import gold -as gold | ||||
| design -import gate -as gate | ||||
| 
 | ||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | ||||
| sat -verify -prove-asserts -show-ports miter | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue