[core] developing top-left style tile info

This commit is contained in:
tangxifan 2023-07-14 22:48:44 -07:00
parent 091ac88c7e
commit c2ef5ca408
8 changed files with 362 additions and 3 deletions

View File

@ -0,0 +1,89 @@
/************************************************************************
* Member functions for class FabricTile
***********************************************************************/
#include "fabric_tile.h"
#include "vtr_assert.h"
#include "vtr_log.h"
/* namespace openfpga begins */
namespace openfpga {
FabricTile::FabricTile(const DeviceRRGSB& device_rr_gsb)
: device_rr_gsb_(device_rr_gsb) {}
vtr::Point<size_t> FabricTile::tile_coordinate(
const FabricTileId& tile_id) const {
VTR_ASSERT(valid_tile_id(tile_id));
return coords_[tile_id];
}
FabricTileId FabricTile::unique_tile(const vtr::Point<size_t>& coord) const {
/* Return invalid Id when out of range! */
if (coord.x() < unique_tile_ids_.size()) {
if (coord.y() < unique_tile_ids_[coord.x()].size()) {
return unique_tile_ids_[coord.x()][coord.y()];
}
}
return FabricTileId::INVALID();
}
FabricTileId FabricTile::create_tile() {
FabricTileId tile_id = FabricTileId(ids_.size());
ids_.push_back(tile_id);
coords_.emplace_back();
pb_coords_.emplace_back();
cbx_coords_.emplace_back();
cby_coords_.emplace_back();
sb_coords_.emplace_back();
return tile_id;
}
void set_tile_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord) {
VTR_ASSERT(valid_tile_id(tile_id));
coords_[tile_id] = coord;
}
void add_pb_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord) {
VTR_ASSERT(valid_tile_id(tile_id));
pb_coords_[tile_id] = coord;
}
void add_cbx_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord) {
VTR_ASSERT(valid_tile_id(tile_id));
/* Ensure the coordinates are not duplicated */
auto result = std::find(cbx_coords_.begin(), cbx_coords_.end(), coord);
if (result == cbx_coords_.end()) {
cbx_coords_[tile_id].push_back(coord);
}
}
void add_cby_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord) {
VTR_ASSERT(valid_tile_id(tile_id));
/* Ensure the coordinates are not duplicated */
auto result = std::find(cby_coords_.begin(), cby_coords_.end(), coord);
if (result == cby_coords_.end()) {
cby_coords_[tile_id].push_back(coord);
}
}
void add_sb_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord) {
VTR_ASSERT(valid_tile_id(tile_id));
/* Ensure the coordinates are not duplicated */
auto result = std::find(sb_coords_.begin(), sb_coords_.end(), coord);
if (result == sb_coords_.end()) {
sb_coords_[tile_id].push_back(coord);
}
}
bool FabricTileId::valid_tile_id(const FabricTileId& tile_id) const {
return (size_t(tile_id) < ids_.size()) && (tile_id == ids_[tile_id]);
}
} /* End namespace openfpga*/

View File

@ -0,0 +1,73 @@
#ifndef FABRIC_TILE_H
#define FABRIC_TILE_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <vector>
#include "device_rr_gsb.h"
#include "fabric_tile_fwd.h"
#include "vtr_geometry.h"
#include "vtr_vector.h"
/* namespace openfpga begins */
namespace openfpga {
/********************************************************************
* Object models the tiles in an FPGA fabric
* This includes:
* 1. a collection of tiles, each which contains a programmable block and
*surrounding routing blocks
* 2. a collection of unique tiles
*******************************************************************/
class FabricTile {
public: /* Contructors */
FabricTile(const DeviceRRGSB& device_rr_gsb);
public: /* Accessors */
vtr::Point<size_t> tile_coordinate(const FabricTileId& tile_id) const;
/** @brief With a given coordinate, find the id of the unique tile (which is
* the same as the tile in structure) */
FabricTileId unique_tile(const vtr::Point<size_t>& coord) const;
public: /* Mutators */
FabricTileId create_tile();
void set_tile_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord);
void add_pb_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord);
void add_cbx_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord);
void add_cby_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord);
void add_sb_coordinate(const FabricTileId& tile_id,
const vtr::Point<size_t>& coord);
/** @brief Build a list of unique tiles by comparing the coordinates in
* DeviceRRGSB */
void build_unique_tiles();
/** @brief Clear all the content */
void clear();
private: /* Validators */
bool valid_tile_id(const FabricTileId& tile_id) const;
private: /* Internal builders */
private: /* Internal Data */
vtr::vector<FabricTileId, FabricTileId> ids_;
vtr::vector<FabricTileId, vtr::Point<size_t>> coords_;
/* Coordinates w.r.t. RRGSB */
vtr::vector<FabricTileId, vtr::Point<size_t>> pb_coords_;
vtr::vector<FabricTileId, std::vector<vtr::Point<size_t>>> cbx_coords_;
vtr::vector<FabricTileId, std::vector<vtr::Point<size_t>>> cby_coords_;
vtr::vector<FabricTileId, std::vector<vtr::Point<size_t>>> sb_coords_;
std::vector<std::vector<FabricTileId>>
unique_tile_ids_; /* Use [x][y] to get the id of the unique tile with a
given coordinate */
/* Cached data */
const DeviceRRGSB& device_rr_gsb_;
};
} /* End namespace openfpga*/
#endif

View File

