mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	Improved opt_muxtree
This commit is contained in:
		
							parent
							
								
									b32ba6f568
								
							
						
					
					
						commit
						3628ca989c
					
				
					 1 changed files with 38 additions and 4 deletions
				
			
		| 
						 | 
					@ -256,7 +256,7 @@ struct OptMuxtreeWorker
 | 
				
			||||||
			list.push_back(value);
 | 
								list.push_back(value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<int> sig2bits(RTLIL::SigSpec sig)
 | 
						std::vector<int> sig2bits(RTLIL::SigSpec sig, bool skip_non_wires = true)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::vector<int> results;
 | 
							std::vector<int> results;
 | 
				
			||||||
		assign_map.apply(sig);
 | 
							assign_map.apply(sig);
 | 
				
			||||||
| 
						 | 
					@ -271,7 +271,8 @@ struct OptMuxtreeWorker
 | 
				
			||||||
					bit2num[info.bit] = info.num;
 | 
										bit2num[info.bit] = info.num;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				results.push_back(bit2num[bit]);
 | 
									results.push_back(bit2num[bit]);
 | 
				
			||||||
			}
 | 
								} else if (!skip_non_wires)
 | 
				
			||||||
 | 
									results.push_back(-1);
 | 
				
			||||||
		return results;
 | 
							return results;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -285,7 +286,7 @@ struct OptMuxtreeWorker
 | 
				
			||||||
		// database of known active signals
 | 
							// database of known active signals
 | 
				
			||||||
		// the 2nd dimension is the list of or-ed signals. so we know that
 | 
							// the 2nd dimension is the list of or-ed signals. so we know that
 | 
				
			||||||
		// for each i there is a j so that known_active[i][j] points to an
 | 
							// for each i there is a j so that known_active[i][j] points to an
 | 
				
			||||||
		// inactive control signal.
 | 
							// active control signal.
 | 
				
			||||||
		std::vector<std::vector<int>> known_active;
 | 
							std::vector<std::vector<int>> known_active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// this is just used to keep track of visited muxes in order to prohibit
 | 
							// this is just used to keep track of visited muxes in order to prohibit
 | 
				
			||||||
| 
						 | 
					@ -331,10 +332,43 @@ struct OptMuxtreeWorker
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void replace_known(knowledge_t &knowledge, muxinfo_t &muxinfo, IdString portname)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SigSpec sig = muxinfo.cell->getPort(portname);
 | 
				
			||||||
 | 
							bool did_something = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::vector<int> bits = sig2bits(sig, false);
 | 
				
			||||||
 | 
							for (int i = 0; i < GetSize(bits); i++) {
 | 
				
			||||||
 | 
								if (bits[i] < 0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								if (knowledge.known_inactive[bits[i]]) {
 | 
				
			||||||
 | 
									sig[i] = State::S0;
 | 
				
			||||||
 | 
									did_something = true;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									for (auto &it : knowledge.known_active)
 | 
				
			||||||
 | 
										if (GetSize(it) == 1 && it.front() == bits[i]) {
 | 
				
			||||||
 | 
											sig[i] = State::S1;
 | 
				
			||||||
 | 
											did_something = true;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (did_something) {
 | 
				
			||||||
 | 
								log("    Replacing known input bits on port %s of cell %s: %s -> %s\n", log_id(portname),
 | 
				
			||||||
 | 
										log_id(muxinfo.cell), log_signal(muxinfo.cell->getPort(portname)), log_signal(sig));
 | 
				
			||||||
 | 
								muxinfo.cell->setPort(portname, sig);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void eval_mux(knowledge_t &knowledge, int mux_idx)
 | 
						void eval_mux(knowledge_t &knowledge, int mux_idx)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		muxinfo_t &muxinfo = mux2info[mux_idx];
 | 
							muxinfo_t &muxinfo = mux2info[mux_idx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// set input ports to constants if we find known active or inactive signals
 | 
				
			||||||
 | 
							replace_known(knowledge, muxinfo, "\\A");
 | 
				
			||||||
 | 
							replace_known(knowledge, muxinfo, "\\B");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// if there is a constant activated port we just use it
 | 
							// if there is a constant activated port we just use it
 | 
				
			||||||
		for (size_t port_idx = 0; port_idx < muxinfo.ports.size()-1; port_idx++)
 | 
							for (size_t port_idx = 0; port_idx < muxinfo.ports.size()-1; port_idx++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -360,7 +394,7 @@ struct OptMuxtreeWorker
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// compare ports with known_inactive and known_active signals. If all control
 | 
							// compare ports with known_inactive and known_active signals. If all control
 | 
				
			||||||
		// signals of the port are know_inactive or if the control signals of all other
 | 
							// signals of the port are known_inactive or if the control signals of all other
 | 
				
			||||||
		// ports are known_active this port can't be activated. this loop includes the
 | 
							// ports are known_active this port can't be activated. this loop includes the
 | 
				
			||||||
		// default port but no known_inactive match is performed on the default port.
 | 
							// default port but no known_inactive match is performed on the default port.
 | 
				
			||||||
		for (size_t port_idx = 0; port_idx < muxinfo.ports.size(); port_idx++)
 | 
							for (size_t port_idx = 0; port_idx < muxinfo.ports.size(); port_idx++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue