blob: 68e60da3824d45c0cfe68a5dc5d5339617dbaeaf [file] [log] [blame]
#ifndef BUILD_SWITCHBLOCKS_H
#define BUILD_SWITCHBLOCKS_H
#include <unordered_map>
#include <vector>
#include <random>
#include "physical_types.h"
#include "vpr_types.h"
#include "device_grid.h"
#include "vtr_random.h"
/************ Classes, structs, typedefs ************/
/* Holds the coordinates of a switch block source connection. Used to index into a
* map which specifies which destination wire segments this source wire should //TODO: what data structure does this index to?
* connect to */
class Switchblock_Lookup {
public:
int x_coord; /* x coordinate of switchblock connection */ //TODO: redundant comment?? add range
int y_coord; /* y coordinate of switchblock connection */
e_side from_side; /* source side of switchblock connection */
e_side to_side; /* destination side of switchblock connection */
/* Empty constructor initializes everything to 0 */
Switchblock_Lookup() {
x_coord = y_coord = -1; //TODO: use set function
}
/* Constructor for initializing member variables */
Switchblock_Lookup(int set_x, int set_y, e_side set_from, e_side set_to) {
this->set_coords(set_x, set_y, set_from, set_to); //TODO: use set function
}
/* Function for setting the segment coordinates */
void set_coords(int set_x, int set_y, e_side set_from, e_side set_to) {
x_coord = set_x;
y_coord = set_y;
from_side = set_from;
to_side = set_to;
}
/* Overload == operator which is used by std::unordered_map */
bool operator==(const Switchblock_Lookup& obj) const {
bool result;
if (x_coord == obj.x_coord && y_coord == obj.y_coord
&& from_side == obj.from_side && to_side == obj.to_side) {
result = true;
} else {
result = false;
}
return result;
}
};
struct t_hash_Switchblock_Lookup {
size_t operator()(const Switchblock_Lookup& obj) const noexcept {
//TODO: use vtr::hash_combine
size_t result;
result = ((((std::hash<int>()(obj.x_coord)
^ std::hash<int>()(obj.y_coord) << 10)
^ std::hash<int>()((int)obj.from_side) << 20)
^ std::hash<int>()((int)obj.to_side) << 30));
return result;
}
};
/* contains the index of the destination wire segment within a channel
* and the index of the switch used to connect to it */
struct t_switchblock_edge {
short from_wire;
short to_wire;
short switch_ind;
};
/* Switchblock connections are made as [x][y][from_side][to_side][from_wire_ind].
* The Switchblock_Lookup class specifies these dimensions.
* Furthermore, a source_wire at a given 5-d coordinate may connect to multiple destination wires so the value
* of the map is a vector of destination wires.
* A matrix specifying connections for all switchblocks in an FPGA would be sparse and possibly very large
* so we use an unordered map to take advantage of the sparsity. */
typedef std::unordered_map<Switchblock_Lookup, std::vector<t_switchblock_edge>, t_hash_Switchblock_Lookup> t_sb_connection_map;
/************ Functions ************/
/* allocate and build switch block permutation map */
t_sb_connection_map* alloc_and_load_switchblock_permutations(const t_chan_details& chan_details_x, const t_chan_details& chan_details_y, const DeviceGrid& grid, std::vector<t_switchblock_inf> switchblocks, t_chan_width* nodes_per_chan, enum e_directionality directionality, vtr::RandState& rand_state);
/* deallocates switch block connections sparse array */
void free_switchblock_permutations(t_sb_connection_map* sb_conns);
#endif