Skip to content

Commit 1fa012b

Browse files
authored
Merge pull request #2259 from verilog-to-routing/modeling_multi_die_stack
Modeling multi die stack
2 parents 7e35660 + fd9322f commit 1fa012b

File tree

66 files changed

+49552
-722
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+49552
-722
lines changed

libs/libarchfpga/src/device_grid.cpp

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,43 @@
11
#include "device_grid.h"
22

3-
DeviceGrid::DeviceGrid(std::string grid_name, vtr::Matrix<t_grid_tile> grid)
3+
DeviceGrid::DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid)
44
: name_(grid_name)
55
, grid_(grid) {
66
count_instances();
77
}
88

9-
DeviceGrid::DeviceGrid(std::string grid_name, vtr::Matrix<t_grid_tile> grid, std::vector<t_logical_block_type_ptr> limiting_res)
9+
DeviceGrid::DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid, std::vector<t_logical_block_type_ptr> limiting_res)
1010
: DeviceGrid(grid_name, grid) {
1111
limiting_resources_ = limiting_res;
1212
}
1313

14-
size_t DeviceGrid::num_instances(t_physical_tile_type_ptr type) const {
15-
auto iter = instance_counts_.find(type);
16-
if (iter != instance_counts_.end()) {
17-
//Return count
18-
return iter->second;
14+
size_t DeviceGrid::num_instances(t_physical_tile_type_ptr type, int layer_num) const {
15+
size_t count = 0;
16+
//instance_counts_ is not initialized
17+
if (instance_counts_.empty()) {
18+
return 0;
1919
}
20-
return 0; //None found
20+
21+
int num_layers = (int)grid_.dim_size(0);
22+
23+
if (layer_num == -1) {
24+
//Count all layers
25+
for (int curr_layer_num = 0; curr_layer_num < num_layers; ++curr_layer_num) {
26+
auto iter = instance_counts_[curr_layer_num].find(type);
27+
if (iter != instance_counts_[curr_layer_num].end()) {
28+
count += iter->second;
29+
}
30+
}
31+
return count;
32+
} else {
33+
auto iter = instance_counts_[layer_num].find(type);
34+
if (iter != instance_counts_[layer_num].end()) {
35+
//Return count
36+
count = iter->second;
37+
}
38+
}
39+
40+
return count;
2141
}
2242

2343
void DeviceGrid::clear() {
@@ -26,16 +46,34 @@ void DeviceGrid::clear() {
2646
}
2747

2848
void DeviceGrid::count_instances() {
49+
int num_layers = (int)grid_.dim_size(0);
2950
instance_counts_.clear();
51+
instance_counts_.resize(num_layers);
52+
53+
//Initialize the instance counts
54+
for (int layer_num = 0; layer_num < num_layers; ++layer_num) {
55+
for (size_t x = 0; x < width(); ++x) {
56+
for (size_t y = 0; y < height(); ++y) {
57+
auto type = grid_[layer_num][x][y].type;
58+
59+
if (grid_[layer_num][x][y].width_offset == 0 && grid_[layer_num][x][y].height_offset == 0) {
60+
//Add capacity only if this is the root location
61+
instance_counts_[layer_num][type] = 0;
62+
}
63+
}
64+
}
65+
}
3066

3167
//Count the number of blocks in the grid
32-
for (size_t x = 0; x < width(); ++x) {
33-
for (size_t y = 0; y < height(); ++y) {
34-
auto type = grid_[x][y].type;
68+
for (int layer_num = 0; layer_num < num_layers; ++layer_num) {
69+
for (size_t x = 0; x < width(); ++x) {
70+
for (size_t y = 0; y < height(); ++y) {
71+
auto type = grid_[layer_num][x][y].type;
3572

36-
if (grid_[x][y].width_offset == 0 && grid_[x][y].height_offset == 0) {
37-
//Add capacity only if this is the root location
38-
instance_counts_[type] += type->capacity;
73+
if (grid_[layer_num][x][y].width_offset == 0 && grid_[layer_num][x][y].height_offset == 0) {
74+
//Add capacity only if this is the root location
75+
instance_counts_[layer_num][type] += type->capacity;
76+
}
3977
}
4078
}
4179
}

libs/libarchfpga/src/device_grid.h

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,119 @@
33

44
#include <string>
55
#include <vector>
6+
#include <cmath>
67
#include "vtr_ndmatrix.h"
78
#include "physical_types.h"
89

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+
*/
1014
struct t_grid_tile {
1115
t_physical_tile_type_ptr type = nullptr; ///<Pointer to type descriptor, NULL for illegal
1216
int width_offset = 0; ///<Number of grid tiles reserved based on width (right) of a block
1317
int height_offset = 0; ///<Number of grid tiles reserved based on height (top) of a block
1418
const t_metadata_dict* meta = nullptr;
1519
};
1620

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.
1723
class DeviceGrid {
1824
public:
1925
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);
2228

2329
const std::string& name() const { return name_; }
2430

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+
}
2735

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); }
3140

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();
3444
}
3545

46+
///@brief deallocate members of DeviceGrid
3647
void clear();
3748

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;
3954

4055
/**
4156
* @brief Returns the block types which limits the device size (may be empty if
4257
* resource limits were not considered when selecting the device).
4358
*/
4459
std::vector<t_logical_block_type_ptr> limiting_resources() const { return limiting_resources_; }
4560

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+
46102
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.
47104
void count_instances();
48105

49106
std::string name_;
50107

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]
55116

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] */
57119

58120
std::vector<t_logical_block_type_ptr> limiting_resources_;
59121
};

