From 019e663e12375ebfa5cbcd40b5a50795da707213 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 23 Aug 2022 11:58:44 -0700 Subject: [PATCH] [engine] fixing the bugs on building global nets to sub tile pins --- .../annotation/annotate_physical_tiles.cpp | 3 + .../src/annotation/vpr_device_annotation.cpp | 26 ++++ .../src/annotation/vpr_device_annotation.h | 13 +- .../src/fabric/build_grid_module_utils.cpp | 11 +- .../fabric/build_top_module_connection.cpp | 120 +++++++++--------- 5 files changed, 104 insertions(+), 69 deletions(-) diff --git a/openfpga/src/annotation/annotate_physical_tiles.cpp b/openfpga/src/annotation/annotate_physical_tiles.cpp index a6c3b072b..f53790b99 100644 --- a/openfpga/src/annotation/annotate_physical_tiles.cpp +++ b/openfpga/src/annotation/annotate_physical_tiles.cpp @@ -27,6 +27,9 @@ void build_physical_tile_pin2port_info(const DeviceContext& vpr_device_ctx, for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { /* Walk through capacity */ for (int subtile_index = sub_tile.capacity.low; subtile_index <= sub_tile.capacity.high; subtile_index++) { + vpr_device_annotation.add_physical_tile_z_to_start_pin_index(&physical_tile, + subtile_index, + curr_pin_index); /* For each sub tile, the starting pin index is (num_pins_per_subtile * index) + abs_index */ for (const t_physical_tile_port& tile_port : sub_tile.ports) { for (int pin_index = 0; pin_index < tile_port.num_pins; ++pin_index) { diff --git a/openfpga/src/annotation/vpr_device_annotation.cpp b/openfpga/src/annotation/vpr_device_annotation.cpp index 9d7e29f25..e8eae0346 100644 --- a/openfpga/src/annotation/vpr_device_annotation.cpp +++ b/openfpga/src/annotation/vpr_device_annotation.cpp @@ -368,6 +368,26 @@ int VprDeviceAnnotation::physical_tile_z_to_subtile_index(t_physical_tile_type_p return pin_search_result->second; } +int VprDeviceAnnotation::physical_tile_z_to_start_pin_index(t_physical_tile_type_ptr physical_tile, + const int& sub_tile_z) const { + /* Try to find the physical tile in the fast look-up */ + auto physical_tile_search_result = physical_tile_z_to_start_pin_indices_.find(physical_tile); + if (physical_tile_search_result == physical_tile_z_to_start_pin_indices_.end()) { + /* Not found. Return an invalid index */ + return -1; + } + + /* Try to find the physical tile port info with pin index */ + auto pin_search_result = physical_tile_search_result->second.find(sub_tile_z); + if (pin_search_result == physical_tile_search_result->second.end()) { + /* Not found. Return an invalid index */ + return -1; + } + + /* Reach here, we should find a port. Return the port information */ + return pin_search_result->second; +} + /************************************************************************ * Public mutators ***********************************************************************/ @@ -663,4 +683,10 @@ void VprDeviceAnnotation::add_physical_tile_z_to_subtile_index(t_physical_tile_t physical_tile_z_to_subtile_indices_[physical_tile][subtile_z] = subtile_index; } +void VprDeviceAnnotation::add_physical_tile_z_to_start_pin_index(t_physical_tile_type_ptr physical_tile, + const int& subtile_z, + const int& start_pin_index) { + physical_tile_z_to_start_pin_indices_[physical_tile][subtile_z] = start_pin_index; +} + } /* End namespace openfpga*/ diff --git a/openfpga/src/annotation/vpr_device_annotation.h b/openfpga/src/annotation/vpr_device_annotation.h index d389d41eb..734f62b66 100644 --- a/openfpga/src/annotation/vpr_device_annotation.h +++ b/openfpga/src/annotation/vpr_device_annotation.h @@ -92,6 +92,8 @@ class VprDeviceAnnotation { const int& pin_index) const; int physical_tile_z_to_subtile_index(t_physical_tile_type_ptr physical_tile, const int& subtile_z) const; + int physical_tile_z_to_start_pin_index(t_physical_tile_type_ptr physical_tile, + const int& subtile_z) const; public: /* Public mutators */ void add_pb_type_physical_mode(t_pb_type* pb_type, t_mode* physical_mode); void add_physical_pb_type(t_pb_type* operating_pb_type, t_pb_type* physical_pb_type); @@ -135,6 +137,9 @@ class VprDeviceAnnotation { void add_physical_tile_z_to_subtile_index(t_physical_tile_type_ptr physical_tile, const int& subtile_z, const int& subtile_index); + void add_physical_tile_z_to_start_pin_index(t_physical_tile_type_ptr physical_tile, + const int& subtile_z, + const int& start_pin_index); private: /* Internal data */ /* Pair a regular pb_type to its physical pb_type */ std::map physical_pb_types_; @@ -230,8 +235,14 @@ class VprDeviceAnnotation { std::map> physical_tile_pin2port_info_map_; /* A fast look-up from pin index in physical tile to sub tile index */ std::map> physical_tile_pin_subtile_indices_; - /* A fast look-up from z (absolute coordinate) in physical tile to the index in sub tile array */ + /* A fast look-up from z (a valid instance index considering all the sub tiles in a given physical tile) to the index in sub tile array + * The instance index starts from 0 to the sum of the capacity of each sub tile + */ std::map> physical_tile_z_to_subtile_indices_; + /* A fast look-up from z (a valid instance index considering all the sub tiles in a given physical tile) to the index of the first pin in a given physcial tile + * The instance index starts from 0 to the sum of the capacity of each sub tile + */ + std::map> physical_tile_z_to_start_pin_indices_; }; } /* End namespace openfpga*/ diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index a206cbdc0..fb1844133 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -62,13 +62,12 @@ void add_grid_module_net_connect_pb_graph_pin(ModuleManager& module_manager, grid_pin_sides = {TOP, RIGHT, BOTTOM, LEFT}; } - /* num_pins/capacity = the number of pins that each type_descriptor has. - * Capacity defines the number of type_descriptors in each grid - * so the pin index at grid level = pin_index_in_type_descriptor - * + type_descriptor_index_in_capacity * num_pins_per_type_descriptor + /* Note that each grid may contain a number of sub tiles, each type of which may a different capacity and number of pins + * We need to find the start pin index for a given z offset (instance id), denotes the index of the first pin regarding the current instance. + * The variable 'pin_count_in_cluster' represent the pin index in the context of current instance only. + * With the information above, we can then calculate the absolute pin index at grid-level (considering all the sub tiles). */ - size_t grid_pin_index = pb_graph_pin->pin_count_in_cluster - + child_instance * grid_type_descriptor->num_pins / grid_type_descriptor->capacity; + size_t grid_pin_index = pb_graph_pin->pin_count_in_cluster + vpr_device_annotation.physical_tile_z_to_start_pin_index(grid_type_descriptor, child_instance); int pin_height = grid_type_descriptor->pin_height_offset[grid_pin_index]; int pin_width = grid_type_descriptor->pin_width_offset[grid_pin_index]; for (const e_side& side : grid_pin_sides) { diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index 43173e64b..a9fcbc4e9 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -744,70 +744,68 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana const vtr::Matrix& grid_instance_ids) { t_physical_tile_type_ptr physical_tile = grids[grid_coordinate.x()][grid_coordinate.y()].type; + /* Find the module name for this type of grid */ + std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX); + std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(physical_tile->name), is_io_type(physical_tile), border_side); + ModuleId grid_module = module_manager.find_module(grid_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); + size_t grid_instance = grid_instance_ids[grid_coordinate.x()][grid_coordinate.y()]; + /* Find the source port at the top-level module */ + BasicPort src_port = module_manager.module_port(top_module, top_module_port); - /* Find the port of the grid module according to the tile annotation */ - int grid_pin_start_index = physical_tile->num_pins; - t_physical_tile_port physical_tile_port; - physical_tile_port.num_pins = 0; - bool found_tile_port = false; - /* TODO: This part may be buggy. Need to investigate how sub tile organize information. - * For example, how the ports are indexed in each sub tile which is repeated a few time (capacity > 1) */ - for (const t_sub_tile& sub_tile : physical_tile->sub_tiles) { - for (const t_physical_tile_port& tile_port : sub_tile.ports) { - if (std::string(tile_port.name) == tile_port_to_connect.get_name()) { - BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); - /* Port size must match!!! */ - if (false == ref_tile_port.contained(tile_port_to_connect)) { - VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", - tile_annotation.global_port_name(tile_global_port).c_str(), - tile_port_to_connect.get_name().c_str(), - tile_port_to_connect.get_lsb(), - tile_port_to_connect.get_msb(), - ref_tile_port.get_name().c_str(), - ref_tile_port.get_lsb(), - ref_tile_port.get_msb()); - return CMD_EXEC_FATAL_ERROR; - } - grid_pin_start_index = tile_port.absolute_first_pin_index; - physical_tile_port = tile_port; - found_tile_port = true; - break; - } - } - /* Found the port, exit early */ - if (found_tile_port) { - break; - } - } - /* Ensure the pin index is valid */ - VTR_ASSERT(grid_pin_start_index < physical_tile->num_pins); - - /* Find the module name for this type of grid */ - std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX); - std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(physical_tile->name), is_io_type(physical_tile), border_side); - ModuleId grid_module = module_manager.find_module(grid_module_name); - VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); - size_t grid_instance = grid_instance_ids[grid_coordinate.x()][grid_coordinate.y()]; - - /* Ensure port width is in range */ - BasicPort src_port = module_manager.module_port(top_module, top_module_port); - VTR_ASSERT(src_port.get_width() == tile_port_to_connect.get_width()); - - /* Create a pin id mapping between the source port (top module) and the sink port (grid module) */ - std::map sink2src_pin_map; - for (size_t ipin = 0; ipin < tile_port_to_connect.get_width(); ++ipin) { - size_t sink_pin = tile_port_to_connect.pins()[ipin]; - size_t src_pin = src_port.pins()[ipin]; - sink2src_pin_map[sink_pin] = src_pin; - } - - /* A tile may consist of multiple subtile, connect to all the pins from sub tiles */ + /* Walk through each instance considering the unique sub tile and capacity range, + * each instance may have an independent pin to be driven by a global net! */ for (const t_sub_tile& sub_tile : physical_tile->sub_tiles) { VTR_ASSERT(1 == sub_tile.equivalent_sites.size()); - for (int iz = 0; iz < sub_tile.capacity.total(); ++iz) { + int grid_pin_start_index = physical_tile->num_pins; + t_physical_tile_port physical_tile_port; + physical_tile_port.num_pins = 0; + + /* Count the total number of pins for this type of sub tile */ + int sub_tile_num_pins = 0; + for (const t_physical_tile_port& tile_port : sub_tile.ports) { + sub_tile_num_pins += tile_port.num_pins; + } + + /* For each instance of the same sub tile type, find the port of the grid module according to the tile annotation + * A tile may consist of multiple subtile, connect to all the pins from sub tiles */ + for (int subtile_index = sub_tile.capacity.low; subtile_index <= sub_tile.capacity.high; subtile_index++) { + for (const t_physical_tile_port& tile_port : sub_tile.ports) { + if (std::string(tile_port.name) == tile_port_to_connect.get_name()) { + BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); + /* Port size must match!!! */ + if (false == ref_tile_port.contained(tile_port_to_connect)) { + VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", + tile_annotation.global_port_name(tile_global_port).c_str(), + tile_port_to_connect.get_name().c_str(), + tile_port_to_connect.get_lsb(), + tile_port_to_connect.get_msb(), + ref_tile_port.get_name().c_str(), + ref_tile_port.get_lsb(), + ref_tile_port.get_msb()); + return CMD_EXEC_FATAL_ERROR; + } + grid_pin_start_index = (subtile_index - sub_tile.capacity.low) * sub_tile_num_pins + tile_port.absolute_first_pin_index; + physical_tile_port = tile_port; + break; + } + } + /* Ensure the pin index is valid */ + VTR_ASSERT(grid_pin_start_index < physical_tile->num_pins); + /* Ensure port width is in range */ + VTR_ASSERT(src_port.get_width() == tile_port_to_connect.get_width()); + + /* Create a pin id mapping between the source port (top module) and the sink port (grid module) */ + std::map sink2src_pin_map; + for (size_t ipin = 0; ipin < tile_port_to_connect.get_width(); ++ipin) { + size_t sink_pin = tile_port_to_connect.pins()[ipin]; + size_t src_pin = src_port.pins()[ipin]; + sink2src_pin_map[sink_pin] = src_pin; + } + + /* Create the connections */ for (size_t pin_id = tile_port_to_connect.get_lsb(); pin_id < tile_port_to_connect.get_msb() + 1; ++pin_id) { - /* TODO: This should be replaced by using a pin mapping data structure from physical tile! */ - int grid_pin_index = grid_pin_start_index + iz * sub_tile.equivalent_sites[0]->pb_type->num_pins + pin_id; + int grid_pin_index = grid_pin_start_index + pin_id; /* Find the module pin */ size_t grid_pin_width = physical_tile->pin_width_offset[grid_pin_index]; size_t grid_pin_height = physical_tile->pin_height_offset[grid_pin_index]; @@ -815,8 +813,6 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana BasicPort grid_pin_info = vpr_device_annotation.physical_tile_pin_port_info(physical_tile, grid_pin_index); VTR_ASSERT(true == grid_pin_info.is_valid()); - int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(physical_tile, grid_pin_index); - VTR_ASSERT(OPEN != subtile_index && subtile_index < physical_tile->capacity); /* Build nets */ for (const e_side& pin_side : pin_sides) {