Skip to content

Commit 5ce9800

Browse files
Merge pull request #3299 from verilog-to-routing/temp_interposer_cut_dim
Draw interposer cuts
2 parents 269e85c + cd2381e commit 5ce9800

29 files changed

+324
-150
lines changed

doc/src/arch/reference.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,10 +582,12 @@ Grid Layout Example
582582
Example FPGA grid
583583
584584
585-
.. arch:tag:: <interposer_cut dim=x|y loc="int"/>
585+
.. arch:tag:: <interposer_cut x="int" y="int"/>
586586
587-
:req_param dim: Dimension or axis of the cut. 'X' or 'x' means a horizontal cut while 'Y' or 'y' means a vertical cut.
588-
:req_param loc: Location of the cut. Cuts are done above or to the right of the tiles at coordinate 'loc'. For example a cut with dim=x and loc=0 would cut the vertical wires above tiles in the 0th row. Currently only integer values are supported.
587+
:opt_param x: Specifies the x-coordinate of a vertical interposer cut.
588+
:opt_param y: Specifies the y-coordinate of a horizontal interposer cut.
589+
590+
.. note:: Exactly one of the ``x`` or ``y`` attributes must be specified.
589591
590592
.. note:: Interposers are experimental and are currently not supported by VPR and using the related tags will not actually result in any changes to the flow.
591593
Defines an interposer cut for modelling 2.5D interposer-based architectures. An interposer cut will cut all connections at location 'loc' along the axis 'dim' Leaving the two sides completely unconnected.

libs/libarchfpga/src/device_grid.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
#include <utility>
44

