aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-12 12:13:11 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-12 12:13:11 +0200
commit2f61a9b98a621a35aa4763abaaf27ca12bfbbefa (patch)
treee1d205548f38a14019d22b757b0bf11a58e7886b
parent5f813410aabdae3de84e11861248dcd0699b41c2 (diff)
downloadnextpnr-2f61a9b98a621a35aa4763abaaf27ca12bfbbefa.tar.gz
nextpnr-2f61a9b98a621a35aa4763abaaf27ca12bfbbefa.tar.bz2
nextpnr-2f61a9b98a621a35aa4763abaaf27ca12bfbbefa.zip
ice40: Start working on a packer, currently not tested
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r--common/design_utils.h4
-rw-r--r--ice40/cells.cc13
-rw-r--r--ice40/cells.h5
-rw-r--r--ice40/pack.cc79
-rw-r--r--ice40/pack.h27
5 files changed, 128 insertions, 0 deletions
diff --git a/common/design_utils.h b/common/design_utils.h
index 43ff180b..9d027d58 100644
--- a/common/design_utils.h
+++ b/common/design_utils.h
@@ -37,6 +37,8 @@ template <typename F1>
CellInfo *net_only_drives(NetInfo *net, F1 cell_pred, IdString port,
bool exclusive = false)
{
+ if (net == nullptr)
+ return nullptr;
if (exclusive && (net->users.size() != 1)) {
return nullptr;
} else {
@@ -54,6 +56,8 @@ CellInfo *net_only_drives(NetInfo *net, F1 cell_pred, IdString port,
template <typename F1>
CellInfo *net_driven_by(NetInfo *net, F1 cell_pred, IdString port)
{
+ if (net == nullptr)
+ return nullptr;
if (cell_pred(net->driver.cell) && net->driver.port == port) {
return net->driver.cell;
} else {
diff --git a/ice40/cells.cc b/ice40/cells.cc
index 328b5f2d..db13a55f 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -64,6 +64,19 @@ CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
return new_cell;
}
+void lut_to_lc(CellInfo *lut, CellInfo *lc, bool no_dff)
+{
+ lc->params["LUT_INIT"] = lut->params["LUT_INIT"];
+ replace_port(lut, "I0", lc, "I0");
+ replace_port(lut, "I1", lc, "I1");
+ replace_port(lut, "I2", lc, "I2");
+ replace_port(lut, "I3", lc, "I3");
+ if (no_dff) {
+ replace_port(lut, "O", lc, "O");
+ lc->params["DFF_ENABLE"] = "0";
+ }
+}
+
void dff_to_lc(CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
{
lc->params["DFF_ENABLE"] = "1";
diff --git a/ice40/cells.h b/ice40/cells.h
index 1fa85413..a2d45df6 100644
--- a/ice40/cells.h
+++ b/ice40/cells.h
@@ -45,6 +45,11 @@ inline bool is_ff(const CellInfo *cell)
cell->type == "SB_DFFNESS" || cell->type == "SB_DFFNES";
}
+// Convert a SB_LUT primitive to (part of) an ICESTORM_LC, swapping ports
+// as needed. Set no_dff if a DFF is not being used, so that the output
+// can be reconnected
+void lut_to_lc(CellInfo *lut, CellInfo *lc, bool no_dff = true);
+
// Convert a SB_DFFx primitive to (part of) an ICESTORM_LC, setting parameters
// and reconnecting signals as necessary. If pass_thru_lut is True, the LUT will
// be configured as pass through and D connected to I0, otherwise D will be
diff --git a/ice40/pack.cc b/ice40/pack.cc
new file mode 100644
index 00000000..692bfba2
--- /dev/null
+++ b/ice40/pack.cc
@@ -0,0 +1,79 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
+ * Copyright (C) 2018 David Shah <dave@ds0.me>
+ *
+ * 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.
+ *
+ */
+
+#include "pack.h"
+#include "cells.h"
+#include "design_utils.h"
+#include "log.h"
+
+#include <unordered_set>
+
+// Pack LUTs and LUT-FF pairs
+static void pack_lut_lutffs(Design *design)
+{
+ std::unordered_set<IdString> packed_cells;
+ for (auto cell : design->cells) {
+ CellInfo *ci = cell.second;
+ if (is_lut(ci)) {
+ CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
+ std::string(ci->name) + "_LC");
+ packed_cells.insert(ci->name);
+ // See if we can pack into a DFF
+ // TODO: LUT cascade
+ NetInfo *o = ci->ports.at("O").net;
+ CellInfo *dff = net_only_drives(o, is_ff, "D", true);
+ if (dff) {
+ lut_to_lc(ci, packed, false);
+ dff_to_lc(dff, packed, false);
+ packed_cells.insert(dff->name);
+ } else {
+ lut_to_lc(ci, packed, true);
+ }
+ }
+ }
+ for (auto pcell : packed_cells) {
+ design->cells.erase(pcell);
+ }
+}
+
+// Pack FFs not packed as LUTFFs
+static void pack_nonlut_ffs(Design *design)
+{
+ std::unordered_set<IdString> packed_cells;
+ for (auto cell : design->cells) {
+ CellInfo *ci = cell.second;
+ if (is_ff(ci)) {
+ CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
+ std::string(ci->name) + "_LC");
+ packed_cells.insert(ci->name);
+ dff_to_lc(ci, packed, true);
+ }
+ }
+ for (auto pcell : packed_cells) {
+ design->cells.erase(pcell);
+ }
+}
+
+// Main pack function
+void pack_design(Design *design)
+{
+ pack_lut_lutffs(design);
+ pack_nonlut_ffs(design);
+}
diff --git a/ice40/pack.h b/ice40/pack.h
new file mode 100644
index 00000000..87a390ff
--- /dev/null
+++ b/ice40/pack.h
@@ -0,0 +1,27 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
+ *
+ * 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 PACK_H
+#define PACK_H
+
+#include "nextpnr.h"
+
+void pack_design(Design *design);
+
+#endif // ROUTE_H