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 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(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||||
| 	RTLIL::SigSpec extract(int offset, int length = 1) 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(const RTLIL::SigSpec &signal); | ||||||
| 	void append_bit(const RTLIL::SigBit &bit); | 	void append_bit(const RTLIL::SigBit &bit); | ||||||
|  | @ -834,6 +835,7 @@ public: | ||||||
| 
 | 
 | ||||||
| 	operator std::vector<RTLIL::SigChunk>() const { return chunks(); } | 	operator std::vector<RTLIL::SigChunk>() const { return chunks(); } | ||||||
| 	operator std::vector<RTLIL::SigBit>() const { return bits(); } | 	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_; }; | 	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; | 					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" || | 		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; | 			int a_size = 0, b_size = 0; | ||||||
| 			if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A")); | 			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); | 			int max_y_size = max(a_size, b_size); | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$add") | 			if (cell->type.in("$add", "$sub")) | ||||||
| 				max_y_size++; | 				max_y_size++; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mul") | 			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