diff options
author | Marcin KoĆcielnicki <mwk@0x04.net> | 2019-12-19 08:49:21 +0100 |
---|---|---|
committer | Marcin KoĆcielnicki <mwk@0x04.net> | 2019-12-19 18:01:43 +0100 |
commit | 561ae1c5c4e694656fb4ce9198e62f0efbe4c705 (patch) | |
tree | eb7b08fbff2fc40aae5afd853c5aa6dc3110e22e /techlibs/xilinx/xilinx_dffopt.cc | |
parent | f52c6efd9da161e625538f9e8c23875efebda60f (diff) | |
download | yosys-561ae1c5c4e694656fb4ce9198e62f0efbe4c705.tar.gz yosys-561ae1c5c4e694656fb4ce9198e62f0efbe4c705.tar.bz2 yosys-561ae1c5c4e694656fb4ce9198e62f0efbe4c705.zip |
xilinx_dffopt: Keep order of LUT inputs.
See rationale at https://github.com/YosysHQ/yosys/pull/1557#discussion_r359196549
Diffstat (limited to 'techlibs/xilinx/xilinx_dffopt.cc')
-rw-r--r-- | techlibs/xilinx/xilinx_dffopt.cc | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index 1256a08cb..13a0b9b83 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -27,20 +27,13 @@ typedef std::pair<Const, std::vector<SigBit>> LutData; // 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) { - // 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; - int idx_alt = -1; - if (alt_data.wire) { - // Check if we already have it. - for (int i = 0; i < GetSize(result.second); i++) - if (result.second[i] == alt_data) - idx_alt = i; - // If not, add it. - if (idx_alt == -1) { - idx_alt = GetSize(result.second); - result.second.push_back(alt_data); - } - } + // 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; @@ -48,11 +41,32 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool if (result.second[i] == bit) idx = i; if (idx == -1) { - idx = GetSize(result.second); - result.second.push_back(bit); + 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; + if (alt_data.wire) { + // Check if we already have it. + for (int i = 0; i < GetSize(result.second); i++) + if (result.second[i] == alt_data) + idx_alt = i; + // If not, add it. + if (idx_alt == -1) { + idx_alt = 0; + result.second.insert(result.second.begin(), alt_data); + idx_data++; + for (int &sidx : idx_sel) + sidx++; + } + } // If LUT would be too large, bail. 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; } else { // 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; } result.first.bits[i] = new_bit ? State::S1 : State::S0; |