|
3 | 3 |
|
4 | 4 | #include <string> |
5 | 5 | #include <vector> |
| 6 | +#include <cmath> |
6 | 7 | #include "vtr_ndmatrix.h" |
7 | 8 | #include "physical_types.h" |
8 | 9 |
|
9 | | -///@brief s_grid_tile is the minimum tile of the fpga |
| 10 | +/** |
| 11 | + * @brief s_grid_tile is the minimum tile of the fpga |
| 12 | + * @note This struct shouldn't be directly accessed by other functions. Use the helper functions in DeviceGrid instead. |
| 13 | + */ |
10 | 14 | struct t_grid_tile { |
11 | 15 | t_physical_tile_type_ptr type = nullptr; ///<Pointer to type descriptor, NULL for illegal |
12 | 16 | int width_offset = 0; ///<Number of grid tiles reserved based on width (right) of a block |
13 | 17 | int height_offset = 0; ///<Number of grid tiles reserved based on height (top) of a block |
14 | 18 | const t_metadata_dict* meta = nullptr; |
15 | 19 | }; |
16 | 20 |
|
| 21 | +///@brief DeviceGrid represents the FPGA fabric. It is used to get information about different layers and tiles. |
| 22 | +// TODO: All of the function that use helper functions of this class should pass the layer_num to the functions, and the default value of layer_num should be deleted eventually. |
17 | 23 | class DeviceGrid { |
18 | 24 | public: |
19 | 25 | DeviceGrid() = default; |
20 | | - DeviceGrid(std::string grid_name, vtr::Matrix<t_grid_tile> grid); |
21 | | - DeviceGrid(std::string grid_name, vtr::Matrix<t_grid_tile> grid, std::vector<t_logical_block_type_ptr> limiting_res); |
| 26 | + DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid); |
| 27 | + DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid, std::vector<t_logical_block_type_ptr> limiting_res); |
22 | 28 |
|
23 | 29 | const std::string& name() const { return name_; } |
24 | 30 |
|
25 | | - size_t width() const { return grid_.dim_size(0); } |
26 | | - size_t height() const { return grid_.dim_size(1); } |
| 31 | + ///@brief Return the number of layers(number of dies) |
| 32 | + inline int get_num_layers() const { |
| 33 | + return (int)grid_.dim_size(0); |
| 34 | + } |
27 | 35 |
|
28 | | - //Note: supports 2-d indexing [0..width()-1][0..height()-1] yielding a t_grid_tile |
29 | | - auto operator[](size_t index) const { return grid_[index]; } |
30 | | - auto operator[](size_t index) { return grid_[index]; } |
| 36 | + ///@brief Return the width of the grid at the specified layer |
| 37 | + size_t width() const { return grid_.dim_size(1); } |
| 38 | + ///@brief Return the height of the grid at the specified layer |
| 39 | + size_t height() const { return grid_.dim_size(2); } |
31 | 40 |
|
32 | | - const vtr::Matrix<t_grid_tile>& matrix() const { |
33 | | - return grid_; |
| 41 | + ///@brief Return the size of the flattened grid on the given layer |
| 42 | + inline size_t grid_size() const { |
| 43 | + return grid_.size(); |
34 | 44 | } |
35 | 45 |
|
| 46 | + ///@brief deallocate members of DeviceGrid |
36 | 47 | void clear(); |
37 | 48 |
|
38 | | - size_t num_instances(t_physical_tile_type_ptr type) const; |
| 49 | + /** |
| 50 | + * @brief Return the number of instances of the specified tile type on the specified layer. If the layer_num is -1, return the total number of instances of the specified tile type on all layers. |
| 51 | + * @note This function should be used if count_instances() is called in the constructor. |
| 52 | + */ |
| 53 | + size_t num_instances(t_physical_tile_type_ptr type, int layer_num = 0) const; |
39 | 54 |
|
40 | 55 | /** |
41 | 56 | * @brief Returns the block types which limits the device size (may be empty if |
42 | 57 | * resource limits were not considered when selecting the device). |
43 | 58 | */ |
44 | 59 | std::vector<t_logical_block_type_ptr> limiting_resources() const { return limiting_resources_; } |
45 | 60 |
|
| 61 | + ///@brief Return the t_physical_tile_type_ptr at the specified location |
| 62 | + inline t_physical_tile_type_ptr get_physical_type(size_t x, size_t y, int layer_num = 0) const { |
| 63 | + return grid_[layer_num][x][y].type; |
| 64 | + } |
| 65 | + |
| 66 | + ///@brief Return the width offset of the tile at the specified location. The root location of the tile is where width_offset and height_offset are 0. |
| 67 | + inline int get_width_offset(size_t x, size_t y, int layer_num = 0) const { |
| 68 | + return grid_[layer_num][x][y].width_offset; |
| 69 | + } |
| 70 | + |
| 71 | + ///@brief Return the height offset of the tile at the specified location. The root location of the tile is where width_offset and height_offset are 0 |
| 72 | + inline int get_height_offset(size_t x, size_t y, int layer_num = 0) const { |
| 73 | + return grid_[layer_num][x][y].height_offset; |
| 74 | + } |
| 75 | + |
| 76 | + ///@brief Return the metadata of the tile at the specified location |
| 77 | + inline const t_metadata_dict* get_metadata(size_t x, size_t y, int layer_num = 0) const { |
| 78 | + return grid_[layer_num][x][y].meta; |
| 79 | + } |
| 80 | + |
| 81 | + ///@brief Given t_grid_tile, return the x coordinate of the tile on the given layer - Used by serializer functions |
| 82 | + inline int get_grid_loc_x(const t_grid_tile*& grid_loc) const { |
| 83 | + int layer_num = std::floor(static_cast<int>(grid_loc - &grid_.get(0)) / (width() * height())); |
| 84 | + auto diff = grid_loc - &grid_.get(layer_num * height() * width()); |
| 85 | + |
| 86 | + return diff / grid_.dim_size(2); |
| 87 | + } |
| 88 | + |
| 89 | + ///@brief Given t_grid_tile, return the y coordinate of the tile on the given layer - Used by serializer functions |
| 90 | + inline int get_grid_loc_y(const t_grid_tile*& grid_loc) const { |
| 91 | + int layer_num = std::floor(static_cast<int>(grid_loc - &grid_.get(0)) / (width() * height())); |
| 92 | + auto diff = grid_loc - &grid_.get(layer_num * height() * width()); |
| 93 | + |
| 94 | + return diff % grid_.dim_size(2); |
| 95 | + } |
| 96 | + |
| 97 | + ///@brief Return the nth t_grid_tile on the given layer of the flattened grid - Used by serializer functions |
| 98 | + inline const t_grid_tile* get_grid_locs_grid_loc(int n) const { |
| 99 | + return &grid_.get(n); |
| 100 | + } |
| 101 | + |
46 | 102 | private: |
| 103 | + ///@brief count_instances() counts the number of each tile type on each layer and store it in instance_counts_. It is called in the constructor. |
47 | 104 | void count_instances(); |
48 | 105 |
|
49 | 106 | std::string name_; |
50 | 107 |
|
51 | | - //Note that vtr::Matrix operator[] returns and intermediate type |
52 | | - //which can be used or indexing in the second dimension, allowing |
53 | | - //traditional 2-d indexing to be used |
54 | | - vtr::Matrix<t_grid_tile> grid_; |
| 108 | + /** |
| 109 | + * @brief grid_ is a 3D matrix that represents the grid of the FPGA chip. |
| 110 | + * @note The first dimension is the layer number (grid_[0] corresponds to the bottom layer), the second dimension is the x coordinate, and the third dimension is the y coordinate. |
| 111 | + * @note Note that vtr::Matrix operator[] returns and intermediate type |
| 112 | + * @note which can be used for indexing in the second dimension, allowing |
| 113 | + * @note traditional 2-d indexing to be used |
| 114 | + */ |
| 115 | + vtr::NdMatrix<t_grid_tile, 3> grid_; //This stores the grid of complex blocks. It is a a 3D matrix: [0..num_layers-1][0..grid.width()-1][0..grid_height()-1] |
55 | 116 |
|
56 | | - std::map<t_physical_tile_type_ptr, size_t> instance_counts_; |
| 117 | + ///@brief instance_counts_ stores the number of each tile type on each layer. It is initialized in count_instances(). |
| 118 | + std::vector<std::map<t_physical_tile_type_ptr, size_t>> instance_counts_; /* [layer_num][physical_tile_type_ptr] */ |
57 | 119 |
|
58 | 120 | std::vector<t_logical_block_type_ptr> limiting_resources_; |
59 | 121 | }; |
|
0 commit comments