Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify a single location or a specific region for a custom switch block #2664

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9376baf
support XY_SPECIFIED in custom SB to allow user to define custom SB f…
saaramahmoudi Jun 17, 2024
4abbb38
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
saaramahmoudi Jul 10, 2024
3b315b6
bug fixed, should check region condition if both x and y are not spec…
saaramahmoudi Jul 10, 2024
89c6a4f
changed the SB struct for code clarity
saaramahmoudi Jul 11, 2024
b699163
choose the correct layout width and height to parse custom SB
saaramahmoudi Jul 12, 2024
da63771
initialized the region values for custom SBs
saaramahmoudi Jul 12, 2024
5b5d8b4
removed log
saaramahmoudi Jul 12, 2024
e40128d
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
saaramahmoudi Jul 19, 2024
d5f44aa
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
saaramahmoudi Jul 19, 2024
219b0fa
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
saaramahmoudi Jul 25, 2024
f6cde44
Merge branch 'master' into specify_loc_for_custom_SB
saaramahmoudi Jul 29, 2024
29df7fb
applied some code suggestions
saaramahmoudi Sep 23, 2024
b93498f
resolved conflict with master branch
saaramahmoudi Sep 23, 2024
e3caf57
Merge branch 'master' into specify_loc_for_custom_SB
saaramahmoudi Sep 24, 2024
4427937
Merge branch 'master' into specify_loc_for_custom_SB
saaramahmoudi Oct 1, 2024
db50dd0
Merge branch 'master' into specify_loc_for_custom_SB
saaramahmoudi Oct 3, 2024
1a4e7ec
applied all requested changes
saaramahmoudi Oct 3, 2024
400b7d7
add new test to strong for custom SB location
saaramahmoudi Oct 3, 2024
5181cb6
fixed a typo
saaramahmoudi Oct 3, 2024
a47fabc
updated the task list and the golden results
saaramahmoudi Oct 3, 2024
a48200d
resolved conflicts with master branch
saaramahmoudi Oct 4, 2024
d9bf330
revert the incorrect merge
saaramahmoudi Oct 4, 2024
2a6d0ff
revert sockpp changes
saaramahmoudi Oct 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,15 @@ enum e_sb_location {
E_CORNER,
E_FRINGE, /* perimeter minus corners */
E_CORE,
E_EVERYWHERE
E_EVERYWHERE,
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
E_XY_SPECIFIED
};

struct e_sb_loc_spec{
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
int start = -1;
int repeat = -1;
int incr = -1;
int end = -1;
};

/*************************************************************************************************/
Expand Down Expand Up @@ -1915,6 +1923,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 */
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
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*/
e_sb_loc_spec reg_x;
e_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 @@ -2066,6 +2081,7 @@ struct t_arch {
std::vector<std::string> ipin_cblock_switch_name;

std::vector<t_grid_def> grid_layouts; //Set of potential device layouts
std::string device_layout; //the layout that is choosen to be used with command line options
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

t_clock_arch_spec clock_arch; // Clock related data types

Expand Down
71 changes: 71 additions & 0 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 @@ -3894,6 +3895,15 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
int num_switchblocks = count_children(Parent, "switchblock", loc_data);
arch->switchblocks.reserve(num_switchblocks);

// get the device layout width and height
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;
}
}

saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
/* read-in all switchblock data */
Node = get_first_child(Parent, "switchblock", loc_data);
for (int i_sb = 0; i_sb < num_switchblocks; i_sb++) {
Expand Down Expand Up @@ -3932,11 +3942,72 @@ static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiu
sb.location = E_CORNER;
} else if (strcmp(tmp, "FRINGE") == 0) {
sb.location = E_FRINGE;
} else if (strcmp(tmp,"XY_SPECIFIED") == 0){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
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){
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;
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

/* 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){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
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);
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
}


/* Location also might be speicified with regular expression, get the region that this SB should be applied to*/
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
if (sb.x == -1 && sb.y == -1){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
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);
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
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);

}

}

saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
/* get switchblock permutation functions */
SubElem = get_first_child(Node, "switchfuncs", loc_data);
read_sb_switchfuncs(SubElem, &sb, loc_data);
Expand Down
3 changes: 3 additions & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ void SetupVPR(const t_options* Options,
SetupNocOpts(*Options, NocOpts);
SetupServerOpts(*Options, ServerOpts);

//save the device layout, which is required to parse the architecture file
Arch->device_layout = Options->device_layout;
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

if (readArchFile == true) {
vtr::ScopedStartFinishTimer t("Loading Architecture Description");
switch (Options->arch_format) {
Expand Down
83 changes: 80 additions & 3 deletions vpr/src/route/build_switchblocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ int get_wire_segment_length(const DeviceGrid& grid, e_rr_type chan_type, const t
static int get_switchpoint_of_wire(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details, int seg_coord, e_side sb_side);

/* returns true if the coordinates x/y do not correspond to the location specified by 'location' */
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location);
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location, int sb_x, int sb_y, const e_sb_loc_spec& sb_reg_x, const e_sb_loc_spec& sb_reg_y);
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

/* checks if the specified coordinates represent a corner of the FPGA */
static bool is_corner(const DeviceGrid& grid, int x, int y);
Expand All @@ -279,6 +279,9 @@ static bool is_perimeter(const DeviceGrid& grid, int x, int y);
/* checks if the specified coordinates correspond to the core of the FPGA (i.e. not perimeter) */
static bool is_core(const DeviceGrid& grid, int x, int y);

/*checks if the specified coordinates matches the exact one specified in the SB architecture description*/
static bool match_sb_xy(const DeviceGrid& grid, int x, int y, int sb_x, int sb_y, const e_sb_loc_spec& sb_reg_x, const e_sb_loc_spec& sb_reg_y);
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

/* adjusts a negative destination wire index calculated from a permutation formula */
static int adjust_formula_result(int dest_wire, int src_W, int dest_W, int connection_ind);

Expand Down Expand Up @@ -324,10 +327,11 @@ t_sb_connection_map* alloc_and_load_switchblock_permutations(const t_chan_detail
if (directionality != sb.directionality) {
VPR_FATAL_ERROR(VPR_ERROR_ARCH, "alloc_and_load_switchblock_connections: Switchblock %s does not match directionality of architecture\n", sb.name.c_str());
}

saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
/* Iterate over the x,y coordinates spanning the FPGA. */
for (size_t x_coord = 0; x_coord < grid.width(); x_coord++) {
for (size_t y_coord = 0; y_coord <= grid.height(); y_coord++) {
if (sb_not_here(grid, x_coord, y_coord, sb.location)) {
if (sb_not_here(grid, x_coord, y_coord, sb.location, sb.x, sb.y, sb.reg_x, sb.reg_y)) {
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
/* now we iterate over all the potential side1->side2 connections */
Expand Down Expand Up @@ -362,7 +366,7 @@ void free_switchblock_permutations(t_sb_connection_map* sb_conns) {
}

/* returns true if the coordinates x/y do not correspond to the location specified by 'location' */
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location) {
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location, int sb_x, int sb_y, const e_sb_loc_spec& sb_reg_x, const e_sb_loc_spec& sb_reg_y) {
bool sb_not_here = true;

switch (location) {
Expand All @@ -388,6 +392,12 @@ static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location loca
if (is_perimeter(grid, x, y) && !is_corner(grid, x, y)) {
sb_not_here = false;
}
break;
case E_XY_SPECIFIED:
if(match_sb_xy(grid, x, y, sb_x, sb_y, sb_reg_x, sb_reg_y)){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
sb_not_here = false;
}

saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
break;
default:
VPR_FATAL_ERROR(VPR_ERROR_ARCH, "sb_not_here: unrecognized location enum: %d\n", location);
Expand Down Expand Up @@ -422,6 +432,73 @@ static bool is_core(const DeviceGrid& grid, int x, int y) {
return is_core;
}

static bool match_sb_xy(const DeviceGrid& grid, int x, int y, int sb_x, int sb_y, const e_sb_loc_spec& sb_reg_x, const e_sb_loc_spec& sb_reg_y){

//if one of sb_x and sb_y is defined, we either know the exact location (x,y) or the exact x location (will apply it to all columns)
//or the exact y location (will apply it to all rows)
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
if(sb_x != -1 || sb_y != -1){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
if(x == sb_x && y == sb_y){
return true;
}

if(x == sb_x && sb_y == -1){
return true;
}

if(sb_x == -1 && y == sb_y){
return true;
}
}

//if both sb_x and sb_y is not defined, we have a region that we should apply this SB pattern to, we just need to check
//whether the location passed into this function falls within this region or not
if(sb_x == -1 && sb_y == -1){
//calculate the appropiate region based on the repeatx/repeaty and current location.
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
//This is to determine whether the given location is part of the current SB specified region with regular expression or not
//After region calculation, the current SB will apply to this location if:
// 1) the given (x,y) location falls into the calculated region
// *AND*
// 2) incrx/incry are respected within the region, this means all locations within the calculated region is
// is not necessary crossponds to the current SB. If incrx/incry is equal to 1, then all locations within the
// calculated region is valid.
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

//calculate the region
int x_reg_step = (sb_reg_x.repeat != 0) ? (x - sb_reg_x.start) / sb_reg_x.repeat : sb_reg_x.start;
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
int y_reg_step = (sb_reg_y.repeat != 0) ? (y - sb_reg_y.start) / sb_reg_y.repeat : sb_reg_y.start;

//step must be non-negative
x_reg_step = (x_reg_step < 0) ? 0 : x_reg_step;
y_reg_step = (y_reg_step < 0) ? 0 : y_reg_step;
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved

int reg_startx = sb_reg_x.start + (x_reg_step * sb_reg_x.repeat);
int reg_endx = sb_reg_x.end + (x_reg_step * sb_reg_x.repeat);
reg_endx = std::min(reg_endx, int(grid.width() - 1));

int reg_starty = sb_reg_y.start + (y_reg_step * sb_reg_y.repeat);
int reg_endy = sb_reg_y.end + (y_reg_step * sb_reg_y.repeat);
reg_endy = std::min(reg_endy, int(grid.height() - 1));

//check x coordinate
if (x >= reg_startx && x <= reg_endx){ //should fall into the region
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
//we also should respect the incrx
//if incrx is not equal to 1, all locations within this region is *NOT* valid
if((y + reg_startx) % sb_reg_x.incr == 0){
saaramahmoudi marked this conversation as resolved.
Show resolved Hide resolved
//valid x coordinate, check for y value
if(y >= reg_starty && y <= reg_endy){
//check for incry, similar as incrx
if((y + reg_starty) % sb_reg_y.incr == 0){
//both x and y are valid
return true;
}
}
}
}
}

//if reach here, we don't have sb in this location
return false;
}

/* Counts the number of wires in each wire type in the specified channel */
static void count_wire_type_sizes(const t_chan_seg_details* channel, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes) {
vtr::string_view wire_type;
Expand Down