[Tool] Extend the support on global tile port for I/O tiles

This commit is contained in:
tangxifan 2020-11-11 15:09:40 -07:00
parent bc43c876b0
commit 372fb261fd
4 changed files with 128 additions and 43 deletions

View File

@ -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<e_side> pin_sides = find_physical_tile_pin_side(physical_tile, physical_pin);
std::vector<e_side> 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;

View File

@ -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<size_t>& grid_coordinate,
const e_side& border_side,
const vtr::Matrix<size_t>& 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<e_side> 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<e_side, std::vector<vtr::Point<size_t>>> 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,46 +801,51 @@ 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<size_t> grid_coordinate(ix, iy);
std::vector<e_side> 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<size_t>(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<size_t>& 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);
}
}
}

View File

@ -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<e_side> 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<e_side> 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<e_side> 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;
}

View File

@ -18,7 +18,8 @@
namespace openfpga {
std::vector<e_side> 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);