diff --git a/openfpga/src/base/openfpga_pb_pin_fixup.cpp b/openfpga/src/base/openfpga_pb_pin_fixup.cpp index ddebdd38d..944a85c70 100644 --- a/openfpga/src/base/openfpga_pb_pin_fixup.cpp +++ b/openfpga/src/base/openfpga_pb_pin_fixup.cpp @@ -65,7 +65,7 @@ void update_cluster_pin_with_post_routing_results(const DeviceContext& device_ct VTR_ASSERT(class_inf.type == RECEIVER); rr_node_type = IPIN; } - std::vector pin_sides = find_physical_tile_pin_side(physical_tile, physical_pin); + std::vector pin_sides = find_physical_tile_pin_side(physical_tile, physical_pin, border_side); /* As some grid has height/width offset, we may not have the pin on any side */ if (0 == pin_sides.size()) { continue; diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index f36977fc2..8843f5210 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -690,6 +690,65 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager, } } +/******************************************************************** + * Add global port connection for a given port of a physical tile + * that are defined as global in tile annotation + *******************************************************************/ +static +void build_top_module_global_net_for_given_grid_module(ModuleManager& module_manager, + const ModuleId& top_module, + const ModulePortId& top_module_port, + const TileAnnotation& tile_annotation, + const TileGlobalPortId& tile_global_port, + const DeviceGrid& grids, + const vtr::Point& grid_coordinate, + const e_side& border_side, + const vtr::Matrix& grid_instance_ids) { + + t_physical_tile_type_ptr physical_tile = grids[grid_coordinate.x()][grid_coordinate.y()].type; + /* Ensure physical tile matches the global port definition */ + VTR_ASSERT(std::string(physical_tile->name) == tile_annotation.global_port_tile_name(tile_global_port)); + + /* Find the port of the grid module according to the tile annotation */ + int grid_pin_index = physical_tile->num_pins; + for (const t_physical_tile_port& tile_port : physical_tile->ports) { + if (std::string(tile_port.name) == tile_annotation.global_port_tile_port(tile_global_port).get_name()) { + /* Port size must match!!! */ + VTR_ASSERT(size_t(tile_port.num_pins) == tile_annotation.global_port_tile_port(tile_global_port).get_width()); + /* TODO: Should check there is only port matching!!! */ + grid_pin_index = tile_port.absolute_first_pin_index; + break; + } + } + /* Ensure the pin index is valid */ + VTR_ASSERT(grid_pin_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()]; + + /* 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]; + std::vector pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index, border_side); + for (const e_side& pin_side : pin_sides) { + std::string grid_port_name = generate_grid_port_name(grid_coordinate, + grid_pin_width, grid_pin_height, + pin_side, + grid_pin_index, false); + ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); + VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, grid_port_id)); + + /* Build nets */ + add_module_bus_nets(module_manager, top_module, + top_module, 0, top_module_port, + grid_module, grid_instance, grid_port_id); + } +} + /******************************************************************** * Add global ports from grid ports that are defined as global in tile annotation *******************************************************************/ @@ -718,13 +777,16 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager, } /* Add module nets */ + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); + for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) { /* Must found one valid port! */ ModulePortId top_module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port)); VTR_ASSERT(ModulePortId::INVALID() != top_module_port); - /* Spot the port from child modules */ - for (size_t ix = 0; ix < grids.width(); ++ix) { - for (size_t iy = 0; iy < grids.height(); ++iy) { + + /* Spot the port from child modules from core grids */ + for (size_t ix = 1; ix < grids.width() - 1; ++ix) { + for (size_t iy = 1; iy < grids.height() - 1; ++iy) { /* Bypass EMPTY tiles */ if (true == is_empty_type(grids[ix][iy].type)) { continue; @@ -739,45 +801,50 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager, if (std::string(grids[ix][iy].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) { continue; } - t_physical_tile_type_ptr physical_tile = grids[ix][iy].type; - /* Find the port of the grid module according to the tile annotation */ - int grid_pin_index = physical_tile->num_pins; - for (const t_physical_tile_port& tile_port : physical_tile->ports) { - if (std::string(tile_port.name) == tile_annotation.global_port_tile_port(tile_global_port).get_name()) { - /* Port size must match!!! */ - VTR_ASSERT(size_t(tile_port.num_pins) == tile_annotation.global_port_tile_port(tile_global_port).get_width()); - /* TODO: Should check there is only port matching!!! */ - grid_pin_index = tile_port.absolute_first_pin_index; - break; - } - } - /* Ensure the pin index is valid */ - VTR_ASSERT(grid_pin_index < physical_tile->num_pins); - /* Find the module name for this type of grid */ - std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX); - /* FIXME: grid side should be inferred from if it is on any border side!!! */ - std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(physical_tile->name), is_io_type(physical_tile), NUM_SIDES); - 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[ix][iy]; - /* 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]; - vtr::Point grid_coordinate(ix, iy); - std::vector pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index); - for (const e_side& pin_side : pin_sides) { - std::string grid_port_name = generate_grid_port_name(grid_coordinate, - grid_pin_width, grid_pin_height, - pin_side, - grid_pin_index, false); - ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); - VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, grid_port_id)); - /* Build nets */ - add_module_bus_nets(module_manager, top_module, - top_module, 0, top_module_port, - grid_module, grid_instance, grid_port_id); + /* Create nets and finish connection build-up */ + build_top_module_global_net_for_given_grid_module(module_manager, + top_module, + top_module_port, + tile_annotation, + tile_global_port, + grids, + vtr::Point(ix, iy), + NUM_SIDES, + grid_instance_ids); + + } + } + + /* Walk through all the grids on the perimeter, which are I/O grids */ + for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) { + for (const vtr::Point& io_coordinate : io_coordinates[io_side]) { + /* Bypass EMPTY grid */ + if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) { + continue; + } + + /* Skip width or height > 1 tiles (mostly heterogeneous blocks) */ + if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset) + || (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) { + continue; } + + /* Bypass the tiles whose names do not match */ + if (std::string(grids[io_coordinate.x()][io_coordinate.y()].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) { + continue; + } + + /* Create nets and finish connection build-up */ + build_top_module_global_net_for_given_grid_module(module_manager, + top_module, + top_module_port, + tile_annotation, + tile_global_port, + grids, + io_coordinate, + io_side, + grid_instance_ids); } } } diff --git a/openfpga/src/utils/openfpga_physical_tile_utils.cpp b/openfpga/src/utils/openfpga_physical_tile_utils.cpp index 63753cf63..95942ccaf 100644 --- a/openfpga/src/utils/openfpga_physical_tile_utils.cpp +++ b/openfpga/src/utils/openfpga_physical_tile_utils.cpp @@ -8,6 +8,9 @@ #include "vtr_assert.h" #include "vtr_time.h" +/* Headers from openfpgautil library */ +#include "openfpga_side_manager.h" + #include "openfpga_device_grid_utils.h" #include "openfpga_physical_tile_utils.h" @@ -22,7 +25,8 @@ namespace openfpga { * are properly set in VPR!!! *******************************************************************/ std::vector find_physical_tile_pin_side(t_physical_tile_type_ptr physical_tile, - const int& physical_pin) { + const int& physical_pin, + const e_side& border_side) { std::vector pin_sides; for (const e_side& side_cand : {TOP, RIGHT, BOTTOM, LEFT}) { int pin_width_offset = physical_tile->pin_width_offset[physical_pin]; @@ -32,6 +36,19 @@ std::vector find_physical_tile_pin_side(t_physical_tile_type_ptr physica } } + /* For regular grid, we should have pin only one side! + * I/O grids: VPR creates the grid with duplicated pins on every side + * but the expected side (only used side) will be opposite side of the border side! + */ + if (NUM_SIDES == border_side) { + VTR_ASSERT(1 == pin_sides.size()); + } else { + SideManager side_manager(border_side); + VTR_ASSERT(pin_sides.end() != std::find(pin_sides.begin(), pin_sides.end(), side_manager.get_opposite())); + pin_sides.clear(); + pin_sides.push_back(side_manager.get_opposite()); + } + return pin_sides; } diff --git a/openfpga/src/utils/openfpga_physical_tile_utils.h b/openfpga/src/utils/openfpga_physical_tile_utils.h index df2cae584..b30ac4b76 100644 --- a/openfpga/src/utils/openfpga_physical_tile_utils.h +++ b/openfpga/src/utils/openfpga_physical_tile_utils.h @@ -18,7 +18,8 @@ namespace openfpga { std::vector find_physical_tile_pin_side(t_physical_tile_type_ptr physical_tile, - const int& physical_pin); + const int& physical_pin, + const e_side& border_side); float find_physical_tile_pin_Fc(t_physical_tile_type_ptr type, const int& pin);