diff --git a/doc/src/api/libarchfpga/grid_types.rst b/doc/src/api/libarchfpga/grid_types.rst new file mode 100644 index 00000000000..39cb5125605 --- /dev/null +++ b/doc/src/api/libarchfpga/grid_types.rst @@ -0,0 +1,14 @@ +======== +Grid Specification Types +======== + +These types are used to capture user's intended grid specification, i.e., which tiles go where in the device. These specifications will be later turned into a flattened device grid according to the device's size. + +.. doxygenstruct:: t_grid_loc_spec + :project: vpr + :members: + +.. doxygenstruct:: t_grid_loc_def + :project: vpr + :members: + \ No newline at end of file diff --git a/doc/src/api/libarchfpga/index.rst b/doc/src/api/libarchfpga/index.rst new file mode 100644 index 00000000000..af2000bee41 --- /dev/null +++ b/doc/src/api/libarchfpga/index.rst @@ -0,0 +1,12 @@ +.. _libarchfpga: + +LIBARCHFPGA +======= + +.. toctree:: + :maxdepth: 1 + + physical_types + grid_types + scatter_gather_types + interposer_types \ No newline at end of file diff --git a/doc/src/api/libarchfpga/interposer_types.rst b/doc/src/api/libarchfpga/interposer_types.rst new file mode 100644 index 00000000000..1e54a242c27 --- /dev/null +++ b/doc/src/api/libarchfpga/interposer_types.rst @@ -0,0 +1,13 @@ +======== +Interposer Types +======== + +These types are used to store information about interposer based architectures. + +.. doxygenstruct:: t_interposer_cut_inf + :project: vpr + :members: + +.. doxygenstruct:: t_interdie_wire_inf + :project: vpr + :members: \ No newline at end of file diff --git a/doc/src/api/libarchfpga/physical_types.rst b/doc/src/api/libarchfpga/physical_types.rst new file mode 100644 index 00000000000..1dcb6d15a80 --- /dev/null +++ b/doc/src/api/libarchfpga/physical_types.rst @@ -0,0 +1,33 @@ +======== +Physical Types +======== + +These types are used to capture user's intended architecture specification. + +.. doxygenstruct:: t_arch + :project: vpr + :members: + +.. doxygenstruct:: t_arch_switch_inf + :project: vpr + :members: + +.. doxygenstruct:: t_segment_inf + :project: vpr + :members: + +.. doxygenstruct:: t_physical_tile_loc + :project: vpr + :members: + +.. doxygenstruct:: t_sub_tile + :project: vpr + :members: + +.. doxygenstruct:: t_layer_def + :project: vpr + :members: + +.. doxygenstruct:: t_grid_def + :project: vpr + :members: diff --git a/doc/src/api/libarchfpga/scatter_gather_types.rst b/doc/src/api/libarchfpga/scatter_gather_types.rst new file mode 100644 index 00000000000..5b3be6d8bfc --- /dev/null +++ b/doc/src/api/libarchfpga/scatter_gather_types.rst @@ -0,0 +1,17 @@ +======== +Scatter-Gather Types +======== + +These types store information about about scatter-gather routing patterns + +.. doxygenstruct:: t_scatter_gather_pattern + :project: vpr + :members: + +.. doxygenstruct:: t_sg_link + :project: vpr + :members: + +.. doxygenstruct:: t_sg_location + :project: vpr + :members: \ No newline at end of file diff --git a/doc/src/arch/reference.rst b/doc/src/arch/reference.rst index aa10a43c541..a374cbeb265 100644 --- a/doc/src/arch/reference.rst +++ b/doc/src/arch/reference.rst @@ -581,6 +581,32 @@ Grid Layout Example Example FPGA grid + +.. 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. + + .. 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. + To reconnect the two sides, this tag can have multiple tags as children to specify the connection between the two sides. + +.. arch:tag:: + + :req_param sg_name: Name of the scatter-gather pattern to be used for the interdie connection. + :req_param sg_link: Name of the scatter-gather link to be used for the interdie connection. + :req_param offset_start: Starting point of scatter-gather instantiations. + :req_param offset_end: Ending point of scatter-gather instantiations + :req_param offset_increment: Increment/distance between scatter-gather instantiations. + :req_param num: Number of scatter-gather instantiations per switchblock location. + + Defines the interdie wiring between the two sides of the cut. Connectivity is defined using scatter-gather patterns. Starting at 'offset_start' from location of the cut and moving by 'offset_increment' until we reach the location of 'offset_end' away from the cut, 'num' scatter-gather patterns defined by 'sg_name' and 'sg_link' will be instantiated. + Note that these offset points always define the starting point of the scatter-gather pattern's sg_link. offset_start, offset_end and offset_increment can be integer values or expressions involving W and H (device width and height.) + + .. figure:: scatter_gather_images/interposer_diagram.png + + An example of how specifying interposers in VTR works. Connections between the two sides of a cut are first severed after which the two sides are reconnected using scatter_gather patterns. In this example the length of the sg_link wire used is 3. Note that there are 'num' of each pattern at each switchblock location. + .. _arch_device_info: FPGA Device Information diff --git a/doc/src/arch/scatter_gather_images/interposer_diagram.png b/doc/src/arch/scatter_gather_images/interposer_diagram.png new file mode 100644 index 00000000000..be0b335985d Binary files /dev/null and b/doc/src/arch/scatter_gather_images/interposer_diagram.png differ diff --git a/doc/src/index.rst b/doc/src/index.rst index 378e46af087..047c2237dee 100644 --- a/doc/src/index.rst +++ b/doc/src/index.rst @@ -64,6 +64,7 @@ For more specific documentation about VPR see :ref:`vpr`. api/vtrutil/index api/ezgl/index api/vprinternals/index + api/libarchfpga/index Indices and tables ================== diff --git a/libs/libarchfpga/src/echo_arch.cpp b/libs/libarchfpga/src/echo_arch.cpp index 70456a8a204..115616a0edb 100644 --- a/libs/libarchfpga/src/echo_arch.cpp +++ b/libs/libarchfpga/src/echo_arch.cpp @@ -101,10 +101,10 @@ void PrintArchInfo(FILE* Echo, const t_arch* arch) { //Layout fprintf(Echo, "*************************************************\n"); for (const auto& grid_layout : arch->grid_layouts) { - if (grid_layout.grid_type == GridDefType::AUTO) { + if (grid_layout.grid_type == e_grid_def_type::AUTO) { fprintf(Echo, "Layout: '%s' Type: auto Aspect_Ratio: %f\n", grid_layout.name.c_str(), grid_layout.aspect_ratio); } else { - VTR_ASSERT(grid_layout.grid_type == GridDefType::FIXED); + VTR_ASSERT(grid_layout.grid_type == e_grid_def_type::FIXED); fprintf(Echo, "Layout: '%s' Type: fixed Width: %d Height %d\n", grid_layout.name.c_str(), grid_layout.width, grid_layout.height); } } diff --git a/libs/libarchfpga/src/grid_types.h b/libs/libarchfpga/src/grid_types.h new file mode 100644 index 00000000000..6c2afd769bc --- /dev/null +++ b/libs/libarchfpga/src/grid_types.h @@ -0,0 +1,134 @@ +#pragma once + +/** + * @file grid_types.h + * @brief FPGA grid layout data types + */ + +#include +#include + +// Forward declerations + +struct t_metadata_dict; + +/** + * @brief Grid location specification + * Each member is a formula evaluated in terms of 'W' (device width), + * and 'H' (device height). Formulas can be evaluated using parse_formula() + * from expr_eval.h. + */ +struct t_grid_loc_spec { + std::string start_expr; /// + * repeatx + * + * startx/endx and endx/endy define a rectangular region instance's dimensions. + * The region instance is then repeated every repeatx/repeaty (if specified). + * + * Within a particular region instance a block of block_type is laid down every + * incrx/incry units (if not specified defaults to block width/height): + * + * + * * = an instance of block_type within the region + * + * +------------------------------+ + * |* * * *| + * | | + * | | + * | | + * | | + * | | + * |* * * *| + * ^ | | + * | | | + * incry | | | + * | | | + * v | | + * |* * * *| + * +------------------------------+ + * + * <-------> + * incrx + * + * In the above diagram incrx = 10, and incry = 6 + */ +struct t_grid_loc_def { + t_grid_loc_def(std::string block_type_val, int priority_val) + : block_type(std::move(block_type_val)) + , priority(priority_val) + , x{"0", "W-1", "max(w+1,W)", "w"} // Fill in x direction, no repeat, incr by block width + , y{"0", "H-1", "max(h+1,H)", "h"} // Fill in y direction, no repeat, incr by block height + {} + + std::string block_type; ///< The block type name + + int priority = 0; ///< Priority of the specification. In case of conflicting specifications the largest priority wins. + + t_grid_loc_spec x; ///< Horizontal location specification + t_grid_loc_spec y; ///< Vertical location specification + + /** + * @brief When 1 metadata tag is split among multiple t_grid_loc_def, one + * t_grid_loc_def is arbitrarily chosen to own the metadata, and the other + * t_grid_loc_def point to the owned version. + * + */ + std::unique_ptr owned_meta; + + /** + * @brief Metadata for this location definition. This + * metadata may be shared with multiple grid_locs + * that come from a common definition. + */ + t_metadata_dict* meta = nullptr; +}; + +/** + * @brief Enum for specfying if the architecture grid specification is for an auto sized device (variable size) + * or a fixed size device. + */ +enum class e_grid_def_type { + AUTO, + FIXED +}; \ No newline at end of file diff --git a/libs/libarchfpga/src/interposer_types.h b/libs/libarchfpga/src/interposer_types.h new file mode 100644 index 00000000000..efdfa24be93 --- /dev/null +++ b/libs/libarchfpga/src/interposer_types.h @@ -0,0 +1,57 @@ +#pragma once + +/** + * @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 +}; + +// 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 + std::string sg_link; ///< Name of the scatter-gather link to be used for the interdie connection + /** + * @brief + * 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. + */ + t_grid_loc_spec offset_definition; + int num; ///< Number of scatter-gather instantiations per switchblock location +}; + +/** + * @brief Struct containing information of an interposer cut + * + */ +struct t_interposer_cut_inf { + e_interposer_cut_dim dim; ///< Dimension or axis of interposer cut. + 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 3418e7ba342..af0aba4a06d 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -48,6 +48,7 @@ #include "vib_inf.h" #include "scatter_gather_types.h" +#include "interposer_types.h" //Forward declarations struct t_clock_network; @@ -80,6 +81,7 @@ class t_pb_graph_edge; struct t_cluster_placement_primitive; struct t_arch; enum class e_sb_type; +struct t_interposer_cut_inf; /****************************************************************************/ /* FPGA metadata types */ @@ -248,130 +250,14 @@ typedef enum e_power_estimation_method_ t_power_estimation_method; /*************************************************************************************************/ /* FPGA grid layout data types */ /*************************************************************************************************/ -/* Grid location specification - * Each member is a formula evaluated in terms of 'W' (device width), - * and 'H' (device height). Formulas can be evaluated using parse_formula() - * from expr_eval.h. - */ -struct t_grid_loc_spec { - t_grid_loc_spec(std::string start, std::string end, std::string repeat, std::string incr) - : start_expr(std::move(start)) - , end_expr(std::move(end)) - , repeat_expr(std::move(repeat)) - , incr_expr(std::move(incr)) {} - - std::string start_expr; //Starting position (inclusive) - std::string end_expr; //Ending position (inclusive) - - std::string repeat_expr; //Distance between repeated - // region instances - - std::string incr_expr; //Distance between block instantiations - // with the region -}; - -/* Definition of how to place physical logic block in the grid. - * This defines a region of the grid to be set to a specific type - * (provided its priority is high enough to override other blocks). - * - * The diagram below illustrates the layout specification. - * - * +----+ +----+ +----+ - * | | | | | | - * | | | | ... | | - * | | | | | | - * +----+ +----+ +----+ - * - * . . . - * . . . - * . . . - * - * +----+ +----+ +----+ - * | | | | | | - * | | | | ... | | - * | | | | | | - * +----+ +----+ +----+ - * ^ - * | - * repeaty | - * | - * v (endx,endy) - * +----+ +----+ +----+ - * | | | | | | - * | | | | ... | | - * | | | | | | - * +----+ +----+ +----+ - * (startx,starty) - * <--------------> - * repeatx - * - * startx/endx and endx/endy define a rectangular region instances dimensions. - * The region instance is then repeated every repeatx/repeaty (if specified). - * - * Within a particular region instance a block of block_type is laid down every - * incrx/incry units (if not specified defaults to block width/height): - * - * - * * = an instance of block_type within the region - * - * +------------------------------+ - * |* * * *| - * | | - * | | - * | | - * | | - * | | - * |* * * *| - * ^ | | - * | | | - * incry | | | - * | | | - * v | | - * |* * * *| - * +------------------------------+ - * - * <-------> - * incrx - * - * In the above diagram incrx = 10, and incry = 6 - */ -struct t_grid_loc_def { - t_grid_loc_def(std::string block_type_val, int priority_val) - : block_type(std::move(block_type_val)) - , priority(priority_val) - , x("0", "W-1", "max(w+1,W)", "w") //Fill in x direction, no repeat, incr by block width - , y("0", "H-1", "max(h+1,H)", "h") //Fill in y direction, no repeat, incr by block height - {} - - std::string block_type; //The block type name - - int priority = 0; //Priority of the specification. - // In case of conflicting specifications - // the largest priority wins. - - t_grid_loc_spec x; //Horizontal location specification - t_grid_loc_spec y; //Vertical location specification - - // When 1 metadata tag is split among multiple t_grid_loc_def, one - // t_grid_loc_def is arbitrarily chosen to own the metadata, and the other - // t_grid_loc_def point to the owned version. - std::unique_ptr owned_meta; - t_metadata_dict* meta = nullptr; // Metadata for this location definition. This - // metadata may be shared with multiple grid_locs - // that come from a common definition. -}; - -enum GridDefType { - AUTO, - FIXED -}; struct t_layer_def { - std::vector loc_defs; //The list of block location definitions for this layer specification + std::vector loc_defs; ///< List of block location definitions for this layer specification + std::vector interposer_cuts; ///< List of interposer cuts in this layer }; struct t_grid_def { - GridDefType grid_type = GridDefType::AUTO; //The type of this grid specification + e_grid_def_type grid_type = e_grid_def_type::AUTO; //The type of this grid specification std::string name = ""; //The name of this device diff --git a/libs/libarchfpga/src/read_fpga_interchange_arch.cpp b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp index d9ad5853570..6268ede1b01 100644 --- a/libs/libarchfpga/src/read_fpga_interchange_arch.cpp +++ b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp @@ -2244,7 +2244,7 @@ struct ArchReader { grid_def.width += 2; grid_def.height += 2; - grid_def.grid_type = GridDefType::FIXED; + grid_def.grid_type = e_grid_def_type::FIXED; if (name == "auto") { // At the moment, the interchange specifies fixed-layout only architectures, diff --git a/libs/libarchfpga/src/read_xml_arch_file.cpp b/libs/libarchfpga/src/read_xml_arch_file.cpp index 676c78d0d35..92cbb979b16 100644 --- a/libs/libarchfpga/src/read_xml_arch_file.cpp +++ b/libs/libarchfpga/src/read_xml_arch_file.cpp @@ -35,19 +35,19 @@ * the two files are swapped on command line. * */ - #include #include -#include #include #include #include +#include #include "logic_types.h" #include "physical_types.h" #include "pugixml.hpp" #include "pugixml_util.hpp" +#include "read_xml_arch_file_interposer.h" #include "read_xml_arch_file_vib.h" #include "vtr_assert.h" #include "vtr_log.h" @@ -71,6 +71,8 @@ #include "read_xml_arch_file_noc_tag.h" #include "read_xml_arch_file_sg.h" +#include "interposer_types.h" + using namespace std::string_literals; using pugiutil::ReqOpt; @@ -2579,11 +2581,11 @@ static t_grid_def process_grid_layout(vtr::string_internment& strings, num_of_avail_layer = get_number_of_layers(layout_type_tag, loc_data); bool has_layer = layout_type_tag.child("layer"); - //Determine the grid specification type + // Determine the grid specification type if (layout_type_tag.name() == std::string("auto_layout")) { expect_only_attributes(layout_type_tag, {"aspect_ratio"}, loc_data); - grid_def.grid_type = GridDefType::AUTO; + grid_def.grid_type = e_grid_def_type::AUTO; grid_def.aspect_ratio = get_attribute(layout_type_tag, "aspect_ratio", loc_data, ReqOpt::OPTIONAL).as_float(1.); grid_def.name = "auto"; @@ -2591,13 +2593,13 @@ static t_grid_def process_grid_layout(vtr::string_internment& strings, } else if (layout_type_tag.name() == std::string("fixed_layout")) { expect_only_attributes(layout_type_tag, {"width", "height", "name"}, loc_data); - grid_def.grid_type = GridDefType::FIXED; + grid_def.grid_type = e_grid_def_type::FIXED; grid_def.width = get_attribute(layout_type_tag, "width", loc_data).as_int(); grid_def.height = get_attribute(layout_type_tag, "height", loc_data).as_int(); std::string name = get_attribute(layout_type_tag, "name", loc_data).value(); if (name == "auto") { - //We name as 'auto', so don't allow a user to specify it + // We name as 'auto', so don't allow a user to specify it archfpga_throw(loc_data.filename_c_str(), loc_data.line(layout_type_tag), vtr::string_fmt("The name '%s' is reserved for auto-sized layouts; please choose another name", name.c_str()).c_str()); } @@ -2612,27 +2614,26 @@ static t_grid_def process_grid_layout(vtr::string_internment& strings, grid_def.layers.resize(num_of_avail_layer); arch->layer_global_routing.resize(num_of_avail_layer); - //No layer tag is specified (only one die is specified in the arch file) - //Need to process layout_type_tag children to get block types locations in the grid + // No layer tag is specified (only one die is specified in the arch file) + // Need to process layout_type_tag children to get block types locations in the grid if (has_layer) { - std::set seen_die_numbers; //Check that die numbers in the specific layout tag are unique - //One or more than one layer tag is specified - auto layer_tag_specified = layout_type_tag.children("layer"); - for (auto layer_child : layer_tag_specified) { - int die_number; - bool has_global_routing; - //More than one layer tag is specified, meaning that multi-die FPGA is specified in the arch file - //Need to process each tag children to get block types locations for each grid - die_number = get_attribute(layer_child, "die", loc_data).as_int(0); - has_global_routing = get_attribute(layer_child, "has_prog_routing", loc_data, ReqOpt::OPTIONAL).as_bool(true); + std::unordered_set seen_die_numbers; //Check that die numbers in the specific layout tag are unique + for (pugi::xml_node layer_child : layout_type_tag.children("layer")) { + + // More than one layer tag is specified, meaning that multi-die FPGA is specified in the arch file + // Need to process each tag children to get block types locations for each grid + int die_number = get_attribute(layer_child, "die", loc_data).as_int(0); + bool has_global_routing = get_attribute(layer_child, "has_prog_routing", loc_data, ReqOpt::OPTIONAL).as_bool(true); arch->layer_global_routing.at(die_number) = has_global_routing; VTR_ASSERT(die_number >= 0 && die_number < num_of_avail_layer); - auto insert_res = seen_die_numbers.insert(die_number); - VTR_ASSERT_MSG(insert_res.second, "Two different layers with a same die number may have been specified in the Architecture file"); + + // If the die number is not actually inserted in the seen_die_numbers set, it means that it's a duplicate + auto [_, did_insert_in_set] = seen_die_numbers.insert(die_number); + VTR_ASSERT_MSG(did_insert_in_set, "Two different layers with a same die number may have been specified in the Architecture file"); process_block_type_locs(grid_def, die_number, strings, layer_child, loc_data); } } else { - //if only one die is available, then global routing resources must exist in that die + // If only one die is available, then global routing resources must exist in that die int die_number = 0; arch->layer_global_routing.at(die_number) = true; process_block_type_locs(grid_def, die_number, strings, layout_type_tag, loc_data); @@ -2646,9 +2647,29 @@ static void process_block_type_locs(t_grid_def& grid_def, pugi::xml_node layout_block_type_tag, const pugiutil::loc_data& loc_data) { //Process all the block location specifications - for (auto loc_spec_tag : layout_block_type_tag.children()) { - auto loc_type = loc_spec_tag.name(); - auto type_name = get_attribute(loc_spec_tag, "type", loc_data).value(); + for (pugi::xml_node loc_spec_tag : layout_block_type_tag.children()) { + const char* loc_type = loc_spec_tag.name(); + + // There are multiple attributes that are shared by every other tag that interposer + // tags do not have. For this reason we check if loc_spec_tag is an interposer tag + // and switch code paths if it is. + if (loc_type == std::string("interposer_cut")) { + if (grid_def.grid_type == e_grid_def_type::AUTO) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposers are not currently supported for auto sized devices."); + } + + 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)) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(loc_spec_tag), "Interposer cut dimensions are outside of device bounds"); + } + + grid_def.layers.at(die_number).interposer_cuts.push_back(interposer_cut); + continue; + } + + // Continue parsing for non-interposer tags + const char* type_name = get_attribute(loc_spec_tag, "type", loc_data).value(); int priority = get_attribute(loc_spec_tag, "priority", loc_data).as_int(); t_metadata_dict meta = process_meta_data(strings, loc_spec_tag, loc_data); diff --git a/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp b/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp new file mode 100644 index 00000000000..f5b9beba193 --- /dev/null +++ b/libs/libarchfpga/src/read_xml_arch_file_interposer.cpp @@ -0,0 +1,46 @@ +#include "read_xml_arch_file_interposer.h" +#include +#include "interposer_types.h" +#include "read_xml_util.h" +#include "pugixml_util.hpp" +#include "arch_error.h" + +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); + + 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."); + } + + interposer.dim = CHAR_INTERPOSER_DIM_MAP.at(interposer_dim[0]); + + 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."); + } + + 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"}}; + pugiutil::expect_only_attributes(interdie_wire_tag, interdie_wire_attributes, loc_data); + + t_interdie_wire_inf interdie_wire; + + interdie_wire.sg_name = pugiutil::get_attribute(interdie_wire_tag, "sg_name", loc_data).as_string(); + interdie_wire.sg_link = pugiutil::get_attribute(interdie_wire_tag, "sg_link", loc_data).as_string(); + + interdie_wire.offset_definition.start_expr = pugiutil::get_attribute(interdie_wire_tag, "offset_start", loc_data).as_string(); + interdie_wire.offset_definition.end_expr = pugiutil::get_attribute(interdie_wire_tag, "offset_end", loc_data).as_string(); + interdie_wire.offset_definition.incr_expr = pugiutil::get_attribute(interdie_wire_tag, "offset_increment", loc_data).as_string(); + + interdie_wire.num = pugiutil::get_attribute(interdie_wire_tag, "num", loc_data).as_int(); + + interposer.interdie_wires.push_back(interdie_wire); + } + + return interposer; +} diff --git a/libs/libarchfpga/src/read_xml_arch_file_interposer.h b/libs/libarchfpga/src/read_xml_arch_file_interposer.h new file mode 100644 index 00000000000..94e5a5f8c62 --- /dev/null +++ b/libs/libarchfpga/src/read_xml_arch_file_interposer.h @@ -0,0 +1,19 @@ +#pragma once + +/** + * @file read_xml_arch_file_interposer.h + * @brief This file contains functions related to parsing and processing interposer tags in the architecture file + * + */ + +#include "interposer_types.h" +#include "read_xml_util.h" + +/** + * @brief Parse an tag and its children + * + * @param interposer_cut_tag xml_node pointing to the tag + * @param loc_data Points to the location in the architecture file where the parser is reading. Used for priting error messages. + * @return t_interposer_cut_inf with parsed information of the tag + */ +t_interposer_cut_inf parse_interposer_cut_tag(pugi::xml_node interposer_cut_tag, const pugiutil::loc_data& loc_data); diff --git a/vpr/src/base/setup_grid.cpp b/vpr/src/base/setup_grid.cpp index ad8030cd9ec..5d3d03744ec 100644 --- a/vpr/src/base/setup_grid.cpp +++ b/vpr/src/base/setup_grid.cpp @@ -84,7 +84,7 @@ DeviceGrid create_device_grid(const std::string& layout_name, const std::vector< if (layout_name == "auto") { VTR_ASSERT(!grid_layouts.empty()); //Auto-size - if (grid_layouts[0].grid_type == GridDefType::AUTO) { + if (grid_layouts[0].grid_type == e_grid_def_type::AUTO) { //Auto layout of the specified dimensions return build_device_grid(grid_layouts[0], width, height); } else { @@ -152,7 +152,7 @@ static DeviceGrid auto_size_device_grid(const std::vector& grid_layo DeviceGrid grid; auto is_auto_grid_def = [](const t_grid_def& grid_def) { - return grid_def.grid_type == GridDefType::AUTO; + 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); @@ -230,8 +230,8 @@ static DeviceGrid auto_size_device_grid(const std::vector& grid_layo grid_layouts_view.push_back(&layout); } auto area_cmp = [](const t_grid_def* lhs, const t_grid_def* rhs) { - VTR_ASSERT(lhs->grid_type == GridDefType::FIXED); - VTR_ASSERT(rhs->grid_type == GridDefType::FIXED); + VTR_ASSERT(lhs->grid_type == e_grid_def_type::FIXED); + VTR_ASSERT(rhs->grid_type == e_grid_def_type::FIXED); int lhs_area = lhs->width * lhs->height; int rhs_area = rhs->width * rhs->height; @@ -339,7 +339,7 @@ static bool grid_satisfies_instance_counts(const DeviceGrid& grid, const std::ma ///@brief Build the specified device grid static DeviceGrid build_device_grid(const t_grid_def& grid_def, size_t grid_width, size_t grid_height, bool warn_out_of_range, const std::vector& limiting_resources) { - if (grid_def.grid_type == GridDefType::FIXED) { + if (grid_def.grid_type == e_grid_def_type::FIXED) { if (grid_def.width != int(grid_width) || grid_def.height != int(grid_height)) { VPR_FATAL_ERROR(VPR_ERROR_OTHER, "Requested grid size (%zu%zu) does not match fixed device size (%dx%d)", diff --git a/vpr/test/test_interchange_device.cpp b/vpr/test/test_interchange_device.cpp index 324d757830a..f698576d8dd 100644 --- a/vpr/test/test_interchange_device.cpp +++ b/vpr/test/test_interchange_device.cpp @@ -51,7 +51,7 @@ TEST_CASE("read_interchange_layout", "[vpr]") { FPGAInterchangeReadArch(kArchFile, /*timing_enabled=*/true, &arch, physical_tile_types, logical_block_types); auto& gd = arch.grid_layouts[0]; - REQUIRE(gd.grid_type == GridDefType::FIXED); + REQUIRE(gd.grid_type == e_grid_def_type::FIXED); REQUIRE(gd.height == 12); REQUIRE(gd.width == 12); diff --git a/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml b/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml new file mode 100644 index 00000000000..e3860430e37 --- /dev/null +++ b/vtr_flow/arch/interposer/k6_N10_40nm_interposer.xml @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + io.outpad io.inpad io.clock + io.outpad io.inpad io.clock + io.outpad io.inpad io.clock + io.outpad io.inpad io.clock + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 82e-12 + 173e-12 + 261e-12 + 263e-12 + 398e-12 + 397e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/config.txt new file mode 100644 index 00000000000..4fcde29969f --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/config.txt @@ -0,0 +1,30 @@ +############################################## +# Configuration file for running experiments +############################################## + +# Path to directory of circuits to use +circuits_dir=benchmarks/verilog + +# Path to directory of architectures to use +archs_dir=arch/interposer + +# Add circuits to list to sweep +circuit_list_add=ch_intrinsics.v + +# Add architectures to list to sweep +arch_list_add=k6_N10_40nm_interposer.xml + +# Use a fixed size device +circuit_constraint_list_add=(ch_intrinsics.v, device=vtr_homogeneous_extra_small) + +# Parse info and how to parse +parse_file=vpr_standard.txt + +# How to parse QoR info +qor_parse_file=qor_standard.txt + +# Pass requirements +pass_requirements_file=pass_requirements.txt + +# Script parameters +script_params_common = -track_memory_usage diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/golden_results.txt new file mode 100644 index 00000000000..36fbc7dfa6b --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_interposer/config/golden_results.txt @@ -0,0 +1,2 @@ +arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time initial_placed_wirelength_est placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time initial_placed_CPD_est placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time +k6_N10_40nm_interposer.xml ch_intrinsics.v common 1.39 vpr 63.27 MiB -1 -1 0.24 32920 3 0.07 -1 -1 37056 -1 -1 25 99 -1 -1 success v8.0.0-13909-g0298a690c-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 15.2.1 on Linux-6.14.9-300.fc42.x86_64 x86_64 2025-09-19T15:59:53 betzgrp-pcamir.eecg /home/amirpoolad/Dev/vtr-verilog-to-routing/vtr_flow/scripts 64792 99 130 342 472 1 225 254 10 10 100 -1 vtr_homogeneous_extra_small 23.6 MiB 0.06 1395.83 666 26786 4334 19176 3276 63.3 MiB 0.05 0.00 2.06334 1.99047 -111.451 -1.99047 1.99047 0.05 0.000410201 0.000382142 0.0164063 0.0152932 -1 -1 -1 -1 30 1038 11 1.152e+06 450000 194421. 1944.21 0.40 0.139057 0.127114 6972 36796 -1 905 11 476 757 28868 8304 1.89907 1.89907 -121.629 -1.89907 0 0 238537. 2385.37 0.01 0.02 0.02 -1 -1 0.01 0.0143138 0.0133681 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt index 9c25c849c96..ba2f042d930 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt @@ -120,3 +120,4 @@ regression_tests/vtr_reg_strong/strong_3d/3d_sb regression_tests/vtr_reg_strong/strong_xilinx_simple regression_tests/vtr_reg_strong/strong_xilinx_flagship regression_tests/vtr_reg_strong/strong_scatter_gather +regression_tests/vtr_reg_strong/strong_interposer \ No newline at end of file