diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index a23b4f0c6..9fd1024a7 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -62,12 +62,37 @@ Here is an example: .. code-block:: xml + ... +For subtile port merge support (see an illustrative example in :numref:`fig_subtile_port_merge`): + +- ``tile=""`` is the name of tile, that is defined in VPR architecture + +- ``port=""`` is the name of a port of the tile, that is defined in VPR architecture + +.. warning:: This is an option for power users. Suggest to enable for those global input ports, such as clock and reset, whose ``Fc`` is set to 0 in VPR architecture!!! + +.. note:: When defined, the given port of all the subtiles of a tile will be merged into one port. For example, a tile consists of 8 subtile ``A`` and 6 subtile ``B`` and all the subtiles have a port ``clk``, in the FPGA fabric, all the ``clk`` of the subtiles ``A`` and ``B`` will be wired to a common port ``clk`` at tile level. + + +.. note:: When merged, the port will have a default side of ``TOP`` and index of ``0`` on all the attributes, such as width, height etc. + +.. _fig_subtile_port_merge: + +.. figure:: ./figures/subtile_port_merge.png + :width: 100% + :alt: Difference in netlists with and without subtile port merging + + Difference in netlists with and without subtile port merging + + +For global port support: + - ``name=""`` is the port name to appear in the top-level FPGA fabric. - ``is_clock=""`` define if the global port is a clock port at the top-level FPGA fabric. An operating clock port will be driven by proper signals in auto-generated testbenches. @@ -111,7 +136,7 @@ A more illustrative example: .. _fig_global_tile_ports: .. figure:: ./figures/global_tile_ports.png - :scale: 100% + :width: 100% :alt: Difference between global port definition through circuit model and tile annotation Difference between global port definition through circuit model and tile annotation diff --git a/docs/source/manual/arch_lang/figures/subtile_port_merge.png b/docs/source/manual/arch_lang/figures/subtile_port_merge.png new file mode 100644 index 000000000..16f7c6021 Binary files /dev/null and b/docs/source/manual/arch_lang/figures/subtile_port_merge.png differ diff --git a/libs/libarchopenfpga/CMakeLists.txt b/libs/libarchopenfpga/CMakeLists.txt index 93c20710d..13b4431f1 100644 --- a/libs/libarchopenfpga/CMakeLists.txt +++ b/libs/libarchopenfpga/CMakeLists.txt @@ -20,6 +20,7 @@ set_target_properties(libarchopenfpga PROPERTIES PREFIX "") #Avoid extra 'lib' p #Specify link-time dependancies target_link_libraries(libarchopenfpga libopenfpgautil + libopenfpgashell libvtrutil libarchfpga libpugiutil) diff --git a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp index 6b27d0017..135e38361 100644 --- a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp +++ b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp @@ -125,6 +125,22 @@ static void read_xml_tile_global_port_annotation( } } +/******************************************************************** + * Parse XML description for an interconnection annotation + * under a XML node + *******************************************************************/ +static void read_xml_tile_merge_port_annotation( + pugi::xml_node& xml_tile, const pugiutil::loc_data& loc_data, + openfpga::TileAnnotation& tile_annotation) { + const std::string& tile_attr = + get_attribute(xml_tile, "tile", loc_data).as_string(); + + const std::string& port_attr = + get_attribute(xml_tile, "port", loc_data).as_string(); + + tile_annotation.add_merge_subtile_ports(tile_attr, port_attr); +} + /******************************************************************** * Top function to parse XML description about tile annotation *******************************************************************/ @@ -146,11 +162,17 @@ openfpga::TileAnnotation read_xml_tile_annotations( */ for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) { /* Error out if the XML child has an invalid name! */ - if (xml_tile_global_port.name() != std::string("global_port")) { - bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port"}); + if (xml_tile_global_port.name() == std::string("global_port")) { + read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data, + tile_annotations); + } else if (xml_tile_global_port.name() == + std::string("merge_subtile_ports")) { + read_xml_tile_merge_port_annotation(xml_tile_global_port, loc_data, + tile_annotations); + } else { + bad_tag(xml_tile_global_port, loc_data, xml_annotations, + {"global_port or merge_subtile_ports"}); } - read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data, - tile_annotations); } return tile_annotations; diff --git a/libs/libarchopenfpga/src/tile_annotation.cpp b/libs/libarchopenfpga/src/tile_annotation.cpp index 7cf41f02e..2ffacd1d0 100644 --- a/libs/libarchopenfpga/src/tile_annotation.cpp +++ b/libs/libarchopenfpga/src/tile_annotation.cpp @@ -3,7 +3,11 @@ ***********************************************************************/ #include "tile_annotation.h" +#include + +#include "command_exit_codes.h" #include "vtr_assert.h" +#include "vtr_log.h" /* namespace openfpga begins */ namespace openfpga { @@ -20,6 +24,27 @@ TileAnnotation::global_port_range TileAnnotation::global_ports() const { return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end()); } +std::vector TileAnnotation::tiles_to_merge_ports() const { + std::vector tile_names; + for (auto it = tile_ports_to_merge_.begin(); it != tile_ports_to_merge_.end(); + it++) { + tile_names.push_back(it->first); + } + return tile_names; +} + +std::vector TileAnnotation::tile_ports_to_merge( + const std::string& tile_name) const { + std::vector port_names; + const auto& result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + VTR_LOG_WARN("Tile '%s' does not contain any ports to merge!\n", + tile_name.c_str()); + return port_names; + } + return result->second; +} + /************************************************************************ * Public Accessors ***********************************************************************/ @@ -77,6 +102,16 @@ std::string TileAnnotation::global_port_clock_arch_tree_name( return global_port_clock_arch_tree_names_[global_port_id]; } +bool TileAnnotation::is_tile_port_to_merge(const std::string& tile_name, + const std::string& port_name) const { + const auto& result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + return false; + } + return result->second.end() != + std::find(result->second.begin(), result->second.end(), port_name); +} + /************************************************************************ * Public Mutators ***********************************************************************/ @@ -178,4 +213,25 @@ bool TileAnnotation::valid_global_port_attributes( return ((0 == attribute_counter) || (1 == attribute_counter)); } +int TileAnnotation::add_merge_subtile_ports(const std::string& tile_name, + const std::string& port_name) { + auto result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + /* Empty list: add a new element */ + tile_ports_to_merge_[tile_name].push_back(port_name); + } else { + /* Check if the port name is already in the list, if yes, error out */ + if (result->second.end() == + std::find(result->second.begin(), result->second.end(), port_name)) { + tile_ports_to_merge_[tile_name].push_back(port_name); + } else { + VTR_LOG_ERROR( + "Port '%s' has already been defined twice for tile '%s' to be merged!", + port_name.c_str(), tile_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } + return CMD_EXEC_SUCCESS; +} + } // namespace openfpga diff --git a/libs/libarchopenfpga/src/tile_annotation.h b/libs/libarchopenfpga/src/tile_annotation.h index ddf951109..36af8a9b4 100644 --- a/libs/libarchopenfpga/src/tile_annotation.h +++ b/libs/libarchopenfpga/src/tile_annotation.h @@ -39,6 +39,9 @@ class TileAnnotation { public: /* Public accessors: aggregators */ global_port_range global_ports() const; + std::vector tiles_to_merge_ports() const; + std::vector tile_ports_to_merge( + const std::string& tile_name) const; public: /* Public accessors */ std::string global_port_name(const TileGlobalPortId& global_port_id) const; @@ -56,6 +59,10 @@ class TileAnnotation { size_t global_port_default_value( const TileGlobalPortId& global_port_id) const; + /** @brief Check if a given tile port should be merged or not */ + bool is_tile_port_to_merge(const std::string& tile_name, + const std::string& port_name) const; + public: /* Public mutators */ /* By default, we do not set it as a clock. * Users should set it through the set_global_port_is_clock() function @@ -77,6 +84,9 @@ class TileAnnotation { void set_global_port_default_value(const TileGlobalPortId& global_port_id, const size_t& default_value); + int add_merge_subtile_ports(const std::string& tile_name, + const std::string& port_name); + public: /* Public validator */ bool valid_global_port_id(const TileGlobalPortId& global_port_id) const; /* Validate attributes of a given global port @@ -102,6 +112,10 @@ class TileAnnotation { /* A fast lookup for port names */ std::map global_port_name2ids_; + + /* Merge port information for tiles */ + std::map> + tile_ports_to_merge_; // tile_name -> port_name }; } // namespace openfpga diff --git a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp index af6bab25a..9db2e01b7 100644 --- a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp +++ b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp @@ -87,6 +87,24 @@ static void write_xml_tile_annotation_global_port( << ""; } +/******************************************************************** + * A writer to output a device variation in a technology library to XML format + *******************************************************************/ +static void write_xml_tile_annotation_subtile_port_to_merge( + std::fstream& fp, const char* fname, const std::string& tile_name, + const std::string& port_name) { + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + fp << "\t\t" + << ""; +} + /******************************************************************** * A writer to output tile annotations to XML format *******************************************************************/ @@ -109,6 +127,13 @@ void write_xml_tile_annotations(std::fstream& fp, const char* fname, write_xml_tile_annotation_global_port(fp, fname, tile_annotation, global_port_id); } + for (std::string tile_name : tile_annotation.tiles_to_merge_ports()) { + for (std::string port_name : + tile_annotation.tile_ports_to_merge(tile_name)) { + write_xml_tile_annotation_subtile_port_to_merge(fp, fname, tile_name, + port_name); + } + } /* Write the root node for pb_type annotations */ fp << "\t" diff --git a/libs/libnamemanager/test/module_rename_assistant.cpp b/libs/libnamemanager/test/module_rename_assistant.cpp index a4e662f02..49de367c3 100644 --- a/libs/libnamemanager/test/module_rename_assistant.cpp +++ b/libs/libnamemanager/test/module_rename_assistant.cpp @@ -36,7 +36,7 @@ static std::vector format_argv(const std::string& cmd_name, * We want a renamed version for fabric B is * */ -int rename_module_names_for_fabricB_from_fabricA( +static int rename_module_names_for_fabricB_from_fabricA( const openfpga::ModuleNameMap& refA_module_names, const openfpga::ModuleNameMap& renamedA_module_names, const openfpga::ModuleNameMap& refB_module_names, diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index d3d94c3e7..63e623398 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -130,6 +130,16 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, return CMD_EXEC_FATAL_ERROR; } } + /* Conflicts: duplicate_grid_pin does not support any port merge */ + if (cmd_context.option_enable(cmd, opt_duplicate_grid_pin)) { + if (openfpga_ctx.arch().tile_annotations.tiles_to_merge_ports().size() > + 0) { + VTR_LOG_ERROR( + "Option '%s' requires no tile ports to be merged due to a conflict!\n", + cmd.option_name(opt_duplicate_grid_pin).c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } if (true == cmd_context.option_enable(cmd, opt_compress_routing)) { compress_routing_hierarchy_template( diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 8a4b176d7..012e3a529 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -87,8 +87,9 @@ int build_device_module_graph( status = build_grid_modules( module_manager, decoder_lib, vpr_device_ctx, openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.mux_lib(), openfpga_ctx.arch().config_protocol.type(), - sram_model, duplicate_grid_pin, group_config_block, verbose); + openfpga_ctx.mux_lib(), openfpga_ctx.arch().tile_annotations, + openfpga_ctx.arch().config_protocol.type(), sram_model, duplicate_grid_pin, + group_config_block, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } @@ -120,13 +121,13 @@ int build_device_module_graph( return status; } /* Build the modules */ - build_tile_modules(module_manager, decoder_lib, openfpga_ctx.fabric_tile(), - vpr_device_ctx.grid, - openfpga_ctx.vpr_device_annotation(), - openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph, - openfpga_ctx.arch().circuit_lib, sram_model, - openfpga_ctx.arch().config_protocol.type(), - name_module_using_index, frame_view, verbose); + build_tile_modules( + module_manager, decoder_lib, openfpga_ctx.fabric_tile(), + vpr_device_ctx.grid, openfpga_ctx.vpr_device_annotation(), + openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph, + openfpga_ctx.arch().tile_annotations, openfpga_ctx.arch().circuit_lib, + sram_model, openfpga_ctx.arch().config_protocol.type(), + name_module_using_index, frame_view, verbose); } /* Build FPGA fabric top-level module */ diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp index 77f4024db..cae215259 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp @@ -54,7 +54,8 @@ namespace openfpga { void add_grid_module_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(false == is_empty_type(grid_type_descriptor)); @@ -109,6 +110,17 @@ void add_grid_module_duplicated_pb_type_ports( (0. == find_physical_tile_pin_Fc(grid_type_descriptor, ipin)))) { std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + /* If the port is required to be merged, we deposit zero as subtile + * index */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), + pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort grid_port(port_name, 0, 0); /* Add the port to the module */ module_manager.add_port(grid_module, grid_port, @@ -297,7 +309,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(false == is_empty_type(grid_type_descriptor)); @@ -314,8 +327,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->input_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } @@ -336,8 +349,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->clock_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } } diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.h b/openfpga/src/fabric/build_grid_module_duplicated_pins.h index 66e1a5634..4f2eafee2 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.h +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.h @@ -7,6 +7,7 @@ #include "module_manager.h" #include "openfpga_side_manager.h" #include "physical_types.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -19,13 +20,15 @@ namespace openfpga { void add_grid_module_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side); + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side); void add_grid_module_nets_connect_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side); + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index c79262805..3b3f14203 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -45,7 +45,8 @@ void add_grid_module_net_connect_pb_graph_pin( const ModuleId& child_module, const size_t& child_instance, const size_t& child_inst_subtile_index, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin, + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin, const e_side& border_side, const e_pin2pin_interc_type& pin2pin_interc_type) { /* Find the pin side for I/O grids*/ std::vector grid_pin_sides; @@ -91,6 +92,13 @@ void add_grid_module_net_connect_pb_graph_pin( subtile_index < grid_type_descriptor->capacity); std::string grid_port_name = generate_grid_port_name( pin_width, pin_height, subtile_index, side, pin_info); + /* If the port is required to be merged, we only consider the source port to + * be the subtile index of 0 */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), pin_info.get_name())) { + /* Exception: use top side for these merged ports */ + grid_port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } ModulePortId grid_module_port_id = module_manager.find_module_port(grid_module, grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id( diff --git a/openfpga/src/fabric/build_grid_module_utils.h b/openfpga/src/fabric/build_grid_module_utils.h index c1f0549dd..a8d5f9d12 100644 --- a/openfpga/src/fabric/build_grid_module_utils.h +++ b/openfpga/src/fabric/build_grid_module_utils.h @@ -8,6 +8,7 @@ #include "module_manager.h" #include "openfpga_interconnect_types.h" #include "physical_types.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -25,7 +26,8 @@ void add_grid_module_net_connect_pb_graph_pin( const ModuleId& child_module, const size_t& child_instance, const size_t& child_inst_subtile_index, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin, + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin, const e_side& border_side, const enum e_pin2pin_interc_type& pin2pin_interc_type); diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index bf8ca86ac..ad49cc63c 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -41,7 +41,8 @@ namespace openfpga { static void add_grid_module_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(nullptr != grid_type_descriptor); @@ -90,6 +91,16 @@ static void add_grid_module_pb_type_ports( subtile_index < grid_type_descriptor->capacity); std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + /* If the port is required to be merged, we use a special index + * index */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort grid_port(port_name, 0, 0); /* Add the port to the module */ module_manager.add_port(grid_module, grid_port, @@ -111,7 +122,8 @@ static void add_grid_module_nets_connect_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(nullptr != grid_type_descriptor); @@ -129,8 +141,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->input_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } @@ -140,8 +152,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->output_pins[iport][ipin]), border_side, - OUTPUT2OUTPUT_INTERC); + tile_annotation, &(top_pb_graph_node->output_pins[iport][ipin]), + border_side, OUTPUT2OUTPUT_INTERC); } } @@ -151,8 +163,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->clock_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } } @@ -1151,8 +1163,9 @@ static int build_physical_tile_module( const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type, - const e_side& border_side, const bool& duplicate_grid_pin, - const bool& group_config_block, const bool& verbose) { + const TileAnnotation& tile_annotation, const e_side& border_side, + const bool& duplicate_grid_pin, const bool& group_config_block, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; /* Create a Module for the top-level physical block, and add to module manager */ @@ -1231,7 +1244,7 @@ static int build_physical_tile_module( /* Default way to add these ports by following the definition in pb_types */ add_grid_module_pb_type_ports(module_manager, grid_module, vpr_device_annotation, phy_block_type, - border_side); + tile_annotation, border_side); /* Add module nets to connect the pb_type ports to sub modules */ for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) { VTR_ASSERT(sub_tile.equivalent_sites.size() == 1); @@ -1248,15 +1261,15 @@ static int build_physical_tile_module( module_manager.child_module_instances(grid_module, pb_module)) { add_grid_module_nets_connect_pb_type_ports( module_manager, grid_module, pb_module, child_instance, sub_tile, - vpr_device_annotation, phy_block_type, border_side); + vpr_device_annotation, phy_block_type, tile_annotation, border_side); } } } else { VTR_ASSERT_SAFE(true == duplicate_grid_pin); /* Add these ports with duplication */ - add_grid_module_duplicated_pb_type_ports(module_manager, grid_module, - vpr_device_annotation, - phy_block_type, border_side); + add_grid_module_duplicated_pb_type_ports( + module_manager, grid_module, vpr_device_annotation, phy_block_type, + tile_annotation, border_side); /* Add module nets to connect the duplicated pb_type ports to sub modules */ for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) { @@ -1274,7 +1287,7 @@ static int build_physical_tile_module( module_manager.child_module_instances(grid_module, pb_module)) { add_grid_module_nets_connect_duplicated_pb_type_ports( module_manager, grid_module, pb_module, child_instance, sub_tile, - vpr_device_annotation, phy_block_type, border_side); + vpr_device_annotation, phy_block_type, tile_annotation, border_side); } } } @@ -1357,6 +1370,7 @@ int build_grid_modules( ModuleManager& module_manager, DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const TileAnnotation& tile_annotation, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, const bool& duplicate_grid_pin, const bool& group_config_block, const bool& verbose) { @@ -1414,8 +1428,8 @@ int build_grid_modules( for (const e_side& io_type_side : io_type_sides) { status = build_physical_tile_module( module_manager, decoder_lib, device_annotation, circuit_lib, - sram_orgz_type, sram_model, &physical_tile, io_type_side, - duplicate_grid_pin, group_config_block, verbose); + sram_orgz_type, sram_model, &physical_tile, tile_annotation, + io_type_side, duplicate_grid_pin, group_config_block, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1424,7 +1438,7 @@ int build_grid_modules( /* For CLB and heterogenenous blocks */ status = build_physical_tile_module( module_manager, decoder_lib, device_annotation, circuit_lib, - sram_orgz_type, sram_model, &physical_tile, NUM_SIDES, + sram_orgz_type, sram_model, &physical_tile, tile_annotation, NUM_SIDES, duplicate_grid_pin, group_config_block, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; diff --git a/openfpga/src/fabric/build_grid_modules.h b/openfpga/src/fabric/build_grid_modules.h index d83cc3ac3..996b9bda2 100644 --- a/openfpga/src/fabric/build_grid_modules.h +++ b/openfpga/src/fabric/build_grid_modules.h @@ -7,6 +7,7 @@ #include "decoder_library.h" #include "module_manager.h" #include "mux_library.h" +#include "tile_annotation.h" #include "vpr_context.h" #include "vpr_device_annotation.h" @@ -21,6 +22,7 @@ int build_grid_modules( ModuleManager& module_manager, DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const TileAnnotation& tile_annotation, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, const bool& duplicate_grid_pin, const bool& group_config_block, const bool& verbose); diff --git a/openfpga/src/fabric/build_tile_modules.cpp b/openfpga/src/fabric/build_tile_modules.cpp index 6fafbcf3d..caf82f075 100644 --- a/openfpga/src/fabric/build_tile_modules.cpp +++ b/openfpga/src/fabric/build_tile_modules.cpp @@ -1004,9 +1004,10 @@ static int build_tile_port_and_nets_from_pb( ModuleManager& module_manager, const ModuleId& tile_module, const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const RRGraphView& rr_graph, - const vtr::Point& pb_coord, const std::vector& pb_instances, - const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, - const size_t& ipb, const bool& frame_view, const bool& verbose) { + const TileAnnotation& tile_annotation, const vtr::Point& pb_coord, + const std::vector& pb_instances, const FabricTile& fabric_tile, + const FabricTileId& curr_fabric_tile_id, const size_t& ipb, + const bool& frame_view, const bool& verbose) { size_t pb_instance = pb_instances[ipb]; t_physical_tile_type_ptr phy_tile = grids.get_physical_type( t_physical_tile_loc(pb_coord.x(), pb_coord.y(), layer)); @@ -1065,6 +1066,14 @@ static int build_tile_port_and_nets_from_pb( subtile_index < phy_tile->capacity); std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + if (tile_annotation.is_tile_port_to_merge(std::string(phy_tile->name), + pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort pb_port(port_name, 0, 0); ModulePortId pb_module_port_id = module_manager.find_module_port(pb_module, port_name); @@ -1193,8 +1202,8 @@ static int build_tile_module_ports_and_nets( const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, - const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, - const std::vector& pb_instances, + const TileAnnotation& tile_annotation, const FabricTile& fabric_tile, + const FabricTileId& fabric_tile_id, const std::vector& pb_instances, const std::map>& cb_instances, const std::vector& sb_instances, const bool& name_module_using_index, const bool& frame_view, const bool& verbose) { @@ -1259,8 +1268,8 @@ static int build_tile_module_ports_and_nets( fabric_tile.pb_coordinates(fabric_tile_id)[ipb]; status_code = build_tile_port_and_nets_from_pb( module_manager, tile_module, grids, layer, vpr_device_annotation, - rr_graph_view, pb_coord, pb_instances, fabric_tile, fabric_tile_id, ipb, - frame_view, verbose); + rr_graph_view, tile_annotation, pb_coord, pb_instances, fabric_tile, + fabric_tile_id, ipb, frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1303,7 +1312,8 @@ static int build_tile_module( const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, - const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, const e_config_protocol_type& sram_orgz_type, const bool& name_module_using_index, const bool& frame_view, const bool& verbose) { @@ -1451,8 +1461,9 @@ static int build_tile_module( /* Add module nets and ports */ status_code = build_tile_module_ports_and_nets( module_manager, tile_module, grids, layer, vpr_device_annotation, - device_rr_gsb, rr_graph_view, fabric_tile, fabric_tile_id, pb_instances, - cb_instances, sb_instances, name_module_using_index, frame_view, verbose); + device_rr_gsb, rr_graph_view, tile_annotation, fabric_tile, fabric_tile_id, + pb_instances, cb_instances, sb_instances, name_module_using_index, + frame_view, verbose); /* Add global ports to the pb_module: * This is a much easier job after adding sub modules (instances), @@ -1521,6 +1532,7 @@ int build_tile_modules(ModuleManager& module_manager, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const e_config_protocol_type& sram_orgz_type, @@ -1536,8 +1548,9 @@ int build_tile_modules(ModuleManager& module_manager, for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) { status_code = build_tile_module( module_manager, decoder_lib, fabric_tile, fabric_tile_id, grids, layer, - vpr_device_annotation, device_rr_gsb, rr_graph_view, circuit_lib, - sram_model, sram_orgz_type, name_module_using_index, frame_view, verbose); + vpr_device_annotation, device_rr_gsb, rr_graph_view, tile_annotation, + circuit_lib, sram_model, sram_orgz_type, name_module_using_index, + frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/openfpga/src/fabric/build_tile_modules.h b/openfpga/src/fabric/build_tile_modules.h index 62f9cbe99..83f219610 100644 --- a/openfpga/src/fabric/build_tile_modules.h +++ b/openfpga/src/fabric/build_tile_modules.h @@ -15,6 +15,7 @@ #include "fabric_tile.h" #include "module_manager.h" #include "rr_graph_view.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -30,6 +31,7 @@ int build_tile_modules(ModuleManager& module_manager, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const e_config_protocol_type& sram_orgz_type, diff --git a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp index b4bc5e8c2..3c1c86c1c 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -1404,6 +1404,15 @@ static int build_top_module_global_net_for_given_tile_module( std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, pin_side, grid_pin_info); + if (tile_annotation.is_tile_port_to_merge( + std::string(physical_tile->name), grid_pin_info.get_name())) { + if (subtile_index == 0) { + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); + } else { + continue; + } + } std::string tile_grid_port_name = generate_tile_module_port_name(grid_instance_name, grid_port_name); ModulePortId tile_grid_port_id = diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index d49a6f1cf..98b256fe0 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -950,6 +950,16 @@ static int build_top_module_global_net_for_given_grid_module( std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, pin_side, grid_pin_info); + if (tile_annotation.is_tile_port_to_merge( + std::string(physical_tile->name), grid_pin_info.get_name())) { + if (subtile_index == 0) { + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); + } else { + continue; + } + } + ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, diff --git a/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml new file mode 100644 index 000000000..a7c1a8bfa --- /dev/null +++ b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + + 10e-12 5e-12 5e-12 + + + 10e-12 5e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga new file mode 100644 index 000000000..956451380 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga @@ -0,0 +1,63 @@ +# Run VPR for the 'and' design +# When the global clock is defined as a port of a tile, clock routing in VPR should be skipped +# This is due to the Fc_in of clock port is set to 0 for global wiring +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing ${OPENFPGA_GROUP_CONFIG_BLOCK_OPTIONS} ${OPENFPGA_GROUP_TILE_CONFIG_OPTIONS} #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 4835a66cd..dd945b427 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -211,6 +211,8 @@ run-task basic_tests/module_naming/renaming_rules_on_indexed_names $@ echo -e "Testing global port definition from tiles"; run-task basic_tests/global_tile_ports/global_tile_clock $@ run-task basic_tests/global_tile_ports/global_tile_clock_subtile $@ +run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge $@ +run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config $@ run-task basic_tests/global_tile_ports/global_tile_reset $@ run-task basic_tests/global_tile_ports/global_tile_4clock $@ run-task basic_tests/global_tile_ports/global_tile_4clock_pin $@ diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf new file mode 100644 index 000000000..adbbaa2cb --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf @@ -0,0 +1,35 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=2x2_hybrid_io + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2_pipelined + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf new file mode 100644 index 000000000..dc9eacdb7 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf @@ -0,0 +1,37 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=2x2_hybrid_io +openfpga_group_tile_config_options=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_group_config_block_options=--group_config_block + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2_pipelined + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml @@ -0,0 +1 @@ +