mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	abc9: Fix breaking of SCCs
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
		
							parent
							
								
									5f4c35c753
								
							
						
					
					
						commit
						e9ce4e658b
					
				
					 2 changed files with 46 additions and 29 deletions
				
			
		|  | @ -94,20 +94,30 @@ void handle_loops(RTLIL::Design *design) | ||||||
| 					if (cell->output(c.first)) { | 					if (cell->output(c.first)) { | ||||||
| 						SigBit b = c.second.as_bit(); | 						SigBit b = c.second.as_bit(); | ||||||
| 						Wire *w = b.wire; | 						Wire *w = b.wire; | ||||||
| 						log_assert(!w->port_input); | 						if (w->port_input) { | ||||||
| 						w->port_input = true; | 							// In this case, hopefully the loop break has been already created
 | ||||||
| 						w = module->wire(stringf("%s.abci", w->name.c_str())); | 							// Get the non-prefixed wire
 | ||||||
| 						if (!w) { | 							Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); | ||||||
| 							w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); | 							log_assert(wo != nullptr); | ||||||
| 							w->port_output = true; | 							log_assert(wo->port_output); | ||||||
|  | 							log_assert(b.offset < GetSize(wo)); | ||||||
|  | 							c.second = RTLIL::SigBit(wo, b.offset); | ||||||
| 						} | 						} | ||||||
| 						else { | 						else { | ||||||
| 							log_assert(w->port_input); | 							// Create a new output/input loop break
 | ||||||
| 							log_assert(b.offset < GetSize(w)); | 							w->port_input = true; | ||||||
|  | 							w = module->wire(stringf("%s.abco", w->name.c_str())); | ||||||
|  | 							if (!w) { | ||||||
|  | 								w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); | ||||||
|  | 								w->port_output = true; | ||||||
|  | 							} | ||||||
|  | 							else { | ||||||
|  | 								log_assert(w->port_input); | ||||||
|  | 								log_assert(b.offset < GetSize(w)); | ||||||
|  | 							} | ||||||
|  | 							w->set_bool_attribute(ID(abc9_scc_break)); | ||||||
|  | 							c.second = RTLIL::SigBit(w, b.offset); | ||||||
| 						} | 						} | ||||||
| 						w->set_bool_attribute(ID(abc9_scc_break)); |  | ||||||
| 						module->swap_names(b.wire, w); |  | ||||||
| 						c.second = RTLIL::SigBit(w, b.offset); |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -420,24 +430,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 
 | 
 | ||||||
| 		design->selection_stack.pop_back(); | 		design->selection_stack.pop_back(); | ||||||
| 
 | 
 | ||||||
| 		// Now 'unexpose' those wires by undoing
 |  | ||||||
| 		// the expose operation -- remove them from PO/PI
 |  | ||||||
| 		// and re-connecting them back together
 |  | ||||||
| 		for (auto wire : module->wires()) { |  | ||||||
| 			auto it = wire->attributes.find(ID(abc9_scc_break)); |  | ||||||
| 			if (it != wire->attributes.end()) { |  | ||||||
| 				wire->attributes.erase(it); |  | ||||||
| 				log_assert(wire->port_output); |  | ||||||
| 				wire->port_output = false; |  | ||||||
| 				RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci"); |  | ||||||
| 				log_assert(i_wire); |  | ||||||
| 				log_assert(i_wire->port_input); |  | ||||||
| 				i_wire->port_input = false; |  | ||||||
| 				module->connect(i_wire, wire); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		module->fixup_ports(); |  | ||||||
| 
 |  | ||||||
| 		log_header(design, "Executing ABC9.\n"); | 		log_header(design, "Executing ABC9.\n"); | ||||||
| 
 | 
 | ||||||
| 		if (!lut_costs.empty()) { | 		if (!lut_costs.empty()) { | ||||||
|  | @ -781,6 +773,25 @@ clone_lut: | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// Now 'unexpose' those wires by undoing
 | ||||||
|  | 		// the expose operation -- remove them from PO/PI
 | ||||||
|  | 		// and re-connecting them back together
 | ||||||
|  | 		for (auto wire : module->wires()) { | ||||||
|  | 			auto it = wire->attributes.find(ID(abc9_scc_break)); | ||||||
|  | 			if (it != wire->attributes.end()) { | ||||||
|  | 				wire->attributes.erase(it); | ||||||
|  | 				log_assert(wire->port_output); | ||||||
|  | 				wire->port_output = false; | ||||||
|  | 				std::string name = wire->name.str(); | ||||||
|  | 				RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); | ||||||
|  | 				log_assert(i_wire); | ||||||
|  | 				log_assert(i_wire->port_input); | ||||||
|  | 				i_wire->port_input = false; | ||||||
|  | 				module->connect(i_wire, wire); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		module->fixup_ports(); | ||||||
|  | 
 | ||||||
| 		//log("ABC RESULTS:        internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
 | 		//log("ABC RESULTS:        internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
 | ||||||
| 		log("ABC RESULTS:           input signals: %8d\n", in_wires); | 		log("ABC RESULTS:           input signals: %8d\n", in_wires); | ||||||
| 		log("ABC RESULTS:          output signals: %8d\n", out_wires); | 		log("ABC RESULTS:          output signals: %8d\n", out_wires); | ||||||
|  |  | ||||||
|  | @ -258,3 +258,9 @@ module abc9_test026(output [3:0] o, p); | ||||||
| assign o = { 1'b1, 1'bx }; | assign o = { 1'b1, 1'bx }; | ||||||
| assign p = { 1'b1, 1'bx, 1'b0 }; | assign p = { 1'b1, 1'bx, 1'b0 }; | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | module abc9_test030(input [3:0] d, input en, output reg [3:0] q); | ||||||
|  | always @* | ||||||
|  |   if (en) | ||||||
|  |     q <= d; | ||||||
|  | endmodule | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue