| #ifndef LIBTRELLIS_ROUTING_GRAPH_H |
| #define LIBTRELLIS_ROUTING_GRAPH_H |
| |
| #include <unordered_map> |
| #include <map> |
| #include <vector> |
| #include <string> |
| #include <set> |
| #include <boost/functional/hash.hpp> |
| |
| using namespace std; |
| |
| namespace Trellis { |
| typedef int32_t ident_t; |
| |
| struct Location |
| { |
| int16_t x = -1, y = -1; |
| |
| Location() : x(-1), y(-1) |
| {}; |
| |
| Location(int16_t x, int16_t y) : x(x), y(y) |
| {}; |
| |
| Location(const Location &loc) : x(loc.x), y(loc.y) |
| {}; |
| |
| bool operator==(const Location &other) const |
| { return x == other.x && y == other.y; } |
| |
| bool operator!=(const Location &other) const |
| { return x != other.x || y == other.y; } |
| |
| bool operator<(const Location &other) const |
| { return y < other.y || (y == other.y && x < other.x); } |
| }; |
| |
| extern const Location GlobalLoc; |
| |
| inline Location operator+(const Location &a, const Location &b) |
| { return Location(a.x + b.x, a.y + b.y); } |
| |
| struct RoutingId |
| { |
| Location loc; |
| ident_t id = -1; |
| |
| bool operator==(const RoutingId &other) const |
| { return loc == other.loc && id == other.id; } |
| |
| bool operator!=(const RoutingId &other) const |
| { return loc != other.loc || id == other.id; } |
| |
| bool operator<(const RoutingId &other) const |
| { return loc < other.loc || (loc == other.loc && id < other.id); } |
| }; |
| |
| struct RoutingArc |
| { |
| ident_t id = -1; |
| ident_t tiletype = -1; |
| RoutingId source; |
| RoutingId sink; |
| bool configurable = false; |
| mutable int cdb_id = 0; |
| }; |
| |
| struct RoutingWire |
| { |
| ident_t id = -1; |
| vector<RoutingId> uphill; |
| vector<RoutingId> downhill; |
| vector<pair<RoutingId, ident_t>> belsUphill; |
| vector<pair<RoutingId, ident_t>> belsDownhill; |
| mutable int cdb_id = 0; |
| }; |
| |
| inline bool operator==(const RoutingWire &a, const RoutingWire &b) |
| { |
| return a.id == b.id; |
| } |
| |
| enum PortDirection { |
| PORT_IN = 0, |
| PORT_OUT = 1, |
| PORT_INOUT = 2 |
| }; |
| |
| struct RoutingBel |
| { |
| ident_t name, type; |
| Location loc; |
| int z; |
| map<ident_t, pair<RoutingId, PortDirection>> pins; |
| mutable int cdb_id = 0; |
| }; |
| |
| struct RoutingTileLoc |
| { |
| Location loc; |
| map<ident_t, RoutingWire> wires; |
| map<ident_t, RoutingArc> arcs; |
| map<ident_t, RoutingBel> bels; |
| }; |
| |
| |
| inline bool operator==(const RoutingArc &a, const RoutingArc &b) |
| { |
| return a.id == b.id; |
| } |
| |
| class Chip; |
| |
| class IdStore |
| { |
| public: |
| // Core functions |
| ident_t ident(const std::string &str) const; |
| |
| std::string to_str(ident_t id) const; |
| |
| RoutingId id_at_loc(int16_t x, int16_t y, const std::string &str) const; |
| private: |
| |
| private: |
| mutable std::vector<std::string> identifiers; |
| mutable std::unordered_map<std::string, int32_t> str_to_id; |
| }; |
| |
| class RoutingGraph : public IdStore |
| { |
| public: |
| explicit RoutingGraph(const Chip &c); |
| |
| // Must be set up beforehand |
| std::string chip_name; |
| std::string chip_prefix; |
| int max_row, max_col; |
| |
| // Routing tiles |
| std::map<Location, RoutingTileLoc> tiles; |
| |
| // Obtain the unique, global identifier for a net inside a tile using the database name |
| // Returns an empty RoutingId if net is to be ignored |
| RoutingId globalise_net(int row, int col, const std::string &db_name); |
| |
| // Add an arc to the graph, automatically adding nets and cross-references as appropriate |
| void add_arc(Location loc, const RoutingArc &arc); |
| |
| // Add a wire to the graph by id (ignoring it if already existing) |
| void add_wire(RoutingId wire); |
| |
| // Add a Bel to the graph |
| void add_bel(RoutingBel &bel); |
| |
| // Add a Bel input or output pin |
| void add_bel_input(RoutingBel &bel, ident_t pin, int wire_x, int wire_y, ident_t wire_name); |
| void add_bel_output(RoutingBel &bel, ident_t pin, int wire_x, int wire_y, ident_t wire_name); |
| }; |
| } |
| |
| namespace std { |
| template <> struct hash <Trellis::Location> |
| { |
| std::size_t operator()(const Trellis::Location &loc) const noexcept |
| { |
| std::size_t seed = 0; |
| boost::hash_combine(seed, hash<int>()(loc.x)); |
| boost::hash_combine(seed, hash<int>()(loc.y)); |
| return seed; |
| } |
| }; |
| } |
| |
| |
| #endif |