[core] developing tile module builder
This commit is contained in:
parent
c8a840f5ad
commit
ba4b7e3522
|
@ -17,6 +17,33 @@ vtr::Point<size_t> FabricTile::tile_coordinate(
|
|||
return coords_[tile_id];
|
||||
}
|
||||
|
||||
std::vector<vtr::Point<size_t>> FabricTile::pb_coordinates(
|
||||
const FabricTileId& tile_id) const {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
return pb_coords_[tile_id];
|
||||
}
|
||||
|
||||
std::vector<vtr::Point<size_t>> FabricTile::cb_coordinates(
|
||||
const FabricTileId& tile_id, const t_rr_type& cb_type) const {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
switch (cb_type) {
|
||||
case CHANX:
|
||||
return cbx_coords_[tile_id];
|
||||
case CHANY:
|
||||
return cby_coords_[tile_id];
|
||||
default:
|
||||
VTR_LOG("Invalid type of connection block!\n");
|
||||
exit(1);
|
||||
}
|
||||
return std::vector<vtr::Point<size_t>>();
|
||||
}
|
||||
|
||||
std::vector<vtr::Point<size_t>> FabricTile::sb_coordinates(
|
||||
const FabricTileId& tile_id) const {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
return sb_coords_[tile_id];
|
||||
}
|
||||
|
||||
FabricTileId FabricTile::unique_tile(const vtr::Point<size_t>& coord) const {
|
||||
/* Return invalid Id when out of range! */
|
||||
if (coord.x() < tile_coord2unique_tile_ids_.size()) {
|
||||
|
@ -45,6 +72,10 @@ FabricTileId FabricTile::find_tile(const vtr::Point<size_t>& coord) const {
|
|||
return tile_coord2id_lookup_[coord.x()][coord.y()];
|
||||
}
|
||||
|
||||
std::vector<FabricTileId> FabricTile::unique_tiles() const {
|
||||
return unique_tile_ids_;
|
||||
}
|
||||
|
||||
FabricTileId FabricTile::create_tile(const vtr::Point<size_t>& coord) {
|
||||
FabricTileId tile_id = FabricTileId(ids_.size());
|
||||
ids_.push_back(tile_id);
|
||||
|
@ -117,19 +148,24 @@ bool FabricTile::set_tile_coordinate(const FabricTileId& tile_id,
|
|||
void FabricTile::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;
|
||||
pb_coords_[tile_id].push_back(coord);
|
||||
}
|
||||
|
||||
void FabricTile::add_cbx_coordinate(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord) {
|
||||
void FabricTile::add_cb_coordinate(const FabricTileId& tile_id,
|
||||
const t_rr_type& cb_type,
|
||||
const vtr::Point<size_t>& coord) {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
cbx_coords_[tile_id].push_back(coord);
|
||||
}
|
||||
|
||||
void FabricTile::add_cby_coordinate(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord) {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
cby_coords_[tile_id].push_back(coord);
|
||||
switch (cb_type) {
|
||||
case CHANX:
|
||||
cbx_coords_[tile_id].push_back(coord);
|
||||
break;
|
||||
case CHANY:
|
||||
cby_coords_[tile_id].push_back(coord);
|
||||
break;
|
||||
default:
|
||||
VTR_LOG("Invalid type of connection block!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void FabricTile::add_sb_coordinate(const FabricTileId& tile_id,
|
||||
|
@ -158,17 +194,22 @@ bool FabricTile::equivalent_tile(const FabricTileId& tile_a,
|
|||
const FabricTileId& tile_b,
|
||||
const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb) const {
|
||||
/* The pb of two tiles should be the same, otherwise not equivalent */
|
||||
if (grids.get_physical_type(pb_coords_[tile_a].x(), pb_coords_[tile_a].y()) !=
|
||||
grids.get_physical_type(pb_coords_[tile_b].x(), pb_coords_[tile_b].y())) {
|
||||
return false;
|
||||
}
|
||||
/* The number of cbx, cby and sb blocks should be the same */
|
||||
if (cbx_coords_[tile_a].size() != cbx_coords_[tile_b].size() ||
|
||||
if (pb_coords_[tile_a].size() != pb_coords_[tile_b].size() ||
|
||||
cbx_coords_[tile_a].size() != cbx_coords_[tile_b].size() ||
|
||||
cby_coords_[tile_a].size() != cby_coords_[tile_b].size() ||
|
||||
sb_coords_[tile_a].size() != sb_coords_[tile_b].size()) {
|
||||
return false;
|
||||
}
|
||||
/* The pb of two tiles should be the same, otherwise not equivalent */
|
||||
for (size_t iblk = 0; iblk < pb_coords_[tile_a].size(); ++iblk) {
|
||||
if (grids.get_physical_type(pb_coords_[tile_a][iblk].x(),
|
||||
pb_coords_[tile_a][iblk].y()) !=
|
||||
grids.get_physical_type(pb_coords_[tile_b][iblk].x(),
|
||||
pb_coords_[tile_b][iblk].y())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* Each CBx should have the same unique modules in the device rr_gsb */
|
||||
for (size_t iblk = 0; iblk < cbx_coords_[tile_a].size(); ++iblk) {
|
||||
if (device_rr_gsb.get_cb_unique_module_index(CHANX,
|
||||
|
|
|
@ -28,11 +28,19 @@ class FabricTile {
|
|||
|
||||
public: /* Accessors */
|
||||
vtr::Point<size_t> tile_coordinate(const FabricTileId& tile_id) const;
|
||||
std::vector<vtr::Point<size_t>> pb_coordinates(
|
||||
const FabricTileId& tile_id) const;
|
||||
std::vector<vtr::Point<size_t>> cb_coordinates(
|
||||
const FabricTileId& tile_id, const t_rr_type& cb_type) const;
|
||||
std::vector<vtr::Point<size_t>> sb_coordinates(
|
||||
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;
|
||||
/** @brief Find the tile info with a given coordinate */
|
||||
FabricTileId find_tile(const vtr::Point<size_t>& coord) const;
|
||||
/** @brief Return a list of unique tiles */
|
||||
std::vector<FabricTileId> unique_tiles() const;
|
||||
|
||||
public: /* Mutators */
|
||||
FabricTileId create_tile(const vtr::Point<size_t>& coord);
|
||||
|
@ -40,10 +48,8 @@ class FabricTile {
|
|||
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_cb_coordinate(const FabricTileId& tile_id, const t_rr_type& cb_type,
|
||||
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
|
||||
|
@ -76,7 +82,7 @@ class FabricTile {
|
|||
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>>> 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_;
|
||||
|
|
|
@ -497,6 +497,13 @@ std::string generate_switch_block_module_name(
|
|||
std::string("_"));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the module name for a switch block with a given index
|
||||
*********************************************************************/
|
||||
std::string generate_tile_module_name(const size_t& index) {
|
||||
return std::string("tile_" + std::to_string(index));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the module name for a connection block with a given coordinate
|
||||
*********************************************************************/
|
||||
|
|
|
@ -110,6 +110,8 @@ std::string generate_switch_block_module_name(
|
|||
std::string generate_connection_block_module_name(
|
||||
const t_rr_type& cb_type, const vtr::Point<size_t>& coordinate);
|
||||
|
||||
std::string generate_tile_module_name(const size_t& index);
|
||||
|
||||
std::string generate_sb_mux_instance_name(const std::string& prefix,
|
||||
const e_side& sb_side,
|
||||
const size_t& track_id,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "build_memory_modules.h"
|
||||
#include "build_mux_modules.h"
|
||||
#include "build_routing_modules.h"
|
||||
#include "build_tile_modules.h"
|
||||
#include "build_top_module.h"
|
||||
#include "build_wire_modules.h"
|
||||
#include "command_exit_codes.h"
|
||||
|
@ -105,14 +106,17 @@ int build_device_module_graph(
|
|||
FabricTile fabric_tile(vtr::Point<size_t>(vpr_device_ctx.grid.width(),
|
||||
vpr_device_ctx.grid.height()));
|
||||
if (!tile_config.is_valid()) {
|
||||
/* TODO: Build detailed tile-level information */
|
||||
/* 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_tile_modules(module_manager, fabric_tile, vpr_device_ctx.grid,
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
openfpga_ctx.arch().circuit_lib, sram_model,
|
||||
openfpga_ctx.arch().config_protocol.type(), verbose);
|
||||
}
|
||||
|
||||
/* Build FPGA fabric top-level module */
|
||||
|
|
|
@ -114,6 +114,7 @@ IoLocationMap build_fabric_io_location_map(const ModuleManager& module_manager,
|
|||
if (curr_io_index == io_counter.end()) {
|
||||
io_counter[gpio_port.get_name()] = 0;
|
||||
}
|
||||
/* FIXME: Will cause critical bugs when tile modules are added */
|
||||
io_location_map.set_io_index(coord.x(), coord.y(), subchild_coord.x(),
|
||||
gpio_port.get_name(),
|
||||
io_counter[gpio_port.get_name()]);
|
||||
|
|
|
@ -93,13 +93,11 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
|
|||
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_sb_coordinate());
|
||||
}
|
||||
if (curr_rr_gsb.is_cb_exist(CHANY)) {
|
||||
fabric_tile.add_cby_coordinate(curr_tile_id,
|
||||
curr_rr_gsb.get_sb_coordinate());
|
||||
for (t_rr_type cb_type : {CHANX, CHANY}) {
|
||||
if (curr_rr_gsb.is_cb_exist(cb_type)) {
|
||||
fabric_tile.add_cb_coordinate(curr_tile_id, cb_type,
|
||||
curr_rr_gsb.get_sb_coordinate());
|
||||
}
|
||||
}
|
||||
if (curr_rr_gsb.is_sb_exist()) {
|
||||
fabric_tile.add_sb_coordinate(curr_tile_id,
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/********************************************************************
|
||||
* 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_tile_modules.h"
|
||||
#include "module_manager_utils.h"
|
||||
#include "openfpga_device_grid_utils.h"
|
||||
#include "openfpga_naming.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Build all the tile modules
|
||||
*******************************************************************/
|
||||
static int build_tile_module(
|
||||
ModuleManager& module_manager, const FabricTile& fabric_tile,
|
||||
const FabricTileId& fabric_tile_id, const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& sram_orgz_type, const bool& verbose) {
|
||||
int status_code = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Create the module */
|
||||
std::string module_name = generate_tile_module_name(size_t(fabric_tile_id));
|
||||
VTR_LOGV(verbose, "Building tile module '%s'...\n");
|
||||
ModuleId tile_module = module_manager.add_module(module_name);
|
||||
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
|
||||
|
||||
/* Add instance of programmable block */
|
||||
for (vtr::Point<size_t> grid_gsb_coord :
|
||||
fabric_tile.pb_coordinates(fabric_tile_id)) {
|
||||
const RRGSB& grid_rr_gsb = device_rr_gsb.get_gsb(grid_gsb_coord);
|
||||
vtr::Point<size_t> grid_coord = grid_rr_gsb.get_grid_coordinate();
|
||||
t_physical_tile_type_ptr phy_tile =
|
||||
grids.get_physical_type(grid_coord.x(), grid_coord.y());
|
||||
/* Empty type does not require a module */
|
||||
if (!is_empty_type(phy_tile)) {
|
||||
e_side grid_side = find_grid_side_by_coordinate(grids, grid_coord);
|
||||
std::string pb_module_name = generate_grid_block_module_name(
|
||||
std::string(GRID_MODULE_NAME_PREFIX), std::string(phy_tile->name),
|
||||
is_io_type(phy_tile), grid_side);
|
||||
ModuleId pb_module = module_manager.find_module(pb_module_name);
|
||||
if (!pb_module) {
|
||||
VTR_LOG_ERROR(
|
||||
"Failed to find pb module '%s' required by tile[%lu][%lu]!\n",
|
||||
pb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
size_t pb_instance = module_manager.num_instance(tile_module, pb_module);
|
||||
module_manager.add_child_module(tile_module, pb_module);
|
||||
if (0 < find_module_num_config_bits(module_manager, pb_module,
|
||||
circuit_lib, sram_model,
|
||||
sram_orgz_type)) {
|
||||
module_manager.add_configurable_child(tile_module, pb_module,
|
||||
pb_instance);
|
||||
}
|
||||
VTR_LOGV(verbose, "Added programmable module '%s' to tile[%lu][%lu]\n",
|
||||
pb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
}
|
||||
|
||||
/* Add instance of connection blocks */
|
||||
for (t_rr_type cb_type : {CHANX, CHANY}) {
|
||||
for (vtr::Point<size_t> cb_coord :
|
||||
fabric_tile.cb_coordinates(fabric_tile_id, cb_type)) {
|
||||
/* get the unique module coord */
|
||||
const RRGSB& unique_rr_gsb =
|
||||
device_rr_gsb.get_cb_unique_module(cb_type, cb_coord);
|
||||
vtr::Point<size_t> unique_cb_coord(unique_rr_gsb.get_cb_x(cb_type),
|
||||
unique_rr_gsb.get_cb_y(cb_type));
|
||||
std::string cb_module_name =
|
||||
generate_connection_block_module_name(cb_type, unique_cb_coord);
|
||||
ModuleId cb_module = module_manager.find_module(cb_module_name);
|
||||
if (!cb_module) {
|
||||
VTR_LOG_ERROR(
|
||||
"Failed to find connection block module '%s' required by "
|
||||
"tile[%lu][%lu]!\n",
|
||||
cb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
size_t cb_instance = module_manager.num_instance(tile_module, cb_module);
|
||||
module_manager.add_child_module(tile_module, cb_module);
|
||||
if (0 < find_module_num_config_bits(module_manager, cb_module,
|
||||
circuit_lib, sram_model,
|
||||
sram_orgz_type)) {
|
||||
module_manager.add_configurable_child(tile_module, cb_module,
|
||||
cb_instance);
|
||||
}
|
||||
VTR_LOGV(verbose,
|
||||
"Added connection block module '%s' to tile[%lu][%lu]\n",
|
||||
cb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
}
|
||||
|
||||
/* Add instance of switch blocks */
|
||||
for (vtr::Point<size_t> sb_coord :
|
||||
fabric_tile.sb_coordinates(fabric_tile_id)) {
|
||||
/* get the unique module coord */
|
||||
const RRGSB& unique_rr_gsb = device_rr_gsb.get_sb_unique_module(sb_coord);
|
||||
vtr::Point<size_t> unique_sb_coord(unique_rr_gsb.get_sb_x(),
|
||||
unique_rr_gsb.get_sb_y());
|
||||
std::string sb_module_name =
|
||||
generate_switch_block_module_name(unique_sb_coord);
|
||||
ModuleId sb_module = module_manager.find_module(sb_module_name);
|
||||
if (!sb_module) {
|
||||
VTR_LOG_ERROR(
|
||||
"Failed to find switch block module '%s' required by tile[%lu][%lu]!\n",
|
||||
sb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
size_t sb_instance = module_manager.num_instance(tile_module, sb_module);
|
||||
module_manager.add_child_module(tile_module, sb_module);
|
||||
if (0 < find_module_num_config_bits(module_manager, sb_module, circuit_lib,
|
||||
sram_model, sram_orgz_type)) {
|
||||
module_manager.add_configurable_child(tile_module, sb_module,
|
||||
sb_instance);
|
||||
}
|
||||
VTR_LOGV(verbose, "Added switch block module '%s' to tile[%lu][%lu]\n",
|
||||
sb_module_name.c_str(), tile_coord.x(), tile_coord.y());
|
||||
}
|
||||
|
||||
/* TODO: Add module nets and ports */
|
||||
|
||||
VTR_LOGV(verbose, "Done\n");
|
||||
return status_code;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Build all the tile modules
|
||||
*******************************************************************/
|
||||
int build_tile_modules(ModuleManager& module_manager,
|
||||
const FabricTile& fabric_tile, const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const bool& verbose) {
|
||||
vtr::ScopedStartFinishTimer timer("Build tile modules for the FPGA fabric");
|
||||
|
||||
int status_code = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Build a module for each unique tile */
|
||||
for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) {
|
||||
status_code = build_tile_module(module_manager, fabric_tile, fabric_tile_id,
|
||||
grids, device_rr_gsb, circuit_lib,
|
||||
sram_model, sram_orgz_type, verbose);
|
||||
if (status_code != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status_code;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef BUILD_TILE_MODULES_H
|
||||
#define BUILD_TILE_MODULES_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "circuit_library.h"
|
||||
#include "config_protocol.h"
|
||||
#include "device_grid.h"
|
||||
#include "device_rr_gsb.h"
|
||||
#include "fabric_tile.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int build_tile_modules(ModuleManager& module_manager,
|
||||
const FabricTile& fabric_tile, const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -13,6 +13,28 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Identify if a grid locates the side of an FPGA fabric
|
||||
* - If on a side, return the side
|
||||
* - If not, return an invalid side
|
||||
*******************************************************************/
|
||||
e_side find_grid_side_by_coordinate(const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& coord) {
|
||||
if (coord.x() == 0) {
|
||||
return LEFT;
|
||||
}
|
||||
if (coord.y() == 0) {
|
||||
return BOTTOM;
|
||||
}
|
||||
if (coord.x() == grids.width() - 1) {
|
||||
return RIGHT;
|
||||
}
|
||||
if (coord.y() == grids.height() - 1) {
|
||||
return TOP;
|
||||
}
|
||||
return NUM_SIDES;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Create a list of the coordinates for the grids on the device perimeter
|
||||
* It follows a clockwise sequence when including the coordinates.
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
e_side find_grid_side_by_coordinate(const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& coord);
|
||||
|
||||
/* A constant array to walk through FPGA border sides clockwise*/
|
||||
constexpr std::array<e_side, 4> FPGA_SIDES_CLOCKWISE{TOP, RIGHT, BOTTOM, LEFT};
|
||||
|
||||
|
|
Loading…
Reference in New Issue