[core] fixed the bugs in fabric tile build-up
This commit is contained in:
parent
5e89b950ed
commit
46d916f0a0
|
@ -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",
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue