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*> cells_to_remove;
 | 
				
			||||||
	std::set<RTLIL::Cell*> recursion_state;
 | 
						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
 | 
						// 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);
 | 
							SigMap sigmap(module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -679,7 +681,32 @@ struct ShareWorker
 | 
				
			||||||
				toposort.edge(c1, c2);
 | 
									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) :
 | 
						ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
 | 
				
			||||||
			config(config), design(design), 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_uni_ops.begin(), config.generic_uni_ops.end());
 | 
				
			||||||
		generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_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");
 | 
									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);
 | 
									shareable_cells.erase(other_cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				int cell_select_score = 0;
 | 
									int cell_select_score = 0;
 | 
				
			||||||
| 
						 | 
					@ -911,6 +949,9 @@ struct ShareWorker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				cells_to_remove.insert(cell);
 | 
									cells_to_remove.insert(cell);
 | 
				
			||||||
				cells_to_remove.insert(other_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;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue