diff --git a/doc/src/arch/reference.rst b/doc/src/arch/reference.rst index d94f29de62..489ab327bf 100644 --- a/doc/src/arch/reference.rst +++ b/doc/src/arch/reference.rst @@ -582,10 +582,12 @@ Grid Layout Example Example FPGA grid -.. arch:tag:: +.. arch:tag:: - :req_param dim: Dimension or axis of the cut. 'X' or 'x' means a horizontal cut while 'Y' or 'y' means a vertical cut. - :req_param loc: Location of the cut. Cuts are done above or to the right of the tiles at coordinate 'loc'. For example a cut with dim=x and loc=0 would cut the vertical wires above tiles in the 0th row. Currently only integer values are supported. + :opt_param x: Specifies the x-coordinate of a vertical interposer cut. + :opt_param y: Specifies the y-coordinate of a horizontal interposer cut. + + .. note:: Exactly one of the ``x`` or ``y`` attributes must be specified. .. note:: Interposers are experimental and are currently not supported by VPR and using the related tags will not actually result in any changes to the flow. Defines an interposer cut for modelling 2.5D interposer-based architectures. An interposer cut will cut all connections at location 'loc' along the axis 'dim' Leaving the two sides completely unconnected. diff --git a/libs/libarchfpga/src/device_grid.cpp b/libs/libarchfpga/src/device_grid.cpp index 43907f50ac..f0644873a4 100644 --- a/libs/libarchfpga/src/device_grid.cpp +++ b/libs/libarchfpga/src/device_grid.cpp @@ -2,16 +2,23 @@ #include -DeviceGrid::DeviceGrid(std::string grid_name, vtr::NdMatrix grid) - : name_(std::move(grid_name)) - , grid_(std::move(grid)) { +DeviceGrid::DeviceGrid(std::string_view grid_name, + vtr::NdMatrix grid, + std::vector>&& horizontal_interposer_cuts, + std::vector>&& vertical_interposer_cuts) + : name_(grid_name) + , grid_(std::move(grid)) + , horizontal_interposer_cuts_(std::move(horizontal_interposer_cuts)) + , vertical_interposer_cuts_(std::move(vertical_interposer_cuts)) { count_instances(); } -DeviceGrid::DeviceGrid(std::string grid_name, +DeviceGrid::DeviceGrid(std::string_view grid_name, vtr::NdMatrix grid, - std::vector limiting_res) - : DeviceGrid(std::move(grid_name), std::move(grid)) { + std::vector limiting_res, + std::vector>&& horizontal_interposer_cuts, + std::vector>&& vertical_interposer_cuts) + : DeviceGrid(grid_name, std::move(grid), std::move(horizontal_interposer_cuts), std::move(vertical_interposer_cuts)) { limiting_resources_ = std::move(limiting_res); } diff --git a/libs/libarchfpga/src/device_grid.h b/libs/libarchfpga/src/device_grid.h index 0e4fb32c00..5a5f1c0105 100644 --- a/libs/libarchfpga/src/device_grid.h +++ b/libs/libarchfpga/src/device_grid.h @@ -26,8 +26,16 @@ struct t_grid_tile { class DeviceGrid { public: DeviceGrid() = default; - DeviceGrid(std::string grid_name, vtr::NdMatrix grid); - DeviceGrid(std::string grid_name, vtr::NdMatrix grid, std::vector limiting_res); + DeviceGrid(std::string_view grid_name, + vtr::NdMatrix grid, + std::vector>&& horizontal_interposer_cuts, + std::vector>&& vertical_interposer_cuts); + + DeviceGrid(std::string_view grid_name, + vtr::NdMatrix grid, + std::vector limiting_res, + std::vector>&& horizontal_interposer_cuts, + std::vector>&& vertical_interposer_cuts); const std::string& name() const { return name_; } @@ -63,7 +71,7 @@ class DeviceGrid { * @brief Returns the block types which limits the device size (may be empty if * resource limits were not considered when selecting the device). */ - std::vector limiting_resources() const { return limiting_resources_; } + const std::vector& limiting_resources() const { return limiting_resources_; } ///@brief Return the t_physical_tile_type_ptr at the specified location inline t_physical_tile_type_ptr get_physical_type(const t_physical_tile_loc& tile_loc) const { @@ -189,15 +197,31 @@ class DeviceGrid { return &grid_.get(n); } + /// Returns the list of horizontal interposer cut locations for each layer, + /// i.e. y value of the tile row just below each cut + /// Accessed as [layer][cut_idx] + inline const std::vector>& get_horizontal_interposer_cuts() const { + return horizontal_interposer_cuts_; + } + + /// Returns the list of vertical interposer cut locations for each layer, + /// i.e. x value of the tile column just to the left each cut + /// Accessed as [layer][cut_idx] + inline const std::vector>& get_vertical_interposer_cuts() const { + return vertical_interposer_cuts_; + } + private: - ///@brief count_instances() counts the number of each tile type on each layer and store it in instance_counts_. It is called in the constructor. + /// @brief Counts the number of each tile type on each layer and store it in instance_counts_. + /// It is called in the constructor. void count_instances(); std::string name_; /** * @brief grid_ is a 3D matrix that represents the grid of the FPGA chip. - * @note The first dimension is the layer number (grid_[0] corresponds to the bottom layer), the second dimension is the x coordinate, and the third dimension is the y coordinate. + * @note The first dimension is the layer number (grid_[0] corresponds to the bottom layer), + * the second dimension is the x coordinate, and the third dimension is the y coordinate. * @note Note that vtr::Matrix operator[] returns and intermediate type * @note which can be used for indexing in the second dimension, allowing * @note traditional 2-d indexing to be used @@ -208,4 +232,13 @@ class DeviceGrid { std::vector> instance_counts_; /* [layer_num][physical_tile_type_ptr] */ std::vector limiting_resources_; + + /// Horizontal interposer cut locations in each layer, + /// i.e. y value of the tile row just below each cut + /// Accessed as [layer][cut_idx] + std::vector> horizontal_interposer_cuts_; + /// Vertical interposer cut location in each layer, + /// i.e. x value of the tile column just to the left each cut + /// Accessed as [layer][cut_idx] + std::vector> vertical_interposer_cuts_; }; diff --git a/libs/libarchfpga/src/interposer_types.h b/libs/libarchfpga/src/interposer_types.h index ad9a33b07c..4f4b41b44b 100644 --- a/libs/libarchfpga/src/interposer_types.h +++ b/libs/libarchfpga/src/interposer_types.h @@ -4,33 +4,20 @@ * @file interposer_types.h * @brief This file contains types used for parsing interposer-related tags such as and * and converting that information into the device architecture-related data structures. - * */ -#include #include #include #include "grid_types.h" -/** - * @brief Enum for direction of an interposer cut. X means horizontal cut and Y means vertical cut. - * - */ -enum class e_interposer_cut_dim { - X, - Y +/// @brief Enum for direction of an interposer cut. +enum class e_interposer_cut_type { + HORZ, + VERT }; -// Lookup table for converting between a character and an e_interposer_cut_dim -inline const std::unordered_map CHAR_INTERPOSER_DIM_MAP = { - {'X', e_interposer_cut_dim::X}, - {'x', e_interposer_cut_dim::X}, - {'Y', e_interposer_cut_dim::Y}, - {'y', e_interposer_cut_dim::Y}}; - /** * @brief Struct containing information of interdire wires i.e. connections between the dies on an interposer - * */ struct t_interdie_wire_inf { std::string sg_name; ///< Name of the scatter-gather pattern to be used for the interdie connection @@ -40,7 +27,8 @@ struct t_interdie_wire_inf { * Contains starting and ending point (both inclusive) of scatter-gather instantiations and the increment/distance between the instantiations. * offset_definition.repeat_expr is not relevant for interdie wires and is not set to anything or used. * - * Locations defined by this offset definition define the starting point or the gathering point of the SG pattern. The end or scatter point of the SG pattern is defined by the sg_link. + * Locations defined by this offset definition define the starting point or the gathering point of the SG pattern. + * The end or scatter point of the SG pattern is defined by the sg_link. */ t_grid_loc_spec offset_definition; int num; ///< Number of scatter-gather instantiations per switchblock location @@ -48,10 +36,9 @@ struct t_interdie_wire_inf { /** * @brief Struct containing information of an interposer cut - * */ struct t_interposer_cut_inf { - e_interposer_cut_dim dim; ///< Dimension or axis of interposer cut. + e_interposer_cut_type dim; ///< Axis of interposer cut location. The cut is perpendicular to this axis. This specifies the dimension of `loc`. int loc; ///< Location of the cut on the grid. Locations start from zero and cuts will happen above or to the right of the tiles at location=loc. std::vector interdie_wires; ///< Connectivity specification between the two sides of the cut. }; diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 2c122e1773..1a529b1f2e 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -241,7 +241,7 @@ enum e_power_estimation_method_ { POWER_METHOD_SPECIFY_SIZES, /* Transistor-level, user-specified buffers/wires */ POWER_METHOD_TOGGLE_PINS, /* Dynamic: Energy per pin toggle, Static: Absolute */ POWER_METHOD_C_INTERNAL, /* Dynamic: Equiv. Internal capacitance, Static: Absolute */ - POWER_METHOD_ABSOLUTE /* Dynamic: Aboslute, Static: Absolute */ + POWER_METHOD_ABSOLUTE /* Dynamic: Absolute, Static: Absolute */ }; typedef enum e_power_estimation_method_ e_power_estimation_method; typedef enum e_power_estimation_method_ t_power_estimation_method; diff --git a/libs/libarchfpga/src/read_xml_arch_file.cpp b/libs/libarchfpga/src/read_xml_arch_file.cpp index fad3679758..79c6a46e6d 100644 --- a/libs/libarchfpga/src/read_xml_arch_file.cpp +++ b/libs/libarchfpga/src/read_xml_arch_file.cpp @@ -2661,7 +2661,8 @@ static void process_block_type_locs(t_grid_def& grid_def, t_interposer_cut_inf interposer_cut = parse_interposer_cut_tag(loc_spec_tag, loc_data); - if ((interposer_cut.dim == e_interposer_cut_dim::X && interposer_cut.loc >= grid_def.height) || (interposer_cut.dim == e_interposer_cut_dim::Y && interposer_cut.loc >= grid_def.width)) { + if ((interposer_cut.dim == e_interposer_cut_type::VERT && interposer_cut.loc >= grid_def.width) + || (interposer_cut.dim == e_interposer_cut_type::HORZ && interposer_cut.loc >= grid_def.height)) { archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer cut dimensions are outside of device bounds"); } diff --git a/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp b/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp index 2faad0ef7a..d6dc3455cf 100644 --- a/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp +++ b/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp @@ -1,5 +1,7 @@ #include "read_xml_arch_file_interposer.h" + #include + #include "interposer_types.h" #include "read_xml_util.h" #include "pugixml_util.hpp" @@ -8,24 +10,37 @@ t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, const pugiutil::loc_data& loc_data) { t_interposer_cut_inf interposer; - pugiutil::expect_only_attributes(interposer_cut_tag, {"dim", "loc"}, loc_data); + pugiutil::expect_only_attributes(interposer_cut_tag, {"x", "y"}, loc_data); + + const int x = pugiutil::get_attribute(interposer_cut_tag, "x", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(ARCH_FPGA_UNDEFINED_VAL); + const int y = pugiutil::get_attribute(interposer_cut_tag, "y", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(ARCH_FPGA_UNDEFINED_VAL); - std::string interposer_dim = pugiutil::get_attribute(interposer_cut_tag, "dim", loc_data).as_string(); - if (interposer_dim.size() != 1 || !CHAR_INTERPOSER_DIM_MAP.contains(interposer_dim[0])) { - archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), "Interposer tag dimension must be a single character of either X, x, Y or y."); + // Both x and y are specified + if (x != ARCH_FPGA_UNDEFINED_VAL && y != ARCH_FPGA_UNDEFINED_VAL) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), + "Interposer cut tag must specify where the cut is to appear using only one of `x` or `y` attributes."); } - interposer.dim = CHAR_INTERPOSER_DIM_MAP.at(interposer_dim[0]); + if (x != ARCH_FPGA_UNDEFINED_VAL) { + interposer.loc = x; + interposer.dim = e_interposer_cut_type::VERT; + } else if (y != ARCH_FPGA_UNDEFINED_VAL) { + interposer.loc = y; + interposer.dim = e_interposer_cut_type::HORZ; + } else { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), + "Interposer cut tag must specify where the cut is to appear using `x` or `y` attributes."); + } - interposer.loc = pugiutil::get_attribute(interposer_cut_tag, "loc", loc_data).as_int(); - if (interposer.loc < 0) { - archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), "Interposer location must be positive."); + if (interposer.loc <= 0) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(interposer_cut_tag), + "Interposer cut location must be a positive number."); } pugiutil::expect_only_children(interposer_cut_tag, {"interdie_wire"}, loc_data); for (pugi::xml_node interdie_wire_tag : interposer_cut_tag.children()) { - const std::vector interdie_wire_attributes = {{"sg_name", "sg_link", "offset_start", "offset_end", "offset_increment", "num"}}; + const std::vector interdie_wire_attributes = {"sg_name", "sg_link", "offset_start", "offset_end", "offset_increment", "num"}; pugiutil::expect_only_attributes(interdie_wire_tag, interdie_wire_attributes, loc_data); t_interdie_wire_inf interdie_wire; @@ -39,6 +54,11 @@ t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, interdie_wire.num = pugiutil::get_attribute(interdie_wire_tag, "num", loc_data).as_int(); + if (interdie_wire.num <= 0) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(interdie_wire_tag), + "The `num` attribute of an `interdie_wire` must be specified with a positive number."); + } + interposer.interdie_wires.push_back(interdie_wire); } diff --git a/vpr/src/base/setup_grid.cpp b/vpr/src/base/setup_grid.cpp index 5d3d03744e..c86708c5d5 100644 --- a/vpr/src/base/setup_grid.cpp +++ b/vpr/src/base/setup_grid.cpp @@ -40,7 +40,7 @@ static void check_grid(const DeviceGrid& grid); static void set_grid_block_type(int priority, const t_physical_tile_type* type, - int layer_num, + size_t layer_num, size_t x_root, size_t y_root, vtr::NdMatrix& grid, @@ -144,18 +144,18 @@ DeviceGrid create_device_grid(const std::string& layout_name, const std::vector< * @brief Create a device grid which satisfies the minimum block counts * * If a set of fixed grid layouts are specified, the smallest satisfying grid is picked - * If an auto grid layouts are specified, the smallest dynamicly sized grid is picked + * If an auto grid layouts are specified, the smallest dynamically sized grid is picked */ static DeviceGrid auto_size_device_grid(const std::vector& grid_layouts, const std::map& minimum_instance_counts, float maximum_device_utilization) { VTR_ASSERT(!grid_layouts.empty()); DeviceGrid grid; - auto is_auto_grid_def = [](const t_grid_def& grid_def) { + auto is_auto_grid_def = [](const t_grid_def& grid_def) noexcept { return grid_def.grid_type == e_grid_def_type::AUTO; }; - auto auto_layout_itr = std::find_if(grid_layouts.begin(), grid_layouts.end(), is_auto_grid_def); + auto auto_layout_itr = std::ranges::find_if(grid_layouts, is_auto_grid_def); if (auto_layout_itr != grid_layouts.end()) { //Automatic grid layout, find the smallest height/width VTR_ASSERT_SAFE_MSG(std::find_if(auto_layout_itr + 1, grid_layouts.end(), is_auto_grid_def) == grid_layouts.end(), "Only one "); @@ -347,22 +347,22 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt } } - auto& device_ctx = g_vpr_ctx.device(); + const DeviceContext& device_ctx = g_vpr_ctx.device(); - //Initialize the grid and each location priority based on available dies in the architecture file + // Initialize the grid and each location priority based on available dies in the architecture file vtr::NdMatrix grid; vtr::NdMatrix grid_priorities; - int num_layers = (int)grid_def.layers.size(); - grid.resize(std::array{(size_t)num_layers, grid_width, grid_height}); + size_t num_layers = grid_def.layers.size(); + grid.resize({num_layers, grid_width, grid_height}); //Track the current priority for each grid location // Note that we initialize it to the lowest (i.e. most negative) possible value, so // any user-specified priority will override the default empty grid - grid_priorities.resize(std::array{(size_t)num_layers, grid_width, grid_height}, std::numeric_limits::lowest()); + grid_priorities.resize({num_layers, grid_width, grid_height}, std::numeric_limits::lowest()); - //Initialize the device to all empty blocks - auto empty_type = device_ctx.EMPTY_PHYSICAL_TILE_TYPE; + // Initialize the device to all empty blocks + t_physical_tile_type_ptr empty_type = device_ctx.EMPTY_PHYSICAL_TILE_TYPE; VTR_ASSERT(empty_type != nullptr); - for (int layer = 0; layer < num_layers; ++layer) { + for (size_t layer = 0; layer < num_layers; ++layer) { for (size_t x = 0; x < grid_width; ++x) { for (size_t y = 0; y < grid_height; ++y) { set_grid_block_type(std::numeric_limits::lowest() + 1, //+1 so it overrides without warning @@ -376,10 +376,24 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt FormulaParser p; std::set seen_types; - for (int layer = 0; layer < num_layers; layer++) { - for (const auto& grid_loc_def : grid_def.layers.at(layer).loc_defs) { - //Fill in the block types according to the specification - auto type = find_tile_type_by_name(grid_loc_def.block_type, device_ctx.physical_tile_types); + std::vector> horizontal_interposer_cuts(num_layers); + std::vector> vertical_interposer_cuts(num_layers); + + for (size_t layer = 0; layer < num_layers; layer++) { + const t_layer_def& layer_def = grid_def.layers[layer]; + + for (const t_interposer_cut_inf& cut_inf : layer_def.interposer_cuts) { + if (cut_inf.dim == e_interposer_cut_type::VERT) { + vertical_interposer_cuts[layer].push_back(cut_inf.loc); + } else { + VTR_ASSERT(cut_inf.dim == e_interposer_cut_type::HORZ); + horizontal_interposer_cuts[layer].push_back(cut_inf.loc); + } + } + + for (const t_grid_loc_def& grid_loc_def : layer_def.loc_defs) { + // Fill in the block types according to the specification + t_physical_tile_type_ptr type = find_tile_type_by_name(grid_loc_def.block_type, device_ctx.physical_tile_types); if (!type) { VPR_FATAL_ERROR(VPR_ERROR_ARCH, @@ -396,7 +410,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt vars.set_var_value("h", type->height); //Load the x specification - auto& xspec = grid_loc_def.x; + const t_grid_loc_spec& xspec = grid_loc_def.x; VTR_ASSERT_MSG(!xspec.start_expr.empty(), "x start position must be specified"); VTR_ASSERT_MSG(!xspec.end_expr.empty(), "x end position must be specified"); @@ -408,8 +422,8 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt size_t incrx = p.parse_formula(xspec.incr_expr, vars); size_t repeatx = p.parse_formula(xspec.repeat_expr, vars); - //Load the y specification - auto& yspec = grid_loc_def.y; + // Load the y specification + const t_grid_loc_spec& yspec = grid_loc_def.y; VTR_ASSERT_MSG(!yspec.start_expr.empty(), "y start position must be specified"); VTR_ASSERT_MSG(!yspec.end_expr.empty(), "y end position must be specified"); @@ -421,7 +435,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt size_t incry = p.parse_formula(yspec.incr_expr, vars); size_t repeaty = p.parse_formula(yspec.repeat_expr, vars); - //Check start against the device dimensions + // Check start against the device dimensions // Start locations outside the device will never create block instances if (startx > grid_width - 1) { if (warn_out_of_range) { @@ -439,7 +453,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt continue; //No instances will be created } - //Check end against the device dimensions + // Check end against the device dimensions if (endx > grid_width - 1) { if (warn_out_of_range) { VTR_LOG_WARN("Block type '%s' grid location specification endx (%s = %d) falls outside device horizontal range [%d,%d]\n", @@ -454,7 +468,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt } } - //The end must fall after (or equal) to the start + // The end must fall after (or equal) to the start if (endx < startx) { VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Grid location specification endx (%s = %d) can not come before startx (%s = %d) for block type '%s'", @@ -467,7 +481,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt yspec.end_expr.c_str(), endy, yspec.start_expr.c_str(), starty, type->name.c_str()); } - //The minimum increment is the block dimension + // The minimum increment is the block dimension VTR_ASSERT(type->width > 0); if (incrx < size_t(type->width)) { VPR_FATAL_ERROR(VPR_ERROR_ARCH, @@ -484,7 +498,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt type->name.c_str(), type->height, yspec.incr_expr.c_str(), incry); } - //The minimum repeat is the region dimension + // The minimum repeat is the region dimension size_t region_width = endx - startx + 1; //+1 since start/end are both inclusive if (repeatx < region_width) { VPR_FATAL_ERROR(VPR_ERROR_ARCH, @@ -501,25 +515,21 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt type->name.c_str(), region_height, xspec.repeat_expr.c_str(), repeaty); } - //VTR_LOG("Applying grid_loc_def for '%s' priority %d startx=%s=%zu, endx=%s=%zu, starty=%s=%zu, endx=%s=%zu,\n", - // type->name, grid_loc_def.priority, - // xspec.start_expr.c_str(), startx, xspec.end_expr.c_str(), endx, - // yspec.start_expr.c_str(), starty, yspec.end_expr.c_str(), endy); - size_t x_end = 0; - for (size_t kx = 0; x_end < grid_width; ++kx) { //Repeat in x direction + for (size_t kx = 0; x_end < grid_width; ++kx) { + // Repeat in x direction size_t x_start = startx + kx * repeatx; x_end = endx + kx * repeatx; size_t y_end = 0; - for (size_t ky = 0; y_end < grid_height; ++ky) { //Repeat in y direction + for (size_t ky = 0; y_end < grid_height; ++ky) { // Repeat in y direction size_t y_start = starty + ky * repeaty; y_end = endy + ky * repeaty; size_t x_max = std::min(x_end, grid_width - 1); size_t y_max = std::min(y_end, grid_height - 1); - //Fill in the region + // Fill in the region for (size_t x = x_start; x + (type->width - 1) <= x_max; x += incrx) { for (size_t y = y_start; y + (type->height - 1) <= y_max; y += incry) { set_grid_block_type(grid_loc_def.priority, @@ -534,9 +544,9 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt } } - //Warn if any types were not specified in the grid layout - for (auto const& type : device_ctx.physical_tile_types) { - if (&type == empty_type) continue; //Don't worry if empty hasn't been specified + // Warn if any types were not specified in the grid layout + for (const t_physical_tile_type& type : device_ctx.physical_tile_types) { + if (&type == empty_type) continue; // Don't worry if empty hasn't been specified if (!seen_types.count(&type)) { VTR_LOG_WARN("Block type '%s' was not specified in device grid layout\n", @@ -544,7 +554,11 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt } } - auto device_grid = DeviceGrid(grid_def.name, grid, limiting_resources); + DeviceGrid device_grid(grid_def.name, + grid, + limiting_resources, + std::move(horizontal_interposer_cuts), + std::move(vertical_interposer_cuts)); check_grid(device_grid); @@ -553,7 +567,7 @@ static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_widt static void set_grid_block_type(int priority, const t_physical_tile_type* type, - int layer_num, + size_t layer_num, size_t x_root, size_t y_root, vtr::NdMatrix& grid, diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index fab47d319c..9dc4d353ae 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -1062,8 +1062,8 @@ RouteStatus vpr_route_flow(const Netlist<>& net_list, print_switch_usage(); } - //Update interactive graphics - update_screen(ScreenUpdatePriority::MAJOR, graphics_msg.c_str(), ROUTING, timing_info); + // Update interactive graphics + update_screen(ScreenUpdatePriority::MAJOR, graphics_msg.c_str(), e_pic_type::ROUTING, timing_info); } return route_status; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index bfed5f4ef1..e1133b64ee 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -383,12 +383,12 @@ enum class e_sched_type { }; /* Annealing schedule */ -enum pic_type { +/// Specifies what is shown on screen +enum class e_pic_type { NO_PICTURE, PLACEMENT, ROUTING }; -/* What's on screen? */ enum pfreq { PLACE_NEVER, diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index 4593410afb..99ff4e6796 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -16,6 +16,8 @@ #include #include #include "draw.h" + +#include "draw_interposer.h" #include "timing_info.h" #include "physical_types.h" @@ -175,11 +177,13 @@ static void draw_main_canvas(ezgl::renderer* g) { g->set_font_size(14); + draw_interposer_cuts(g); + draw_block_pin_util(); drawplace(g); draw_internal_draw_subblk(g); - if (draw_state->pic_on_screen == ROUTING) { // ROUTING on screen + if (draw_state->pic_on_screen == e_pic_type::ROUTING) { // ROUTING on screen draw_rr(g); @@ -255,12 +259,12 @@ static void on_stage_change_setup(ezgl::application* app, bool is_new_window) { t_draw_state* draw_state = get_draw_state_vars(); - if (draw_state->pic_on_screen == PLACEMENT) { + if (draw_state->pic_on_screen == e_pic_type::PLACEMENT) { hide_widget("RoutingMenuButton", app); draw_state->save_graphics_file_base = "vpr_placement"; - } else if (draw_state->pic_on_screen == ROUTING) { + } else if (draw_state->pic_on_screen == e_pic_type::ROUTING) { show_widget("RoutingMenuButton", app); draw_state->save_graphics_file_base = "vpr_routing"; @@ -274,7 +278,10 @@ static void on_stage_change_setup(ezgl::application* app, bool is_new_window) { #endif //NO_GRAPHICS -void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type pic_on_screen_val, std::shared_ptr setup_timing_info) { +void update_screen(ScreenUpdatePriority priority, + const char* msg, + e_pic_type pic_on_screen_val, + std::shared_ptr setup_timing_info) { #ifndef NO_GRAPHICS /* Updates the screen if the user has requested graphics. The priority * @@ -297,10 +304,9 @@ void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type state_change = true; - if (draw_state->pic_on_screen == NO_PICTURE) { + if (draw_state->pic_on_screen == e_pic_type::NO_PICTURE) { // Only add the canvas the first time we open graphics - application.add_canvas("MainCanvas", draw_main_canvas, - initial_world); + application.add_canvas("MainCanvas", draw_main_canvas, initial_world); } draw_state->setup_timing_info = setup_timing_info; @@ -373,8 +379,8 @@ void alloc_draw_structs(const t_arch* arch) { /* Allocate the structures needed to draw the placement and routing-> Set * * up the default colors for blocks and nets. */ - draw_coords->tile_x = new float[device_ctx.grid.width()]; - draw_coords->tile_y = new float[device_ctx.grid.height()]; + draw_coords->tile_x.resize(device_ctx.grid.width(), 0.f); + draw_coords->tile_y.resize(device_ctx.grid.height(), 0.f); /* For sub-block drawings inside clbs */ draw_internal_alloc_blk(); @@ -415,10 +421,8 @@ void free_draw_structs() { t_draw_coords* draw_coords = get_draw_coords_vars(); if (draw_coords != nullptr) { - delete[] draw_coords->tile_x; - draw_coords->tile_x = nullptr; - delete[] draw_coords->tile_y; - draw_coords->tile_y = nullptr; + vtr::release_memory(draw_coords->tile_x); + vtr::release_memory(draw_coords->tile_y); } #else @@ -454,7 +458,7 @@ void init_draw_coords(float clb_width, const BlkLocRegistry& blk_loc_registry) { draw_coords->set_tile_width(clb_width); draw_coords->pin_size = 0.3; for (const auto& type : device_ctx.physical_tile_types) { - auto num_pins = type.num_pins; + int num_pins = type.num_pins; if (num_pins > 0) { draw_coords->pin_size = std::min(draw_coords->pin_size, (draw_coords->get_tile_width() / (4.0F * num_pins))); diff --git a/vpr/src/draw/draw.h b/vpr/src/draw/draw.h index 294e3d37ff..e64fee1ee1 100644 --- a/vpr/src/draw/draw.h +++ b/vpr/src/draw/draw.h @@ -40,7 +40,10 @@ extern ezgl::application application; #endif /* NO_GRAPHICS */ -void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type pic_on_screen_val, std::shared_ptr timing_info); +void update_screen(ScreenUpdatePriority priority, + const char* msg, + e_pic_type pic_on_screen_val, + std::shared_ptr timing_info); //FIXME: Currently broken if no rr-graph is loaded /** diff --git a/vpr/src/draw/draw_interposer.cpp b/vpr/src/draw/draw_interposer.cpp new file mode 100644 index 0000000000..8af385fc3c --- /dev/null +++ b/vpr/src/draw/draw_interposer.cpp @@ -0,0 +1,83 @@ + +#ifndef NO_GRAPHICS + +#include "draw_interposer.h" + +#include "draw_global.h" +#include "vtr_assert.h" +#include "globals.h" + +void draw_interposer_cuts(ezgl::renderer* g) { + const t_draw_state* draw_state = get_draw_state_vars(); + const DeviceContext& device_ctx = g_vpr_ctx.device(); + const DeviceGrid& grid = device_ctx.grid; + const t_draw_coords* draw_coords = get_draw_coords_vars(); + + if (draw_state->pic_on_screen == e_pic_type::NO_PICTURE) { + return; + } + VTR_ASSERT_SAFE(draw_state->pic_on_screen == e_pic_type::PLACEMENT || draw_state->pic_on_screen == e_pic_type::ROUTING); + + // A rectangle containing the FPGA fabric with some padding. + // Used to determine the start and end coordinates of an interposer cut whose x or y position is fixed. + const ezgl::rectangle world{ + {draw_coords->tile_x.front() - draw_coords->get_tile_width(), + draw_coords->tile_y.front() - draw_coords->get_tile_height()}, + {draw_coords->tile_x.back() + 2 * draw_coords->get_tile_width(), + draw_coords->tile_y.back() + 2 * draw_coords->get_tile_height()} + }; + + g->set_color(ezgl::BLACK, 255); + g->set_line_dash(ezgl::line_dash::asymmetric_5_3); + g->set_line_width(2); + + const std::vector>& horizontal_cuts = grid.get_horizontal_interposer_cuts(); + const std::vector>& vertical_cuts = grid.get_vertical_interposer_cuts(); + std::vector> lines_to_draw; + + for (size_t layer = 0; layer < grid.get_num_layers(); layer++) { + if (!draw_state->draw_layer_display[layer].visible) { + continue; + } + + for (int cut_y : horizontal_cuts[layer]) { + float y; + if (draw_state->pic_on_screen == e_pic_type::PLACEMENT) { + // Draw the interposer line exactly in the middle of routing channel. + y = (draw_coords->tile_y[cut_y + 1] + draw_coords->tile_y[cut_y] + draw_coords->get_tile_height()) / 2.0f; + } else if (draw_state->pic_on_screen == e_pic_type::ROUTING) { + // Draw the interposer above the last track and below the next tile. + // The row below the cut owns the channel, so the cut is drawn closer + // to the row above the cut to make this ownership explicit. + y = draw_coords->tile_y[cut_y + 1] - 0.5f; + } else { + VTR_ASSERT(false); + } + + lines_to_draw.push_back({{world.left(), y}, {world.right(), y}}); + } + + for (int cut_x : vertical_cuts[layer]) { + float x; + if (draw_state->pic_on_screen == e_pic_type::PLACEMENT) { + // Draw the interposer line exactly in the middle of routing channel. + x = (draw_coords->tile_x[cut_x + 1] + draw_coords->tile_x[cut_x] + draw_coords->get_tile_width()) / 2.0f; + } else if (draw_state->pic_on_screen == e_pic_type::ROUTING) { + // Draw the interposer line between the last track and the next column. + // The channel belongs to the column on the left of the cut, so the cut is + // positioned closer to the column on the right to make this ownership clear. + x = draw_coords->tile_x[cut_x + 1] - 0.5f; + } else { + VTR_ASSERT(false); + } + + lines_to_draw.push_back({{x, world.bottom()}, {x, world.top()}}); + } + } + + for (const auto& [start, end] : lines_to_draw) { + g->draw_line(start, end); + } +} + +#endif \ No newline at end of file diff --git a/vpr/src/draw/draw_interposer.h b/vpr/src/draw/draw_interposer.h new file mode 100644 index 0000000000..7350b30d13 --- /dev/null +++ b/vpr/src/draw/draw_interposer.h @@ -0,0 +1,24 @@ +#pragma once + +/** + * @file draw_interposer.h + * @brief Declares functions to draw interposer cut lines in the FPGA device. + * + * Cut lines are drawn at channel centers during placement and slightly offset + * during routing for better channel ownership visualization. + */ + +#ifndef NO_GRAPHICS + +// forward declaration +namespace ezgl { +class renderer; +} + +/// @brief Draws interposer cut lines. +/// During placement stage, the cut lines are drawn in the middle of routing channels. +/// During routing, the cut lines are drawn closer to the side of routing channel to make it clear +/// which side of the cut owns the channel. +void draw_interposer_cuts(ezgl::renderer* g); + +#endif \ No newline at end of file diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 4901ab14e8..a814a03c8d 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -7,11 +7,6 @@ #ifndef NO_GRAPHICS -#include -#include -#include -#include - #include "draw_types.h" #include "rr_graph_fwd.h" diff --git a/vpr/src/draw/draw_toggle_functions.cpp b/vpr/src/draw/draw_toggle_functions.cpp index a909e5f8ba..2abdc17c3d 100644 --- a/vpr/src/draw/draw_toggle_functions.cpp +++ b/vpr/src/draw/draw_toggle_functions.cpp @@ -310,7 +310,7 @@ void toggle_crit_path_cbk(GtkSwitch*, gboolean state, ezgl::application* app) { gtk_widget_set_sensitive(GTK_WIDGET(app->get_object("ToggleCritPathFlylines")), state); gtk_widget_set_sensitive(GTK_WIDGET(app->get_object("ToggleCritPathDelays")), state); - if (draw_state->setup_timing_info && draw_state->pic_on_screen == ROUTING) { + if (draw_state->setup_timing_info && draw_state->pic_on_screen == e_pic_type::ROUTING) { gtk_widget_set_sensitive(GTK_WIDGET(app->get_object("ToggleCritPathRouting")), state); } @@ -343,7 +343,7 @@ void toggle_expansion_cost_cbk(GtkComboBoxText* self, ezgl::application* app) { } else if (strcmp(combo_box_content, "Expected (with edges)") == 0) { new_state = DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES; } else { - VPR_THROW(VPR_ERROR_DRAW, "Unrecognzied draw RR cost option"); + VPR_THROW(VPR_ERROR_DRAW, "Unrecognized draw RR cost option"); } g_free(combo_box_content); diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index e3b6e7791e..3e3bf7e157 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -80,15 +80,13 @@ ezgl::rectangle& t_draw_pb_type_info::get_pb_bbox_ref(const t_pb_graph_node& pb_ t_draw_coords::t_draw_coords() { tile_width = 0; pin_size = 0; - tile_x = nullptr; - tile_y = nullptr; } -float t_draw_coords::get_tile_width() { +float t_draw_coords::get_tile_width() const { return tile_width; } -float t_draw_coords::get_tile_height() { +float t_draw_coords::get_tile_height() const { //For now, same as width return tile_width; } diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h index b05aadcd84..7d8937cf0d 100644 --- a/vpr/src/draw/draw_types.h +++ b/vpr/src/draw/draw_types.h @@ -179,7 +179,7 @@ struct t_draw_layer_display { */ struct t_draw_state { ///@brief What to draw on the screen (ROUTING, PLACEMENT, NO_PICTURE) - pic_type pic_on_screen = NO_PICTURE; + e_pic_type pic_on_screen = e_pic_type::NO_PICTURE; ///@brief Whether to draw nets or not bool show_nets = false; @@ -433,7 +433,7 @@ struct t_draw_coords { * to (tile_x[device_ctx.grid.width()-1]+tile_width, tile_y[device_ctx.grid.height()-1]+tile_width) in * the upper right corner. */ - float *tile_x, *tile_y; + std::vector tile_x, tile_y; ///@brief Half-width or Half-height of a pin. Set when init_draw_coords is called float pin_size; @@ -456,10 +456,10 @@ struct t_draw_coords { } ///@brief returns tile width - float get_tile_width(); + float get_tile_width() const; ///@brief returns tile width - float get_tile_height(); + float get_tile_height() const; ///@brief returns bounding box for given pb in given clb ezgl::rectangle get_pb_bbox(ClusterBlockId clb_index, const t_pb_graph_node& pb_gnode); diff --git a/vpr/src/draw/manual_moves.cpp b/vpr/src/draw/manual_moves.cpp index e1b56e8811..bcc58acbbd 100644 --- a/vpr/src/draw/manual_moves.cpp +++ b/vpr/src/draw/manual_moves.cpp @@ -93,10 +93,6 @@ void draw_manual_moves_window(const std::string& block_id) { void calculate_cost_callback(GtkWidget* /*widget*/, GtkWidget* grid) { int block_id = -1; - int x_location = -1; - int y_location = -1; - int layer_location = -1; - int subtile_location = -1; bool valid_input = true; t_draw_state* draw_state = get_draw_state_vars(); @@ -119,10 +115,10 @@ void calculate_cost_callback(GtkWidget* /*widget*/, GtkWidget* grid) { GtkWidget* layer_position_entry = gtk_grid_get_child_at((GtkGrid*)grid, 2, 3); GtkWidget* subtile_position_entry = gtk_grid_get_child_at((GtkGrid*)grid, 2, 4); - x_location = std::atoi(gtk_entry_get_text((GtkEntry*)x_position_entry)); - y_location = std::atoi(gtk_entry_get_text((GtkEntry*)y_position_entry)); - layer_location = std::atoi(gtk_entry_get_text((GtkEntry*)layer_position_entry)); - subtile_location = std::atoi(gtk_entry_get_text((GtkEntry*)subtile_position_entry)); + int x_location = std::atoi(gtk_entry_get_text((GtkEntry*)x_position_entry)); + int y_location = std::atoi(gtk_entry_get_text((GtkEntry*)y_position_entry)); + int layer_location = std::atoi(gtk_entry_get_text((GtkEntry*)layer_position_entry)); + int subtile_location = std::atoi(gtk_entry_get_text((GtkEntry*)subtile_position_entry)); if (std::string(gtk_entry_get_text((GtkEntry*)block_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)x_position_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)y_position_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)layer_position_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)subtile_position_entry)).empty()) { invalid_breakpoint_entry_window("Not all fields are complete"); @@ -324,7 +320,7 @@ e_create_move manual_move_display_and_propose(ManualMoveGenerator& manual_move_g const t_placer_opts& placer_opts, const PlacerCriticalities* criticalities) { draw_manual_moves_window(""); - update_screen(ScreenUpdatePriority::MAJOR, " ", PLACEMENT, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, " ", e_pic_type::PLACEMENT, nullptr); move_type = e_move_type::MANUAL_MOVE; t_propose_action proposed_action{move_type, -1}; //no need to specify block type in manual move "propose_move" function return manual_move_generator.propose_move(blocks_affected, proposed_action, rlim, placer_opts, criticalities); diff --git a/vpr/src/draw/ui_setup.cpp b/vpr/src/draw/ui_setup.cpp index 5ce1332726..9d37ae3eaf 100644 --- a/vpr/src/draw/ui_setup.cpp +++ b/vpr/src/draw/ui_setup.cpp @@ -272,7 +272,7 @@ void crit_path_button_setup(ezgl::application* app) { */ void hide_crit_path_routing(ezgl::application* app) { t_draw_state* draw_state = get_draw_state_vars(); - bool state = draw_state->setup_timing_info && draw_state->pic_on_screen == ROUTING && draw_state->show_crit_path; + bool state = draw_state->setup_timing_info && draw_state->pic_on_screen == e_pic_type::ROUTING && draw_state->show_crit_path; gtk_widget_set_sensitive(GTK_WIDGET(app->get_object("ToggleCritPathRouting")), state); } @@ -283,7 +283,7 @@ void hide_draw_routing(ezgl::application* app) { // Enable the option to draw routing only during the routing stage int route_item_index = get_item_index_by_text(toggle_nets, "Routing"); - if (draw_state->pic_on_screen == PLACEMENT) { + if (draw_state->pic_on_screen == e_pic_type::PLACEMENT) { if (route_item_index != -1) { gtk_combo_box_text_remove(toggle_nets, route_item_index); } diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index c5d46b5af3..91777f4576 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -156,6 +156,6 @@ static void update_screen_debug(); //This function with no arguments is useful for calling from a debugger to //look at the intermediate implemetnation state. static void update_screen_debug() { - update_screen(ScreenUpdatePriority::MAJOR, "DEBUG", PLACEMENT, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, "DEBUG", e_pic_type::PLACEMENT, nullptr); } #endif diff --git a/vpr/src/place/placement_log_printer.cpp b/vpr/src/place/placement_log_printer.cpp index 1e811740ec..268010a237 100644 --- a/vpr/src/place/placement_log_printer.cpp +++ b/vpr/src/place/placement_log_printer.cpp @@ -98,7 +98,7 @@ void PlacementLogPrinter::print_place_status(float elapsed_sec) const { sprintf(msg_.data(), "Cost: %g BB Cost %g TD Cost %g Temperature: %g", costs.cost, costs.bb_cost, costs.timing_cost, annealing_state.t); - update_screen(ScreenUpdatePriority::MINOR, msg_.data(), PLACEMENT, timing_info); + update_screen(ScreenUpdatePriority::MINOR, msg_.data(), e_pic_type::PLACEMENT, timing_info); } void PlacementLogPrinter::print_resources_utilization() const { @@ -217,7 +217,7 @@ void PlacementLogPrinter::print_initial_placement_stats() const { costs.cost, costs.bb_cost, costs.timing_cost, placer_opts.place_chan_width); // Draw the initial placement - update_screen(ScreenUpdatePriority::MAJOR, msg_.data(), PLACEMENT, timing_info); + update_screen(ScreenUpdatePriority::MAJOR, msg_.data(), e_pic_type::PLACEMENT, timing_info); if (placer_opts.placement_saves_per_temperature >= 1) { std::string filename = vtr::string_fmt("placement_%03d_%03d.place", 0, 0); @@ -270,7 +270,7 @@ void PlacementLogPrinter::print_post_placement_stats() const { placer_.costs_.cost, placer_.costs_.bb_cost, placer_.costs_.timing_cost, placer_.placer_opts_.place_chan_width); VTR_LOG("Placement cost: %g, bb_cost: %g, td_cost: %g, \n", placer_.costs_.cost, placer_.costs_.bb_cost, placer_.costs_.timing_cost); - update_screen(ScreenUpdatePriority::MAJOR, msg_.data(), PLACEMENT, placer_.timing_info_); + update_screen(ScreenUpdatePriority::MAJOR, msg_.data(), e_pic_type::PLACEMENT, placer_.timing_info_); // print the noc costs info if (placer_.noc_opts_.noc) { diff --git a/vpr/src/place/placer_breakpoint.cpp b/vpr/src/place/placer_breakpoint.cpp index 4ca967ab85..0f4c1f0856 100644 --- a/vpr/src/place/placer_breakpoint.cpp +++ b/vpr/src/place/placer_breakpoint.cpp @@ -57,7 +57,7 @@ void stop_placement_and_check_breakpoints(t_pl_blocks_to_be_moved& blocks_affect msg += vtr::string_fmt(", Delta_cost: %1.6f (bb_delta_cost= %1.5f , timing_delta_c= %6.1e)", delta_c, bb_delta_c, timing_delta_c); highlight_moved_block_and_its_terminals(blocks_affected); - update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), PLACEMENT, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), e_pic_type::PLACEMENT, nullptr); } } diff --git a/vpr/src/route/route.cpp b/vpr/src/route/route.cpp index 1a9f74e226..0696996cf8 100644 --- a/vpr/src/route/route.cpp +++ b/vpr/src/route/route.cpp @@ -342,9 +342,9 @@ bool route(const Netlist<>& net_list, //Update graphics if (itry == 1) { - update_screen(first_iteration_priority, ("Initial Route: " + iteration_msg).c_str(), ROUTING, timing_info); + update_screen(first_iteration_priority, ("Initial Route: " + iteration_msg).c_str(), e_pic_type::ROUTING, timing_info); } else { - update_screen(ScreenUpdatePriority::MINOR, ("Route: " + iteration_msg).c_str(), ROUTING, timing_info); + update_screen(ScreenUpdatePriority::MINOR, ("Route: " + iteration_msg).c_str(), e_pic_type::ROUTING, timing_info); } if (router_opts.save_routing_per_iteration) { diff --git a/vpr/src/route/route_net.tpp b/vpr/src/route/route_net.tpp index b413f6ff33..d6d9aba3c8 100644 --- a/vpr/src/route/route_net.tpp +++ b/vpr/src/route/route_net.tpp @@ -340,7 +340,7 @@ inline NetResultFlags pre_route_to_clock_root(ConnectionRouterType& router, net_list.net_name(net_id).c_str(), size_t(net_id)); if (f_router_debug) { - update_screen(ScreenUpdatePriority::MAJOR, "Unable to route connection.", ROUTING, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, "Unable to route connection.", e_pic_type::ROUTING, nullptr); } router.reset_path_costs(); out.success = false; @@ -361,7 +361,7 @@ inline NetResultFlags pre_route_to_clock_root(ConnectionRouterType& router, if (f_router_debug) { std::string msg = vtr::string_fmt("Routed Net %zu connection to RR node %d successfully", size_t(net_id), sink_node); - update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), ROUTING, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), e_pic_type::ROUTING, nullptr); } if (new_branch) @@ -472,7 +472,7 @@ inline NetResultFlags route_sink(ConnectionRouterType& router, net_list.net_name(net_id).c_str(), size_t(net_id)); if (f_router_debug) { - update_screen(ScreenUpdatePriority::MAJOR, "Unable to route connection.", ROUTING, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, "Unable to route connection.", e_pic_type::ROUTING, nullptr); } flags.success = false; router.reset_path_costs(); @@ -488,7 +488,7 @@ inline NetResultFlags route_sink(ConnectionRouterType& router, if (f_router_debug) { std::string msg = vtr::string_fmt("Routed Net %zu connection %d to RR node %d successfully", size_t(net_id), itarget, sink_node); - update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), ROUTING, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), e_pic_type::ROUTING, nullptr); } if (budgeting_inf.if_set() && cheapest.rcv_path_backward_delay != std::numeric_limits::infinity() && cost_params.delay_budget) { diff --git a/vpr/src/route/route_utils.cpp b/vpr/src/route/route_utils.cpp index fe6d9cdc41..89a5117a9d 100644 --- a/vpr/src/route/route_utils.cpp +++ b/vpr/src/route/route_utils.cpp @@ -692,7 +692,7 @@ void update_router_info_and_check_bp(bp_router_type type, int net_id) { } if (hit_bp) { breakpoint_info_window(get_bp_state_globals()->get_glob_breakpoint_state()->bp_description, *get_bp_state_globals()->get_glob_breakpoint_state(), false); - update_screen(ScreenUpdatePriority::MAJOR, "Breakpoint Encountered", ROUTING, nullptr); + update_screen(ScreenUpdatePriority::MAJOR, "Breakpoint Encountered", e_pic_type::ROUTING, nullptr); } } #endif diff --git a/vpr/test/test_compressed_grid.cpp b/vpr/test/test_compressed_grid.cpp index cd65133ca5..d3b4b71fe9 100644 --- a/vpr/test/test_compressed_grid.cpp +++ b/vpr/test/test_compressed_grid.cpp @@ -162,7 +162,8 @@ TEST_CASE("test_compressed_grid", "[vpr_compressed_grid]") { } auto& grid = g_vpr_ctx.mutable_device().grid; - grid = DeviceGrid("test_device_grid", test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + grid = DeviceGrid("test_device_grid", test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); std::vector compressed_grids = create_compressed_block_grids(); diff --git a/vpr/test/test_setup_noc.cpp b/vpr/test/test_setup_noc.cpp index 283ef07e3e..e0c4a48e0e 100644 --- a/vpr/test/test_setup_noc.cpp +++ b/vpr/test/test_setup_noc.cpp @@ -129,7 +129,8 @@ TEST_CASE("test_identify_and_store_noc_router_tile_positions", "[vpr_setup_noc]" } // create a new device grid - DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); // call the test function list_of_routers = identify_and_store_noc_router_tile_positions(test_device, router_tile_name); @@ -246,7 +247,8 @@ TEST_CASE("test_identify_and_store_noc_router_tile_positions", "[vpr_setup_noc]" } // create a new device grid - DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); // call the test function list_of_routers = identify_and_store_noc_router_tile_positions(test_device, router_tile_name); @@ -363,7 +365,8 @@ TEST_CASE("test_identify_and_store_noc_router_tile_positions", "[vpr_setup_noc]" } // create a new device grid - DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + DeviceGrid test_device = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); // call the test function list_of_routers = identify_and_store_noc_router_tile_positions(test_device, router_tile_name); @@ -404,7 +407,7 @@ TEST_CASE("test_create_noc_routers", "[vpr_setup_noc]") { /* * Setup: * - The router will take over a 2x3 grid area - * - The NoC will be a 3x3 Mesh topology and located at + * - The NoC will be a 3x3 Mesh topology and located at * the following positions: * - router 1: (0,0) * - router 2: (4,0) @@ -590,7 +593,7 @@ TEST_CASE("test_create_noc_links", "[vpr_setup_noc]") { /* * Setup: * - The router will take over a 2x3 grid area - * - The NoC will be a 3x3 Mesh topology and located at + * - The NoC will be a 3x3 Mesh topology and located at * the following positions: * - router 1: (0,0) * - router 2: (4,0) @@ -738,7 +741,7 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") { /* * Setup: * - The router will take over a 2x3 grid area - * - The NoC will be a 3x3 Mesh topology and located at + * - The NoC will be a 3x3 Mesh topology and located at * the following positions: * - router 1: (0,0) * - router 2: (4,0) @@ -929,7 +932,8 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") { } } - device_ctx.grid = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + device_ctx.grid = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); REQUIRE_THROWS_WITH(setup_noc(arch), "The Provided NoC topology information in the architecture file has more number of routers than what is available in the FPGA device."); } @@ -980,7 +984,8 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") { noc_info.router_list.clear(); - device_ctx.grid = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + device_ctx.grid = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); REQUIRE_THROWS_WITH(setup_noc(arch), "No physical NoC routers were found on the FPGA device. Either the provided name for the physical router tile was incorrect or the FPGA device has no routers."); } @@ -1215,7 +1220,8 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") { noc_info.link_bandwidth_overrides.insert({{noc_router_user_id, neighbor_router_user_id}, LINK_BANDWIDTH_OVERRIDE}); } - device_ctx.grid = DeviceGrid(device_grid_name, test_grid); + std::vector> dummy_cuts0, dummy_cuts1; + device_ctx.grid = DeviceGrid(device_grid_name, test_grid, std::move(dummy_cuts0), std::move(dummy_cuts1)); REQUIRE_NOTHROW(setup_noc(arch)); diff --git a/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml b/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml index e3860430e3..eec03e97c7 100644 --- a/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml +++ b/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml @@ -114,7 +114,7 @@ - +