Skip to content

Commit

Permalink
Merge pull request #2664 from verilog-to-routing/specify_loc_for_cust…
Browse files Browse the repository at this point in the history
…om_SB

Specify a single location or a specific region for a custom switch block
  • Loading branch information
vaughnbetz authored Oct 8, 2024
2 parents f85b422 + b3d803b commit 762e816
Show file tree
Hide file tree
Showing 8 changed files with 48,543 additions and 137 deletions.
27 changes: 25 additions & 2 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,23 @@ typedef enum e_power_estimation_method_ e_power_estimation_method;
typedef enum e_power_estimation_method_ t_power_estimation_method;

/* Specifies what part of the FPGA a custom switchblock should be built in (i.e. perimeter, core, everywhere) */
enum e_sb_location {
enum class e_sb_location {
E_PERIMETER = 0,
E_CORNER,
E_FRINGE, /* perimeter minus corners */
E_CORE,
E_EVERYWHERE
E_EVERYWHERE,
E_XY_SPECIFIED
};

/**
* @brief Describes regions that a specific switch block specifications should be applied to
*/
struct t_sb_loc_spec {
int start = -1;
int repeat = -1;
int incr = -1;
int end = -1;
};

/*************************************************************************************************/
Expand Down Expand Up @@ -1933,6 +1944,13 @@ struct t_switchblock_inf {
e_sb_location location; /* where on the FPGA this switchblock should be built (i.e. perimeter, core, everywhere) */
e_directionality directionality; /* the directionality of this switchblock (unidir/bidir) */

int x = -1; /* The exact x-axis location that this SB is used, meaningful when type is set to E_XY_specified */
int y = -1; /* The exact y-axis location that this SB is used, meanignful when type is set to E_XY_specified */

/* We can also define a region to apply this SB to all locations falls into this region using regular expression in the architecture file*/
t_sb_loc_spec reg_x;
t_sb_loc_spec reg_y;

t_permutation_map permutation_map; /* map holding the permutation functions attributed to this switchblock */

std::vector<t_wireconn_inf> wireconns; /* list of wire types/groups this SB will connect */
Expand Down Expand Up @@ -2086,6 +2104,11 @@ struct t_arch {
std::vector<std::string> ipin_cblock_switch_name;

std::vector<t_grid_def> grid_layouts; //Set of potential device layouts

//the layout that is chosen to be used with command line options
//It is used to generate custom SB for a specific locations within the device
//If the layout is not specified in the command line options, this variable will be set to "auto"
std::string device_layout;

t_clock_arch_spec clock_arch; // Clock related data types

Expand Down
92 changes: 87 additions & 5 deletions libs/libarchfpga/src/read_xml_arch_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "parse_switchblocks.h"

#include "physical_types_util.h"
#include "vtr_expr_eval.h"

#include "read_xml_arch_file_noc_tag.h"

Expand Down Expand Up @@ -3936,6 +3937,43 @@ static void ProcessSegments(pugi::xml_node Parent,
"Atleast one segment per-axis needs to get specified if no segments with non-specified (default) axis attribute exist.");
}
}


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){
auto startx_attr = get_attribute(SubElem, "startx", loc_data, ReqOpt::OPTIONAL);
auto endx_attr = get_attribute(SubElem, "endx", loc_data, ReqOpt::OPTIONAL);

auto starty_attr = get_attribute(SubElem, "starty", loc_data, ReqOpt::OPTIONAL);
auto endy_attr = get_attribute(SubElem, "endy", loc_data, ReqOpt::OPTIONAL);

auto repeatx_attr = get_attribute(SubElem, "repeatx", loc_data, ReqOpt::OPTIONAL);
auto repeaty_attr = get_attribute(SubElem, "repeaty", loc_data, ReqOpt::OPTIONAL);

auto incrx_attr = get_attribute(SubElem, "incrx", loc_data, ReqOpt::OPTIONAL);
auto incry_attr = get_attribute(SubElem, "incry", loc_data, ReqOpt::OPTIONAL);

//parse the values from the architecture file and fill out SB region information
vtr::FormulaParser p;

vtr::t_formula_data vars;
vars.set_var_value("W", grid_width);
vars.set_var_value("H", grid_height);


sb.reg_x.start = startx_attr.empty() ? 0 : p.parse_formula(startx_attr.value(), vars);
sb.reg_y.start = starty_attr.empty() ? 0 : p.parse_formula(starty_attr.value(), vars);

sb.reg_x.end = endx_attr.empty() ? (grid_width - 1) : p.parse_formula(endx_attr.value(), vars);
sb.reg_y.end = endy_attr.empty() ? (grid_height -1) : p.parse_formula(endy_attr.value(), vars);

sb.reg_x.repeat = repeatx_attr.empty() ? 0 : p.parse_formula(repeatx_attr.value(), vars);
sb.reg_y.repeat = repeaty_attr.empty() ? 0 : p.parse_formula(repeaty_attr.value(), vars);

sb.reg_x.incr = incrx_attr.empty() ? 1 : p.parse_formula(incrx_attr.value(), vars);
sb.reg_y.incr = incry_attr.empty() ? 1 : p.parse_formula(incry_attr.value(), vars);

}

/* Processes the switchblocklist section from the xml architecture file.
* See vpr/SRC/route/build_switchblocks.c for a detailed description of this
* switch block format */
Expand All @@ -3947,6 +3985,14 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
/* get the number of switchblocks */
int num_switchblocks = count_children(Parent, "switchblock", loc_data);
arch->switchblocks.reserve(num_switchblocks);

int layout_index = -1;
for(layout_index = 0; layout_index < (int) arch->grid_layouts.size(); layout_index++){
if(arch->grid_layouts.at(layout_index).name == arch->device_layout){
//found the used layout
break;
}
}

/* read-in all switchblock data */
Node = get_first_child(Parent, "switchblock", loc_data);
Expand Down Expand Up @@ -3977,20 +4023,56 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
tmp = get_attribute(SubElem, "type", loc_data).as_string(nullptr);
if (tmp) {
if (strcmp(tmp, "EVERYWHERE") == 0) {
sb.location = E_EVERYWHERE;
sb.location = e_sb_location::E_EVERYWHERE;
} else if (strcmp(tmp, "PERIMETER") == 0) {
sb.location = E_PERIMETER;
sb.location = e_sb_location::E_PERIMETER;
} else if (strcmp(tmp, "CORE") == 0) {
sb.location = E_CORE;
sb.location = e_sb_location::E_CORE;
} else if (strcmp(tmp, "CORNER") == 0) {
sb.location = E_CORNER;
sb.location = e_sb_location::E_CORNER;
} else if (strcmp(tmp, "FRINGE") == 0) {
sb.location = E_FRINGE;
sb.location = e_sb_location::E_FRINGE;
} else if (strcmp(tmp, "XY_SPECIFIED") == 0) {
sb.location = e_sb_location::E_XY_SPECIFIED;
} else {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), "unrecognized switchblock location: %s\n", tmp);
}
}

/* get the switchblock coordinate only if sb.location is set to E_XY_SPECIFIED*/
if(sb.location == e_sb_location::E_XY_SPECIFIED){
if (arch->device_layout == "auto"){
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), "Specifying SB locations for auto layout devices are not supported yet!\n");
}
expect_only_attributes(SubElem,
{"x", "y", "type",
"startx", "endx", "repeatx", "incrx",
"starty", "endy", "repeaty", "incry"},
loc_data);

int grid_width = arch->grid_layouts.at(layout_index).width;
int grid_height = arch->grid_layouts.at(layout_index).height;

/* Absolute location that this SB must be applied to, -1 if not specified*/
sb.x = get_attribute(SubElem, "x", loc_data, ReqOpt::OPTIONAL).as_int(-1);
sb.y = get_attribute(SubElem, "y", loc_data, ReqOpt::OPTIONAL).as_int(-1);

//check if the absolute value is within the device grid width and height
if(sb.x >= grid_width || sb.y >= grid_height) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), \
"Location (%d,%d) is not valid within the grid! grid dimensions are: (%d,%d)\n", sb.x, sb.y, grid_width, grid_height);
}

/* if the the switchblock exact location is not specified and a region is specified within the architecture file,
* we have to parse the region specification and apply the SB pattern to all the locations fall into the specified
* region based on device width and height.
*/
if (sb.x == -1 && sb.y == -1) {
calculate_custom_SB_locations(loc_data, SubElem, grid_width, grid_height, sb);
}

}

/* get switchblock permutation functions */
SubElem = get_first_child(Node, "switchfuncs", loc_data);
read_sb_switchfuncs(SubElem, &sb, loc_data);
Expand Down
Loading

0 comments on commit 762e816

Please sign in to comment.