Skip to content

Commit 31c1cb1

Browse files
[SQUASHME] More code polish
1 parent 01a12d2 commit 31c1cb1

File tree

5 files changed

+118
-50
lines changed

5 files changed

+118
-50
lines changed

libs/libarchfpga/src/interposer_types.h

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,51 @@
11
#pragma once
22

3+
/**
4+
* @file interposer_types.h
5+
* @brief This file contains types used for parsing interposer-related tags such as <interposer_cut> and <interdie_wire>
6+
* and converting that information into the device architecture-related data structures.
7+
*
8+
*/
9+
310
#include <unordered_map>
411
#include <vector>
512
#include <string>
6-
#include "vtr_vector.h"
713

14+
/**
15+
* @brief Enum for direction of an interposer cut. X means horizontal cut and Y means vertical cut.
16+
*
17+
*/
818
enum class e_interposer_cut_dim {
919
X,
1020
Y
1121
};
1222

23+
// Lookup table for converting between a character and an e_interposer_cut_dim
1324
inline const std::unordered_map<char, e_interposer_cut_dim> CHAR_INTERPOSER_DIM_MAP = {
1425
{'X', e_interposer_cut_dim::X},
1526
{'x', e_interposer_cut_dim::X},
1627
{'Y', e_interposer_cut_dim::Y},
1728
{'y', e_interposer_cut_dim::Y}};
1829

30+
/**
31+
* @brief Struct containing information of interdire wires i.e. connections between the dies on an interposer
32+
*
33+
*/
1934
struct t_interdie_wire_inf {
20-
std::string sg_name;
21-
std::string sg_offset;
22-
int offset_start;
23-
int offset_end;
24-
int offset_incr;
25-
int offset_num;
35+
std::string sg_name; ///< Name of the scatter-gather pattern to be used for the interdie connection
36+
std::string sg_link; ///< Name of the scatter-gather link to be used for the interdie connection
37+
int offset_start; ///< Starting point of scatter-gather instantiations
38+
int offset_end; ///< Ending point of scatter-gather instantiations
39+
int offset_increment; ///< Increment/distance between scatter-gather instantiations
40+
int num; ///< Number of scatter-gather instantiations per switchblock location
2641
};
2742

43+
/**
44+
* @brief Struct containing information of an interposer cut
45+
*
46+
*/
2847
struct t_interposer_cut_inf {
29-
e_interposer_cut_dim dim; // find an enum with x and y
30-
int loc; // handle expressions
31-
std::vector<t_interdie_wire_inf> interdie_wires;
48+
e_interposer_cut_dim dim; ///< Dimension or axis of interposer cut
49+
int loc; ///< Location of the cut on the grid
50+
std::vector<t_interdie_wire_inf> interdie_wires; ///< Connectivity specification between the two sides of the cut
3251
};
33-

libs/libarchfpga/src/physical_types.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <limits>
3737
#include <unordered_set>
3838

39+
#include "interposer_types.h"
3940
#include "vtr_ndmatrix.h"
4041
#include "vtr_bimap.h"
4142
#include "vtr_string_interning.h"
@@ -361,13 +362,14 @@ struct t_grid_loc_def {
361362
// that come from a common definition.
362363
};
363364

