aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/luts.h
diff options
context:
space:
mode:
authorKeith Rothman <537074+litghost@users.noreply.github.com>2021-02-24 14:02:21 -0800
committerKeith Rothman <537074+litghost@users.noreply.github.com>2021-02-26 11:01:22 -0800
commitcfa449c3f3c5b151eb11ef79bc2cf571e98bbbed (patch)
tree38d78928c17745e07689a9d6d4bfdfcdf4e36b1f /fpga_interchange/luts.h
parent9cbfd0b967f5804472afbb91d8df92e69dffe659 (diff)
downloadnextpnr-cfa449c3f3c5b151eb11ef79bc2cf571e98bbbed.tar.gz
nextpnr-cfa449c3f3c5b151eb11ef79bc2cf571e98bbbed.tar.bz2
nextpnr-cfa449c3f3c5b151eb11ef79bc2cf571e98bbbed.zip
Initial LUT rotation logic.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'fpga_interchange/luts.h')
-rw-r--r--fpga_interchange/luts.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/fpga_interchange/luts.h b/fpga_interchange/luts.h
new file mode 100644
index 00000000..0218653a
--- /dev/null
+++ b/fpga_interchange/luts.h
@@ -0,0 +1,101 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021 Symbiflow Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef NEXTPNR_H
+#error Include "luts.h" via "nextpnr.h" only.
+#endif
+
+#include "dynamic_bitarray.h"
+
+#ifndef LUTS_H
+#define LUTS_H
+
+NEXTPNR_NAMESPACE_BEGIN
+
+struct CellInfo;
+struct Context;
+
+enum LogicLevel {
+ LL_Zero,
+ LL_One,
+ LL_DontCare
+};
+
+struct LutCell {
+ // LUT cell pins for equation, LSB first.
+ std::vector<IdString> pins;
+ std::unordered_set<IdString> lut_pins;
+ std::unordered_set<IdString> vcc_pins;
+ nextpnr::DynamicBitarray<> equation;
+};
+
+struct LutBel {
+ // LUT BEL pins to LUT array index.
+ std::vector<IdString> pins;
+ std::unordered_map<IdString, size_t> pin_to_index;
+
+ // What part of the LUT equation does this LUT output use?
+ // This assumes contiguous LUT bits.
+ uint32_t low_bit;
+ uint32_t high_bit;
+
+ int32_t min_pin;
+ int32_t max_pin;
+};
+
+// Work forward from cell definition and cell -> bel pin map and check that
+// equation is valid.
+void check_equation(
+ const LutCell & lut_cell,
+ const std::unordered_map<IdString, IdString> &cell_to_bel_map,
+ const LutBel & lut_bel,
+ const std::vector<LogicLevel> &equation,
+ uint32_t used_pins);
+
+struct LutElement {
+ size_t width;
+ std::unordered_map<IdString, LutBel> lut_bels;
+
+ void compute_pin_order();
+
+ std::vector<IdString> pins;
+ std::unordered_map<IdString, size_t> pin_to_index;
+};
+
+struct LutMapper {
+ LutMapper(const LutElement & element) : element(element) {}
+ const LutElement & element;
+
+ std::vector<CellInfo*> cells;
+
+ bool remap_luts(const Context *ctx);
+};
+
+// Rotate and merge a LUT equation into an array of levels.
+//
+// If a conflict arises, return false and result is in an indeterminate state.
+bool rotate_and_merge_lut_equation(std::vector<LogicLevel> * result,
+ const LutBel & lut_bel,
+ const nextpnr::DynamicBitarray<> &old_equation,
+ const std::vector<size_t> &pin_map,
+ uint32_t used_pins);
+
+NEXTPNR_NAMESPACE_END
+
+#endif /* LUTS_H */