From c2ef5ca4089984f5f2b202bea3e6b914980c6241 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 14 Jul 2023 22:48:44 -0700 Subject: [PATCH] [core] developing top-left style tile info --- openfpga/src/annotation/fabric_tile.cpp | 89 ++++++++++++ openfpga/src/annotation/fabric_tile.h | 73 ++++++++++ openfpga/src/annotation/fabric_tile_fwd.h | 23 +++ .../src/base/openfpga_build_fabric_template.h | 2 +- openfpga/src/fabric/build_device_module.cpp | 15 +- openfpga/src/fabric/build_device_module.h | 4 +- openfpga/src/fabric/build_fabric_tile.cpp | 133 ++++++++++++++++++ openfpga/src/fabric/build_fabric_tile.h | 26 ++++ 8 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 openfpga/src/annotation/fabric_tile.cpp create mode 100644 openfpga/src/annotation/fabric_tile.h create mode 100644 openfpga/src/annotation/fabric_tile_fwd.h create mode 100644 openfpga/src/fabric/build_fabric_tile.cpp create mode 100644 openfpga/src/fabric/build_fabric_tile.h diff --git a/openfpga/src/annotation/fabric_tile.cpp b/openfpga/src/annotation/fabric_tile.cpp new file mode 100644 index 000000000..1d3754d90 --- /dev/null +++ b/openfpga/src/annotation/fabric_tile.cpp @@ -0,0 +1,89 @@ +/************************************************************************ + * Member functions for class FabricTile + ***********************************************************************/ +#include "fabric_tile.h" + +#include "vtr_assert.h" +#include "vtr_log.h" + +/* namespace openfpga begins */ +namespace openfpga { + +FabricTile::FabricTile(const DeviceRRGSB& device_rr_gsb) + : device_rr_gsb_(device_rr_gsb) {} + +vtr::Point FabricTile::tile_coordinate( + const FabricTileId& tile_id) const { + VTR_ASSERT(valid_tile_id(tile_id)); + return coords_[tile_id]; +} + +FabricTileId FabricTile::unique_tile(const vtr::Point& coord) const { + /* Return invalid Id when out of range! */ + if (coord.x() < unique_tile_ids_.size()) { + if (coord.y() < unique_tile_ids_[coord.x()].size()) { + return unique_tile_ids_[coord.x()][coord.y()]; + } + } + return FabricTileId::INVALID(); +} + +FabricTileId FabricTile::create_tile() { + FabricTileId tile_id = FabricTileId(ids_.size()); + ids_.push_back(tile_id); + coords_.emplace_back(); + pb_coords_.emplace_back(); + cbx_coords_.emplace_back(); + cby_coords_.emplace_back(); + sb_coords_.emplace_back(); + + return tile_id; +} + +void set_tile_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord) { + VTR_ASSERT(valid_tile_id(tile_id)); + coords_[tile_id] = coord; +} + +void add_pb_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord) { + VTR_ASSERT(valid_tile_id(tile_id)); + pb_coords_[tile_id] = coord; +} + +void add_cbx_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord) { + VTR_ASSERT(valid_tile_id(tile_id)); + /* Ensure the coordinates are not duplicated */ + auto result = std::find(cbx_coords_.begin(), cbx_coords_.end(), coord); + if (result == cbx_coords_.end()) { + cbx_coords_[tile_id].push_back(coord); + } +} + +void add_cby_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord) { + VTR_ASSERT(valid_tile_id(tile_id)); + /* Ensure the coordinates are not duplicated */ + auto result = std::find(cby_coords_.begin(), cby_coords_.end(), coord); + if (result == cby_coords_.end()) { + cby_coords_[tile_id].push_back(coord); + } +} + +void add_sb_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord) { + VTR_ASSERT(valid_tile_id(tile_id)); + /* Ensure the coordinates are not duplicated */ + auto result = std::find(sb_coords_.begin(), sb_coords_.end(), coord); + if (result == sb_coords_.end()) { + sb_coords_[tile_id].push_back(coord); + } +} + +bool FabricTileId::valid_tile_id(const FabricTileId& tile_id) const { + return (size_t(tile_id) < ids_.size()) && (tile_id == ids_[tile_id]); +} + +} /* End namespace openfpga*/ diff --git a/openfpga/src/annotation/fabric_tile.h b/openfpga/src/annotation/fabric_tile.h new file mode 100644 index 000000000..43a6488a0 --- /dev/null +++ b/openfpga/src/annotation/fabric_tile.h @@ -0,0 +1,73 @@ +#ifndef FABRIC_TILE_H +#define FABRIC_TILE_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include + +#include "device_rr_gsb.h" +#include "fabric_tile_fwd.h" +#include "vtr_geometry.h" +#include "vtr_vector.h" + +/* namespace openfpga begins */ +namespace openfpga { + +/******************************************************************** + * Object models the tiles in an FPGA fabric + * This includes: + * 1. a collection of tiles, each which contains a programmable block and + *surrounding routing blocks + * 2. a collection of unique tiles + *******************************************************************/ +class FabricTile { + public: /* Contructors */ + FabricTile(const DeviceRRGSB& device_rr_gsb); + + public: /* Accessors */ + vtr::Point tile_coordinate(const FabricTileId& tile_id) const; + /** @brief With a given coordinate, find the id of the unique tile (which is + * the same as the tile in structure) */ + FabricTileId unique_tile(const vtr::Point& coord) const; + + public: /* Mutators */ + FabricTileId create_tile(); + void set_tile_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord); + void add_pb_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord); + void add_cbx_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord); + void add_cby_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord); + void add_sb_coordinate(const FabricTileId& tile_id, + const vtr::Point& coord); + /** @brief Build a list of unique tiles by comparing the coordinates in + * DeviceRRGSB */ + void build_unique_tiles(); + /** @brief Clear all the content */ + void clear(); + + private: /* Validators */ + bool valid_tile_id(const FabricTileId& tile_id) const; + + private: /* Internal builders */ + private: /* Internal Data */ + vtr::vector ids_; + vtr::vector> coords_; + /* Coordinates w.r.t. RRGSB */ + vtr::vector> pb_coords_; + vtr::vector>> cbx_coords_; + vtr::vector>> cby_coords_; + vtr::vector>> sb_coords_; + std::vector> + unique_tile_ids_; /* Use [x][y] to get the id of the unique tile with a + given coordinate */ + /* Cached data */ + const DeviceRRGSB& device_rr_gsb_; +}; + +} /* End namespace openfpga*/ + +#endif diff --git a/openfpga/src/annotation/fabric_tile_fwd.h b/openfpga/src/annotation/fabric_tile_fwd.h new file mode 100644 index 000000000..ee51de07a --- /dev/null +++ b/openfpga/src/annotation/fabric_tile_fwd.h @@ -0,0 +1,23 @@ +/************************************************** + * This file includes only declarations for + * the data structures for fabric tiles + * Please refer to fabric_tiles.h for more details + *************************************************/ +#ifndef FABRIC_TILE_FWD_H +#define FABRIC_TILE_FWD_H + +#include "vtr_strong_id.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/* Strong Ids for ModuleManager */ +struct fabric_tile_id_tag; + +typedef vtr::StrongId FabricTileId; + +class FabricTile; + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 2fc4b3d69..21c3216f4 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -153,7 +153,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, cmd_context.option_enable(cmd, opt_frame_view), cmd_context.option_enable(cmd, opt_compress_routing), cmd_context.option_enable(cmd, opt_duplicate_grid_pin), - predefined_fabric_key, + predefined_fabric_key, tile_config, cmd_context.option_enable(cmd, opt_gen_random_fabric_key), cmd_context.option_enable(cmd, opt_verbose)); diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 4a6313870..5edbdec9e 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -35,7 +35,8 @@ int build_device_module_graph( const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, const bool& frame_view, const bool& compress_routing, const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const bool& generate_random_fabric_key, const bool& verbose) { + const TileConfig& tile_config, const bool& generate_random_fabric_key, + const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build fabric module graph"); int status = CMD_EXEC_SUCCESS; @@ -99,6 +100,18 @@ int build_device_module_graph( openfpga_ctx.arch().config_protocol.type(), sram_model, verbose); } + /* Build tile modules if defined */ + FabricTile fabric_tile(openfpga_ctx.device_rr_gsb()); + if (!tile_config.empty()) { + /* TODO: Build detailed tile-level information */ + status = build_fabric_tile(fabric_tile, tile_config, vpr_device_ctx.grid, openfpga_ctx.device_rr_gsb()); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + /* TODO: Build the modules */ + // build_tile_modules(module_manager, fabric_tile); + } + /* Build FPGA fabric top-level module */ status = build_top_module( module_manager, decoder_lib, blwl_sr_banks, openfpga_ctx.arch().circuit_lib, diff --git a/openfpga/src/fabric/build_device_module.h b/openfpga/src/fabric/build_device_module.h index add422e5d..513982aa9 100644 --- a/openfpga/src/fabric/build_device_module.h +++ b/openfpga/src/fabric/build_device_module.h @@ -7,6 +7,7 @@ #include "fabric_key.h" #include "io_name_map.h" #include "openfpga_context.h" +#include "tile_config.h" #include "vpr_context.h" /******************************************************************** @@ -22,7 +23,8 @@ int build_device_module_graph( const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, const bool& frame_view, const bool& compress_routing, const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const bool& generate_random_fabric_key, const bool& verbose); + const TileConfig& tile_config, const bool& generate_random_fabric_key, + const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_fabric_tile.cpp b/openfpga/src/fabric/build_fabric_tile.cpp new file mode 100644 index 000000000..83f94c523 --- /dev/null +++ b/openfpga/src/fabric/build_fabric_tile.cpp @@ -0,0 +1,133 @@ +/******************************************************************** + * This file includes functions that are used to build the location + * map information for the top-level module of the FPGA fabric + * It helps OpenFPGA to link the I/O port index in top-level module + * to the VPR I/O mapping results + *******************************************************************/ +#include +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from vpr library */ +#include "build_fabric_tile.h" +#include "openfpga_naming.h" +#include "openfpga_reserved_words.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Build tiles by following the top-level style. + * - The programmble block, e.g., clb, is placed on the top-left corner + * - The connection blocks and switch block are placed on the right and bottom + *sides + *******************************************************************/ +static int build_fabric_tile_top_left(FabricTile& fabric_tile, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb) { + int status_code = CMD_EXEC_SUCCESS; + + /* Walk through all the device rr_gsb and create tile one by one */ + for (size_t ix = 0; ix < grids.width(); ++ix) { + for (size_t iy = 0; iy < grids.height(); ++iy) { + t_physical_tile_type_ptr phy_tile_type = grids.get_physical_type(ix, iy); + bool skip_add_pb = false; + vtr::Point curr_tile_coord(ix, iy); + FabricTileId curr_tile_id = FabricTileId::INVALID(); + /* For EMPTY grid, routing blocks may still be required if there is a gsb + */ + if (true == is_empty_type(phy_tile_type)) { + skip_add_pb = true; + /* Need to create a new tile here */ + curr_tile_id = fabric_tile.create_tile(); + fabric_tile.set_coordinate(curr_tile_coord); + } + /* Skip width, height > 1 tiles (mostly heterogeneous blocks) */ + if ((0 < grids.get_width_offset(ix, iy)) || + (0 < grids.get_height_offset(ix, iy))) { + /* Find the root of this grid, the instance id should be valid. + * We just copy it here + */ + vtr::Point root_tile_coord( + ix - grids.get_width_offset(ix, iy), + iy - grids.get_height_offset(ix, iy)); + skip_add_pb = true; + curr_tile_id = fabric_tile.find_tile(root_tile_coord); + } else { + /* Need to create a new tile here */ + curr_tile_id = fabric_tile.create_tile(); + fabric_tile.set_coordinate(curr_tile_coord); + } + + /* Ensure that we have a valid id */ + if (fabric_tile.valid_tile_id(curr_tile_id)) { + VTR_LOG_ERROR("Failed to get a valid id for tile[%lu][%lu]!\n", ix, iy); + return CMD_EXEC_FATAL_ERROR; + } + + /* Add components: pb, cbx, cby, and sb if exists */ + if (!skip_add_pb) { + fabric_tile.add_pb_coordinate(curr_tile_id, curr_tile_coord); + } + /* The gsb coordinate is different than the grid coordinate when the + * top-left style is considered + * + * +----------+ +----------+ + * | Grid | | CBx | + * | [x][y] | | [x][y] | + * +----------+ +----------+ + * +----------+ +----------+ + * | CBy | | SB | + * | [x][y-1] | | [x][y-1] | + * +----------+ +----------+ + * + */ + vtr::Point curr_gsb_coord(ix, iy - 1); + if (!device_rr_gsb.is_gsb_exist(curr_gsb_coord)) { + continue; + } + const RRGSB& curr_rr_gsb = device_rr_gsb.get_gsb(curr_gsb_coord); + if (curr_rr_gsb.is_cb_exist(CHANX)) { + fabric_tile.add_cbx_coordinate(curr_tile_id, + curr_rr_gsb.get_cb_coordinate(CHANX)); + } + if (curr_rr_gsb.is_cb_exist(CHANY)) { + fabric_tile.add_cby_coordinate(curr_tile_id, + curr_rr_gsb.get_cb_coordinate(CHANY)); + } + if (curr_rr_gsb.is_sb_exist()) { + fabric_tile.add_sb_coordinate(curr_tile_id, + curr_rr_gsb.get_sb_coordinate()); + } + } + } + + return status_code; +} + +/******************************************************************** + * Build tile-level information for a given FPGA fabric, w.r.t. to configuration + *******************************************************************/ +int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb) { + vtr::ScopedStartFinishTimer timer( + "Build tile-level information for the FPGA fabric"); + + int status_code = CMD_EXEC_SUCCESS; + + /* Depending on the selected style, follow different approaches */ + if (tile_config.style() == TileConfig::e_style::TOP_LEFT) { + status_code = build_fabric_tile_style_top_left(fabric_tile, grids, device_rr_gsb); + } else { + /* Error out for styles that are not supported yet! */ + VTR_LOG_ERROR("Tile style '%s' is not supported yet!\n", + tile_config.style_to_string().c_str()); + status_code = CMD_EXEC_FATAL_ERROR; + } + + return status_code; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_fabric_tile.h b/openfpga/src/fabric/build_fabric_tile.h new file mode 100644 index 000000000..b70f66f07 --- /dev/null +++ b/openfpga/src/fabric/build_fabric_tile.h @@ -0,0 +1,26 @@ +#ifndef BUILD_FABRIC_TILE_H +#define BUILD_FABRIC_TILE_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ + +#include + +#include "fabric_tile.h" +#include "tile_config.h" +#include "device_grid.h" +#include "device_rr_gsb.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int build_fabric_tile(FabricTile& fabric_tile, const TileConfig& tile_config, const DeviceGrid& grids, const DeviceRRGSB& device_rr_gsb); + +} /* end namespace openfpga */ + +#endif