5-
DeviceGrid::DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid)
6-
: name_(std::move(grid_name))
7-
, grid_(std::move(grid)) {
5+
DeviceGrid::DeviceGrid(std::string_view grid_name,
6+
vtr::NdMatrix<t_grid_tile, 3> grid,
7+
std::vector<std::vector<int>>&& horizontal_interposer_cuts,
8+
std::vector<std::vector<int>>&& vertical_interposer_cuts)
9+
: name_(grid_name)
10+
, grid_(std::move(grid))
11+
, horizontal_interposer_cuts_(std::move(horizontal_interposer_cuts))
12+
, vertical_interposer_cuts_(std::move(vertical_interposer_cuts)) {
813
count_instances();
914
}
1015

11-
DeviceGrid::DeviceGrid(std::string grid_name,
16+
DeviceGrid::DeviceGrid(std::string_view grid_name,
1217
vtr::NdMatrix<t_grid_tile, 3> grid,
13-
std::vector<t_logical_block_type_ptr> limiting_res)
14-
: DeviceGrid(std::move(grid_name), std::move(grid)) {
18+
std::vector<t_logical_block_type_ptr> limiting_res,
19+
std::vector<std::vector<int>>&& horizontal_interposer_cuts,
20+
std::vector<std::vector<int>>&& vertical_interposer_cuts)
21+
: DeviceGrid(grid_name, std::move(grid), std::move(horizontal_interposer_cuts), std::move(vertical_interposer_cuts)) {
1522
limiting_resources_ = std::move(limiting_res);
1623
}
1724

libs/libarchfpga/src/device_grid.h

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,16 @@ struct t_grid_tile {
2626
class DeviceGrid {
2727
public:
2828
DeviceGrid() = default;
29-
DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid);
30-
DeviceGrid(std::string grid_name, vtr::NdMatrix<t_grid_tile, 3> grid, std::vector<t_logical_block_type_ptr> limiting_res);
29+
DeviceGrid(std::string_view grid_name,
30+
vtr::NdMatrix<t_grid_tile, 3> grid,
31+
std::vector<std::vector<int>>&& horizontal_interposer_cuts,
32+
std::vector<std::vector<int>>&& vertical_interposer_cuts);
33+
34+
DeviceGrid(std::string_view grid_name,
35+
vtr::NdMatrix<t_grid_tile, 3> grid,
36+
std::vector<t_logical_block_type_ptr> limiting_res,
37+
std::vector<std::vector<int>>&& horizontal_interposer_cuts,
38+
std::vector<std::vector<int>>&& vertical_interposer_cuts);
3139

3240
const std::string& name() const { return name_; }
3341

@@ -63,7 +71,7 @@ class DeviceGrid {
6371
* @brief Returns the block types which limits the device size (may be empty if
6472
* resource limits were not considered when selecting the device).
6573
*/
66-
std::vector<t_logical_block_type_ptr> limiting_resources() const { return limiting_resources_; }
74+
const std::vector<t_logical_block_type_ptr>& limiting_resources() const { return limiting_resources_; }
6775

6876
///@brief Return the t_physical_tile_type_ptr at the specified location
6977
inline t_physical_tile_type_ptr get_physical_type(const t_physical_tile_loc& tile_loc) const {
@@ -189,15 +197,31 @@ class DeviceGrid {
189197
return &grid_.get(n);
190198
}
191199

200+
/// Returns the list of horizontal interposer cut locations for each layer,
201+
/// i.e. y value of the tile row just below each cut
202+
/// Accessed as [layer][cut_idx]
203+
inline const std::vector<std::vector<int>>& get_horizontal_interposer_cuts() const {
204+
return horizontal_interposer_cuts_;
205+
}
206+
207+
/// Returns the list of vertical interposer cut locations for each layer,
208+
/// i.e. x value of the tile column just to the left each cut
209+
/// Accessed as [layer][cut_idx]
210+
inline const std::vector<std::vector<int>>& get_vertical_interposer_cuts() const {
211+
return vertical_interposer_cuts_;
212+
}
213+
192214
private:
193-
///@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.
215+
/// @brief Counts the number of each tile type on each layer and store it in instance_counts_.
216+
/// It is called in the constructor.
194217
void count_instances();
195218

196219
std::string name_;
197220

198221
/**
199222
* @brief grid_ is a 3D matrix that represents the grid of the FPGA chip.
200-
* @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.
223+
* @note The first dimension is the layer number (grid_[0] corresponds to the bottom layer),
224+
* the second dimension is the x coordinate, and the third dimension is the y coordinate.
201225
* @note Note that vtr::Matrix operator[] returns and intermediate type
202226
* @note which can be used for indexing in the second dimension, allowing
203227
* @note traditional 2-d indexing to be used
@@ -208,4 +232,13 @@ class DeviceGrid {
208232
std::vector<std::map<t_physical_tile_type_ptr, size_t>> instance_counts_; /* [layer_num][physical_tile_type_ptr] */
209233

210234
std::vector<t_logical_block_type_ptr> limiting_resources_;
235+
236+
/// Horizontal interposer cut locations in each layer,
237+
/// i.e. y value of the tile row just below each cut
238+
/// Accessed as [layer][cut_idx]
239+
std::vector<std::vector<int>> horizontal_interposer_cuts_;
240+
/// Vertical interposer cut location in each layer,
241+
/// i.e. x value of the tile column just to the left each cut
242+
/// Accessed as [layer][cut_idx]
243+
std::vector<std::vector<int>> vertical_interposer_cuts_;
211244
};

libs/libarchfpga/src/interposer_types.h

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,20 @@
44
* @file interposer_types.h
55
* @brief This file contains types used for parsing interposer-related tags such as <interposer_cut> and <interdie_wire>
66
* and converting that information into the device architecture-related data structures.
7-
*
87
*/
98

10-
#include <unordered_map>
119
#include <vector>
1210
#include <string>
1311
#include "grid_types.h"
1412

15-
/**
16-
* @brief Enum for direction of an interposer cut. X means horizontal cut and Y means vertical cut.
17-
*
18-
*/
19-
enum class e_interposer_cut_dim {
20-
X,
21-
Y
13+
/// @brief Enum for direction of an interposer cut.
14+
enum class e_interposer_cut_type {
15+
HORZ,
16+
VERT
2217
};
2318

24-
// Lookup table for converting between a character and an e_interposer_cut_dim
25-
inline const std::unordered_map<char, e_interposer_cut_dim> CHAR_INTERPOSER_DIM_MAP = {
26-
{'X', e_interposer_cut_dim::X},
27-
{'x', e_interposer_cut_dim::X},
28-
{'Y', e_interposer_cut_dim::Y},
29-
{'y', e_interposer_cut_dim::Y}};
30-
3119
/**
3220
* @brief Struct containing information of interdire wires i.e. connections between the dies on an interposer
33-
*
3421
*/
3522
struct t_interdie_wire_inf {
3623
std::string sg_name; ///< Name of the scatter-gather pattern to be used for the interdie connection
@@ -40,18 +27,18 @@ struct t_interdie_wire_inf {
4027
* Contains starting and ending point (both inclusive) of scatter-gather instantiations and the increment/distance between the instantiations.
4128
* offset_definition.repeat_expr is not relevant for interdie wires and is not set to anything or used.
4229
*
43-
* Locations defined by this offset definition define the starting point or the gathering point of the SG pattern. The end or scatter point of the SG pattern is defined by the sg_link.
30+
* Locations defined by this offset definition define the starting point or the gathering point of the SG pattern.
31+
* The end or scatter point of the SG pattern is defined by the sg_link.
4432
*/
4533
t_grid_loc_spec offset_definition;
4634
int num; ///< Number of scatter-gather instantiations per switchblock location
4735
};
4836

4937
/**
5038
* @brief Struct containing information of an interposer cut
51-
*
5239
*/
5340
struct t_interposer_cut_inf {
54-
e_interposer_cut_dim dim; ///< Dimension or axis of interposer cut.
41+
e_interposer_cut_type dim; ///< Axis of interposer cut location. The cut is perpendicular to this axis. This specifies the dimension of `loc`.
5542
int loc; ///< Location of the cut on the grid. Locations start from zero and cuts will happen above or to the right of the tiles at location=loc.
5643
std::vector<t_interdie_wire_inf> interdie_wires; ///< Connectivity specification between the two sides of the cut.
5744
};

libs/libarchfpga/src/physical_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ enum e_power_estimation_method_ {
241241
POWER_METHOD_SPECIFY_SIZES, /* Transistor-level, user-specified buffers/wires */
242242
POWER_METHOD_TOGGLE_PINS, /* Dynamic: Energy per pin toggle, Static: Absolute */
243243
POWER_METHOD_C_INTERNAL, /* Dynamic: Equiv. Internal capacitance, Static: Absolute */
244-
POWER_METHOD_ABSOLUTE /* Dynamic: Aboslute, Static: Absolute */
244+
POWER_METHOD_ABSOLUTE /* Dynamic: Absolute, Static: Absolute */
245245
};
246246
typedef enum e_power_estimation_method_ e_power_estimation_method;
247247
typedef enum e_power_estimation_method_ t_power_estimation_method;

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2661,7 +2661,8 @@ static void process_block_type_locs(t_grid_def& grid_def,
26612661

26622662
t_interposer_cut_inf interposer_cut = parse_interposer_cut_tag(loc_spec_tag, loc_data);
26632663

2664-
if ((interposer_cut.dim == e_interposer_cut_dim::X && interposer_cut.loc >= grid_def.height) || (interposer_cut.dim == e_interposer_cut_dim::Y && interposer_cut.loc >= grid_def.width)) {
2664+
if ((interposer_cut.dim == e_interposer_cut_type::VERT && interposer_cut.loc >= grid_def.width)
2665+
|| (interposer_cut.dim == e_interposer_cut_type::HORZ && interposer_cut.loc >= grid_def.height)) {
26652666
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer cut dimensions are outside of device bounds");
26662667
}
26672668

libs/libarchfpga/src/read_xml_arch_file_interposer.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "read_xml_arch_file_interposer.h"
2+
23
#include <vector>
4+
35
#include "interposer_types.h"
46
#include "read_xml_util.h"
57
#include "pugixml_util.hpp"
@@ -8,24 +10,37 @@
810
t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, const pugiutil::loc_data& loc_data) {
911
t_interposer_cut_inf interposer;
1012

11-
pugiutil::expect_only_attributes(interposer_cut_tag, {"dim", "loc"}, loc_data);
13+
pugiutil::expect_only_attributes(interposer_cut_tag, {"x", "y"}, loc_data);
14+
15+
const int x = pugiutil::get_attribute(interposer_cut_tag, "x", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(ARCH_FPGA_UNDEFINED_VAL);
16+
const int y = pugiutil::get_attribute(interposer_cut_tag, "y", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(ARCH_FPGA_UNDEFINED_VAL);
1217

13-
std::string interposer_dim = pugiutil::get_attribute(interposer_cut_tag, "dim", loc_data).as_string();
14-
if (interposer_dim.size() != 1 || !CHAR_INTERPOSER_DIM_MAP.contains(interposer_dim[0])) {
15-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), "Interposer tag dimension must be a single character of either X, x, Y or y.");
18+
// Both x and y are specified
19+
if (x != ARCH_FPGA_UNDEFINED_VAL && y != ARCH_FPGA_UNDEFINED_VAL) {
20+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag),
21+
"Interposer cut tag must specify where the cut is to appear using only one of `x` or `y` attributes.");
1622
}
1723

18-
interposer.dim = CHAR_INTERPOSER_DIM_MAP.at(interposer_dim[0]);
24+
if (x != ARCH_FPGA_UNDEFINED_VAL) {
25+
interposer.loc = x;
26+
interposer.dim = e_interposer_cut_type::VERT;
27+
} else if (y != ARCH_FPGA_UNDEFINED_VAL) {
28+
interposer.loc = y;
29+
interposer.dim = e_interposer_cut_type::HORZ;
30+
} else {
31+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag),
32+
"Interposer cut tag must specify where the cut is to appear using `x` or `y` attributes.");
33+
}
1934

20-
interposer.loc = pugiutil::get_attribute(interposer_cut_tag, "loc", loc_data).as_int();
21-
if (interposer.loc < 0) {
22-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), "Interposer location must be positive.");
35+
if (interposer.loc <= 0) {
36+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag),
37+
"Interposer cut location must be a positive number.");
2338
}
2439

2540
pugiutil::expect_only_children(interposer_cut_tag, {"interdie_wire"}, loc_data);
2641

2742
for (pugi::xml_node interdie_wire_tag : interposer_cut_tag.children()) {
28-
const std::vector<std::string> interdie_wire_attributes = {{"sg_name", "sg_link", "offset_start", "offset_end", "offset_increment", "num"}};
43+
const std::vector<std::string> interdie_wire_attributes = {"sg_name", "sg_link", "offset_start", "offset_end", "offset_increment", "num"};
2944
pugiutil::expect_only_attributes(interdie_wire_tag, interdie_wire_attributes, loc_data);
3045

3146
t_interdie_wire_inf interdie_wire;
@@ -39,6 +54,11 @@ t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag,
3954

4055
interdie_wire.num = pugiutil::get_attribute(interdie_wire_tag, "num", loc_data).as_int();
4156

57+
if (interdie_wire.num <= 0) {
58+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(interdie_wire_tag),
59+
"The `num` attribute of an `interdie_wire` must be specified with a positive number.");
60+
}
61+
4262
interposer.interdie_wires.push_back(interdie_wire);
4363
}
4464

0 commit comments

Comments
 (0)