[core] now start to develop the tile instances under the top module
This commit is contained in:
parent
2e69eebea0
commit
a06b9a0f48
|
@ -1,9 +1,9 @@
|
|||
/************************************************************************
|
||||
* Member functions for class FabricTile
|
||||
***********************************************************************/
|
||||
#include "build_top_module_utils.h"
|
||||
#include "fabric_tile.h"
|
||||
|
||||
#include "build_top_module_utils.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
|
@ -75,15 +75,17 @@ bool FabricTile::pb_in_tile(const FabricTileId& tile_id,
|
|||
const vtr::Point<size_t>& coord,
|
||||
const bool& use_gsb_coord) const {
|
||||
if (use_gsb_coord) {
|
||||
return !pb_gsb_coords_[tile_id].empty() && find_pb_index_in_tile(tile_id, coord, use_gsb_coord) != pb_gsb_coords_[tile_id].size();
|
||||
return !pb_gsb_coords_[tile_id].empty() &&
|
||||
find_pb_index_in_tile(tile_id, coord, use_gsb_coord) !=
|
||||
pb_gsb_coords_[tile_id].size();
|
||||
}
|
||||
return !pb_coords_[tile_id].empty() && find_pb_index_in_tile(tile_id, coord) != pb_coords_[tile_id].size();
|
||||
return !pb_coords_[tile_id].empty() &&
|
||||
find_pb_index_in_tile(tile_id, coord) != pb_coords_[tile_id].size();
|
||||
}
|
||||
|
||||
size_t FabricTile::find_pb_index_in_tile(
|
||||
const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord,
|
||||
const bool& use_gsb_coord) const {
|
||||
size_t FabricTile::find_pb_index_in_tile(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord,
|
||||
const bool& use_gsb_coord) const {
|
||||
VTR_ASSERT(valid_tile_id(tile_id));
|
||||
if (use_gsb_coord) {
|
||||
for (size_t idx = 0; idx < pb_gsb_coords_[tile_id].size(); ++idx) {
|
||||
|
@ -108,7 +110,8 @@ size_t FabricTile::find_pb_index_in_tile(
|
|||
|
||||
bool FabricTile::sb_in_tile(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord) const {
|
||||
return !sb_coords_[tile_id].empty() && find_sb_index_in_tile(tile_id, coord) != sb_coords_[tile_id].size();
|
||||
return !sb_coords_[tile_id].empty() &&
|
||||
find_sb_index_in_tile(tile_id, coord) != sb_coords_[tile_id].size();
|
||||
}
|
||||
|
||||
size_t FabricTile::find_sb_index_in_tile(
|
||||
|
@ -129,11 +132,13 @@ bool FabricTile::cb_in_tile(const FabricTileId& tile_id,
|
|||
const vtr::Point<size_t>& coord) const {
|
||||
switch (cb_type) {
|
||||
case CHANX:
|
||||
return !cbx_coords_[tile_id].empty() && find_cb_index_in_tile(tile_id, cb_type, coord) ==
|
||||
cbx_coords_[tile_id].size();
|
||||
return !cbx_coords_[tile_id].empty() &&
|
||||
find_cb_index_in_tile(tile_id, cb_type, coord) ==
|
||||
cbx_coords_[tile_id].size();
|
||||
case CHANY:
|
||||
return !cby_coords_[tile_id].empty() && find_cb_index_in_tile(tile_id, cb_type, coord) ==
|
||||
cby_coords_[tile_id].size();
|
||||
return !cby_coords_[tile_id].empty() &&
|
||||
find_cb_index_in_tile(tile_id, cb_type, coord) ==
|
||||
cby_coords_[tile_id].size();
|
||||
default:
|
||||
VTR_LOG("Invalid type of connection block!\n");
|
||||
exit(1);
|
||||
|
@ -307,7 +312,10 @@ bool FabricTile::equivalent_tile(const FabricTileId& tile_a,
|
|||
for (size_t iblk = 0; iblk < pb_coords_[tile_a].size(); ++iblk) {
|
||||
vtr::Point<size_t> tile_a_pb_coord = pb_coords_[tile_a][iblk];
|
||||
vtr::Point<size_t> tile_b_pb_coord = pb_coords_[tile_b][iblk];
|
||||
if (generate_grid_block_module_name_in_top_module(std::string(), grids, tile_a_pb_coord) != generate_grid_block_module_name_in_top_module(std::string(), grids, tile_b_pb_coord)) {
|
||||
if (generate_grid_block_module_name_in_top_module(std::string(), grids,
|
||||
tile_a_pb_coord) !=
|
||||
generate_grid_block_module_name_in_top_module(std::string(), grids,
|
||||
tile_b_pb_coord)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ class FabricTile {
|
|||
/** @brief Return a list of unique tiles */
|
||||
std::vector<FabricTileId> unique_tiles() const;
|
||||
/** @brief Find the index of a programmable block in the internal list by a
|
||||
* given coordinate. Note that the coord can be either the one in device grid or the one of gsb which the programmable block belongs to */
|
||||
* given coordinate. Note that the coord can be either the one in device grid
|
||||
* or the one of gsb which the programmable block belongs to */
|
||||
size_t find_pb_index_in_tile(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord,
|
||||
const bool& use_gsb_coord = false) const;
|
||||
|
@ -52,10 +53,11 @@ class FabricTile {
|
|||
size_t find_cb_index_in_tile(const FabricTileId& tile_id,
|
||||
const t_rr_type& cb_type,
|
||||
const vtr::Point<size_t>& coord) const;
|
||||
/** @brief Check if a programmable block (with a coordinate) exists in a tile. Note that the coord can be either the one in device grid or the one of gsb which the programmable block belongs to
|
||||
/** @brief Check if a programmable block (with a coordinate) exists in a tile.
|
||||
* Note that the coord can be either the one in device grid or the one of gsb
|
||||
* which the programmable block belongs to
|
||||
*/
|
||||
bool pb_in_tile(const FabricTileId& tile_id,
|
||||
const vtr::Point<size_t>& coord,
|
||||
bool pb_in_tile(const FabricTileId& tile_id, const vtr::Point<size_t>& coord,
|
||||
const bool& use_gsb_coord = false) const;
|
||||
/** @brief Check if a switch block (with a coordinate) exists in a tile */
|
||||
bool sb_in_tile(const FabricTileId& tile_id,
|
||||
|
@ -107,7 +109,12 @@ class FabricTile {
|
|||
vtr::vector<FabricTileId, FabricTileId> ids_;
|
||||
vtr::vector<FabricTileId, vtr::Point<size_t>> coords_;
|
||||
/* Coordinates w.r.t. RRGSB
|
||||
* Note that we keep two coordinates for the programmable block: regular one (in device grid) and the one in gsb. This is to ease the lookup/search for coordinates through both device grid and gsb. Client functions need one of the them depending on the scenario. In future, once we refactor the RRGSB organization (to follow bottom-left corner style). This limitation can be resolved.
|
||||
* Note that we keep two coordinates for the programmable block: regular one
|
||||
* (in device grid) and the one in gsb. This is to ease the lookup/search for
|
||||
* coordinates through both device grid and gsb. Client functions need one of
|
||||
* the them depending on the scenario. In future, once we refactor the RRGSB
|
||||
* organization (to follow bottom-left corner style). This limitation can be
|
||||
* resolved.
|
||||
*/
|
||||
vtr::vector<FabricTileId, std::vector<vtr::Point<size_t>>> pb_coords_;
|
||||
vtr::vector<FabricTileId, std::vector<vtr::Point<size_t>>> pb_gsb_coords_;
|
||||
|
|
|
@ -46,15 +46,19 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
|
|||
if (true == is_empty_type(phy_tile_type)) {
|
||||
skip_add_pb = true;
|
||||
if (!device_rr_gsb.is_gsb_exist(curr_gsb_coord)) {
|
||||
VTR_LOGV(verbose, "Skip tile[%lu][%lu] as it is empty\n", curr_tile_coord.x(), curr_tile_coord.y());
|
||||
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());
|
||||
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(ix, iy)) ||
|
||||
(0 < grids.get_height_offset(ix, iy))) {
|
||||
/* Skip width, height > 1 tiles (mostly heterogeneous blocks) */
|
||||
(0 < grids.get_height_offset(ix, iy))) {
|
||||
/* 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
|
||||
*/
|
||||
|
@ -62,11 +66,16 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
|
|||
ix - grids.get_width_offset(ix, iy),
|
||||
iy - grids.get_height_offset(ix, iy));
|
||||
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());
|
||||
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);
|
||||
} 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());
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -78,7 +87,8 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
|
|||
|
||||
/* 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);
|
||||
fabric_tile.add_pb_coordinate(curr_tile_id, curr_tile_coord,
|
||||
curr_gsb_coord);
|
||||
}
|
||||
/* The gsb coordinate is different than the grid coordinate when the
|
||||
* top-left style is considered
|
||||
|
@ -116,10 +126,8 @@ static int build_fabric_tile_style_top_left(FabricTile& fabric_tile,
|
|||
/********************************************************************
|
||||
* 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,
|
||||
int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config,
|
||||
const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb,
|
||||
const bool& verbose) {
|
||||
vtr::ScopedStartFinishTimer timer(
|
||||
"Build tile-level information for the FPGA fabric");
|
||||
|
@ -130,8 +138,8 @@ int build_fabric_tile(FabricTile& fabric_tile,
|
|||
|
||||
/* 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, verbose);
|
||||
status_code = build_fabric_tile_style_top_left(fabric_tile, grids,
|
||||
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",
|
||||
|
@ -146,7 +154,8 @@ int build_fabric_tile(FabricTile& fabric_tile,
|
|||
/* Build unique tiles to compress the number of tile modules to be built in
|
||||
* later steps */
|
||||
status_code = fabric_tile.build_unique_tiles(grids, device_rr_gsb);
|
||||
VTR_LOGV(verbose, "Extracted %lu uniques tiles from the FPGA fabric\n", fabric_tile.unique_tiles().size());
|
||||
VTR_LOGV(verbose, "Extracted %lu uniques tiles from the FPGA fabric\n",
|
||||
fabric_tile.unique_tiles().size());
|
||||
|
||||
return status_code;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int build_fabric_tile(FabricTile& fabric_tile,
|
||||
const TileConfig& tile_config,
|
||||
const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config,
|
||||
const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -168,10 +168,14 @@ static int build_tile_module_port_and_nets_between_sb_and_pb(
|
|||
|
||||
/* Check if the grid is inside the tile, if not, create ports */
|
||||
if (fabric_tile.pb_in_tile(fabric_tile_id, grid_coordinate)) {
|
||||
VTR_LOGV(verbose, "Build intra-tile nets between switch block '%s' and programmable block '%s[%lu][%lu]'\n", sink_sb_module_name.c_str(), src_grid_module_name.c_str(), grid_coordinate.x(), grid_coordinate.y());
|
||||
VTR_LOGV(verbose,
|
||||
"Build intra-tile nets between switch block '%s' and "
|
||||
"programmable block '%s[%lu][%lu]'\n",
|
||||
sink_sb_module_name.c_str(), src_grid_module_name.c_str(),
|
||||
grid_coordinate.x(), grid_coordinate.y());
|
||||
if (!frame_view) {
|
||||
size_t src_grid_instance =
|
||||
pb_instances[fabric_tile.find_pb_index_in_tile(fabric_tile_id,
|
||||
pb_instances[fabric_tile.find_pb_index_in_tile(fabric_tile_id,
|
||||
grid_coordinate)];
|
||||
|
||||
/* Source and sink port should match in size */
|
||||
|
@ -388,7 +392,7 @@ static int build_tile_module_port_and_nets_between_cb_and_pb(
|
|||
if (fabric_tile.pb_in_tile(fabric_tile_id, grid_coordinate)) {
|
||||
if (!frame_view) {
|
||||
size_t sink_grid_instance =
|
||||
pb_instances[fabric_tile.find_pb_index_in_tile(fabric_tile_id,
|
||||
pb_instances[fabric_tile.find_pb_index_in_tile(fabric_tile_id,
|
||||
grid_coordinate)];
|
||||
|
||||
/* Source and sink port should match in size */
|
||||
|
@ -1004,7 +1008,8 @@ static int build_tile_module(
|
|||
fabric_tile.pb_coordinates(fabric_tile_id)) {
|
||||
t_physical_tile_type_ptr phy_tile =
|
||||
grids.get_physical_type(grid_coord.x(), grid_coord.y());
|
||||
VTR_LOGV(verbose, "Try to find pb at [%lu][%lu]\n", grid_coord.x(), grid_coord.y());
|
||||
VTR_LOGV(verbose, "Try to find pb at [%lu][%lu]\n", 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_border_side(
|
||||
|
|
|
@ -421,18 +421,12 @@ static void add_top_module_io_children(
|
|||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print the top-level module for the FPGA fabric in Verilog format
|
||||
* This function will
|
||||
* 1. name the top-level module
|
||||
* 2. include dependent netlists
|
||||
* - User defined netlists
|
||||
* - Auto-generated netlists
|
||||
* 3. Add the submodules to the top-level graph
|
||||
* 4. Add module nets to connect datapath ports
|
||||
* 5. Add module nets/submodules to connect configuration ports
|
||||
* Add the fine-grained instances to the top module of FPGA fabric
|
||||
* The fine-grained instances include programmable blocks, connection blocks and
|
||||
*switch blocks, each of which is an instance under the top module
|
||||
*******************************************************************/
|
||||
int build_top_module(
|
||||
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
||||
static int build_top_module_fine_grained_child_instances(
|
||||
ModuleManager& module_manager, const ModuleId& top_module,
|
||||
MemoryBankShiftRegisterBanks& blwl_sr_banks,
|
||||
const CircuitLibrary& circuit_lib, const ClockNetwork& clk_ntwk,
|
||||
const RRClockSpatialLookup& rr_clock_lookup,
|
||||
|
@ -442,19 +436,8 @@ int build_top_module(
|
|||
const ArchDirect& arch_direct, const ConfigProtocol& config_protocol,
|
||||
const CircuitModelId& sram_model, const bool& frame_view,
|
||||
const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin,
|
||||
const FabricKey& fabric_key, const bool& generate_random_fabric_key) {
|
||||
vtr::ScopedStartFinishTimer timer("Build FPGA fabric module");
|
||||
|
||||
const FabricKey& fabric_key) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Create a module as the top-level fabric, and add it to the module manager
|
||||
*/
|
||||
std::string top_module_name = generate_fpga_top_module_name();
|
||||
ModuleId top_module = module_manager.add_module(top_module_name);
|
||||
|
||||
/* Label module usage */
|
||||
module_manager.set_module_usage(top_module, ModuleManager::MODULE_TOP);
|
||||
|
||||
std::map<t_rr_type, vtr::Matrix<size_t>> cb_instance_ids;
|
||||
|
||||
/* Add sub modules, which are grid, SB and CBX/CBY modules as instances */
|
||||
|
@ -551,6 +534,52 @@ int build_top_module(
|
|||
return status;
|
||||
}
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print the top-level module for the FPGA fabric in Verilog format
|
||||
* This function will
|
||||
* 1. name the top-level module
|
||||
* 2. include dependent netlists
|
||||
* - User defined netlists
|
||||
* - Auto-generated netlists
|
||||
* 3. Add the submodules to the top-level graph
|
||||
* 4. Add module nets to connect datapath ports
|
||||
* 5. Add module nets/submodules to connect configuration ports
|
||||
*******************************************************************/
|
||||
int build_top_module(
|
||||
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
||||
MemoryBankShiftRegisterBanks& blwl_sr_banks,
|
||||
const CircuitLibrary& circuit_lib, const ClockNetwork& clk_ntwk,
|
||||
const RRClockSpatialLookup& rr_clock_lookup,
|
||||
const VprDeviceAnnotation& vpr_device_annotation, const DeviceGrid& grids,
|
||||
const TileAnnotation& tile_annotation, const RRGraphView& rr_graph,
|
||||
const DeviceRRGSB& device_rr_gsb, const TileDirect& tile_direct,
|
||||
const ArchDirect& arch_direct, const ConfigProtocol& config_protocol,
|
||||
const CircuitModelId& sram_model, const bool& frame_view,
|
||||
const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin,
|
||||
const FabricKey& fabric_key, const bool& generate_random_fabric_key) {
|
||||
vtr::ScopedStartFinishTimer timer("Build FPGA fabric module");
|
||||
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Create a module as the top-level fabric, and add it to the module manager
|
||||
*/
|
||||
std::string top_module_name = generate_fpga_top_module_name();
|
||||
ModuleId top_module = module_manager.add_module(top_module_name);
|
||||
|
||||
/* Label module usage */
|
||||
module_manager.set_module_usage(top_module, ModuleManager::MODULE_TOP);
|
||||
|
||||
status = build_top_module_fine_grained_child_instances(
|
||||
module_manager, top_module, blwl_sr_banks, circuit_lib, clk_ntwk,
|
||||
rr_clock_lookup, vpr_device_annotation, grids, tile_annotation, rr_graph,
|
||||
device_rr_gsb, tile_direct, arch_direct, config_protocol, sram_model,
|
||||
frame_view, compact_routing_hierarchy, duplicate_grid_pin, fabric_key);
|
||||
if (status != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Shuffle the configurable children in a random sequence */
|
||||
if (true == generate_random_fabric_key) {
|
||||
|
|
Loading…
Reference in New Issue