@ -0,0 +1,23 @@
/**************************************************
* This file includes only declarations for
* the data structures for fabric tiles
* Please refer to fabric_tiles.h for more details
*************************************************/
#ifndef FABRIC_TILE_FWD_H
#define FABRIC_TILE_FWD_H
#include "vtr_strong_id.h"
/* begin namespace openfpga */
namespace openfpga {
/* Strong Ids for ModuleManager */
struct fabric_tile_id_tag;
typedef vtr::StrongId<fabric_tile_id_tag> FabricTileId;
class FabricTile;
} /* end namespace openfpga */
#endif

View File

@ -153,7 +153,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
cmd_context.option_enable(cmd, opt_frame_view),
cmd_context.option_enable(cmd, opt_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
predefined_fabric_key,
predefined_fabric_key, tile_config,
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
cmd_context.option_enable(cmd, opt_verbose));

View File

@ -35,7 +35,8 @@ int build_device_module_graph(
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const bool& generate_random_fabric_key, const bool& verbose) {
const TileConfig& tile_config, const bool& generate_random_fabric_key,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build fabric module graph");
int status = CMD_EXEC_SUCCESS;
@ -99,6 +100,18 @@ int build_device_module_graph(
openfpga_ctx.arch().config_protocol.type(), sram_model, verbose);
}
/* Build tile modules if defined */
FabricTile fabric_tile(openfpga_ctx.device_rr_gsb());
if (!tile_config.empty()) {
/* TODO: Build detailed tile-level information */
status = build_fabric_tile(fabric_tile, tile_config, vpr_device_ctx.grid, openfpga_ctx.device_rr_gsb());
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
/* TODO: Build the modules */
// build_tile_modules(module_manager, fabric_tile);
}
/* Build FPGA fabric top-level module */
status = build_top_module(
module_manager, decoder_lib, blwl_sr_banks, openfpga_ctx.arch().circuit_lib,

View File

@ -7,6 +7,7 @@
#include "fabric_key.h"
#include "io_name_map.h"
#include "openfpga_context.h"
#include "tile_config.h"
#include "vpr_context.h"
/********************************************************************
@ -22,7 +23,8 @@ int build_device_module_graph(
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const bool& generate_random_fabric_key, const bool& verbose);
const TileConfig& tile_config, const bool& generate_random_fabric_key,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -0,0 +1,133 @@
/********************************************************************
* This file includes functions that are used to build the location
* map information for the top-level module of the FPGA fabric
* It helps OpenFPGA to link the I/O port index in top-level module
* to the VPR I/O mapping results
*******************************************************************/
#include <algorithm>
#include <map>
/* Headers from vtrutil library */
#include "command_exit_codes.h"
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from vpr library */
#include "build_fabric_tile.h"
#include "openfpga_naming.h"
#include "openfpga_reserved_words.h"
/* begin namespace openfpga */
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
*******************************************************************/
static int build_fabric_tile_top_left(FabricTile& fabric_tile, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb) {
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_type_ptr phy_tile_type = grids.get_physical_type(ix, iy);
bool skip_add_pb = false;
vtr::Point<size_t> curr_tile_coord(ix, iy);
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;
/* Need to create a new tile here */
curr_tile_id = fabric_tile.create_tile();
fabric_tile.set_coordinate(curr_tile_coord);
}
/* Skip width, height > 1 tiles (mostly heterogeneous blocks) */
if ((0 < grids.get_width_offset(ix, iy)) ||
(0 < grids.get_height_offset(ix, iy))) {
/* 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(ix, iy),
iy - grids.get_height_offset(ix, iy));
skip_add_pb = true;
curr_tile_id = fabric_tile.find_tile(root_tile_coord);
} else {
/* Need to create a new tile here */
curr_tile_id = fabric_tile.create_tile();
fabric_tile.set_coordinate(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);
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);
}
/* 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 - 1);
if (!device_rr_gsb.is_gsb_exist(curr_gsb_coord)) {
continue;
}
const RRGSB& curr_rr_gsb = device_rr_gsb.get_gsb(curr_gsb_coord);
if (curr_rr_gsb.is_cb_exist(CHANX)) {
fabric_tile.add_cbx_coordinate(curr_tile_id,
curr_rr_gsb.get_cb_coordinate(CHANX));
}
if (curr_rr_gsb.is_cb_exist(CHANY)) {
fabric_tile.add_cby_coordinate(curr_tile_id,
curr_rr_gsb.get_cb_coordinate(CHANY));
}
if (curr_rr_gsb.is_sb_exist()) {
fabric_tile.add_sb_coordinate(curr_tile_id,
curr_rr_gsb.get_sb_coordinate());
}
}
}
return status_code;
}
/********************************************************************
* Build tile-level information for a given FPGA fabric, w.r.t. to configuration
*******************************************************************/
int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb) {
vtr::ScopedStartFinishTimer timer(
"Build tile-level information for the FPGA fabric");
int status_code = CMD_EXEC_SUCCESS;
/* Depending on the selected style, follow different approaches */
if (tile_config.style() == TileConfig::e_style::TOP_LEFT) {
status_code = build_fabric_tile_style_top_left(fabric_tile, grids, device_rr_gsb);
} else {
/* Error out for styles that are not supported yet! */
VTR_LOG_ERROR("Tile style '%s' is not supported yet!\n",
tile_config.style_to_string().c_str());
status_code = CMD_EXEC_FATAL_ERROR;
}
return status_code;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,26 @@
#ifndef BUILD_FABRIC_TILE_H
#define BUILD_FABRIC_TILE_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include "fabric_tile.h"
#include "tile_config.h"
#include "device_grid.h"
#include "device_rr_gsb.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb);
} /* end namespace openfpga */
#endif