diff options
author | YRabbit <rabbit@yrabbit.cyou> | 2022-07-04 10:32:39 +1000 |
---|---|---|
committer | YRabbit <rabbit@yrabbit.cyou> | 2022-07-04 10:32:39 +1000 |
commit | 3172a38daeb4588d3aaa686816c09d64ccf08587 (patch) | |
tree | 7dd071befb4f13acf4a135984856867fed881531 /gowin/globals.h | |
parent | 6d85de43ee1f9585e3c3a170f52513755ed924b5 (diff) | |
download | nextpnr-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.h | 66 |
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 |