1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
#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;
string variant;
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 row_bias;
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 SpineInfo {
int row;
int down;
};
struct MachXO2GlobalsInfo
{
std::vector<std::vector<int>> ud_conns;
std::vector<SpineInfo> spines;
};
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 part name and variant
explicit Chip(string name, string variant);
// 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;
uint32_t ctrl1 = 0x45000000;
uint32_t sed = 0xffffffff;
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, bool split_slice_mode = false);
vector<vector<vector<pair<string, string>>>> tiles_at_location;
// Generate data needed for MachXO2/3 global routing
MachXO2GlobalsInfo generate_global_info_machxo2();
// Block RAM initialisation (WIP)
map<uint16_t, vector<uint16_t>> bram_data;
// BRAM block data size
int bram_data_size;
// 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, bool split_slice_mode = false);
shared_ptr<RoutingGraph> get_routing_graph_machxo(bool include_lutperm_pips = false, bool split_slice_mode = false);
shared_ptr<RoutingGraph> get_routing_graph_machxo2(bool include_lutperm_pips = false, bool split_slice_mode = false);
};
ChipDelta operator-(const Chip &a, const Chip &b);
}
#endif //LIBTRELLIS_CHIP_HPP
|