aboutsummaryrefslogtreecommitdiffstats
path: root/common/kernel/nextpnr_types.h
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2022-04-08 13:42:54 +0100
committergatecat <gatecat@ds0.me>2022-04-08 13:42:54 +0100
commit49f178ed94b5fad00d25dbd12adea0bf4732f803 (patch)
treeea642e20bc07441a800944390e1f904e6ce5b113 /common/kernel/nextpnr_types.h
parente42e22575f20b59634f88b5cf694efdb413ff0a0 (diff)
downloadnextpnr-49f178ed94b5fad00d25dbd12adea0bf4732f803.tar.gz
nextpnr-49f178ed94b5fad00d25dbd12adea0bf4732f803.tar.bz2
nextpnr-49f178ed94b5fad00d25dbd12adea0bf4732f803.zip
Split up common into kernel,place,route
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'common/kernel/nextpnr_types.h')
-rw-r--r--common/kernel/nextpnr_types.h364
1 files changed, 364 insertions, 0 deletions
diff --git a/common/kernel/nextpnr_types.h b/common/kernel/nextpnr_types.h
new file mode 100644
index 00000000..c21182cc
--- /dev/null
+++ b/common/kernel/nextpnr_types.h
@@ -0,0 +1,364 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Claire Xenia Wolf <claire@yosyshq.com>
+ * Copyright (C) 2018 Serge Bazanski <q3k@q3k.org>
+ *
+ * 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.
+ *
+ */
+
+// Types defined in this header use one or more user defined types (e.g. BelId).
+// If a new common type is desired that doesn't depend on a user defined type,
+// either put it in it's own header, or in nextpnr_base_types.h.
+#ifndef NEXTPNR_TYPES_H
+#define NEXTPNR_TYPES_H
+
+#include <unordered_map>
+#include <unordered_set>
+
+#include "archdefs.h"
+#include "hashlib.h"
+#include "indexed_store.h"
+#include "nextpnr_base_types.h"
+#include "nextpnr_namespaces.h"
+#include "property.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+struct DecalXY
+{
+ DecalId decal;
+ float x = 0, y = 0;
+
+ bool operator==(const DecalXY &other) const { return (decal == other.decal && x == other.x && y == other.y); }
+};
+
+struct BelPin
+{
+ BelId bel;
+ IdString pin;
+};
+
+struct Region
+{
+ IdString name;
+
+ bool constr_bels = false;
+ bool constr_wires = false;
+ bool constr_pips = false;
+
+ pool<BelId> bels;
+ pool<WireId> wires;
+ pool<Loc> piplocs;
+};
+
+struct PipMap
+{
+ PipId pip = PipId();
+ PlaceStrength strength = STRENGTH_NONE;
+};
+
+struct CellInfo;
+
+struct PortRef
+{
+ CellInfo *cell = nullptr;
+ IdString port;
+ delay_t budget = 0;
+};
+
+// minimum and maximum delay
+struct DelayPair
+{
+ DelayPair(){};
+ explicit DelayPair(delay_t delay) : min_delay(delay), max_delay(delay){};
+ DelayPair(delay_t min_delay, delay_t max_delay) : min_delay(min_delay), max_delay(max_delay){};
+ delay_t minDelay() const { return min_delay; };
+ delay_t maxDelay() const { return max_delay; };
+ delay_t min_delay, max_delay;
+ DelayPair operator+(const DelayPair &other) const
+ {
+ return {min_delay + other.min_delay, max_delay + other.max_delay};
+ }
+ DelayPair operator-(const DelayPair &other) const
+ {
+ return {min_delay - other.min_delay, max_delay - other.max_delay};
+ }
+};
+
+// four-quadrant, min and max rise and fall delay
+struct DelayQuad
+{
+ DelayPair rise, fall;
+ DelayQuad(){};
+ explicit DelayQuad(delay_t delay) : rise(delay), fall(delay){};
+ DelayQuad(delay_t min_delay, delay_t max_delay) : rise(min_delay, max_delay), fall(min_delay, max_delay){};
+ DelayQuad(DelayPair rise, DelayPair fall) : rise(rise), fall(fall){};
+ DelayQuad(delay_t min_rise, delay_t max_rise, delay_t min_fall, delay_t max_fall)
+ : rise(min_rise, max_rise), fall(min_fall, max_fall){};
+
+ delay_t minRiseDelay() const { return rise.minDelay(); };
+ delay_t maxRiseDelay() const { return rise.maxDelay(); };
+ delay_t minFallDelay() const { return fall.minDelay(); };
+ delay_t maxFallDelay() const { return fall.maxDelay(); };
+ delay_t minDelay() const { return std::min<delay_t>(rise.minDelay(), fall.minDelay()); };
+ delay_t maxDelay() const { return std::max<delay_t>(rise.maxDelay(), fall.maxDelay()); };
+
+ DelayPair delayPair() const { return DelayPair(minDelay(), maxDelay()); };
+
+ DelayQuad operator+(const DelayQuad &other) const { return {rise + other.rise, fall + other.fall}; }
+ DelayQuad operator-(const DelayQuad &other) const { return {rise - other.rise, fall - other.fall}; }
+};
+
+struct ClockConstraint;
+
+struct NetInfo : ArchNetInfo
+{
+ explicit NetInfo(IdString name) : name(name){};
+ IdString name, hierpath;
+ int32_t udata = 0;
+
+ PortRef driver;
+ indexed_store<PortRef> users;
+ dict<IdString, Property> attrs;
+
+ // wire -> uphill_pip
+ dict<WireId, PipMap> wires;
+
+ std::vector<IdString> aliases; // entries in net_aliases that point to this net
+
+ std::unique_ptr<ClockConstraint> clkconstr;
+
+ Region *region = nullptr;
+};
+
+enum PortType
+{
+ PORT_IN = 0,
+ PORT_OUT = 1,
+ PORT_INOUT = 2
+};
+
+struct PortInfo
+{
+ IdString name;
+ NetInfo *net;
+ PortType type;
+ store_index<PortRef> user_idx{};
+};
+
+struct Context;
+
+struct CellInfo : ArchCellInfo
+{
+ CellInfo(Context *ctx, IdString name, IdString type) : ctx(ctx), name(name), type(type){};
+ Context *ctx = nullptr;
+
+ IdString name, type, hierpath;
+ int32_t udata;
+
+ dict<IdString, PortInfo> ports;
+ dict<IdString, Property> attrs, params;
+
+ BelId bel;
+ PlaceStrength belStrength = STRENGTH_NONE;
+
+ // cell is part of a cluster if != ClusterId
+ ClusterId cluster;
+
+ Region *region = nullptr;
+
+ void addInput(IdString name);
+ void addOutput(IdString name);
+ void addInout(IdString name);
+
+ void setParam(IdString name, Property value);
+ void unsetParam(IdString name);
+ void setAttr(IdString name, Property value);
+ void unsetAttr(IdString name);
+ // check whether a bel complies with the cell's region constraint
+ bool testRegion(BelId bel) const;
+
+ NetInfo *getPort(IdString name)
+ {
+ auto found = ports.find(name);
+ return (found == ports.end()) ? nullptr : found->second.net;
+ }
+ const NetInfo *getPort(IdString name) const
+ {
+ auto found = ports.find(name);
+ return (found == ports.end()) ? nullptr : found->second.net;
+ }
+ void connectPort(IdString port, NetInfo *net);
+ void disconnectPort(IdString port);
+ void connectPorts(IdString port, CellInfo *other, IdString other_port);
+ void movePortTo(IdString port, CellInfo *other, IdString other_port);
+ void renamePort(IdString old_name, IdString new_name);
+ void movePortBusTo(IdString old_name, int old_offset, bool old_brackets, CellInfo *new_cell, IdString new_name,
+ int new_offset, bool new_brackets, int width);
+ void copyPortTo(IdString port, CellInfo *other, IdString other_port);
+ void copyPortBusTo(IdString old_name, int old_offset, bool old_brackets, CellInfo *new_cell, IdString new_name,
+ int new_offset, bool new_brackets, int width);
+};
+
+enum TimingPortClass
+{
+ TMG_CLOCK_INPUT, // Clock input to a sequential cell
+ TMG_GEN_CLOCK, // Generated clock output (PLL, DCC, etc)
+ TMG_REGISTER_INPUT, // Input to a register, with an associated clock (may also have comb. fanout too)
+ TMG_REGISTER_OUTPUT, // Output from a register
+ TMG_COMB_INPUT, // Combinational input, no paths end here
+ TMG_COMB_OUTPUT, // Combinational output, no paths start here
+ TMG_STARTPOINT, // Unclocked primary startpoint, such as an IO cell output
+ TMG_ENDPOINT, // Unclocked primary endpoint, such as an IO cell input
+ TMG_IGNORE, // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis
+};
+
+enum ClockEdge
+{
+ RISING_EDGE,
+ FALLING_EDGE
+};
+
+struct TimingClockingInfo
+{
+ IdString clock_port; // Port name of clock domain
+ ClockEdge edge;
+ DelayPair setup, hold; // Input timing checks
+ DelayQuad clockToQ; // Output clock-to-Q time
+};
+
+struct ClockConstraint
+{
+ DelayPair high;
+ DelayPair low;
+ DelayPair period;
+};
+
+struct ClockFmax
+{
+ float achieved;
+ float constraint;
+};
+
+struct ClockEvent
+{
+ IdString clock;
+ ClockEdge edge;
+
+ bool operator==(const ClockEvent &other) const { return clock == other.clock && edge == other.edge; }
+ unsigned int hash() const { return mkhash(clock.hash(), int(edge)); }
+};
+
+struct ClockPair
+{
+ ClockEvent start, end;
+
+ bool operator==(const ClockPair &other) const { return start == other.start && end == other.end; }
+ unsigned int hash() const { return mkhash(start.hash(), end.hash()); }
+};
+
+struct CriticalPath
+{
+ struct Segment
+ {
+
+ // Segment type
+ enum class Type
+ {
+ CLK_TO_Q, // Clock-to-Q delay
+ SOURCE, // Delayless source
+ LOGIC, // Combinational logic delay
+ ROUTING, // Routing delay
+ SETUP // Setup time in sink
+ };
+
+ // Type
+ Type type;
+ // Net name (routing only)
+ IdString net;
+ // From cell.port
+ std::pair<IdString, IdString> from;
+ // To cell.port
+ std::pair<IdString, IdString> to;
+ // Segment delay
+ delay_t delay;
+ // Segment budget (routing only)
+ delay_t budget;
+ };
+
+ // Clock pair
+ ClockPair clock_pair;
+ // Total path delay
+ delay_t delay;
+ // Period (max allowed delay)
+ delay_t period;
+ // Individual path segments
+ std::vector<Segment> segments;
+};
+
+// Holds timing information of a single source to sink path of a net
+struct NetSinkTiming
+{
+ // Clock event pair
+ ClockPair clock_pair;
+ // Cell and port (the sink)
+ std::pair<IdString, IdString> cell_port;
+ // Delay
+ delay_t delay;
+ // Delay budget
+ delay_t budget;
+};
+
+struct TimingResult
+{
+ // Achieved and target Fmax for all clock domains
+ dict<IdString, ClockFmax> clock_fmax;
+ // Single domain critical paths
+ dict<IdString, CriticalPath> clock_paths;
+ // Cross-domain critical paths
+ std::vector<CriticalPath> xclock_paths;
+
+ // Detailed net timing data
+ dict<IdString, std::vector<NetSinkTiming>> detailed_net_timings;
+};
+
+// Represents the contents of a non-leaf cell in a design
+// with hierarchy
+
+struct HierarchicalPort
+{
+ IdString name;
+ PortType dir;
+ std::vector<IdString> nets;
+ int offset;
+ bool upto;
+};
+
+struct HierarchicalCell
+{
+ IdString name, type, parent, fullpath;
+ // Name inside cell instance -> global name
+ dict<IdString, IdString> leaf_cells, nets;
+ // Global name -> name inside cell instance
+ dict<IdString, IdString> leaf_cells_by_gname, nets_by_gname;
+ // Cell port to net
+ dict<IdString, HierarchicalPort> ports;
+ // Name inside cell instance -> global name
+ dict<IdString, IdString> hier_cells;
+};
+
+NEXTPNR_NAMESPACE_END
+
+#endif /* NEXTPNR_TYPES_H */