364-
enum GridDefType {
365+
enum class GridDefType {
365366
AUTO,
366367
FIXED
367368
};
368369

369370
struct t_layer_def {
370-
std::vector<t_grid_loc_def> loc_defs; //The list of block location definitions for this layer specification
371+
std::vector<t_grid_loc_def> loc_defs; ///< List of block location definitions for this layer specification
372+
std::vector<t_interposer_cut_inf> interposer_cuts; ///< List of interposer cuts in this layer
371373
};
372374

373375
struct t_grid_def {

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "pugixml.hpp"
5050
#include "pugixml_util.hpp"
5151

52+
#include "read_xml_arch_file_interposer.h"
5253
#include "read_xml_arch_file_vib.h"
5354
#include "vtr_assert.h"
5455
#include "vtr_log.h"
@@ -2620,7 +2621,7 @@ static t_grid_def process_grid_layout(vtr::string_internment& strings,
26202621
if (has_layer) {
26212622
// TODO ASSERT INTERPOSER
26222623
std::unordered_set<int> seen_die_numbers; //Check that die numbers in the specific layout tag are unique
2623-
for (auto layer_child : layout_type_tag.children("layer")) {
2624+
for (pugi::xml_node layer_child : layout_type_tag.children("layer")) {
26242625

26252626
// More than one layer tag is specified, meaning that multi-die FPGA is specified in the arch file
26262627
// Need to process each <layer> tag children to get block types locations for each grid
@@ -2651,6 +2652,26 @@ static void process_block_type_locs(t_grid_def& grid_def,
26512652
//Process all the block location specifications
26522653
for (pugi::xml_node loc_spec_tag : layout_block_type_tag.children()) {
26532654
const char* loc_type = loc_spec_tag.name();
2655+
2656+
// There are multiple attributes that are shared by every other tag that interposer
2657+
// tags do not have. For this reason we check if loc_spec_tag is an interposer tag
2658+
// and switch code paths if it is.
2659+
if (loc_type == std::string("interposer_cut")) {
2660+
if (grid_def.grid_type == GridDefType::AUTO) {
2661+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposers are not currently supported for auto sized devices.");
2662+
}
2663+
2664+
t_interposer_cut_inf interposer_cut = parse_interposer_cut_tag(loc_spec_tag, loc_data);
2665+
2666+
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)) {
2667+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer cut dimensions are outside of device bounds");
2668+
}
2669+
2670+
grid_def.layers.at(die_number).interposer_cuts.push_back(interposer_cut);
2671+
continue;
2672+
}
2673+
2674+
// Continue parsing for non-interposer tags
26542675
const char* type_name = get_attribute(loc_spec_tag, "type", loc_data).value();
26552676
int priority = get_attribute(loc_spec_tag, "priority", loc_data).as_int();
26562677
t_metadata_dict meta = process_meta_data(strings, loc_spec_tag, loc_data);
@@ -2872,42 +2893,6 @@ static void process_block_type_locs(t_grid_def& grid_def,
28722893
region.meta = region.owned_meta.get();
28732894

28742895
grid_def.layers.at(die_number).loc_defs.emplace_back(std::move(region));
2875-
} else if (loc_type == std::string("interposer_cut")) {
2876-
t_interposer_cut_inf interposer;
2877-
pugiutil::expect_only_attributes(loc_spec_tag, {"dim", "loc"}, loc_data);
2878-
2879-
std::string interposer_dim = pugiutil::get_attribute(loc_spec_tag, "dim", loc_data).as_string();
2880-
if (interposer_dim.size() != 1 || !CHAR_INTERPOSER_DIM_MAP.contains(interposer_dim[0])) {
2881-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer tag dimension must be a single character of either X, x, Y or y.");
2882-
}
2883-
2884-
interposer.dim = CHAR_INTERPOSER_DIM_MAP.at(interposer_dim[0]);
2885-
2886-
interposer.loc = pugiutil::get_attribute(loc_spec_tag, "loc", loc_data).as_int();
2887-
if (interposer.loc < 0) {
2888-
// TODO: should also check if it's inside device bounds
2889-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer location must be positive.");
2890-
}
2891-
2892-
pugiutil::expect_only_children(loc_spec_tag, {"interdie_wire"}, loc_data);
2893-
2894-
for (pugi::xml_node interdie_wire_tag : loc_spec_tag.children()) {
2895-
pugiutil::expect_only_attributes(interdie_wire_tag, {"sg", "sg_offset"}, loc_data);
2896-
2897-
t_interdie_wire_inf interdie_wire;
2898-
2899-
interdie_wire.sg_name = pugiutil::get_attribute(interdie_wire_tag, "sg_name", loc_data).as_string();
2900-
interdie_wire.sg_offset = pugiutil::get_attribute(interdie_wire_tag, "sg_offset", loc_data).as_string();
2901-
interdie_wire.offset_start = pugiutil::get_attribute(interdie_wire_tag, "offset_start", loc_data).as_int();
2902-
interdie_wire.offset_end = pugiutil::get_attribute(interdie_wire_tag, "offset_end", loc_data).as_int();
2903-
interdie_wire.offset_incr = pugiutil::get_attribute(interdie_wire_tag, "offset_incr", loc_data).as_int();
2904-
interdie_wire.offset_num = pugiutil::get_attribute(interdie_wire_tag, "offset_num", loc_data).as_int();
2905-
2906-
interposer.interdie_wires.push_back(interdie_wire);
2907-
}
2908-
2909-
//TODO: save interposer somewhere (need to add *arch to this function's args)
2910-
29112896
} else {
29122897
archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag),
29132898
vtr::string_fmt("Unrecognized grid location specification type '%s'\n", loc_type).c_str());
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "read_xml_arch_file_interposer.h"
2+
#include <vector>
3+
#include "interposer_types.h"
4+
#include "read_xml_util.h"
5+
#include "pugixml_util.hpp"
6+
#include "arch_error.h"
7+
8+
t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, const pugiutil::loc_data& loc_data) {
9+
t_interposer_cut_inf interposer;
10+
11+
pugiutil::expect_only_attributes(interposer_cut_tag, {"dim", "loc"}, loc_data);
12+
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.");
16+
}
17+
18+
interposer.dim = CHAR_INTERPOSER_DIM_MAP.at(interposer_dim[0]);
19+
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.");
23+
}
24+
25+
pugiutil::expect_only_children(interposer_cut_tag, {"interdie_wire"}, loc_data);
26+
27+
for (pugi::xml_node interdie_wire_tag : interposer_cut_tag.children()) {
28+
const std::vector<std::string> interdie_wire_attributes = {{"sg", "sg_link", "offset_start", "offset_end", "offset_increment", "num"}};
29+
pugiutil::expect_only_attributes(interdie_wire_tag, interdie_wire_attributes, loc_data);
30+
31+
t_interdie_wire_inf interdie_wire;
32+
33+
interdie_wire.sg_name = pugiutil::get_attribute(interdie_wire_tag, "sg_name", loc_data).as_string();
34+
interdie_wire.sg_link = pugiutil::get_attribute(interdie_wire_tag, "sg_link", loc_data).as_string();
35+
interdie_wire.offset_start = pugiutil::get_attribute(interdie_wire_tag, "offset_start", loc_data).as_int();
36+
interdie_wire.offset_end = pugiutil::get_attribute(interdie_wire_tag, "offset_end", loc_data).as_int();
37+
interdie_wire.offset_increment = pugiutil::get_attribute(interdie_wire_tag, "offset_increment", loc_data).as_int();
38+
interdie_wire.num = pugiutil::get_attribute(interdie_wire_tag, "num", loc_data).as_int();
39+
40+
interposer.interdie_wires.push_back(interdie_wire);
41+
}
42+
43+
return interposer;
44+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
/**
4+
* @file read_xml_arch_file_interposer.h
5+
* @brief This file contains functions related to parsing and processing interposer tags in the architecture file
6+
*
7+
*/
8+
9+
#include "interposer_types.h"
10+
#include "read_xml_util.h"
11+
12+
/**
13+
* @brief Parse an <interposer_cut> tag and its children
14+
*
15+
* @param interposer_cut_tag xml_node pointing to the <interposer_cut> tag
16+
* @param loc_data Points to the location in the architecture file where the parser is reading. Used for priting error messages.
17+
* @return t_interposer_cut_inf with parsed information of the <interposer_cut> tag
18+
*/
19+
t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, const pugiutil::loc_data& loc_data);

0 commit comments

Comments
 (0)