[Tool] Extend the support on global tile port for I/O tiles
This commit is contained in:
parent
bc43c876b0
commit
372fb261fd
|
@ -65,7 +65,7 @@ void update_cluster_pin_with_post_routing_results(const DeviceContext& device_ct
|
||||||
VTR_ASSERT(class_inf.type == RECEIVER);
|
VTR_ASSERT(class_inf.type == RECEIVER);
|
||||||
rr_node_type = IPIN;
|
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 */
|
/* As some grid has height/width offset, we may not have the pin on any side */
|
||||||
if (0 == pin_sides.size()) {
|
if (0 == pin_sides.size()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -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
|
* 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 */
|
/* 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()) {
|
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
|
||||||
/* Must found one valid port! */
|
/* Must found one valid port! */
|
||||||
ModulePortId top_module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_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);
|
VTR_ASSERT(ModulePortId::INVALID() != top_module_port);
|
||||||
/* Spot the port from child modules */
|
|
||||||
for (size_t ix = 0; ix < grids.width(); ++ix) {
|
/* Spot the port from child modules from core grids */
|
||||||
for (size_t iy = 0; iy < grids.height(); ++iy) {
|
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
|
||||||
|
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
|
||||||
/* Bypass EMPTY tiles */
|
/* Bypass EMPTY tiles */
|
||||||
if (true == is_empty_type(grids[ix][iy].type)) {
|
if (true == is_empty_type(grids[ix][iy].type)) {
|
||||||
continue;
|
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)) {
|
if (std::string(grids[ix][iy].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) {
|
||||||
continue;
|
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 */
|
/* Create nets and finish connection build-up */
|
||||||
add_module_bus_nets(module_manager, top_module,
|
build_top_module_global_net_for_given_grid_module(module_manager,
|
||||||
top_module, 0, top_module_port,
|
top_module,
|
||||||
grid_module, grid_instance, grid_port_id);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "vtr_time.h"
|
#include "vtr_time.h"
|
||||||
|
|
||||||
|
/* Headers from openfpgautil library */
|
||||||
|
#include "openfpga_side_manager.h"
|
||||||
|
|
||||||
#include "openfpga_device_grid_utils.h"
|
#include "openfpga_device_grid_utils.h"
|
||||||
#include "openfpga_physical_tile_utils.h"
|
#include "openfpga_physical_tile_utils.h"
|
||||||
|
|
||||||
|
@ -22,7 +25,8 @@ namespace openfpga {
|
||||||
* are properly set in VPR!!!
|
* are properly set in VPR!!!
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
std::vector<e_side> find_physical_tile_pin_side(t_physical_tile_type_ptr physical_tile,
|
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;
|
std::vector<e_side> pin_sides;
|
||||||
for (const e_side& side_cand : {TOP, RIGHT, BOTTOM, LEFT}) {
|
for (const e_side& side_cand : {TOP, RIGHT, BOTTOM, LEFT}) {
|
||||||
int pin_width_offset = physical_tile->pin_width_offset[physical_pin];
|
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;
|
return pin_sides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
std::vector<e_side> find_physical_tile_pin_side(t_physical_tile_type_ptr physical_tile,
|
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,
|
float find_physical_tile_pin_Fc(t_physical_tile_type_ptr type,
|
||||||
const int& pin);
|
const int& pin);
|
||||||
|
|
Loading…
Reference in New Issue