libs/libarchfpga/src/physical_types.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,10 @@ enum GridDefType {
374374
FIXED
375375
};
376376

377+
struct t_layer_def {
378+
std::vector<t_grid_loc_def> loc_defs; //The list of block location definitions for this layer specification
379+
};
380+
377381
struct t_grid_def {
378382
GridDefType grid_type = GridDefType::AUTO; //The type of this grid specification
379383

@@ -384,8 +388,7 @@ struct t_grid_def {
384388

385389
float aspect_ratio = 1.; //Aspect ratio for auto-sized devices (only valid for
386390
//grid_type == AUTO)
387-
388-
std::vector<t_grid_loc_def> loc_defs; //The list of grid location definitions for this grid specification
391+
std::vector<t_layer_def> layers;
389392
};
390393

391394
/************************* POWER ***********************************/

libs/libarchfpga/src/read_fpga_interchange_arch.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,8 @@ struct ArchReader {
22432243

22442244
for (auto name : packages) {
22452245
t_grid_def grid_def;
2246+
int num_layers = 1;
2247+
grid_def.layers.resize(num_layers);
22462248
grid_def.width = grid_def.height = 0;
22472249
for (auto tile : tiles) {
22482250
grid_def.width = std::max(grid_def.width, tile.getCol() + 1);
@@ -2293,7 +2295,7 @@ struct ArchReader {
22932295

22942296
single.owned_meta = std::make_unique<t_metadata_dict>(data);
22952297
single.meta = single.owned_meta.get();
2296-
grid_def.loc_defs.emplace_back(std::move(single));
2298+
grid_def.layers.at(num_layers - 1).loc_defs.emplace_back(std::move(single));
22972299
}
22982300

22992301
// The constant source tile will be placed at (0, 0)
@@ -2304,7 +2306,7 @@ struct ArchReader {
23042306
constant.x.end_expr = constant.x.start_expr + " + w - 1";
23052307
constant.y.end_expr = constant.y.start_expr + " + h - 1";
23062308

2307-
grid_def.loc_defs.emplace_back(std::move(constant));
2309+
grid_def.layers.at(num_layers - 1).loc_defs.emplace_back(std::move(constant));
23082310

23092311
arch_->grid_layouts.emplace_back(std::move(grid_def));
23102312
}

0 commit comments

Comments
 (0)