[core] added tile instances to top module builder

This commit is contained in:
tangxifan 2023-07-19 23:26:55 -07:00
parent a06b9a0f48
commit bd265334b5
5 changed files with 211 additions and 13 deletions

View File

@ -127,8 +127,8 @@ int build_device_module_graph(
openfpga_ctx.arch().tile_annotations, vpr_device_ctx.rr_graph,
openfpga_ctx.device_rr_gsb(), openfpga_ctx.tile_direct(),
openfpga_ctx.arch().arch_direct, openfpga_ctx.arch().config_protocol,
sram_model, frame_view, compress_routing, duplicate_grid_pin, fabric_key,
generate_random_fabric_key);
sram_model, fabric_tile, frame_view, compress_routing, duplicate_grid_pin,
fabric_key, generate_random_fabric_key);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;

View File

@ -537,6 +537,132 @@ static int build_top_module_fine_grained_child_instances(
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Add a instance of a tile module to the top module
*******************************************************************/
static size_t add_top_module_tile_instance(ModuleManager& module_manager,
const ModuleId& top_module,
const FabricTile& fabric_tile,
const FabricTileId& fabric_tile_id) {
/* Find the module name for this type of grid */
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
FabricTileId unique_fabric_tile_id = fabric_tile.unique_tile(tile_coord);
vtr::Point<size_t> unique_tile_coord =
fabric_tile.tile_coordinate(unique_fabric_tile_id);
std::string tile_module_name = generate_tile_module_name(unique_tile_coord);
ModuleId tile_module = module_manager.find_module(tile_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(tile_module));
/* Record the instance id */
size_t tile_instance = module_manager.num_instance(top_module, tile_module);
/* Add the module to top_module */
module_manager.add_child_module(top_module, tile_module, false);
/* Set an unique name to the instance
* Note: it is your risk to gurantee the name is unique!
*/
std::string instance_name = generate_tile_module_name(tile_coord);
module_manager.set_child_instance_name(top_module, tile_module, tile_instance,
instance_name);
return tile_instance;
}
/********************************************************************
* Add all the tiles as sub-modules across the fabric
* Here, we will iterate over the full fabric (coordinates)
* and instanciate the tile modules
*
* Return an 2-D array of instance ids of the grid modules that
* have been added
*
* This function assumes an island-style floorplanning for FPGA fabric
*
*
* +-----------------------------------+
* | I/O tiles |
* | TOP side |
* +-----------------------------------+
*
* +-----------+ +-----------------------------------+ +------------+
* | | | | | |
* | I/O tiles | | Core tiles | | I/O tiles |
* | LEFT side | | (CLB, Heterogeneous blocks, etc.) | | RIGHT side |
* | | | | | |
* +-----------+ +-----------------------------------+ +------------+
*
* +-----------------------------------+
* | I/O tiles |
* | BOTTOM side |
* +-----------------------------------+
*
*******************************************************************/
static int add_top_module_tile_instances(ModuleManager& module_manager,
const ModuleId& top_module,
vtr::Matrix<size_t>& tile_instance_ids,
const DeviceGrid& grids,
const FabricTile& fabric_tile) {
vtr::ScopedStartFinishTimer timer("Add tile instances to top module");
int status = CMD_EXEC_SUCCESS;
/* Reserve an array for the instance ids */
tile_instance_ids.resize({grids.width(), grids.height()});
tile_instance_ids.fill(size_t(-1));
/* Instanciate I/O grids */
/* Create the coordinate range for each side of FPGA fabric */
std::map<e_side, std::vector<vtr::Point<size_t>>> io_coordinates =
generate_perimeter_tile_coordinates(grids);
for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
for (const vtr::Point<size_t>& io_coord : io_coordinates[io_side]) {
FabricTileId fabric_tile_id = fabric_tile.find_tile(io_coord);
if (!fabric_tile.valid_tile_id(fabric_tile_id)) {
continue;
}
/* Add a tile module to top_module*/
tile_instance_ids[io_coord.x()][io_coord.y()] =
add_top_module_tile_instance(module_manager, top_module, fabric_tile,
fabric_tile_id);
}
}
/* Instanciate core grids
* IMPORTANT: sequence matters here, it impacts the I/O indexing.
* We should follow the same sequence as the build_io_location_map()!
* If you change the sequence of walking through grids here, you should change
* it in the build_io_location map()!
*/
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
vtr::Point<size_t> curr_coord(ix, iy);
FabricTileId fabric_tile_id = fabric_tile.find_tile(curr_coord);
if (!fabric_tile.valid_tile_id(fabric_tile_id)) {
continue;
}
/* Add a tile module to top_module*/
tile_instance_ids[curr_coord.x()][curr_coord.y()] =
add_top_module_tile_instance(module_manager, top_module, fabric_tile,
fabric_tile_id);
}
}
return status;
}
/********************************************************************
* Add the tile-level instances to the top module of FPGA fabric
* and build connects between them
*******************************************************************/
static int build_top_module_tile_child_instances(
ModuleManager& module_manager, const ModuleId& top_module,
const DeviceGrid& grids, const FabricTile& fabric_tile) {
int status = CMD_EXEC_SUCCESS;
vtr::Matrix<size_t> tile_instance_ids;
status = add_top_module_tile_instances(module_manager, top_module,
tile_instance_ids, grids, fabric_tile);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Print the top-level module for the FPGA fabric in Verilog format
* This function will
@ -557,9 +683,10 @@ int build_top_module(
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) {
const CircuitModelId& sram_model, const FabricTile& fabric_tile,
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;
@ -572,11 +699,18 @@ int build_top_module(
/* 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 (fabric_tile.empty()) {
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);
} else {
/* TODO: Build the tile instances under the top module */
status = build_top_module_tile_child_instances(module_manager, top_module,
grids, fabric_tile);
}
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}

View File

@ -15,6 +15,7 @@
#include "device_grid.h"
#include "device_rr_gsb.h"
#include "fabric_key.h"
#include "fabric_tile.h"
#include "memory_bank_shift_register_banks.h"
#include "module_manager.h"
#include "rr_clock_spatial_lookup.h"
@ -40,9 +41,10 @@ int build_top_module(
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);
const CircuitModelId& sram_model, const FabricTile& fabric_tile,
const bool& frame_view, const bool& compact_routing_hierarchy,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const bool& generate_random_fabric_key);
} /* end namespace openfpga */

View File

@ -61,4 +61,63 @@ generate_perimeter_grid_coordinates(const DeviceGrid& grids) {
return io_coordinates;
}
/********************************************************************
* Create a list of the coordinates for the tiles on the device perimeter
* It follows a clockwise sequence when including the coordinates.
* Note that different from the function for grids, this function include corner
*tiles! Detailed sequence is as follows:
* - Top-left
* - TOP side, from left most to the right
* - Top-right
* - Right side, from top to the bottom
* - Bottom-right
* - Bottom side, from right to the left
* - Bottom-left
* - Left side, from bottom to top
*
* Note:
* - This function offers a standard sequence to walk through the
* grids on the perimeter of an FPGA device
* When sequence matters, this function should be used to ensure
* consistency between functions.
*******************************************************************/
std::map<e_side, std::vector<vtr::Point<size_t>>>
generate_perimeter_tile_coordinates(const DeviceGrid& grids) {
/* Search the border side */
/* Create the coordinate range for each side of FPGA fabric */
std::vector<e_side> fpga_sides{TOP, RIGHT, BOTTOM, LEFT};
std::map<e_side, std::vector<vtr::Point<size_t>>> io_coordinates;
/* Top-left */
io_coordinates[TOP].push_back(vtr::Point<size_t>(0, grids.height() - 1));
/* TOP side*/
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
io_coordinates[TOP].push_back(vtr::Point<size_t>(ix, grids.height() - 1));
}
/* Top-Right */
io_coordinates[RIGHT].push_back(
vtr::Point<size_t>(grids.width() - 1, grids.height() - 1));
/* RIGHT side */
for (size_t iy = grids.height() - 2; iy > 0; --iy) {
io_coordinates[RIGHT].push_back(vtr::Point<size_t>(grids.width() - 1, iy));
}
/* Bottom-right */
io_coordinates[BOTTOM].push_back(vtr::Point<size_t>(grids.width() - 1, 0));
/* BOTTOM side*/
for (size_t ix = grids.width() - 2; ix > 0; --ix) {
io_coordinates[BOTTOM].push_back(vtr::Point<size_t>(ix, 0));
}
/* Bottom-left */
io_coordinates[BOTTOM].push_back(vtr::Point<size_t>(0, 0));
/* LEFT side */
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
io_coordinates[LEFT].push_back(vtr::Point<size_t>(0, iy));
}
return io_coordinates;
}
} /* end namespace openfpga */

View File

@ -24,6 +24,9 @@ constexpr std::array<e_side, 4> FPGA_SIDES_CLOCKWISE{TOP, RIGHT, BOTTOM, LEFT};
std::map<e_side, std::vector<vtr::Point<size_t>>>
generate_perimeter_grid_coordinates(const DeviceGrid& grids);
std::map<e_side, std::vector<vtr::Point<size_t>>>
generate_perimeter_tile_coordinates(const DeviceGrid& grids);
} /* end namespace openfpga */
#endif