aboutsummaryrefslogtreecommitdiffstats
path: root/generic/viaduct/fabulous/validity_check.h
diff options
context:
space:
mode:
Diffstat (limited to 'generic/viaduct/fabulous/validity_check.h')
-rw-r--r--generic/viaduct/fabulous/validity_check.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/generic/viaduct/fabulous/validity_check.h b/generic/viaduct/fabulous/validity_check.h
new file mode 100644
index 00000000..43291f6e
--- /dev/null
+++ b/generic/viaduct/fabulous/validity_check.h
@@ -0,0 +1,127 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021-22 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.
+ *
+ */
+#ifndef VALIDITY_CHECKING_H
+#define VALIDITY_CHECKING_H
+
+#include "fab_cfg.h"
+#include "fab_defs.h"
+#include "sso_array.h"
+
+#include "nextpnr.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+// The validity checking engine for the fabulous configurable CLB
+
+// data that we tag onto cells for fast lookup, so we aren't doing slow hash map accesses in the inner-loop-critical
+// validity checking code
+struct ControlSig
+{
+ ControlSig() : net(), invert(false){};
+ ControlSig(IdString net, bool invert) : net(net), invert(invert){};
+ IdString net;
+ bool invert;
+ bool operator==(const ControlSig &other) const { return net == other.net && invert == other.invert; }
+ bool operator!=(const ControlSig &other) const { return net != other.net || invert != other.invert; }
+};
+
+struct CellTags
+{
+ struct
+ {
+ SSOArray<IdString, MAX_LUTK> lut_inputs; // for checking fracturable LUTs
+ bool carry_used = false;
+ const NetInfo *lut_out = nullptr;
+ // ...
+ } comb; // data for LUTs, or the LUT part of combined LUT+FF cells
+ struct
+ {
+ ControlSig clk, sr, en;
+ bool ff_used = false;
+ bool async = false;
+ bool latch = false;
+ const NetInfo *d = nullptr, *q = nullptr;
+ } ff; // data for FFs, or the FF part of combined LUT+FF cells
+};
+
+// map between cell and tags, using the flat_index that viaduct defines for this purpose
+struct CellTagger
+{
+ std::vector<CellTags> data;
+ const CellTags &get(const CellInfo *ci) const { return data.at(ci->flat_index); }
+ void assign_for(const Context *ctx, const FabricConfig &cfg, const CellInfo *ci);
+};
+
+// we need to add some extra data to CLB bels to track what they do, so we can update CLBState accordingly
+struct BelFlags
+{
+ enum BlockType : uint8_t
+ {
+ BLOCK_OTHER,
+ BLOCK_CLB,
+ // ...
+ } block = BlockType::BLOCK_OTHER;
+ enum FuncType : uint8_t
+ {
+ FUNC_LC_COMB,
+ FUNC_FF,
+ FUNC_MUX,
+ FUNC_OTHER,
+ } func;
+ uint8_t index;
+ // ...
+};
+
+// state of a CLB, for fast bel->cell lookup
+// TODO: add valid/dirty tracking for incremental validity re-checking, important once we have bigger/more complex CLBs
+// (cf. xilinx/intel arches in nextpnr)
+struct CLBState
+{
+ explicit CLBState(const LogicConfig &cfg);
+ // In combined-LC mode (LC bel contains LUT and FF), this indexes the entire LC bel to cell. In separate mode, this
+ // indexes the combinational part (LUT or LUT+carry only).
+ std::unique_ptr<CellInfo *[]> lc_comb;
+ // In split-LC mode only, this maps FF bel (in CLB) index to cell
+ std::unique_ptr<CellInfo *[]> ff;
+ // If there is (a) separate mux bel(s), map them to cells
+ std::unique_ptr<CellInfo *[]> mux;
+ bool check_validity(const LogicConfig &cfg, const CellTagger &cell_data);
+};
+
+struct BlockTracker
+{
+ Context *ctx;
+ const FabricConfig &cfg;
+ std::vector<BelFlags> bel_data;
+
+ BlockTracker(Context *ctx, const FabricConfig &cfg) : ctx(ctx), cfg(cfg){};
+ void set_bel_type(BelId bel, BelFlags::BlockType block, BelFlags::FuncType func, uint8_t index);
+ void update_bel(BelId bel, CellInfo *old_cell, CellInfo *new_cell);
+ struct TileData
+ {
+ std::unique_ptr<CLBState> clb;
+ // ...
+ };
+ std::vector<std::vector<TileData>> tiles;
+ bool check_validity(BelId bel, const FabricConfig &cfg, const CellTagger &cell_data);
+};
+
+NEXTPNR_NAMESPACE_END
+
+#endif