From 6b92299e392a147d1df2e2b5328c195682531130 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 20 Jul 2023 17:38:13 -0700 Subject: [PATCH] [core] start working on the net build-up for tile instances under the top-level module --- openfpga/src/annotation/fabric_tile.cpp | 7 + openfpga/src/annotation/fabric_tile.h | 3 + openfpga/src/fabric/build_top_module.cpp | 5 +- .../build_top_module_child_tile_instance.cpp | 192 +++++++++++++++++- .../build_top_module_child_tile_instance.h | 10 +- 5 files changed, 204 insertions(+), 13 deletions(-) diff --git a/openfpga/src/annotation/fabric_tile.cpp b/openfpga/src/annotation/fabric_tile.cpp index 24072a5ba..14880b8e0 100644 --- a/openfpga/src/annotation/fabric_tile.cpp +++ b/openfpga/src/annotation/fabric_tile.cpp @@ -16,6 +16,13 @@ vtr::Point FabricTile::tile_coordinate( return coords_[tile_id]; } +vtr::Point FabricTile::unique_tile_coordinate( + const FabricTileId& tile_id) const { + vtr::Point tile_coord = tile_coordinate(tile_id); + FabricTileId unique_fabric_tile_id = unique_tile(tile_coord); + return tile_coordinate(unique_fabric_tile_id); +} + std::vector> FabricTile::pb_coordinates( const FabricTileId& tile_id) const { VTR_ASSERT(valid_tile_id(tile_id)); diff --git a/openfpga/src/annotation/fabric_tile.h b/openfpga/src/annotation/fabric_tile.h index 323d5d7ec..903ec42f2 100644 --- a/openfpga/src/annotation/fabric_tile.h +++ b/openfpga/src/annotation/fabric_tile.h @@ -36,6 +36,9 @@ class FabricTile { FabricTileId unique_tile(const vtr::Point& coord) const; /** @brief Find the tile info with a given coordinate */ FabricTileId find_tile(const vtr::Point& coord) const; + /** @brief Find the coordinate of the unique tile w.r.t the tile with a tile + * id */ + vtr::Point unique_tile_coordinate(const FabricTileId& tile_id) const; /** @brief Return a list of unique tiles */ std::vector unique_tiles() const; /** @brief Find the index of a programmable block in the internal list by a diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index 2502ec379..9614407f4 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -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) { diff --git a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp index 3b7005905..5aeb78fe2 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -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 tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); - FabricTileId unique_fabric_tile_id = fabric_tile.unique_tile(tile_coord); vtr::Point 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 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& tile_instance_ids) { + /* Create the coordinate range for the perimeter I/Os of FPGA fabric */ + std::map>> io_coordinates = + generate_perimeter_tile_coordinates(grids); + + for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) { + for (const vtr::Point& 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 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(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> coords; + while (xmin < xmax && ymin < ymax) { + for (size_t iy = ymin; iy < ymax + 1; iy++) { + coords.push_back(vtr::Point(xmin, iy)); + } + for (size_t ix = xmin + 1; ix < xmax + 1; ix++) { + coords.push_back(vtr::Point(ix, ymax)); + } + for (size_t iy = ymax - 1; iy > ymin; iy--) { + coords.push_back(vtr::Point(xmax, iy)); + } + for (size_t ix = xmax; ix > xmin; ix--) { + coords.push_back(vtr::Point(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(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(xmin, iy)); + } + } + } + + /* Now walk through the coordinates */ + for (vtr::Point 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 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(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 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; } diff --git a/openfpga/src/fabric/build_top_module_child_tile_instance.h b/openfpga/src/fabric/build_top_module_child_tile_instance.h index 5d2b40928..f779d2ccd 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.h +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.h @@ -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 */