Skip to content

Commit 2eb6eb6

Browse files
authored
Merge branch 'master' into openfpga
2 parents 727ecf6 + edbe700 commit 2eb6eb6

File tree

18 files changed

+50879
-2406
lines changed

18 files changed

+50879
-2406
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,23 @@ typedef enum e_power_estimation_method_ e_power_estimation_method;
256256
typedef enum e_power_estimation_method_ t_power_estimation_method;
257257

258258
/* Specifies what part of the FPGA a custom switchblock should be built in (i.e. perimeter, core, everywhere) */
259-
enum e_sb_location {
259+
enum class e_sb_location {
260260
E_PERIMETER = 0,
261261
E_CORNER,
262262
E_FRINGE, /* perimeter minus corners */
263263
E_CORE,
264-
E_EVERYWHERE
264+
E_EVERYWHERE,
265+
E_XY_SPECIFIED
266+
};
267+
268+
/**
269+
* @brief Describes regions that a specific switch block specifications should be applied to
270+
*/
271+
struct t_sb_loc_spec {
272+
int start = -1;
273+
int repeat = -1;
274+
int incr = -1;
275+
int end = -1;
265276
};
266277

267278
/*************************************************************************************************/
@@ -1936,6 +1947,13 @@ struct t_switchblock_inf {
19361947
e_sb_location location; /* where on the FPGA this switchblock should be built (i.e. perimeter, core, everywhere) */
19371948
e_directionality directionality; /* the directionality of this switchblock (unidir/bidir) */
19381949

1950+
int x = -1; /* The exact x-axis location that this SB is used, meaningful when type is set to E_XY_specified */
1951+
int y = -1; /* The exact y-axis location that this SB is used, meanignful when type is set to E_XY_specified */
1952+
1953+
/* We can also define a region to apply this SB to all locations falls into this region using regular expression in the architecture file*/
1954+
t_sb_loc_spec reg_x;
1955+
t_sb_loc_spec reg_y;
1956+
19391957
t_permutation_map permutation_map; /* map holding the permutation functions attributed to this switchblock */
19401958

19411959
std::vector<t_wireconn_inf> wireconns; /* list of wire types/groups this SB will connect */
@@ -2100,6 +2118,11 @@ struct t_arch {
21002118
std::vector<std::string> ipin_cblock_switch_name;
21012119

21022120
std::vector<t_grid_def> grid_layouts; //Set of potential device layouts
2121+
2122+
//the layout that is chosen to be used with command line options
2123+
//It is used to generate custom SB for a specific locations within the device
2124+
//If the layout is not specified in the command line options, this variable will be set to "auto"
2125+
std::string device_layout;
21032126

21042127
t_clock_arch_spec clock_arch; // Clock related data types
21052128

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include "parse_switchblocks.h"
6565

6666
#include "physical_types_util.h"
67+
#include "vtr_expr_eval.h"
6768

6869
#include "read_xml_arch_file_noc_tag.h"
6970

@@ -4100,6 +4101,43 @@ static void ProcessSegments(pugi::xml_node Parent,
41004101
"Atleast one segment per-axis needs to get specified if no segments with non-specified (default) axis attribute exist.");
41014102
}
41024103
}
4104+
4105+
4106+
static void calculate_custom_SB_locations(const pugiutil::loc_data& loc_data, const pugi::xml_node& SubElem, const int grid_width, const int grid_height, t_switchblock_inf& sb){
4107+
auto startx_attr = get_attribute(SubElem, "startx", loc_data, ReqOpt::OPTIONAL);
4108+
auto endx_attr = get_attribute(SubElem, "endx", loc_data, ReqOpt::OPTIONAL);
4109+
4110+
auto starty_attr = get_attribute(SubElem, "starty", loc_data, ReqOpt::OPTIONAL);
4111+
auto endy_attr = get_attribute(SubElem, "endy", loc_data, ReqOpt::OPTIONAL);
4112+
4113+
auto repeatx_attr = get_attribute(SubElem, "repeatx", loc_data, ReqOpt::OPTIONAL);
4114+
auto repeaty_attr = get_attribute(SubElem, "repeaty", loc_data, ReqOpt::OPTIONAL);
4115+
4116+
auto incrx_attr = get_attribute(SubElem, "incrx", loc_data, ReqOpt::OPTIONAL);
4117+
auto incry_attr = get_attribute(SubElem, "incry", loc_data, ReqOpt::OPTIONAL);
4118+
4119+
//parse the values from the architecture file and fill out SB region information
4120+
vtr::FormulaParser p;
4121+
4122+
vtr::t_formula_data vars;
4123+
vars.set_var_value("W", grid_width);
4124+
vars.set_var_value("H", grid_height);
4125+
4126+
4127+
sb.reg_x.start = startx_attr.empty() ? 0 : p.parse_formula(startx_attr.value(), vars);
4128+
sb.reg_y.start = starty_attr.empty() ? 0 : p.parse_formula(starty_attr.value(), vars);
4129+
4130+
sb.reg_x.end = endx_attr.empty() ? (grid_width - 1) : p.parse_formula(endx_attr.value(), vars);
4131+
sb.reg_y.end = endy_attr.empty() ? (grid_height -1) : p.parse_formula(endy_attr.value(), vars);
4132+
4133+
sb.reg_x.repeat = repeatx_attr.empty() ? 0 : p.parse_formula(repeatx_attr.value(), vars);
4134+
sb.reg_y.repeat = repeaty_attr.empty() ? 0 : p.parse_formula(repeaty_attr.value(), vars);
4135+
4136+
sb.reg_x.incr = incrx_attr.empty() ? 1 : p.parse_formula(incrx_attr.value(), vars);
4137+
sb.reg_y.incr = incry_attr.empty() ? 1 : p.parse_formula(incry_attr.value(), vars);
4138+
4139+
}
4140+
41034141
/* Processes the switchblocklist section from the xml architecture file.
41044142
* See vpr/SRC/route/build_switchblocks.c for a detailed description of this
41054143
* switch block format */
@@ -4111,6 +4149,14 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
41114149
/* get the number of switchblocks */
41124150
int num_switchblocks = count_children(Parent, "switchblock", loc_data);
41134151
arch->switchblocks.reserve(num_switchblocks);
4152+
4153+
int layout_index = -1;
4154+
for(layout_index = 0; layout_index < (int) arch->grid_layouts.size(); layout_index++){
4155+
if(arch->grid_layouts.at(layout_index).name == arch->device_layout){
4156+
//found the used layout
4157+
break;
4158+
}
4159+
}
41144160

41154161
/* read-in all switchblock data */
41164162
Node = get_first_child(Parent, "switchblock", loc_data);
@@ -4141,20 +4187,56 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
41414187
tmp = get_attribute(SubElem, "type", loc_data).as_string(nullptr);
41424188
if (tmp) {
41434189
if (strcmp(tmp, "EVERYWHERE") == 0) {
4144-
sb.location = E_EVERYWHERE;
4190+
sb.location = e_sb_location::E_EVERYWHERE;
41454191
} else if (strcmp(tmp, "PERIMETER") == 0) {
4146-
sb.location = E_PERIMETER;
4192+
sb.location = e_sb_location::E_PERIMETER;
41474193
} else if (strcmp(tmp, "CORE") == 0) {
4148-
sb.location = E_CORE;
4194+
sb.location = e_sb_location::E_CORE;
41494195
} else if (strcmp(tmp, "CORNER") == 0) {
4150-
sb.location = E_CORNER;
4196+
sb.location = e_sb_location::E_CORNER;
41514197
} else if (strcmp(tmp, "FRINGE") == 0) {
4152-
sb.location = E_FRINGE;
4198+
sb.location = e_sb_location::E_FRINGE;
4199+
} else if (strcmp(tmp, "XY_SPECIFIED") == 0) {
4200+
sb.location = e_sb_location::E_XY_SPECIFIED;
41534201
} else {
41544202
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), "unrecognized switchblock location: %s\n", tmp);
41554203
}
41564204
}
41574205

