[core] developing top-left style tile info
This commit is contained in:
parent
091ac88c7e
commit
c2ef5ca408
|
@ -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*/
|
|
@ -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
|
|
@ -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
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
Loading…
Reference in New Issue