From 4a2874b2bcf721da1c67aad4063074e62714812c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 3 Nov 2020 13:21:50 -0700 Subject: [PATCH] [Tool] Refactor the codes for walking through io blocks --- .../fabric/build_fabric_io_location_map.cpp | 26 +------- openfpga/src/fabric/build_top_module.cpp | 28 +-------- .../fpga_bitstream/build_grid_bitstream.cpp | 27 ++------ .../src/fpga_sdc/analysis_sdc_grid_writer.cpp | 26 +------- .../src/utils/openfpga_device_grid_utils.cpp | 63 +++++++++++++++++++ .../src/utils/openfpga_device_grid_utils.h | 27 ++++++++ .../utils/openfpga_physical_tile_utils.cpp | 25 +------- 7 files changed, 106 insertions(+), 116 deletions(-) create mode 100644 openfpga/src/utils/openfpga_device_grid_utils.cpp create mode 100644 openfpga/src/utils/openfpga_device_grid_utils.h diff --git a/openfpga/src/fabric/build_fabric_io_location_map.cpp b/openfpga/src/fabric/build_fabric_io_location_map.cpp index 195b04f62b..a99d890e57 100644 --- a/openfpga/src/fabric/build_fabric_io_location_map.cpp +++ b/openfpga/src/fabric/build_fabric_io_location_map.cpp @@ -18,6 +18,7 @@ #include "openfpga_reserved_words.h" #include "openfpga_naming.h" +#include "openfpga_device_grid_utils.h" #include "build_fabric_io_location_map.h" /* begin namespace openfpga */ @@ -36,31 +37,10 @@ IoLocationMap build_fabric_io_location_map(const ModuleManager& module_manager, std::map io_counter; /* Create the coordinate range for each side of FPGA fabric */ - std::vector io_sides{TOP, RIGHT, BOTTOM, LEFT}; - std::map>> io_coordinates; - - /* TOP side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); - } - - /* RIGHT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); - } - - /* BOTTOM side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); - } - - /* LEFT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[LEFT].push_back(vtr::Point(0, iy)); - } + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); /* Walk through all the grids on the perimeter, which are I/O grids */ - for (const e_side& io_side : io_sides) { + 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)) { diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index d0df28eca4..ef45bb4bca 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -26,6 +26,7 @@ #include "build_top_module_directs.h" #include "build_module_graph_utils.h" +#include "openfpga_device_grid_utils.h" #include "build_top_module.h" /* begin namespace openfpga */ @@ -131,32 +132,9 @@ vtr::Matrix add_top_module_grid_instances(ModuleManager& module_manager, /* Instanciate I/O grids */ /* Create the coordinate range for each side of FPGA fabric */ - std::vector io_sides{TOP, RIGHT, BOTTOM, LEFT}; - std::map>> io_coordinates; - - /* TOP side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); - } - - /* RIGHT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); - } - - /* BOTTOM side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); - } - - /* LEFT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[LEFT].push_back(vtr::Point(0, iy)); - } + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); - /* Add instances of I/O grids to top_module */ - size_t io_counter = 0; - for (const e_side& io_side : io_sides) { + 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)) { diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 550f6e86fd..9cc8753a75 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -27,6 +27,8 @@ #include "module_manager_utils.h" #include "build_mux_bitstream.h" +#include "openfpga_device_grid_utils.h" + #include "build_grid_bitstream.h" /* begin namespace openfpga */ @@ -725,31 +727,10 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager, VTR_LOGV(verbose, "Generating bitstream for I/O grids..."); /* Create the coordinate range for each side of FPGA fabric */ - std::vector io_sides{TOP, RIGHT, BOTTOM, LEFT}; - std::map>> io_coordinates; - - /* TOP side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); - } - - /* RIGHT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); - } - - /* BOTTOM side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); - } - - /* LEFT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[LEFT].push_back(vtr::Point(0, iy)); - } + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); /* Add instances of I/O grids to top_module */ - for (const e_side& io_side : io_sides) { + 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)) { diff --git a/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp b/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp index bc51cc0c40..a49b2c85bb 100644 --- a/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp +++ b/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp @@ -16,6 +16,7 @@ #include "openfpga_naming.h" #include "pb_type_utils.h" +#include "openfpga_device_grid_utils.h" #include "sdc_writer_utils.h" #include "analysis_sdc_writer_utils.h" @@ -628,31 +629,10 @@ void print_analysis_sdc_disable_unused_grids(std::fstream& fp, /* Instanciate I/O grids */ /* Create the coordinate range for each side of FPGA fabric */ - std::vector io_sides{TOP, RIGHT, BOTTOM, LEFT}; - std::map>> io_coordinates; - - /* TOP side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); - } - - /* RIGHT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); - } - - /* BOTTOM side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); - } - - /* LEFT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[LEFT].push_back(vtr::Point(0, iy)); - } + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); /* Add instances of I/O grids to top_module */ - for (const e_side& io_side : io_sides) { + for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) { for (const vtr::Point& io_coordinate : io_coordinates[io_side]) { print_analysis_sdc_disable_unused_grid(fp, io_coordinate, grids, device_annotation, cluster_annotation, place_annotation, diff --git a/openfpga/src/utils/openfpga_device_grid_utils.cpp b/openfpga/src/utils/openfpga_device_grid_utils.cpp new file mode 100644 index 0000000000..ee3d5b60cf --- /dev/null +++ b/openfpga/src/utils/openfpga_device_grid_utils.cpp @@ -0,0 +1,63 @@ +/*************************************************************************************** + * This file includes most utilized functions that are used to acquire data from + * VPR DeviceGrid + ***************************************************************************************/ + +/* Headers from vtrutil library */ +#include "vtr_log.h" +#include "vtr_assert.h" +#include "vtr_time.h" + +#include "openfpga_device_grid_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Create a list of the coordinates for the grids on the device perimeter + * It follows a clockwise sequence when including the coordinates. + * Detailed sequence is as follows: + * - TOP side, from left most to the right + * - Right side, from top to the bottom + * - Bottom side, from right to the left + * - Left side, from bottom to top + * + * This function currently does not include corner cells! + * i.e., the top-left, top-right, bottom-left and bottom-right + * + * Note: + * - This function offers a standard sequence to walk through the + * grids on the perimeter of an FPGA device + * When sequence matters, this function should be used to ensure + * consistency between functions. + *******************************************************************/ +std::map>> generate_perimeter_grid_coordinates(const DeviceGrid& grids) { + /* Search the border side */ + /* Create the coordinate range for each side of FPGA fabric */ + std::vector fpga_sides{TOP, RIGHT, BOTTOM, LEFT}; + std::map>> io_coordinates; + + /* TOP side*/ + for (size_t ix = 1; ix < grids.width() - 1; ++ix) { + io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); + } + + /* RIGHT side */ + for (size_t iy = 1; iy < grids.height() - 1; ++iy) { + io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); + } + + /* BOTTOM side*/ + for (size_t ix = 1; ix < grids.width() - 1; ++ix) { + io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); + } + + /* LEFT side */ + for (size_t iy = 1; iy < grids.height() - 1; ++iy) { + io_coordinates[LEFT].push_back(vtr::Point(0, iy)); + } + + return io_coordinates; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/utils/openfpga_device_grid_utils.h b/openfpga/src/utils/openfpga_device_grid_utils.h new file mode 100644 index 0000000000..ae6fa29496 --- /dev/null +++ b/openfpga/src/utils/openfpga_device_grid_utils.h @@ -0,0 +1,27 @@ +#ifndef OPENFPGA_DEVICE_GRID_UTILS_H +#define OPENFPGA_DEVICE_GRID_UTILS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include +#include +#include "device_grid.h" +#include "vtr_geometry.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +/* A constant array to walk through FPGA border sides clockwise*/ +constexpr std::array FPGA_SIDES_CLOCKWISE{TOP, RIGHT, BOTTOM, LEFT}; + +std::map>> generate_perimeter_grid_coordinates(const DeviceGrid& grids); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/utils/openfpga_physical_tile_utils.cpp b/openfpga/src/utils/openfpga_physical_tile_utils.cpp index 375c70a199..9b4eeba161 100644 --- a/openfpga/src/utils/openfpga_physical_tile_utils.cpp +++ b/openfpga/src/utils/openfpga_physical_tile_utils.cpp @@ -8,6 +8,7 @@ #include "vtr_assert.h" #include "vtr_time.h" +#include "openfpga_device_grid_utils.h" #include "openfpga_physical_tile_utils.h" /* begin namespace openfpga */ @@ -60,29 +61,9 @@ std::set find_physical_io_tile_located_sides(const DeviceGrid& grids, /* Search the border side */ /* Create the coordinate range for each side of FPGA fabric */ - std::vector fpga_sides{TOP, RIGHT, BOTTOM, LEFT}; - std::map>> io_coordinates; + std::map>> io_coordinates = generate_perimeter_grid_coordinates( grids); - /* TOP side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[TOP].push_back(vtr::Point(ix, grids.height() - 1)); - } - - /* RIGHT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[RIGHT].push_back(vtr::Point(grids.width() - 1, iy)); - } - - /* BOTTOM side*/ - for (size_t ix = 1; ix < grids.width() - 1; ++ix) { - io_coordinates[BOTTOM].push_back(vtr::Point(ix, 0)); - } - - /* LEFT side */ - for (size_t iy = 1; iy < grids.height() - 1; ++iy) { - io_coordinates[LEFT].push_back(vtr::Point(0, iy)); - } - for (const e_side& fpga_side : fpga_sides) { + for (const e_side& fpga_side : FPGA_SIDES_CLOCKWISE) { for (const vtr::Point& io_coordinate : io_coordinates[fpga_side]) { /* If located in center, we add a NUM_SIDES and finish */ if (physical_tile == grids[io_coordinate.x()][io_coordinate.y()].type) {