aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx/xilinx_dffopt.cc
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <mwk@0x04.net>2019-12-19 08:49:21 +0100
committerMarcin Koƛcielnicki <mwk@0x04.net>2019-12-19 18:01:43 +0100
commit561ae1c5c4e694656fb4ce9198e62f0efbe4c705 (patch)
treeeb7b08fbff2fc40aae5afd853c5aa6dc3110e22e /techlibs/xilinx/xilinx_dffopt.cc
parentf52c6efd9da161e625538f9e8c23875efebda60f (diff)
downloadyosys-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.cc46
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;