aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/globals.h
diff options
context:
space:
mode:
authorYRabbit <rabbit@yrabbit.cyou>2022-07-04 10:32:39 +1000
committerYRabbit <rabbit@yrabbit.cyou>2022-07-04 10:32:39 +1000
commit3172a38daeb4588d3aaa686816c09d64ccf08587 (patch)
tree7dd071befb4f13acf4a135984856867fed881531 /gowin/globals.h
parent6d85de43ee1f9585e3c3a170f52513755ed924b5 (diff)
downloadnextpnr-3172a38daeb4588d3aaa686816c09d64ccf08587.tar.gz
nextpnr-3172a38daeb4588d3aaa686816c09d64ccf08587.tar.bz2
nextpnr-3172a38daeb4588d3aaa686816c09d64ccf08587.zip
gowin: Let the placer know about global networks
Refactor in order to detect networks that will be routed in a special mode earlier. This makes it possible to mark the source of such networks as a global buffer, thereby removing their influence on element placement. In addition, timing classes are set for some cells. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
Diffstat (limited to 'gowin/globals.h')
-rw-r--r--gowin/globals.h66
1 files changed, 65 insertions, 1 deletions
diff --git a/gowin/globals.h b/gowin/globals.h
index 41a8727a..69232d7c 100644
--- a/gowin/globals.h
+++ b/gowin/globals.h
@@ -18,10 +18,74 @@
*
*/
+#ifndef GOWIN_GLOBALS_H
+#define GOWIN_GLOBALS_H
+
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
-void route_gowin_globals(Context *ctx);
+class GowinGlobalRouter
+{
+ public:
+ GowinGlobalRouter() {}
+
+ private:
+ // wire -> clock#
+ dict<WireId, int> used_wires;
+
+ // ordered nets
+ struct globalnet_t
+ {
+ IdString name;
+ int clock_ports;
+ BelId clock_io_bel;
+ WireId clock_io_wire; // IO wire if there is one
+ int clock; // clock #
+
+ globalnet_t()
+ {
+ name = IdString();
+ clock_ports = 0;
+ clock_io_bel = BelId();
+ clock_io_wire = WireId();
+ clock = -1;
+ }
+ globalnet_t(IdString _name)
+ {
+ name = _name;
+ clock_ports = 0;
+ clock_io_bel = BelId();
+ clock_io_wire = WireId();
+ clock = -1;
+ }
+
+ // sort
+ bool operator<(const globalnet_t &other) const
+ {
+ if ((clock_io_wire != WireId()) ^ (other.clock_io_wire != WireId())) {
+ return !(clock_io_wire != WireId());
+ }
+ return clock_ports < other.clock_ports;
+ }
+ // search
+ bool operator==(const globalnet_t &other) const { return name == other.name; }
+ };
+
+ // discovered nets
+ std::vector<globalnet_t> nets;
+
+ bool is_clock_port(PortRef const &user);
+ std::pair<WireId, BelId> clock_io(Context *ctx, PortRef const &driver);
+ void gather_clock_nets(Context *ctx, std::vector<globalnet_t> &clock_nets);
+ IdString route_to_non_clock_port(Context *ctx, WireId const dstWire, int clock, pool<IdString> &used_pips,
+ pool<IdString> &undo_wires);
+ void route_net(Context *ctx, globalnet_t const &net);
+
+ public:
+ void mark_globals(Context *ctx);
+ void route_globals(Context *ctx);
+};
NEXTPNR_NAMESPACE_END
+#endif // GOWIN_GLOBALS_H