mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Do not introduce new logic loops in "share"
This commit is contained in:
		
							parent
							
								
									edf11c635a
								
							
						
					
					
						commit
						8d60754aef
					
				
					 1 changed files with 47 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -47,6 +47,8 @@ struct ShareWorker
 | 
			
		|||
	std::set<RTLIL::Cell*> cells_to_remove;
 | 
			
		||||
	std::set<RTLIL::Cell*> recursion_state;
 | 
			
		||||
 | 
			
		||||
	std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> to_drivers_edges;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// ------------------------------------------------------------------------------
 | 
			
		||||
	// Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree
 | 
			
		||||
| 
						 | 
				
			
			@ -641,11 +643,11 @@ struct ShareWorker
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// ------------------------------------------------------------------------------------------------
 | 
			
		||||
	// Find SCCs (logic loops). This is only used to make sure that this pass does not introduce loops.
 | 
			
		||||
	// ------------------------------------------------------------------------------------------------
 | 
			
		||||
	// -------------------------------------------------------------------------------------
 | 
			
		||||
	// Helper functions used to make sure that this pass does not introduce new logic loops.
 | 
			
		||||
	// -------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	bool module_has_scc()
 | 
			
		||||
	bool module_has_scc(std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> *edges = NULL)
 | 
			
		||||
	{
 | 
			
		||||
		SigMap sigmap(module);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -679,7 +681,32 @@ struct ShareWorker
 | 
			
		|||
				toposort.edge(c1, c2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return !toposort.sort();
 | 
			
		||||
		bool found_scc = !toposort.sort();
 | 
			
		||||
		if (edges)
 | 
			
		||||
			*edges = std::move(toposort.database);
 | 
			
		||||
		return found_scc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool find_in_input_cone_worker(RTLIL::Cell *root, RTLIL::Cell *needle, std::set<RTLIL::Cell*> &stop)
 | 
			
		||||
	{
 | 
			
		||||
		if (root == needle)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		if (stop.count(root))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		stop.insert(root);
 | 
			
		||||
 | 
			
		||||
		for (auto c : to_drivers_edges[root])
 | 
			
		||||
			if (find_in_input_cone_worker(c, needle, stop))
 | 
			
		||||
				return true;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool find_in_input_cone(RTLIL::Cell *root, RTLIL::Cell *needle)
 | 
			
		||||
	{
 | 
			
		||||
		std::set<RTLIL::Cell*> stop;
 | 
			
		||||
		return find_in_input_cone_worker(root, needle, stop);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -690,7 +717,7 @@ struct ShareWorker
 | 
			
		|||
	ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
 | 
			
		||||
			config(config), design(design), module(module)
 | 
			
		||||
	{
 | 
			
		||||
		bool before_scc = module_has_scc();
 | 
			
		||||
		bool before_scc = module_has_scc(&to_drivers_edges);
 | 
			
		||||
 | 
			
		||||
		generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end());
 | 
			
		||||
		generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end());
 | 
			
		||||
| 
						 | 
				
			
			@ -878,6 +905,17 @@ struct ShareWorker
 | 
			
		|||
				}
 | 
			
		||||
 | 
			
		||||
				log("      According to the SAT solver this pair of cells can be shared.\n");
 | 
			
		||||
 | 
			
		||||
				if (find_in_input_cone(cell, other_cell)) {
 | 
			
		||||
					log("      Sharing not possible: %s is in input cone of %s.\n", log_id(other_cell), log_id(cell));
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (find_in_input_cone(other_cell, cell)) {
 | 
			
		||||
					log("      Sharing not possible: %s is in input cone of %s.\n", log_id(cell), log_id(other_cell));
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				shareable_cells.erase(other_cell);
 | 
			
		||||
 | 
			
		||||
				int cell_select_score = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -911,6 +949,9 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
				cells_to_remove.insert(cell);
 | 
			
		||||
				cells_to_remove.insert(other_cell);
 | 
			
		||||
 | 
			
		||||
				to_drivers_edges[cell].insert(to_drivers_edges[other_cell].begin(), to_drivers_edges[other_cell].end());
 | 
			
		||||
				to_drivers_edges[other_cell] = to_drivers_edges[cell];
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue