[core] start working on the net build-up for tile instances under the top-level module

This commit is contained in:
tangxifan 2023-07-20 17:38:13 -07:00
parent 88c5d122ca
commit 6b92299e39
5 changed files with 204 additions and 13 deletions

View File

@ -16,6 +16,13 @@ vtr::Point<size_t> FabricTile::tile_coordinate(
return coords_[tile_id];
}
vtr::Point<size_t> FabricTile::unique_tile_coordinate(
const FabricTileId& tile_id) const {
vtr::Point<size_t> tile_coord = tile_coordinate(tile_id);
FabricTileId unique_fabric_tile_id = unique_tile(tile_coord);
return tile_coordinate(unique_fabric_tile_id);
}
std::vector<vtr::Point<size_t>> FabricTile::pb_coordinates(
const FabricTileId& tile_id) const {
VTR_ASSERT(valid_tile_id(tile_id));

View File

@ -36,6 +36,9 @@ class FabricTile {
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 Find the coordinate of the unique tile w.r.t the tile with a tile
* id */
vtr::Point<size_t> unique_tile_coordinate(const FabricTileId& tile_id) const;
/** @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

View File

@ -78,8 +78,9 @@ int build_top_module(
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);
status = build_top_module_tile_child_instances(
module_manager, top_module, blwl_sr_banks, circuit_lib, grids,
fabric_tile, config_protocol, fabric_key, frame_view);
}
if (status != CMD_EXEC_SUCCESS) {

View File

@ -40,10 +40,8 @@ static size_t add_top_module_tile_instance(ModuleManager& module_manager,
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);
fabric_tile.unique_tile_coordinate(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));
@ -54,6 +52,7 @@ static size_t add_top_module_tile_instance(ModuleManager& module_manager,
/* Set an unique name to the instance
* Note: it is your risk to gurantee the name is unique!
*/
vtr::Point<size_t> tile_coord = fabric_tile.tile_coordinate(fabric_tile_id);
std::string instance_name = generate_tile_module_name(tile_coord);
module_manager.set_child_instance_name(top_module, tile_module, tile_instance,
instance_name);
@ -141,14 +140,124 @@ static int add_top_module_tile_instances(ModuleManager& module_manager,
return status;
}
/********************************************************************
* Add the I/O children to the top-level module, which impacts the I/O indexing
* This is the default function to build the I/O sequence/indexing
* The I/O children is added in a maze shape
* The function supports I/Os in the center of grids, starting from the
*bottom-left corner and ending at the center
*
* +----------------------+
* |+--------------------+|
* ||+------------------+||
* |||+----------------+|||
* ||||+-------------->||||
* ||||+---------------+|||
* |||+-----------------+||
* ||+-------------------+|
* |+---------------------+
* ^
* io[0]
*******************************************************************/
static void add_top_module_tile_io_children(
ModuleManager& module_manager, const ModuleId& top_module,
const DeviceGrid& grids, const FabricTile& fabric_tile,
const vtr::Matrix<size_t>& tile_instance_ids) {
/* Create the coordinate range for the perimeter I/Os 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;
}
/* Find the module name for this type of tile */
vtr::Point<size_t> unique_tile_coord =
fabric_tile.unique_tile_coordinate(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));
/* Add a I/O children to top_module*/
module_manager.add_io_child(top_module, tile_module,
tile_instance_ids[io_coord.x()][io_coord.y()],
vtr::Point<int>(io_coord.x(), io_coord.y()));
}
}
/* Walk through the center grids */
size_t xmin = 1;
size_t xmax = grids.width() - 2;
size_t ymin = 1;
size_t ymax = grids.height() - 2;
std::vector<vtr::Point<size_t>> coords;
while (xmin < xmax && ymin < ymax) {
for (size_t iy = ymin; iy < ymax + 1; iy++) {
coords.push_back(vtr::Point<size_t>(xmin, iy));
}
for (size_t ix = xmin + 1; ix < xmax + 1; ix++) {
coords.push_back(vtr::Point<size_t>(ix, ymax));
}
for (size_t iy = ymax - 1; iy > ymin; iy--) {
coords.push_back(vtr::Point<size_t>(xmax, iy));
}
for (size_t ix = xmax; ix > xmin; ix--) {
coords.push_back(vtr::Point<size_t>(ix, ymin));
}
xmin++;
ymin++;
xmax--;
ymax--;
}
/* If height is odd, add the missing horizental line */
if ((grids.height() - 2) % 2 == 1) {
if (ymin == ymax) {
for (size_t ix = xmin; ix < xmax + 1; ix++) {
coords.push_back(vtr::Point<size_t>(ix, ymin));
}
}
}
/* If width is odd, add the missing vertical line */
if ((grids.width() - 2) % 2 == 1) {
if (xmin == xmax) {
for (size_t iy = ymin; iy < ymax + 1; iy++) {
coords.push_back(vtr::Point<size_t>(xmin, iy));
}
}
}
/* Now walk through the coordinates */
for (vtr::Point<size_t> coord : coords) {
FabricTileId fabric_tile_id = fabric_tile.find_tile(coord);
if (!fabric_tile.valid_tile_id(fabric_tile_id)) {
continue;
}
/* Find the module name for this type of tile */
vtr::Point<size_t> unique_tile_coord =
fabric_tile.unique_tile_coordinate(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));
/* Add a I/O children to top_module*/
module_manager.add_io_child(top_module, tile_module,
tile_instance_ids[coord.x()][coord.y()],
vtr::Point<int>(coord.x(), coord.y()));
}
}
/********************************************************************
* Add the tile-level instances to the top module of FPGA fabric
* and build connects between them
*******************************************************************/
int build_top_module_tile_child_instances(ModuleManager& module_manager,
const ModuleId& top_module,
const DeviceGrid& grids,
const FabricTile& fabric_tile) {
int build_top_module_tile_child_instances(
ModuleManager& module_manager, const ModuleId& top_module,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
const CircuitLibrary& circuit_lib, const DeviceGrid& grids,
const FabricTile& fabric_tile, const ConfigProtocol& config_protocol,
const FabricKey& fabric_key, const bool& frame_view) {
int status = CMD_EXEC_SUCCESS;
vtr::Matrix<size_t> tile_instance_ids;
status = add_top_module_tile_instances(module_manager, top_module,
@ -157,7 +266,76 @@ int build_top_module_tile_child_instances(ModuleManager& module_manager,
return CMD_EXEC_FATAL_ERROR;
}
/* Update the I/O children list */
add_top_module_tile_io_children(module_manager, top_module, grids,
fabric_tile, tile_instance_ids);
/* TODO: Build the nets between tiles */
if (false == frame_view) {
/* Reserve nets to be memory efficient */
reserve_module_manager_module_nets(module_manager, top_module);
/* TODO: Regular nets between tiles */
/* TODO: Inter-tile direct connections */
}
/* TODO: Add global ports from tile modules: how to connect to clock
architecture and the global port from tile annotation status =
add_top_module_global_ports_from_grid_modules( module_manager, top_module,
tile_annotation, vpr_device_annotation, grids, rr_graph, device_rr_gsb,
cb_instance_ids, grid_instance_ids, clk_ntwk, rr_clock_lookup); if
(CMD_EXEC_FATAL_ERROR == status) { return status;
}
*/
/* Add GPIO ports from the sub-modules under this Verilog module
* For top-level module, we follow a special sequencing for I/O modules. So we
* rebuild the I/O children list here
*/
add_module_gpio_ports_from_child_modules(module_manager, top_module);
/* Organize the list of memory modules and instances
* If we have an empty fabric key, we organize the memory modules as routine
* Otherwise, we will load the fabric key directly
*/
if (true == fabric_key.empty()) {
/* TODO: need a special one for tiles
organize_top_module_memory_modules(
module_manager, top_module, circuit_lib, config_protocol, sram_model,
grids, grid_instance_ids, device_rr_gsb, sb_instance_ids, cb_instance_ids,
compact_routing_hierarchy);
*/
} else {
VTR_ASSERT_SAFE(false == fabric_key.empty());
/* Throw a fatal error when the fabric key has a mismatch in region
* organization. between architecture file and fabric key
*/
if (size_t(config_protocol.num_regions()) != fabric_key.regions().size()) {
VTR_LOG_ERROR(
"Fabric key has a different number of configurable regions (='%ld') "
"than architecture definition (=%d)!\n",
fabric_key.regions().size(), config_protocol.num_regions());
return CMD_EXEC_FATAL_ERROR;
}
status = load_top_module_memory_modules_from_fabric_key(
module_manager, top_module, circuit_lib, config_protocol, fabric_key);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
status = load_top_module_shift_register_banks_from_fabric_key(
fabric_key, blwl_sr_banks);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
/* Update the memory organization in sub module (non-top) */
status = load_submodules_memory_modules_from_fabric_key(
module_manager, circuit_lib, config_protocol, fabric_key);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
return CMD_EXEC_SUCCESS;
}

View File

@ -32,10 +32,12 @@
/* begin namespace openfpga */
namespace openfpga {
int build_top_module_tile_child_instances(ModuleManager& module_manager,
const ModuleId& top_module,
const DeviceGrid& grids,
const FabricTile& fabric_tile);
int build_top_module_tile_child_instances(
ModuleManager& module_manager, const ModuleId& top_module,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
const CircuitLibrary& circuit_lib, const DeviceGrid& grids,
const FabricTile& fabric_tile, const ConfigProtocol& config_protocol,
const FabricKey& fabric_key, const bool& frame_view);
} /* end namespace openfpga */