4206+
/* get the switchblock coordinate only if sb.location is set to E_XY_SPECIFIED*/
4207+
if(sb.location == e_sb_location::E_XY_SPECIFIED){
4208+
if (arch->device_layout == "auto"){
4209+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), "Specifying SB locations for auto layout devices are not supported yet!\n");
4210+
}
4211+
expect_only_attributes(SubElem,
4212+
{"x", "y", "type",
4213+
"startx", "endx", "repeatx", "incrx",
4214+
"starty", "endy", "repeaty", "incry"},
4215+
loc_data);
4216+
4217+
int grid_width = arch->grid_layouts.at(layout_index).width;
4218+
int grid_height = arch->grid_layouts.at(layout_index).height;
4219+
4220+
/* Absolute location that this SB must be applied to, -1 if not specified*/
4221+
sb.x = get_attribute(SubElem, "x", loc_data, ReqOpt::OPTIONAL).as_int(-1);
4222+
sb.y = get_attribute(SubElem, "y", loc_data, ReqOpt::OPTIONAL).as_int(-1);
4223+
4224+
//check if the absolute value is within the device grid width and height
4225+
if(sb.x >= grid_width || sb.y >= grid_height) {
4226+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), \
4227+
"Location (%d,%d) is not valid within the grid! grid dimensions are: (%d,%d)\n", sb.x, sb.y, grid_width, grid_height);
4228+
}
4229+
4230+
/* if the the switchblock exact location is not specified and a region is specified within the architecture file,
4231+
* we have to parse the region specification and apply the SB pattern to all the locations fall into the specified
4232+
* region based on device width and height.
4233+
*/
4234+
if (sb.x == -1 && sb.y == -1) {
4235+
calculate_custom_SB_locations(loc_data, SubElem, grid_width, grid_height, sb);
4236+
}
4237+
4238+
}
4239+
41584240
/* get switchblock permutation functions */
41594241
SubElem = get_first_child(Node, "switchfuncs", loc_data);
41604242
read_sb_switchfuncs(SubElem, &sb, loc_data);

0 commit comments

Comments
 (0)