mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-28 10:19:26 +00:00 
			
		
		
		
	iopadmap: Look harder for already-present buffers. (#1731)
iopadmap: Look harder for already-present buffers. Fixes #1720.
This commit is contained in:
		
							parent
							
								
									4f889b2f57
								
							
						
					
					
						commit
						968956badb
					
				
					 2 changed files with 77 additions and 18 deletions
				
			
		|  | @ -83,6 +83,20 @@ struct IopadmapPass : public Pass { | |||
| 		log("Tristate PADS (-toutpad, -tinoutpad) always operate in -bits mode.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) { | ||||
| 		if (modules_processed.count(module)) | ||||
| 			return; | ||||
| 		for (auto cell : module->cells()) { | ||||
| 			Module *submodule = design->module(cell->type); | ||||
| 			if (!submodule) | ||||
| 				continue; | ||||
| 			module_queue(design, submodule, modules_sorted, modules_processed); | ||||
| 		} | ||||
| 		modules_sorted.push_back(module); | ||||
| 		modules_processed.insert(module); | ||||
| 	} | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); | ||||
|  | @ -172,23 +186,50 @@ struct IopadmapPass : public Pass { | |||
| 		if (!tinoutpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad))); | ||||
| 
 | ||||
| 		for (auto module : design->modules()) | ||||
| 			if (module->get_blackbox_attribute()) | ||||
| 				for (auto wire : module->wires()) | ||||
| 					if (wire->get_bool_attribute("\\iopad_external_pin")) | ||||
| 						ignore.insert(make_pair(module->name, wire->name)); | ||||
| 		// Recursively collect list of (module, port, bit) triples that already have buffers.
 | ||||
| 
 | ||||
| 		pool<pair<IdString, pair<IdString, int>>> buf_ports; | ||||
| 
 | ||||
| 		// Process submodules before module using them.
 | ||||
| 		std::vector<Module *> modules_sorted; | ||||
| 		pool<Module *> modules_processed; | ||||
| 		for (auto module : design->selected_modules()) | ||||
| 			module_queue(design, module, modules_sorted, modules_processed); | ||||
| 
 | ||||
| 		for (auto module : modules_sorted) | ||||
| 		{ | ||||
| 			pool<SigBit> buf_bits; | ||||
| 			SigMap sigmap(module); | ||||
| 
 | ||||
| 			// Collect explicitly-marked already-buffered SigBits.
 | ||||
| 			for (auto wire : module->wires()) | ||||
| 				if (wire->get_bool_attribute("\\iopad_external_pin") || ignore.count(make_pair(module->name, wire->name))) | ||||
| 					for (int i = 0; i < GetSize(wire); i++) | ||||
| 						buf_bits.insert(sigmap(SigBit(wire, i))); | ||||
| 
 | ||||
| 			// Collect SigBits connected to already-buffered ports.
 | ||||
| 			for (auto cell : module->cells()) | ||||
| 			for (auto port : cell->connections()) | ||||
| 			for (int i = 0; i < port.second.size(); i++) | ||||
| 				if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i)))) | ||||
| 					buf_bits.insert(sigmap(port.second[i])); | ||||
| 
 | ||||
| 			// Now fill buf_ports.
 | ||||
| 			for (auto wire : module->wires()) | ||||
| 				if (wire->port_input || wire->port_output) | ||||
| 					for (int i = 0; i < GetSize(wire); i++) | ||||
| 						if (buf_bits.count(sigmap(SigBit(wire, i)))) { | ||||
| 							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||
| 							log("Marking already mapped port: %s.%s[%d].\n", log_id(module), log_id(wire), i); | ||||
| 						} | ||||
| 		} | ||||
| 
 | ||||
| 		// Now do the actual buffer insertion.
 | ||||
| 
 | ||||
| 		for (auto module : design->selected_modules()) | ||||
| 		{ | ||||
| 			pool<SigBit> skip_wire_bits; | ||||
| 			dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; | ||||
| 
 | ||||
| 			for (auto cell : module->cells()) | ||||
| 			for (auto port : cell->connections()) | ||||
| 				if (ignore.count(make_pair(cell->type, port.first))) | ||||
| 					for (auto bit : port.second) | ||||
| 						skip_wire_bits.insert(bit); | ||||
| 
 | ||||
| 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | ||||
| 			{ | ||||
| 				dict<SigBit, Cell *> tbuf_bits; | ||||
|  | @ -234,7 +275,7 @@ struct IopadmapPass : public Pass { | |||
| 						SigBit wire_bit(wire, i); | ||||
| 						Cell *tbuf_cell = nullptr; | ||||
| 
 | ||||
| 						if (skip_wire_bits.count(wire_bit)) | ||||
| 						if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i)))) | ||||
| 							continue; | ||||
| 
 | ||||
| 						if (tbuf_bits.count(wire_bit)) | ||||
|  | @ -282,7 +323,6 @@ struct IopadmapPass : public Pass { | |||
| 								cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); | ||||
| 								cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); | ||||
| 							} | ||||
| 							skip_wire_bits.insert(wire_bit); | ||||
| 							if (!tinoutpad_portname_pad.empty()) | ||||
| 								rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); | ||||
| 						} else { | ||||
|  | @ -298,10 +338,10 @@ struct IopadmapPass : public Pass { | |||
| 								module->remove(tbuf_cell); | ||||
| 								module->connect(wire_bit, data_sig); | ||||
| 							} | ||||
| 							skip_wire_bits.insert(wire_bit); | ||||
| 							if (!toutpad_portname_pad.empty()) | ||||
| 								rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad)); | ||||
| 						} | ||||
| 						buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | @ -315,7 +355,7 @@ struct IopadmapPass : public Pass { | |||
| 				pool<int> skip_bit_indices; | ||||
| 
 | ||||
| 				for (int i = 0; i < GetSize(wire); i++) | ||||
| 					if (skip_wire_bits.count(SigBit(wire, i))) | ||||
| 					if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i)))) | ||||
| 						skip_bit_indices.insert(i); | ||||
| 
 | ||||
| 				if (GetSize(wire) == GetSize(skip_bit_indices)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue