blob: 9f411872cdf50f676dee785b78bbb221ac3be674 [file] [log] [blame]
#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