aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-05-08 13:38:17 +0100
committergatecat <gatecat@ds0.me>2021-05-15 14:54:33 +0100
commite5e2f7bc62c1cfba2f43ea74199a5a3a379e5de7 (patch)
treed1da2c022356f3a5b50daa762e14561282e0c933
parent879ac39e53c76558766460cfa948d97227119f37 (diff)
downloadnextpnr-e5e2f7bc62c1cfba2f43ea74199a5a3a379e5de7.tar.gz
nextpnr-e5e2f7bc62c1cfba2f43ea74199a5a3a379e5de7.tar.bz2
nextpnr-e5e2f7bc62c1cfba2f43ea74199a5a3a379e5de7.zip
mistral: Add stub pack/place/route functions
Signed-off-by: gatecat <gatecat@ds0.me>
-rw-r--r--common/base_arch.h2
-rw-r--r--mistral/arch.cc73
-rw-r--r--mistral/arch.h11
-rw-r--r--mistral/lab.cc27
-rw-r--r--mistral/pack.cc35
5 files changed, 143 insertions, 5 deletions
diff --git a/common/base_arch.h b/common/base_arch.h
index e9cc8cf0..fbafee99 100644
--- a/common/base_arch.h
+++ b/common/base_arch.h
@@ -75,7 +75,7 @@ typename std::enable_if<std::is_same<Tret, Tc>::value, Tret>::type return_if_mat
}
template <typename Tret, typename Tc>
-typename std::enable_if<!std::is_same<Tret, Tc>::value, Tret>::type return_if_match(Tret r)
+typename std::enable_if<!std::is_same<Tret, Tc>::value, Tc>::type return_if_match(Tret r)
{
NPNR_ASSERT_FALSE("default implementations of cell type and bel bucket range functions only available when the "
"respective range types are 'const std::vector&'");
diff --git a/mistral/arch.cc b/mistral/arch.cc
index fd2f345d..aa149a3c 100644
--- a/mistral/arch.cc
+++ b/mistral/arch.cc
@@ -21,6 +21,13 @@
#include "log.h"
#include "nextpnr.h"
+#include "placer1.h"
+#include "placer_heap.h"
+#include "router1.h"
+#include "router2.h"
+#include "timing.h"
+#include "util.h"
+
#include "cyclonev.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -244,10 +251,6 @@ BelBucketId Arch::getBelBucketForCellType(IdString cell_type) const
return cell_type;
}
-bool Arch::pack() { return true; }
-bool Arch::place() { return true; }
-bool Arch::route() { return true; }
-
BelId Arch::add_bel(int x, int y, IdString name, IdString type)
{
auto &bels = bels_by_tile.at(pos2idx(x, y));
@@ -321,6 +324,68 @@ void Arch::assign_default_pinmap(CellInfo *cell)
}
}
+void Arch::assignArchInfo()
+{
+ for (auto cell : sorted(cells)) {
+ CellInfo *ci = cell.second;
+ if (is_comb_cell(ci->type))
+ assign_comb_info(ci);
+ else if (ci->type == id_MISTRAL_FF)
+ assign_ff_info(ci);
+ assign_default_pinmap(ci);
+ }
+}
+
+bool Arch::place()
+{
+ std::string placer = str_or_default(settings, id("placer"), defaultPlacer);
+
+ if (placer == "heap") {
+ PlacerHeapCfg cfg(getCtx());
+ cfg.ioBufTypes.insert(id_MISTRAL_IO);
+ cfg.ioBufTypes.insert(id_MISTRAL_IB);
+ cfg.ioBufTypes.insert(id_MISTRAL_OB);
+ cfg.cellGroups.emplace_back();
+ cfg.cellGroups.back().insert({id_MISTRAL_COMB});
+ cfg.cellGroups.back().insert({id_MISTRAL_FF});
+
+ cfg.beta = 0.5; // TODO: find a good value of beta for sensible ALM spreading
+ cfg.criticalityExponent = 7;
+ if (!placer_heap(getCtx(), cfg))
+ return false;
+ } else if (placer == "sa") {
+ if (!placer1(getCtx(), Placer1Cfg(getCtx())))
+ return false;
+ } else {
+ log_error("Mistral architecture does not support placer '%s'\n", placer.c_str());
+ }
+
+ getCtx()->attrs[getCtx()->id("step")] = std::string("place");
+ archInfoToAttributes();
+ return true;
+}
+
+bool Arch::route()
+{
+ assign_budget(getCtx(), true);
+
+ lab_pre_route();
+
+ std::string router = str_or_default(settings, id("router"), defaultRouter);
+ bool result;
+ if (router == "router1") {
+ result = router1(getCtx(), Router1Cfg(getCtx()));
+ } else if (router == "router2") {
+ router2(getCtx(), Router2Cfg(getCtx()));
+ result = true;
+ } else {
+ log_error("Mistral architecture does not support router '%s'\n", router.c_str());
+ }
+ getCtx()->attrs[getCtx()->id("step")] = std::string("route");
+ archInfoToAttributes();
+ return result;
+}
+
#ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap";
#else
diff --git a/mistral/arch.h b/mistral/arch.h
index ff006881..dd684dfe 100644
--- a/mistral/arch.h
+++ b/mistral/arch.h
@@ -214,6 +214,7 @@ struct ArchRanges : BaseArchRanges
using AllBelsRangeT = const std::vector<BelId> &;
using TileBelsRangeT = std::vector<BelId>;
using BelPinsRangeT = std::vector<IdString>;
+ using CellBelPinRangeT = const std::vector<IdString> &;
// Wires
using AllWiresRangeT = AllWireRange;
using DownhillPipRangeT = UpDownhillPipRange;
@@ -315,11 +316,17 @@ struct Arch : BaseArch<ArchRanges>
// -------------------------------------------------
+ const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override
+ {
+ return cell_info->pin_data.at(pin).bel_pins;
+ }
+
bool isValidBelForCellType(IdString cell_type, BelId bel) const override;
BelBucketId getBelBucketForCellType(IdString cell_type) const override;
// -------------------------------------------------
+ void assignArchInfo() override;
bool pack() override;
bool place() override;
bool route() override;
@@ -350,6 +357,10 @@ struct Arch : BaseArch<ArchRanges>
void assign_comb_info(CellInfo *cell) const; // lab.cc
void assign_ff_info(CellInfo *cell) const; // lab.cc
+ void lab_pre_route(); // lab.cc
+ void assign_control_sets(uint32_t lab); // lab.cc
+ void reassign_alm_inputs(uint32_t lab, uint8_t alm); // lab.cc
+
// -------------------------------------------------
bool is_io_cell(IdString cell_type) const; // io.cc
diff --git a/mistral/lab.cc b/mistral/lab.cc
index 1f117106..f01c6e95 100644
--- a/mistral/lab.cc
+++ b/mistral/lab.cc
@@ -388,6 +388,33 @@ bool Arch::is_lab_ctrlset_legal(uint32_t lab) const
return true;
}
+void Arch::lab_pre_route()
+{
+ for (uint32_t lab = 0; lab < labs.size(); lab++) {
+ assign_control_sets(lab);
+ for (uint8_t alm = 0; alm < 10; alm++) {
+ reassign_alm_inputs(lab, alm);
+ }
+ }
+}
+
+void Arch::assign_control_sets(uint32_t lab)
+{
+ // TODO: set up reservations for checkPipAvailForNet for control set signals
+ // This will be needed because clock and CE are routed together and must be kept together, there isn't free choice
+ // e.g. CLK0 & ENA0 must be use for one control set, and CLK1 & ENA1 for another, they can't be mixed and matched
+}
+
+void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm)
+{
+ // TODO: based on the usage of LUTs inside the ALM, set up cell-bel pin map for the combinational cells in the ALM
+ // so that each physical bel pin is only used for one net; and the logical functions can be implemented correctly.
+ // This function should also insert route-through LUTs to legalise flipflop inputs as needed.
+ // TODO: in the future, as well as the reassignment here we will also have pseudo PIPs in front of the ALM so that
+ // the router can permute LUTs for routeability; too. Here we will need to lock out some of those PIPs depending on
+ // the usage of the ALM, as not all inputs are always interchangeable.
+}
+
// This default cell-bel pin mapping is used to provide estimates during placement only. It will have errors and
// overlaps and a correct mapping will be resolved twixt placement and routing
const std::unordered_map<IdString, IdString> Arch::comb_pinmap = {
diff --git a/mistral/pack.cc b/mistral/pack.cc
new file mode 100644
index 00000000..78a000d9
--- /dev/null
+++ b/mistral/pack.cc
@@ -0,0 +1,35 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021 gatecat <gatecat@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 "log.h"
+#include "nextpnr.h"
+#include "util.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+bool Arch::pack()
+{
+ // TODO:
+ // - Insert constant driver LUTs
+ // - Fold constants and inverters into cell pins
+ // - Constrain IO
+ return true;
+}
+
+NEXTPNR_NAMESPACE_END \ No newline at end of file