blob: 3d0b749074329096e104a8c585b753690ab5f24e [file] [log] [blame]
#ifndef LIBTRELLIS_CHIP_HPP
#define LIBTRELLIS_CHIP_HPP
#include <string>
#include <memory>
#include <vector>
#include <cstdint>
#include <map>
#include <set>
#include "CRAM.hpp"
using namespace std;
namespace Trellis {
// Basic information about a chip that may be needed elsewhere
struct ChipInfo
{
string name;
string family;
uint32_t idcode;
int num_frames;
int bits_per_frame;
int pad_bits_before_frame;
int pad_bits_after_frame;
// 0-based.
int max_row;
int max_col;
// Trellis uses 0-based indexing, but some devices don't.
int col_bias;
};
// Information about the global networks in a chip
struct GlobalRegion
{
string name;
int x0, y0, x1, y1;
bool matches(int row, int col) const;
};
inline bool operator==(const GlobalRegion &a, const GlobalRegion &b)
{
return (a.name == b.name) && (a.x0 == b.x0) && (a.x1 == b.x1) && (a.y0 == b.y0) && (a.y1 == b.y1);
}
struct TapSegment
{
int tap_col;
int lx0, lx1, rx0, rx1;
bool matches_left(int row, int col) const;
bool matches_right(int row, int col) const;
};
inline bool operator==(const TapSegment &a, const TapSegment &b)
{
return (a.tap_col == b.tap_col) && (a.lx0 == b.lx0) && (a.lx1 == b.lx1) && (a.rx0 == b.rx0) && (a.rx1 == b.rx1);
}
struct TapDriver
{
int col;
enum TapDir
{
LEFT,
RIGHT
} dir;
};
struct SpineSegment
{
int tap_col;
string quadrant;
int spine_row, spine_col;
};
struct Ecp5GlobalsInfo
{
vector<GlobalRegion> quadrants;
vector<TapSegment> tapsegs;
vector<SpineSegment> spinesegs;
string get_quadrant(int row, int col) const;
TapDriver get_tap_driver(int row, int col) const;
pair<int, int> get_spine_driver(std::string quadrant, int col);
};
struct LeftRightConn
{
string name;
int row;
std::pair<int, int> row_span;
};
inline bool operator==(const LeftRightConn &a, const LeftRightConn &b)
{
return (a.name == b.name) && (a.row == b.row) && (a.row_span == b.row_span);
}
// Some columns contain global routing which EPIC shows as missing DCCA
// primitives between L/R and U/D connections. None of the DCCs between these
// connections appear to physically exist on-chip. However, the bitstream
// does appear to treat them specially, so keep this info around.
struct MissingDccs
{
int row;
std::vector<int> missing;
};
inline bool operator==(const MissingDccs &a, const MissingDccs &b)
{
return (a.row == b.row) && (a.missing == b.missing);
}
struct MachXO2GlobalsInfo
{
std::vector<LeftRightConn> lr_conns;
std::vector<std::vector<int>> ud_conns;
std::vector<std::vector<pair<int, int>>> branch_spans;
std::vector<MissingDccs> missing_dccs;
};
class Tile;
// A difference between two Chips
// A list of pairs mapping between tile identifier (name:type) and tile difference
typedef map<string, CRAMDelta> ChipDelta;
class RoutingGraph;
class Chip
{
public:
// Construct a chip by looking up part name
explicit Chip(string name);
// Construct a chip by looking up device ID
explicit Chip(uint32_t idcode);
// Construct a chip from a ChipInfo
explicit Chip(const ChipInfo &info);
// Basic information about a chip
ChipInfo info;
// The chip's configuration memory
CRAM cram;
// Tile access
shared_ptr<Tile> get_tile_by_name(string name);
vector<shared_ptr<Tile>> get_tiles_by_position(int row, int col);
vector<shared_ptr<Tile>> get_tiles_by_type(string type);
vector<shared_ptr<Tile>> get_all_tiles();
string get_tile_by_position_and_type(int row, int col, string type);
string get_tile_by_position_and_type(int row, int col, set<string> type);
// Map tile name to a tile reference
map<string, shared_ptr<Tile>> tiles;
// Miscellaneous information
uint32_t usercode = 0x0;
uint32_t ctrl0 = 0x40000000;
vector<string> metadata;
// Get max row and column
int get_max_row() const;
int get_max_col() const;
// Build the routing graph for the chip
shared_ptr<RoutingGraph> get_routing_graph(bool include_lutperm_pips = false);
vector<vector<vector<pair<string, string>>>> tiles_at_location;
// Block RAM initialisation (WIP)
map<uint16_t, vector<uint16_t>> bram_data;
// Globals data- Should be a variant, but I couldn't get boost::python
// to behave with boost::variant.
Ecp5GlobalsInfo global_data_ecp5;
MachXO2GlobalsInfo global_data_machxo2;
private:
// Factory functions
shared_ptr<RoutingGraph> get_routing_graph_ecp5(bool include_lutperm_pips = false);
shared_ptr<RoutingGraph> get_routing_graph_machxo2();
};
ChipDelta operator-(const Chip &a, const Chip &b);
}
#endif //LIBTRELLIS_CHIP_HPP