mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	xilinx_dffopt: Keep order of LUT inputs.
See rationale at https://github.com/YosysHQ/yosys/pull/1557#discussion_r359196549
This commit is contained in:
		
							parent
							
								
									f52c6efd9d
								
							
						
					
					
						commit
						561ae1c5c4
					
				
					 1 changed files with 30 additions and 16 deletions
				
			
		| 
						 | 
					@ -27,8 +27,31 @@ typedef std::pair<Const, std::vector<SigBit>> LutData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Compute a LUT implementing (select ^ select_inv) ? alt_data : data.  Returns true if successful.
 | 
					// Compute a LUT implementing (select ^ select_inv) ? alt_data : data.  Returns true if successful.
 | 
				
			||||||
bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) {
 | 
					bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) {
 | 
				
			||||||
	// First, gather input signals.
 | 
						// First, gather input signals -- insert new signals at the beginning
 | 
				
			||||||
 | 
						// of the vector, so they don't disturb the likely-critical D LUT input
 | 
				
			||||||
 | 
						// timings.
 | 
				
			||||||
	result.second = data.second;
 | 
						result.second = data.second;
 | 
				
			||||||
 | 
						// D lut inputs initially start at 0.
 | 
				
			||||||
 | 
						int idx_data = 0;
 | 
				
			||||||
 | 
						// Now add the control input LUT inputs.
 | 
				
			||||||
 | 
						std::vector<int> idx_sel;
 | 
				
			||||||
 | 
						for (auto bit : select.second) {
 | 
				
			||||||
 | 
							int idx = -1;
 | 
				
			||||||
 | 
							for (int i = 0; i < GetSize(result.second); i++)
 | 
				
			||||||
 | 
								if (result.second[i] == bit)
 | 
				
			||||||
 | 
									idx = i;
 | 
				
			||||||
 | 
							if (idx == -1) {
 | 
				
			||||||
 | 
								idx = 0;
 | 
				
			||||||
 | 
								// Insert new signal at the beginning and bump all indices.
 | 
				
			||||||
 | 
								result.second.insert(result.second.begin(), bit);
 | 
				
			||||||
 | 
								idx_data++;
 | 
				
			||||||
 | 
								for (int &sidx : idx_sel)
 | 
				
			||||||
 | 
									sidx++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							idx_sel.push_back(idx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Insert the Q signal, if any, to the slowest input -- it will have
 | 
				
			||||||
 | 
						// no problem meeting timing.
 | 
				
			||||||
	int idx_alt = -1;
 | 
						int idx_alt = -1;
 | 
				
			||||||
	if (alt_data.wire) {
 | 
						if (alt_data.wire) {
 | 
				
			||||||
		// Check if we already have it.
 | 
							// Check if we already have it.
 | 
				
			||||||
| 
						 | 
					@ -37,22 +60,13 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool
 | 
				
			||||||
				idx_alt = i;
 | 
									idx_alt = i;
 | 
				
			||||||
		// If not, add it.
 | 
							// If not, add it.
 | 
				
			||||||
		if (idx_alt == -1) {
 | 
							if (idx_alt == -1) {
 | 
				
			||||||
			idx_alt = GetSize(result.second);
 | 
								idx_alt = 0;
 | 
				
			||||||
			result.second.push_back(alt_data);
 | 
								result.second.insert(result.second.begin(), alt_data);
 | 
				
			||||||
 | 
								idx_data++;
 | 
				
			||||||
 | 
								for (int &sidx : idx_sel)
 | 
				
			||||||
 | 
									sidx++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	std::vector<int> idx_sel;
 | 
					 | 
				
			||||||
	for (auto bit : select.second) {
 | 
					 | 
				
			||||||
		int idx = -1;
 | 
					 | 
				
			||||||
		for (int i = 0; i < GetSize(result.second); i++)
 | 
					 | 
				
			||||||
			if (result.second[i] == bit)
 | 
					 | 
				
			||||||
				idx = i;
 | 
					 | 
				
			||||||
		if (idx == -1) {
 | 
					 | 
				
			||||||
			idx = GetSize(result.second);
 | 
					 | 
				
			||||||
			result.second.push_back(bit);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		idx_sel.push_back(idx);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If LUT would be too large, bail.
 | 
						// If LUT would be too large, bail.
 | 
				
			||||||
	if (GetSize(result.second) > max_lut_size)
 | 
						if (GetSize(result.second) > max_lut_size)
 | 
				
			||||||
| 
						 | 
					@ -75,7 +89,7 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool
 | 
				
			||||||
				new_bit = alt_data.data == State::S1;
 | 
									new_bit = alt_data.data == State::S1;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Use original LUT.
 | 
								// Use original LUT.
 | 
				
			||||||
			int lut_idx = i & ((1 << GetSize(data.second)) - 1);
 | 
								int lut_idx = i >> idx_data & ((1 << GetSize(data.second)) - 1);
 | 
				
			||||||
			new_bit = data.first.bits[lut_idx] == State::S1;
 | 
								new_bit = data.first.bits[lut_idx] == State::S1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		result.first.bits[i] = new_bit ? State::S1 : State::S0;
 | 
							result.first.bits[i] = new_bit ? State::S1 : State::S0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue