mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Do not re-order carry chain ports, just precompute iteration order
This commit is contained in:
		
							parent
							
								
									6b825c719b
								
							
						
					
					
						commit
						cac7f5d82e
					
				
					 2 changed files with 32 additions and 44 deletions
				
			
		|  | @ -93,6 +93,7 @@ struct XAigerWriter | ||||||
| 	dict<SigBit, int> ordered_outputs; | 	dict<SigBit, int> ordered_outputs; | ||||||
| 
 | 
 | ||||||
| 	vector<Cell*> box_list; | 	vector<Cell*> box_list; | ||||||
|  | 	dict<IdString, std::vector<IdString>> box_ports; | ||||||
| 
 | 
 | ||||||
| 	int mkgate(int a0, int a1) | 	int mkgate(int a0, int a1) | ||||||
| 	{ | 	{ | ||||||
|  | @ -404,12 +405,34 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 				bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); | 				bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); | ||||||
| 
 | 
 | ||||||
|  | 				auto r = box_ports.insert(cell->type); | ||||||
|  | 				if (r.second) { | ||||||
|  | 					// Make carry in the last PI, and carry out the last PO
 | ||||||
|  | 					//   since ABC requires it this way
 | ||||||
|  | 					IdString carry_in, carry_out; | ||||||
|  | 					for (const auto &port_name : box_module->ports) { | ||||||
|  | 						auto w = box_module->wire(port_name); | ||||||
|  | 						log_assert(w); | ||||||
|  | 						if (w->get_bool_attribute("\\abc9_carry")) { | ||||||
|  | 							if (w->port_input) | ||||||
|  | 								carry_in = port_name; | ||||||
|  | 							if (w->port_output) | ||||||
|  | 								carry_out = port_name; | ||||||
|  | 						} | ||||||
|  | 						else | ||||||
|  | 							r.first->second.push_back(port_name); | ||||||
|  | 					} | ||||||
|  | 					if (carry_in != IdString()) { | ||||||
|  | 						log_assert(carry_out != IdString()); | ||||||
|  | 						r.first->second.push_back(carry_in); | ||||||
|  | 						r.first->second.push_back(carry_out); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				// Fully pad all unused input connections of this box cell with S0
 | 				// Fully pad all unused input connections of this box cell with S0
 | ||||||
| 				// Fully pad all undriven output connections of this box cell with anonymous wires
 | 				// Fully pad all undriven output connections of this box cell with anonymous wires
 | ||||||
| 				// NB: Assume box_module->ports are sorted alphabetically
 | 				for (auto port_name : r.first->second) { | ||||||
| 				//     (as RTLIL::Module::fixup_ports() would do)
 | 					auto w = box_module->wire(port_name); | ||||||
| 				for (const auto &port_name : box_module->ports) { |  | ||||||
| 					RTLIL::Wire* w = box_module->wire(port_name); |  | ||||||
| 					log_assert(w); | 					log_assert(w); | ||||||
| 					auto it = cell->connections_.find(port_name); | 					auto it = cell->connections_.find(port_name); | ||||||
| 					if (w->port_input) { | 					if (w->port_input) { | ||||||
|  | @ -424,7 +447,7 @@ struct XAigerWriter | ||||||
| 							cell->setPort(port_name, rhs); | 							cell->setPort(port_name, rhs); | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						for (auto b : rhs.bits()) { | 						for (auto b : rhs) { | ||||||
| 							SigBit I = sigmap(b); | 							SigBit I = sigmap(b); | ||||||
| 							if (b == RTLIL::Sx) | 							if (b == RTLIL::Sx) | ||||||
| 								b = State::S0; | 								b = State::S0; | ||||||
|  | @ -455,11 +478,10 @@ struct XAigerWriter | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						for (const auto &b : rhs.bits()) { | 						for (const auto &b : rhs.bits()) { | ||||||
| 							ci_bits.emplace_back(b); |  | ||||||
| 							SigBit O = sigmap(b); | 							SigBit O = sigmap(b); | ||||||
| 							if (O != b) | 							if (O != b) | ||||||
| 								alias_map[O] = b; | 								alias_map[O] = b; | ||||||
| 							input_bits.erase(O); | 							ci_bits.emplace_back(b); | ||||||
| 							undriven_bits.erase(O); | 							undriven_bits.erase(O); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -653,33 +675,21 @@ struct XAigerWriter | ||||||
| 				if (box_module->has_processes()) | 				if (box_module->has_processes()) | ||||||
| 					Pass::call_on_module(module->design, box_module, "proc"); | 					Pass::call_on_module(module->design, box_module, "proc"); | ||||||
| 
 | 
 | ||||||
| 				int box_inputs = 0, box_outputs = 0; |  | ||||||
| 				auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); | 				auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); | ||||||
| 				Cell *holes_cell = r.first->second; | 				Cell *holes_cell = r.first->second; | ||||||
| 				if (r.second && box_module->get_bool_attribute("\\whitebox")) { | 				if (r.second && box_module->get_bool_attribute("\\whitebox")) { | ||||||
| 					holes_cell = holes_module->addCell(cell->name, cell->type); | 					holes_cell = holes_module->addCell(cell->name, cell->type); | ||||||
| 					holes_cell->parameters = cell->parameters; | 					holes_cell->parameters = cell->parameters; | ||||||
| 					r.first->second = holes_cell; | 					r.first->second = holes_cell; | ||||||
| 
 |  | ||||||
| 					// Since Module::derive() will create a new module, there
 |  | ||||||
| 					//   is a chance that the ports will be alphabetically ordered
 |  | ||||||
| 					//   again, which is a problem when carry-chains are involved.
 |  | ||||||
| 					//   Inherit the port ordering from the original module here...
 |  | ||||||
| 					//   (and set the port_id below, when iterating through those)
 |  | ||||||
| 					log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); |  | ||||||
| 					box_module->ports = orig_box_module->ports; |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// NB: Assume box_module->ports are sorted alphabetically
 | 				int box_inputs = 0, box_outputs = 0; | ||||||
| 				//     (as RTLIL::Module::fixup_ports() would do)
 | 				for (auto port_name : box_ports.at(cell->type)) { | ||||||
| 				int box_port_id = 1; |  | ||||||
| 				for (const auto &port_name : box_module->ports) { |  | ||||||
| 					RTLIL::Wire *w = box_module->wire(port_name); | 					RTLIL::Wire *w = box_module->wire(port_name); | ||||||
| 					log_assert(w); | 					log_assert(w); | ||||||
| 					if (r.second) |  | ||||||
| 						w->port_id = box_port_id++; |  | ||||||
| 					RTLIL::Wire *holes_wire; | 					RTLIL::Wire *holes_wire; | ||||||
| 					RTLIL::SigSpec port_sig; | 					RTLIL::SigSpec port_sig; | ||||||
|  | 
 | ||||||
| 					if (w->port_input) | 					if (w->port_input) | ||||||
| 						for (int i = 0; i < GetSize(w); i++) { | 						for (int i = 0; i < GetSize(w); i++) { | ||||||
| 							box_inputs++; | 							box_inputs++; | ||||||
|  |  | ||||||
|  | @ -1003,28 +1003,6 @@ struct Abc9Pass : public Pass { | ||||||
| 					log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); | 					log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); | ||||||
| 				if (!carry_in && carry_out) | 				if (!carry_in && carry_out) | ||||||
| 					log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); | 					log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); | ||||||
| 				// Make carry_in the last PI, and carry_out the last PO
 |  | ||||||
| 				//   since ABC requires it this way
 |  | ||||||
| 				auto &ports = m->ports; |  | ||||||
| 				for (auto it = ports.begin(); it != ports.end(); ) { |  | ||||||
| 					RTLIL::Wire* w = m->wire(*it); |  | ||||||
| 					log_assert(w); |  | ||||||
| 					if (w == carry_in || w == carry_out) { |  | ||||||
| 						it = ports.erase(it); |  | ||||||
| 						continue; |  | ||||||
| 					} |  | ||||||
| 					if (w->port_id > carry_in->port_id) |  | ||||||
| 						--w->port_id; |  | ||||||
| 					if (w->port_id > carry_out->port_id) |  | ||||||
| 						--w->port_id; |  | ||||||
| 					log_assert(w->port_input || w->port_output); |  | ||||||
| 					log_assert(ports[w->port_id-1] == w->name); |  | ||||||
| 					++it; |  | ||||||
| 				} |  | ||||||
| 				ports.push_back(carry_in->name); |  | ||||||
| 				carry_in->port_id = ports.size(); |  | ||||||
| 				ports.push_back(carry_out->name); |  | ||||||
| 				carry_out->port_id = ports.size(); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue