[core] added tile instances to top module builder
This commit is contained in:
parent
a06b9a0f48
commit
bd265334b5
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue