[core] fixed the bugs in fabric tile build-up

This commit is contained in:
tangxifan 2024-07-05 16:59:08 -07:00
parent 5e89b950ed
commit 46d916f0a0
2 changed files with 186 additions and 79 deletions

View File

@ -22,12 +22,110 @@
namespace openfpga {
/********************************************************************
* Build tiles by following the top-level style.
* - The programmble block, e.g., clb, is placed on the top-left corner
* - The connection blocks and switch block are placed on the right and bottom
*sides
* With a given coordinate of a grid, find an existing fabric tile
* or create a new fabric tile
* - A grid may never exist in any fabric tile (no coordinate matches)
* Create a new one
* - A grid already in another fabric tile (occur in heterogeneous blocks)
* Find the existing one
*******************************************************************/
static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
static int find_or_create_one_fabric_tile_from_grid(
FabricTile& fabric_tile,
FabricTileId& curr_tile_id,
const DeviceGrid& grids,
const t_physical_tile_loc& tile_loc,
const RRGraphView& rr_graph,
const DeviceRRGSB& device_rr_gsb,
const bool& verbose) {
t_physical_tile_type_ptr phy_tile_type =
grids.get_physical_type(tile_loc);
vtr::Point<size_t> curr_tile_coord(tile_loc.x, tile_loc.y);
vtr::Point<size_t> curr_gsb_coord(tile_loc.x, tile_loc.y);
bool skip_add_pb = false;
/* For EMPTY grid, routing blocks may still be required if there is a gsb
*/
if (true == is_empty_type(phy_tile_type)) {
skip_add_pb = true;
if (!device_rr_gsb.is_gsb_exist(rr_graph, curr_gsb_coord)) {
VTR_LOGV(verbose, "Skip tile[%lu][%lu] as it is empty\n",
curr_tile_coord.x(), curr_tile_coord.y());
return CMD_EXEC_SUCCESS;
}
/* Need to create a new tile here */
VTR_LOGV(verbose,
"Create tile[%lu][%lu] which only has routing but not a "
"programmable block\n",
curr_tile_coord.x(), curr_tile_coord.y());
curr_tile_id = fabric_tile.create_tile(curr_tile_coord);
} else if ((0 < grids.get_width_offset(tile_loc)) ||
(0 < grids.get_height_offset(tile_loc))) {
/* Skip width, height > 1 tiles (mostly heterogeneous blocks) */
/* Find the root of this grid, the instance id should be valid.
* We just copy it here
*/
vtr::Point<size_t> root_tile_coord(
curr_tile_coord.x() - grids.get_width_offset(tile_loc),
curr_tile_coord.y() - grids.get_height_offset(tile_loc));
skip_add_pb = true;
VTR_LOGV(verbose,
"Tile[%lu][%lu] contains a heterogeneous block which is "
"rooted from tile[%lu][%lu]\n",
curr_tile_coord.x(), curr_tile_coord.y(), root_tile_coord.x(),
root_tile_coord.y());
curr_tile_id = fabric_tile.find_tile(root_tile_coord);
/* Update the coordinates of the pb in tiles */
size_t root_pb_idx_in_curr_tile =
fabric_tile.find_pb_index_in_tile(curr_tile_id, root_tile_coord);
int status_code = fabric_tile.set_pb_max_coordinate(
curr_tile_id, root_pb_idx_in_curr_tile, curr_tile_coord);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
} else {
/* Need to create a new tile here */
VTR_LOGV(verbose, "Create a regular tile[%lu][%lu]\n",
curr_tile_coord.x(), curr_tile_coord.y());
curr_tile_id = fabric_tile.create_tile(curr_tile_coord);
}
/* Ensure that we have a valid id */
if (!fabric_tile.valid_tile_id(curr_tile_id)) {
VTR_LOG_ERROR("Failed to get a valid id for tile[%lu][%lu]!\n",
curr_tile_coord.x(), curr_tile_coord.y());
return CMD_EXEC_FATAL_ERROR;
}
/* Add components: pb, cbx, cby, and sb if exists */
if (!skip_add_pb) {
fabric_tile.add_pb_coordinate(curr_tile_id, curr_tile_coord,
curr_gsb_coord);
}
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Build tiles by following the bottom style.
* - The programmble block, e.g., clb, is placed on the bottom-left corner
* - The connection blocks and switch block are placed on the top and bottom
*sides
* This is exactly how GSB is organized. Just need to transfer data from one GSB
* The gsb coordinate is the same as the grid coordinate when the
* bottom-left style is considered
*
* ------------------------------
* +----------+ +----------+ ^
* | CBx | | SB | |
* | [x][y] | | [x][y] | GSB[x][y]
* +----------+ +----------+ |
* +----------+ +----------+ |
* | Grid | | CBy | |
* | [x][y] | | [x][y] | |
* +----------+ +----------+ v
* ------------------------------
*
*******************************************************************/
static int build_fabric_tile_style_bottom_left(FabricTile& fabric_tile,
const DeviceGrid& grids,
const size_t& layer,
const RRGraphView& rr_graph,
@ -39,82 +137,16 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
for (size_t ix = 0; ix < grids.width(); ++ix) {
for (size_t iy = 0; iy < grids.height(); ++iy) {
t_physical_tile_loc tile_loc(ix, iy, layer);
t_physical_tile_type_ptr phy_tile_type =
grids.get_physical_type(tile_loc);
bool skip_add_pb = false;
vtr::Point<size_t> curr_tile_coord(ix, iy);
vtr::Point<size_t> curr_gsb_coord(ix, iy - 1);
FabricTileId curr_tile_id = FabricTileId::INVALID();
/* For EMPTY grid, routing blocks may still be required if there is a gsb
*/
if (true == is_empty_type(phy_tile_type)) {
skip_add_pb = true;
if (!device_rr_gsb.is_gsb_exist(rr_graph, curr_gsb_coord)) {
VTR_LOGV(verbose, "Skip tile[%lu][%lu] as it is empty\n",
curr_tile_coord.x(), curr_tile_coord.y());
continue;
}
/* Need to create a new tile here */
VTR_LOGV(verbose,
"Create tile[%lu][%lu] which only has routing but not a "
"programmable block\n",
curr_tile_coord.x(), curr_tile_coord.y());
curr_tile_id = fabric_tile.create_tile(curr_tile_coord);
} else if ((0 < grids.get_width_offset(tile_loc)) ||
(0 < grids.get_height_offset(tile_loc))) {
/* Skip width, height > 1 tiles (mostly heterogeneous blocks) */
/* Find the root of this grid, the instance id should be valid.
* We just copy it here
*/
vtr::Point<size_t> root_tile_coord(
ix - grids.get_width_offset(tile_loc),
iy - grids.get_height_offset(tile_loc));
skip_add_pb = true;
VTR_LOGV(verbose,
"Tile[%lu][%lu] contains a heterogeneous block which is "
"rooted from tile[%lu][%lu]\n",
curr_tile_coord.x(), curr_tile_coord.y(), root_tile_coord.x(),
root_tile_coord.y());
curr_tile_id = fabric_tile.find_tile(root_tile_coord);
/* Update the coordinates of the pb in tiles */
size_t root_pb_idx_in_curr_tile =
fabric_tile.find_pb_index_in_tile(curr_tile_id, root_tile_coord);
status_code = fabric_tile.set_pb_max_coordinate(
curr_tile_id, root_pb_idx_in_curr_tile, vtr::Point<size_t>(ix, iy));
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
} else {
/* Need to create a new tile here */
VTR_LOGV(verbose, "Create a regular tile[%lu][%lu]\n",
curr_tile_coord.x(), curr_tile_coord.y());
curr_tile_id = fabric_tile.create_tile(curr_tile_coord);
}
/* Ensure that we have a valid id */
if (!fabric_tile.valid_tile_id(curr_tile_id)) {
VTR_LOG_ERROR("Failed to get a valid id for tile[%lu][%lu]!\n", ix, iy);
status_code = find_or_create_one_fabric_tile_from_grid(fabric_tile, curr_tile_id, grids, tile_loc, rr_graph, device_rr_gsb, verbose);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
/* Add components: pb, cbx, cby, and sb if exists */
if (!skip_add_pb) {
fabric_tile.add_pb_coordinate(curr_tile_id, curr_tile_coord,
curr_gsb_coord);
/* If no valid tile is created or spotted, the tile does not exist physically, skip */
if (fabric_tile.valid_tile_id(curr_tile_id)) {
continue;
}
/* The gsb coordinate is different than the grid coordinate when the
* top-left style is considered
*
* +----------+ +----------+
* | Grid | | CBx |
* | [x][y] | | [x][y] |
* +----------+ +----------+
* +----------+ +----------+
* | CBy | | SB |
* | [x][y-1] | | [x][y-1] |
* +----------+ +----------+
*
*/
vtr::Point<size_t> curr_gsb_coord(ix, iy);
if (!device_rr_gsb.is_gsb_exist(rr_graph, curr_gsb_coord)) {
continue;
}
@ -135,6 +167,77 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
return status_code;
}
/********************************************************************
* Build tiles by following the top-left style.
* - The programmble block, e.g., clb, is placed on the top-left corner
* - The connection blocks and switch block are placed on the right and bottom
*sides
* Tile[x][y]
* ------------------------------
* +----------+ +----------+ ^
* | Grid | | CBy | GSB[x][y]
* | [x][y] | | [x][y] | |
* +----------+ +----------+ v
* ------------------------------
* +----------+ +----------+ ^
* | CBx | | SB | |
* | [x][y-1] | | [x][y-1] | GSB[x][y-1]
* +----------+ +----------+ |
* ------------------------------
*******************************************************************/
static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
const DeviceGrid& grids,
const size_t& layer,
const RRGraphView& rr_graph,
const DeviceRRGSB& device_rr_gsb,
const bool& verbose) {
int status_code = CMD_EXEC_SUCCESS;
/* Walk through all the device rr_gsb and create tile one by one */
for (size_t ix = 0; ix < grids.width(); ++ix) {
for (size_t iy = 0; iy < grids.height(); ++iy) {
t_physical_tile_loc tile_loc(ix, iy, layer);
FabricTileId curr_tile_id = FabricTileId::INVALID();
status_code = find_or_create_one_fabric_tile_from_grid(fabric_tile, curr_tile_id, grids, tile_loc, rr_graph, device_rr_gsb, verbose);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
/* If no valid tile is created or spotted, the tile does not exist physically, skip */
if (fabric_tile.valid_tile_id(curr_tile_id)) {
continue;
}
/* For the cby in the same gsb */
vtr::Point<size_t> curr_gsb_coord(ix, iy);
if (!device_rr_gsb.is_gsb_exist(rr_graph, curr_gsb_coord)) {
continue;
}
const RRGSB& curr_rr_gsb = device_rr_gsb.get_gsb(curr_gsb_coord);
if (curr_rr_gsb.is_cb_exist(CHANY)) {
fabric_tile.add_cb_coordinate(curr_tile_id, CHANY,
curr_rr_gsb.get_sb_coordinate());
}
/* For the cbx and sb in the neighbour gsb */
vtr::Point<size_t> neighbor_gsb_coord(ix, iy - 1);
if (!device_rr_gsb.is_gsb_exist(rr_graph, neighbor_gsb_coord)) {
continue;
}
const RRGSB& neighbor_rr_gsb = device_rr_gsb.get_gsb(neighbor_gsb_coord);
if (neighbor_rr_gsb.is_cb_exist(CHANX)) {
fabric_tile.add_cb_coordinate(curr_tile_id, CHANX,
neighbor_rr_gsb.get_sb_coordinate());
}
if (neighbor_rr_gsb.is_sb_exist(rr_graph)) {
fabric_tile.add_sb_coordinate(curr_tile_id,
neighbor_rr_gsb.get_sb_coordinate());
}
}
}
return status_code;
}
/********************************************************************
* Build tile-level information for a given FPGA fabric, w.r.t. to configuration
*******************************************************************/
@ -152,6 +255,10 @@ int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config,
if (tile_config.style() == TileConfig::e_style::TOP_LEFT) {
status_code = build_fabric_tile_style_top_left(
fabric_tile, grids, 0, rr_graph, device_rr_gsb, verbose);
} else if (tile_config.style() == TileConfig::e_style::BOTTOM_LEFT) {
status_code = build_fabric_tile_style_bottom_left(
fabric_tile, grids, 0, rr_graph, device_rr_gsb, verbose);
} else {
/* Error out for styles that are not supported yet! */
VTR_LOG_ERROR("Tile style '%s' is not supported yet!\n",

View File

@ -732,13 +732,13 @@ static int build_tile_module_port_and_nets_between_sb_and_cb(
* is_cb_exist() FOr RIGHT and BOTTOM side, find the adjacent RRGSB and then
* use is_cb_exist()
*/
if (TOP == side_manager.get_side() || LEFT == side_manager.get_side()) {
if (BOTTOM == side_manager.get_side() || LEFT == side_manager.get_side()) {
if (false == rr_gsb.is_cb_exist(cb_type)) {
continue;
}
}
if (RIGHT == side_manager.get_side() || BOTTOM == side_manager.get_side()) {
if (RIGHT == side_manager.get_side() || TOP == side_manager.get_side()) {
const RRGSB& adjacent_gsb =
device_rr_gsb.get_gsb(module_gsb_cb_coordinate);
if (false == adjacent_gsb.is_cb_exist(cb_type)) {