From b019a5b3657abfdf86abe88a10f00953848c839d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 06:45:36 +0000 Subject: [PATCH 001/174] Bump yosys from `9e00442` to `b84ed5d` Bumps [yosys](https://github.com/YosysHQ/yosys) from `9e00442` to `b84ed5d`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/9e004426e0783d5bbbe846be54b8266451cd5f7f...b84ed5d3ad2ac8b533e1d6a83dbdb6d5c2be9ce7) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 9e004426e..b84ed5d3a 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 9e004426e0783d5bbbe846be54b8266451cd5f7f +Subproject commit b84ed5d3ad2ac8b533e1d6a83dbdb6d5c2be9ce7 From af67b02cca81d7654d5db9ff43ccee1853ec3b49 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 13:51:14 -0700 Subject: [PATCH 002/174] [lib] rename lib to namemanager as a unified library to provide naming support on FPGA modules --- libs/CMakeLists.txt | 2 +- .../CMakeLists.txt | 14 +++++++------- .../example/example.xml | 0 .../src/base/io_name_map.cpp | 0 .../src/base/io_name_map.h | 0 .../src/io/io_name_map_xml_constants.h | 0 .../src/io/read_xml_io_name_map.cpp | 0 .../src/io/read_xml_io_name_map.h | 0 .../src/io/write_xml_io_name_map.cpp | 0 .../src/io/write_xml_io_name_map.h | 0 .../test/xml_io_io_name_map.cpp | 0 openfpga/CMakeLists.txt | 2 +- 12 files changed, 9 insertions(+), 9 deletions(-) rename libs/{libionamemap => libnamemanager}/CMakeLists.txt (72%) rename libs/{libionamemap => libnamemanager}/example/example.xml (100%) rename libs/{libionamemap => libnamemanager}/src/base/io_name_map.cpp (100%) rename libs/{libionamemap => libnamemanager}/src/base/io_name_map.h (100%) rename libs/{libionamemap => libnamemanager}/src/io/io_name_map_xml_constants.h (100%) rename libs/{libionamemap => libnamemanager}/src/io/read_xml_io_name_map.cpp (100%) rename libs/{libionamemap => libnamemanager}/src/io/read_xml_io_name_map.h (100%) rename libs/{libionamemap => libnamemanager}/src/io/write_xml_io_name_map.cpp (100%) rename libs/{libionamemap => libnamemanager}/src/io/write_xml_io_name_map.h (100%) rename libs/{libionamemap => libnamemanager}/test/xml_io_io_name_map.cpp (100%) diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index ab8e6dbd8..537a46357 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -8,5 +8,5 @@ add_subdirectory(libfabrickey) add_subdirectory(libfpgabitstream) add_subdirectory(libpcf) add_subdirectory(libbusgroup) -add_subdirectory(libionamemap) +add_subdirectory(libnamemanager) add_subdirectory(libtileconfig) diff --git a/libs/libionamemap/CMakeLists.txt b/libs/libnamemanager/CMakeLists.txt similarity index 72% rename from libs/libionamemap/CMakeLists.txt rename to libs/libnamemanager/CMakeLists.txt index e99236d35..3a3420acc 100644 --- a/libs/libionamemap/CMakeLists.txt +++ b/libs/libnamemanager/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.9) -project("libionamemap") +project("libnamemanager") file(GLOB_RECURSE EXEC_SOURCES test/*.cpp) file(GLOB_RECURSE LIB_SOURCES src/*/*.cpp) @@ -11,14 +11,14 @@ files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS) list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES}) #Create the library -add_library(libionamemap STATIC +add_library(libnamemanager STATIC ${LIB_HEADERS} ${LIB_SOURCES}) -target_include_directories(libionamemap PUBLIC ${LIB_INCLUDE_DIRS}) -set_target_properties(libionamemap PROPERTIES PREFIX "") #Avoid extra 'lib' prefix +target_include_directories(libnamemanager PUBLIC ${LIB_INCLUDE_DIRS}) +set_target_properties(libnamemanager PROPERTIES PREFIX "") #Avoid extra 'lib' prefix #Specify link-time dependancies -target_link_libraries(libionamemap +target_link_libraries(libnamemanager libarchopenfpga libopenfpgautil libopenfpgashell @@ -31,7 +31,7 @@ foreach(testsourcefile ${EXEC_SOURCES}) get_filename_component(testname ${testsourcefile} NAME_WE) add_executable(${testname} ${testsourcefile}) # Make sure the library is linked to each test executable - target_link_libraries(${testname} libionamemap) + target_link_libraries(${testname} libnamemanager) endforeach(testsourcefile ${EXEC_SOURCES}) -install(TARGETS libionamemap DESTINATION bin) +install(TARGETS libnamemanager DESTINATION bin) diff --git a/libs/libionamemap/example/example.xml b/libs/libnamemanager/example/example.xml similarity index 100% rename from libs/libionamemap/example/example.xml rename to libs/libnamemanager/example/example.xml diff --git a/libs/libionamemap/src/base/io_name_map.cpp b/libs/libnamemanager/src/base/io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/base/io_name_map.cpp rename to libs/libnamemanager/src/base/io_name_map.cpp diff --git a/libs/libionamemap/src/base/io_name_map.h b/libs/libnamemanager/src/base/io_name_map.h similarity index 100% rename from libs/libionamemap/src/base/io_name_map.h rename to libs/libnamemanager/src/base/io_name_map.h diff --git a/libs/libionamemap/src/io/io_name_map_xml_constants.h b/libs/libnamemanager/src/io/io_name_map_xml_constants.h similarity index 100% rename from libs/libionamemap/src/io/io_name_map_xml_constants.h rename to libs/libnamemanager/src/io/io_name_map_xml_constants.h diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.cpp b/libs/libnamemanager/src/io/read_xml_io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/io/read_xml_io_name_map.cpp rename to libs/libnamemanager/src/io/read_xml_io_name_map.cpp diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.h b/libs/libnamemanager/src/io/read_xml_io_name_map.h similarity index 100% rename from libs/libionamemap/src/io/read_xml_io_name_map.h rename to libs/libnamemanager/src/io/read_xml_io_name_map.h diff --git a/libs/libionamemap/src/io/write_xml_io_name_map.cpp b/libs/libnamemanager/src/io/write_xml_io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/io/write_xml_io_name_map.cpp rename to libs/libnamemanager/src/io/write_xml_io_name_map.cpp diff --git a/libs/libionamemap/src/io/write_xml_io_name_map.h b/libs/libnamemanager/src/io/write_xml_io_name_map.h similarity index 100% rename from libs/libionamemap/src/io/write_xml_io_name_map.h rename to libs/libnamemanager/src/io/write_xml_io_name_map.h diff --git a/libs/libionamemap/test/xml_io_io_name_map.cpp b/libs/libnamemanager/test/xml_io_io_name_map.cpp similarity index 100% rename from libs/libionamemap/test/xml_io_io_name_map.cpp rename to libs/libnamemanager/test/xml_io_io_name_map.cpp diff --git a/openfpga/CMakeLists.txt b/openfpga/CMakeLists.txt index bea2fa94d..96c450876 100644 --- a/openfpga/CMakeLists.txt +++ b/openfpga/CMakeLists.txt @@ -41,7 +41,7 @@ target_link_libraries(libopenfpga libpcf libvtrutil libbusgroup - libionamemap + libnamemanager libtileconfig libpugixml libvpr) From b65dda90c43d79e54d3a99bc323dd3810db936ae Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 16:02:13 -0700 Subject: [PATCH 003/174] [lib] developing naming manager --- .../src/base/module_name_map.cpp | 50 +++++++++++++++++++ .../libnamemanager/src/base/module_name_map.h | 34 +++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 libs/libnamemanager/src/base/module_name_map.cpp create mode 100644 libs/libnamemanager/src/base/module_name_map.h diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp new file mode 100644 index 000000000..bcb1c23c2 --- /dev/null +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Memember functions for data structure ModuleNameMap + ******************************************************************************/ +/* Headers from vtrutil library */ +#include "module_name_map.h" + +#include + +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/************************************************** + * Public Accessors + *************************************************/ +std::string ModuleNameMap::name(const std::string& tag) const { + auto result = tag2names_.find(tag); + if (result == tag2names_.end()) { + VTR_LOG_ERROR("The given built-in name '%s' does not exist!\n", tag.c_str()); + return std::string(); + } + return result->second; +} + +int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::string& name) { + /* tagA <--x--> nameA + * | + * +----> nameB + * tagB <--x--> nameB + * Scenarios to be considered: + * - Remove the double links between tagA and nameA + * - nameB should NOT be mapped to any other tags! + */ + auto result = name2tags_.find(name); + if (result != name2tags_.end() && result->second != tag) { + VTR_LOG_ERROR("The customized name '%s' has already been mapped to a built-in name '%s'! Fail to bind it to a new built-in name '%s'\n", name.c_str(), result->second.c_str(), tag.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Create double link */ + name2tags_[name] = tag; + tag2names_[tag] = name; + /* Clean up */ + name2tags_.erase(name); +} + +} /* end namespace openfpga */ diff --git a/libs/libnamemanager/src/base/module_name_map.h b/libs/libnamemanager/src/base/module_name_map.h new file mode 100644 index 000000000..d2c921b81 --- /dev/null +++ b/libs/libnamemanager/src/base/module_name_map.h @@ -0,0 +1,34 @@ +#ifndef MODULE_NAME_MAP_H +#define MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include + +/* Begin namespace openfpga */ +namespace openfpga { + +/** + * @brief Module name map is a data structure to show mapping between a tag (built-in name) and customized names (may be given by users) + */ +class ModuleNameMap { + public: /* Public accessors */ + /** @brief Get customized name with a given tag */ + std::string name(const std::string& tag) const; + + public: /* Public mutators */ + /** @brief Create the one-on-one mapping between an built-in name and a customized name. Return 0 for success, return 1 for fail */ + int set_tag_to_name_pair(const std::string& tag, const std::string& name); + private: /* Internal Data */ + /* built-in name -> customized_name + * Create a double link to check any customized name is mapped to more than 1 built-in name! + */ + std::map tag2names_; + std::map name2tags_; +}; + +} /* End namespace openfpga*/ + +#endif From e5bc936144d1b456874bec88bb9356b6efdcf3a7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 16:19:10 -0700 Subject: [PATCH 004/174] [lib] developing io --- .../src/io/module_name_map_xml_constants.h | 11 +++ .../src/io/read_xml_module_name_map.cpp | 77 +++++++++++++++++++ .../src/io/read_xml_module_name_map.h | 21 +++++ .../src/io/write_xml_module_name_map.h | 20 +++++ 4 files changed, 129 insertions(+) create mode 100644 libs/libnamemanager/src/io/module_name_map_xml_constants.h create mode 100644 libs/libnamemanager/src/io/read_xml_module_name_map.cpp create mode 100644 libs/libnamemanager/src/io/read_xml_module_name_map.h create mode 100644 libs/libnamemanager/src/io/write_xml_module_name_map.h diff --git a/libs/libnamemanager/src/io/module_name_map_xml_constants.h b/libs/libnamemanager/src/io/module_name_map_xml_constants.h new file mode 100644 index 000000000..ae8e02338 --- /dev/null +++ b/libs/libnamemanager/src/io/module_name_map_xml_constants.h @@ -0,0 +1,11 @@ +#ifndef MODULE_NAME_MAP_XML_CONSTANTS_H +#define MODULE_NAME_MAP_XML_CONSTANTS_H + +/* Constants required by XML parser */ + +constexpr const char* XML_MODULE_NAMES_ROOT_NAME = "module_names"; +constexpr const char* XML_MODULE_NAME_NODE_NAME = "module_name"; +constexpr const char* XML_MODULE_NAME_ATTRIBUTE_DEFAULT = "default"; +constexpr const char* XML_MODULE_NAME_ATTRIBUTE_GIVEN = "given"; + +#endif diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp new file mode 100644 index 000000000..3b93a543e --- /dev/null +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp @@ -0,0 +1,77 @@ +/******************************************************************** + * This file includes the top-level function of this library + * which reads an XML of clock network file to the associated + * data structures + *******************************************************************/ +#include + +/* Headers from pugi XML library */ +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/* Headers from vtr util library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from libarchfpga */ +#include "arch_error.h" +#include "command_exit_codes.h" +#include "module_name_map_xml_constants.h" +#include "read_xml_module_name_map.h" +#include "read_xml_util.h" + +namespace openfpga { // Begin namespace openfpga + +/******************************************************************** + * Parse XML codes of a to an object of I/O naming + *******************************************************************/ +static int read_xml_module_name_binding(pugi::xml_node& xml_binding, + const pugiutil::loc_data& loc_data, + ModuleNameMap& module_name_map) { + std::string default_name = + get_attribute(xml_port, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, loc_data) + .as_string(); + std::string given_name = + get_attribute(xml_port, XML_MODULE_NAME_ATTRIBUTE_GIVEN, loc_data) + .as_string(); + + return module_name_map.set_tag_to_name_pair(default_name, given_name); +} + +/******************************************************************** + * Parse XML codes about to an object of ClockNetwork + *******************************************************************/ +int read_xml_module_name_map(const char* fname, ModuleNameMap& module_name_map) { + vtr::ScopedStartFinishTimer timer("Read module rename rules"); + + int status = CMD_EXEC_SUCCESS; + + /* Parse the file */ + pugi::xml_document doc; + pugiutil::loc_data loc_data; + + try { + loc_data = pugiutil::load_xml(doc, fname); + + pugi::xml_node xml_root = + get_single_child(doc, XML_MODULE_NAMES_ROOT_NAME, loc_data); + + for (pugi::xml_node xml_binding : xml_root.children()) { + /* Error out if the XML child has an invalid name! */ + if (xml_binding.name() != std::string(XML_MODULE_NAME_NODE_NAME)) { + bad_tag(xml_binding, loc_data, xml_root, {XML_MODULE_NAME_NODE_NAME}); + } + status = read_xml_module_name_binding(xml_binding, loc_data, module_name_map); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_FATAL_ERROR; + } + } + } catch (pugiutil::XmlError& e) { + archfpga_throw(fname, e.line(), "%s", e.what()); + } + + return status; +} + +} // End of namespace openfpga diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.h b/libs/libnamemanager/src/io/read_xml_module_name_map.h new file mode 100644 index 000000000..140c752dd --- /dev/null +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.h @@ -0,0 +1,21 @@ +#ifndef READ_XML_MODULE_NAME_MAP_H +#define READ_XML_MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "module_name_map.h" +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +namespace openfpga { // Begin namespace openfpga + +int read_xml_module_name_map(const char* fname, ModuleNameMap& module_name_map); + +} // End of namespace openfpga + +#endif diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.h b/libs/libnamemanager/src/io/write_xml_module_name_map.h new file mode 100644 index 000000000..ae47c70d3 --- /dev/null +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.h @@ -0,0 +1,20 @@ +#ifndef WRITE_XML_MODULE_NAME_MAP_H +#define WRITE_XML_MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +#include "module_name_map.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ +namespace openfpga { // Begin namespace openfpga + +int write_xml_module_name_map(const char* fname, const ModuleNameMap& module_name_map); + +} // End of namespace openfpga + +#endif From 636647902ed67d6b298db6e6595787daeed60527 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 16:53:24 -0700 Subject: [PATCH 005/174] [lib] developing io for module name map --- .../src/io/write_xml_module_name_map.cpp | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 libs/libnamemanager/src/io/write_xml_module_name_map.cpp diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp new file mode 100644 index 000000000..90b529316 --- /dev/null +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp @@ -0,0 +1,102 @@ +/******************************************************************** + * This file includes functions that outputs a clock network object to XML + *format + *******************************************************************/ +/* Headers from system goes first */ +#include +#include + +/* Headers from vtr util library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpga util library */ +#include "openfpga_digest.h" + +/* Headers from arch openfpga library */ +#include "write_xml_utils.h" + +/* Headers from pin constraint library */ +#include "module_name_map_xml_constants.h" +#include "write_xml_module_name_map.h" + +namespace openfpga { // Begin namespace openfpga + +/******************************************************************** + * A writer to output a I/O name mapping to XML format + * + * Return 0 if successful + * Return 1 if there are more serious bugs in the architecture + * Return 2 if fail when creating files + *******************************************************************/ +static int write_xml_module_name_binding(std::fstream& fp, const ModuleNameMap& module_name_map, + const std::string& built_in_name) { + /* Validate the file stream */ + if (false == openfpga::valid_file_stream(fp)) { + return 2; + } + + openfpga::write_tab_to_file(fp, 1); + fp << "<" << XML_MODULE_NAME_NODE_NAME << ""; + write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, + built_in_name.c_str()); + + std::string given_name = module_name_map.name(built_in_name); + if (given_name.empty()) { + VTR_LOG_ERROR("Default name '%s' is not mapped to any given name!\n", built_in_name.c_str()); + return 1; + } + write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_GIVEN, + given_name.c_str()); + fp << ">" + << "\n"; + + return 0; +} + +/******************************************************************** + * A writer to output an object to XML format + * + * Return 0 if successful + * Return 1 if there are more serious bugs in the architecture + * Return 2 if fail when creating files + *******************************************************************/ +int write_xml_module_name_map(const char* fname, const ModuleNameMap& module_name_map) { + vtr::ScopedStartFinishTimer timer("Write module renaming rules"); + + /* Create a file handler */ + std::fstream fp; + /* Open the file stream */ + fp.open(std::string(fname), std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + /* Write the root node */ + fp << "<" << XML_MODULE_NAMES_ROOT_NAME; + fp << ">" + << "\n"; + + int err_code = 0; + + /* Write each port */ + for (std::string built_in_name : module_name_map.tags()) { + /* Write bus */ + err_code = write_xml_module_name_binding(fp, module_name_map, built_in_name); + if (0 != err_code) { + return err_code; + } + } + + /* Finish writing the root node */ + fp << "" + << "\n"; + + /* Close the file stream */ + fp.close(); + + return err_code; +} + +} // End of namespace openfpga From 74b9f673ec0490a2ab7e38f6c4b2072c0ea4deb1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 17:00:02 -0700 Subject: [PATCH 006/174] [lib] syntax and add missing api --- libs/libnamemanager/src/base/module_name_map.cpp | 9 +++++++++ libs/libnamemanager/src/base/module_name_map.h | 3 +++ libs/libnamemanager/src/io/read_xml_module_name_map.cpp | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp index bcb1c23c2..7cceb6506 100644 --- a/libs/libnamemanager/src/base/module_name_map.cpp +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -26,6 +26,14 @@ std::string ModuleNameMap::name(const std::string& tag) const { return result->second; } +std::vector ModuleNameMap::tags() const { + std::vector keys; + for (auto const& element : tag2names_) { + keys.push_back(element.first); + } + return keys; +} + int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::string& name) { /* tagA <--x--> nameA * | @@ -45,6 +53,7 @@ int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::strin tag2names_[tag] = name; /* Clean up */ name2tags_.erase(name); + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/libs/libnamemanager/src/base/module_name_map.h b/libs/libnamemanager/src/base/module_name_map.h index d2c921b81..c9bcf1c81 100644 --- a/libs/libnamemanager/src/base/module_name_map.h +++ b/libs/libnamemanager/src/base/module_name_map.h @@ -5,6 +5,7 @@ * Include header files required by the data structure definition *******************************************************************/ #include +#include #include /* Begin namespace openfpga */ @@ -17,6 +18,8 @@ class ModuleNameMap { public: /* Public accessors */ /** @brief Get customized name with a given tag */ std::string name(const std::string& tag) const; + /** @brief return a list of all the current keys */ + std::vector tags() const; public: /* Public mutators */ /** @brief Create the one-on-one mapping between an built-in name and a customized name. Return 0 for success, return 1 for fail */ diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp index 3b93a543e..3b1f76ed2 100644 --- a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp @@ -30,10 +30,10 @@ static int read_xml_module_name_binding(pugi::xml_node& xml_binding, const pugiutil::loc_data& loc_data, ModuleNameMap& module_name_map) { std::string default_name = - get_attribute(xml_port, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, loc_data) + get_attribute(xml_binding, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, loc_data) .as_string(); std::string given_name = - get_attribute(xml_port, XML_MODULE_NAME_ATTRIBUTE_GIVEN, loc_data) + get_attribute(xml_binding, XML_MODULE_NAME_ATTRIBUTE_GIVEN, loc_data) .as_string(); return module_name_map.set_tag_to_name_pair(default_name, given_name); From 71b32616fa871adbeaba183a4a6b6bd0d12420c0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Sep 2023 00:02:23 +0000 Subject: [PATCH 007/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index a9e3c4814..f03e01af8 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1529 +1.2.1535 From b5cf08a3c57b088ca5e91806642d45bc67a217dc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 17:15:05 -0700 Subject: [PATCH 008/174] [lib] add testing --- .../example/example_module_names.xml | 5 +++ .../test/xml_io_module_name_map.cpp | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 libs/libnamemanager/example/example_module_names.xml create mode 100644 libs/libnamemanager/test/xml_io_module_name_map.cpp diff --git a/libs/libnamemanager/example/example_module_names.xml b/libs/libnamemanager/example/example_module_names.xml new file mode 100644 index 000000000..72534edc1 --- /dev/null +++ b/libs/libnamemanager/example/example_module_names.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/libs/libnamemanager/test/xml_io_module_name_map.cpp b/libs/libnamemanager/test/xml_io_module_name_map.cpp new file mode 100644 index 000000000..bf8b364a6 --- /dev/null +++ b/libs/libnamemanager/test/xml_io_module_name_map.cpp @@ -0,0 +1,38 @@ +/******************************************************************** + * Unit test functions to validate the correctness of + * 1. parser of data structures + * 2. writer of data structures + *******************************************************************/ +/* Headers from vtrutils */ +#include "vtr_assert.h" +#include "vtr_log.h" + +/* Headers from readarchopenfpga */ +#include "read_xml_module_name_map.h" +#include "write_xml_module_name_map.h" + +int main(int argc, const char** argv) { + /* Ensure we have only one or two argument */ + VTR_ASSERT((2 == argc) || (3 == argc)); + + int status = 0; + + /* Parse the circuit library from an XML file */ + openfpga::ModuleNameMap module_name_map; + status = openfpga::read_xml_module_name_map(argv[1], module_name_map); + if (status != 0) { + return status; + } + VTR_LOG("Parsed %lu default names from XML.\n", + module_name_map.tags().size()); + + /* Output the bus group to an XML file + * This is optional only used when there is a second argument + */ + if (3 <= argc) { + status = openfpga::write_xml_module_name_map(argv[2], module_name_map); + VTR_LOG("Write the module name mapping to an XML file: %s.\n", argv[2]); + } + + return status; +} From 7913e6cc6ab9765a366d0e337ae8094e8059586c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 17:38:51 -0700 Subject: [PATCH 009/174] [lib] update tests and fixed some bugs --- libs/libnamemanager/example/example_module_names.xml | 4 ++-- .../example/example_module_names_expect_errors.xml | 6 ++++++ libs/libnamemanager/src/base/module_name_map.cpp | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 libs/libnamemanager/example/example_module_names_expect_errors.xml diff --git a/libs/libnamemanager/example/example_module_names.xml b/libs/libnamemanager/example/example_module_names.xml index 72534edc1..336eeb9c1 100644 --- a/libs/libnamemanager/example/example_module_names.xml +++ b/libs/libnamemanager/example/example_module_names.xml @@ -1,5 +1,5 @@ - + - + diff --git a/libs/libnamemanager/example/example_module_names_expect_errors.xml b/libs/libnamemanager/example/example_module_names_expect_errors.xml new file mode 100644 index 000000000..186ce92df --- /dev/null +++ b/libs/libnamemanager/example/example_module_names_expect_errors.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp index 7cceb6506..9fa435ee8 100644 --- a/libs/libnamemanager/src/base/module_name_map.cpp +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -48,11 +48,11 @@ int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::strin VTR_LOG_ERROR("The customized name '%s' has already been mapped to a built-in name '%s'! Fail to bind it to a new built-in name '%s'\n", name.c_str(), result->second.c_str(), tag.c_str()); return CMD_EXEC_FATAL_ERROR; } + /* Clean up */ + name2tags_.erase(name); /* Create double link */ name2tags_[name] = tag; tag2names_[tag] = name; - /* Clean up */ - name2tags_.erase(name); return CMD_EXEC_SUCCESS; } From 2a45b49890b59f62ebb1581c2d3ade42649a9c0d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 19:15:18 -0700 Subject: [PATCH 010/174] [core] developing renaming commands. options and functions --- .../src/base/openfpga_build_fabric_template.h | 33 ++++++++++++- openfpga/src/base/openfpga_context.h | 4 ++ .../base/openfpga_setup_command_template.h | 47 +++++++++++++++++++ openfpga/src/fabric/build_device_module.cpp | 23 ++++++++- 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 39e181b6d..73fcae766 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -18,6 +18,7 @@ #include "openfpga_naming.h" #include "read_xml_fabric_key.h" #include "read_xml_io_name_map.h" +#include "read_xml_module_name_map.h" #include "read_xml_tile_config.h" #include "vtr_log.h" #include "vtr_time.h" @@ -103,6 +104,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, CommandOptionId opt_load_fabric_key = cmd.option("load_fabric_key"); CommandOptionId opt_group_tile = cmd.option("group_tile"); CommandOptionId opt_group_config_block = cmd.option("group_config_block"); + CommandOptionId opt_name_module_using_index = cmd.option("name_module_using_index"); CommandOptionId opt_verbose = cmd.option("verbose"); /* Report conflicts with options: @@ -173,12 +175,15 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, curr_status = build_device_module_graph( openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_decoder_lib(), openfpga_ctx.mutable_blwl_shift_register_banks(), - openfpga_ctx.mutable_fabric_tile(), const_cast(openfpga_ctx), + openfpga_ctx.mutable_fabric_tile(), + openfpga_ctx.mutable_module_name_map(), + const_cast(openfpga_ctx), g_vpr_ctx.device(), cmd_context.option_enable(cmd, opt_frame_view), cmd_context.option_enable(cmd, opt_compress_routing), cmd_context.option_enable(cmd, opt_duplicate_grid_pin), predefined_fabric_key, tile_config, cmd_context.option_enable(cmd, opt_group_config_block), + cmd_context.option_enable(cmd, opt_name_module_using_index), cmd_context.option_enable(cmd, opt_gen_random_fabric_key), cmd_context.option_enable(cmd, opt_verbose)); @@ -336,6 +341,32 @@ int add_fpga_core_to_fabric_template(T& openfpga_ctx, const Command& cmd, core_inst_name, frame_view, verbose_output); } +/******************************************************************** + * Rename modules in module graph with a set of given rules + *******************************************************************/ +template +int rename_modules_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + CommandOptionId opt_file = cmd.option("file"); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + + if (CMD_EXEC_SUCCESS != read_xml_module_name_map(file_name.c_str(), openfpga_ctx.mutable_module_name_map())) { + return CMD_EXEC_FATAL_ERROR; + } + + /* Write hierarchy to a file */ + return rename_fabric_modules(openfpga_ctx.mutable_module_graph(), openfpga_ctx.module_name_map(), cmd_context.option_enable(cmd, opt_verbose)); +} + } /* end namespace openfpga */ #endif diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index 9473ecc65..b67b2a572 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -13,6 +13,7 @@ #include "fabric_tile.h" #include "io_location_map.h" #include "io_name_map.h" +#include "module_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" #include "mux_library.h" @@ -107,6 +108,7 @@ class OpenfpgaContext : public Context { return io_location_map_; } const openfpga::IoNameMap& io_name_map() const { return io_name_map_; } + const openfpga::ModuleNameMap& module_name_map() const { return module_name_map_; } const openfpga::FabricTile& fabric_tile() const { return fabric_tile_; } const openfpga::FabricGlobalPortInfo& fabric_global_port_info() const { return fabric_global_port_info_; @@ -167,6 +169,7 @@ class OpenfpgaContext : public Context { return io_location_map_; } openfpga::IoNameMap& mutable_io_name_map() { return io_name_map_; } + openfpga::ModuleNameMap& mutable_module_name_map() { return module_name_map_; } openfpga::FabricTile& mutable_fabric_tile() { return fabric_tile_; } openfpga::FabricGlobalPortInfo& mutable_fabric_global_port_info() { return fabric_global_port_info_; @@ -223,6 +226,7 @@ class OpenfpgaContext : public Context { openfpga::ModuleManager module_graph_; openfpga::IoLocationMap io_location_map_; openfpga::IoNameMap io_name_map_; + openfpga::ModuleNameMap module_name_map_; openfpga::FabricTile fabric_tile_; openfpga::FabricGlobalPortInfo fabric_global_port_info_; diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index 55b0ae52f..b2e18a839 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -395,6 +395,10 @@ ShellCommandId add_build_fabric_command_template( shell_cmd.add_option("duplicate_grid_pin", false, "Duplicate the pins on the same side of a grid"); + /* Add an option '--name_module_using_index' */ + shell_cmd.add_option("name_module_using_index", false, + "Use index to name modules, such as cbx_0_, rather than coordinates, such as cbx_1__0_"); + /* Add an option '--load_fabric_key' */ CommandOptionId opt_load_fkey = shell_cmd.add_option( "load_fabric_key", false, "load the fabric key from the given file"); @@ -786,6 +790,37 @@ ShellCommandId add_write_fabric_key_command_template( return shell_cmd_id; } +/******************************************************************** + * - Add a command to Shell environment: rename_modules + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_rename_modules_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("rename_modules"); + /* Add an option '--file' in short '-f'*/ + CommandOptionId opt_file = + shell_cmd.add_option("file", true, "file path to the XML file that contains renaming rules"); + shell_cmd.set_option_short_name(opt_file, "f"); + shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); + + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "Rename modules with a set of given rules", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_const_execute_function(shell_cmd_id, + rename_modules_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + template void add_setup_command_templates(openfpga::Shell& shell, const bool& hidden = false) { @@ -1005,6 +1040,18 @@ void add_setup_command_templates(openfpga::Shell& shell, add_write_fabric_io_info_command_template( shell, openfpga_setup_cmd_class, cmd_dependency_write_fabric_io_info, hidden); + + /******************************** + * Command 'rename_modules' + */ + /* The 'rename_modules' command should NOT be executed before + * 'build_fabric' */ + std::vector cmd_dependency_rename_modules; + cmd_dependency_rename_modules.push_back(build_fabric_cmd_id); + add_rename_modules_command_template( + shell, openfpga_setup_cmd_class, cmd_dependency_rename_modules, + hidden); + } } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 5279c9fc7..eec3731cb 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -34,11 +34,14 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, const bool& frame_view, const bool& compress_routing, const bool& duplicate_grid_pin, const FabricKey& fabric_key, const TileConfig& tile_config, const bool& group_config_block, - const bool& generate_random_fabric_key, const bool& verbose) { + const bool& name_module_using_index, + const bool& generate_random_fabric_key, + const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build fabric module graph"); int status = CMD_EXEC_SUCCESS; @@ -151,6 +154,24 @@ int build_device_module_graph( rename_primitive_module_port_names(module_manager, openfpga_ctx.arch().circuit_lib); + /* Collect module names and initialize module name mapping */ + status = init_fabric_module_map_name(module_manager, module_name_map); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + if (name_module_using_index) { + /* Update module name data */ + status = update_module_map_name_with_indexing_names(module_name_map, device_rr_gsb, fabric_tile); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + /* Apply module naming */ + status = rename_fabric_modules(module_manager, module_name_map, verbose); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + } + return status; } From bc407e5d692f4b7536db62c72e76cecaeca4ecb2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 23:22:31 -0700 Subject: [PATCH 011/174] [core] code complete for rename modules --- .../src/base/module_name_map.cpp | 5 + .../libnamemanager/src/base/module_name_map.h | 2 + .../src/base/openfpga_build_fabric_template.h | 1 + openfpga/src/base/openfpga_naming.cpp | 38 ++++++++ openfpga/src/base/openfpga_naming.h | 8 ++ openfpga/src/fabric/build_device_module.cpp | 5 +- openfpga/src/fabric/rename_modules.cpp | 93 +++++++++++++++++++ openfpga/src/fabric/rename_modules.h | 30 ++++++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 openfpga/src/fabric/rename_modules.cpp create mode 100644 openfpga/src/fabric/rename_modules.h diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp index 9fa435ee8..bfcc02046 100644 --- a/libs/libnamemanager/src/base/module_name_map.cpp +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -54,6 +54,11 @@ int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::strin name2tags_[name] = tag; tag2names_[tag] = name; return CMD_EXEC_SUCCESS; +} + +void ModuleNameMap::clear() { + tag2names_.clear(); + name2tags_.clear(); } } /* end namespace openfpga */ diff --git a/libs/libnamemanager/src/base/module_name_map.h b/libs/libnamemanager/src/base/module_name_map.h index c9bcf1c81..0d2c5301e 100644 --- a/libs/libnamemanager/src/base/module_name_map.h +++ b/libs/libnamemanager/src/base/module_name_map.h @@ -24,6 +24,8 @@ class ModuleNameMap { public: /* Public mutators */ /** @brief Create the one-on-one mapping between an built-in name and a customized name. Return 0 for success, return 1 for fail */ int set_tag_to_name_pair(const std::string& tag, const std::string& name); + /** @brief Reset to empty status. Clear all the storage */ + void clear(); private: /* Internal Data */ /* built-in name -> customized_name * Create a double link to check any customized name is mapped to more than 1 built-in name! diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 73fcae766..9c897d2f3 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -22,6 +22,7 @@ #include "read_xml_tile_config.h" #include "vtr_log.h" #include "vtr_time.h" +#include "rename_modules.h" /* begin namespace openfpga */ namespace openfpga { diff --git a/openfpga/src/base/openfpga_naming.cpp b/openfpga/src/base/openfpga_naming.cpp index 1623df96f..81b057a09 100644 --- a/openfpga/src/base/openfpga_naming.cpp +++ b/openfpga/src/base/openfpga_naming.cpp @@ -503,6 +503,15 @@ std::string generate_switch_block_module_name( std::string("_")); } +/********************************************************************* + * Generate the module name for a switch block with a given index + *********************************************************************/ +std::string generate_switch_block_module_name_using_index( + const size_t& index) { + return std::string("sb_" + std::to_string(index) + + std::string("_")); +} + /********************************************************************* * Generate the module name for a tile module with a given coordinate *********************************************************************/ @@ -511,6 +520,13 @@ std::string generate_tile_module_name(const vtr::Point& tile_coord) { std::to_string(tile_coord.y()) + "_"); } +/********************************************************************* + * Generate the module name for a tile module with a given index + *********************************************************************/ +std::string generate_tile_module_name_using_index(const size_t& index) { + return std::string("tile_" + std::to_string(index) + "_"); +} + /********************************************************************* * Generate the port name for a tile. Note that use the index to make the tile *port name unique! @@ -560,6 +576,28 @@ std::string generate_connection_block_module_name( std::string("_")); } +/********************************************************************* + * Generate the module name for a connection block with a given index + *********************************************************************/ +std::string generate_connection_block_module_name_using_index( + const t_rr_type& cb_type, const size_t& index) { + std::string prefix("cb"); + switch (cb_type) { + case CHANX: + prefix += std::string("x_"); + break; + case CHANY: + prefix += std::string("y_"); + break; + default: + VTR_LOG_ERROR("Invalid type of connection block!\n"); + exit(1); + } + + return std::string(prefix + std::to_string(index) + + std::string("_")); +} + /********************************************************************* * Generate the port name for a grid in top-level netlists, i.e., full FPGA *fabric This function will generate a full port name including coordinates so diff --git a/openfpga/src/base/openfpga_naming.h b/openfpga/src/base/openfpga_naming.h index 4a1d35e8e..b415231c2 100644 --- a/openfpga/src/base/openfpga_naming.h +++ b/openfpga/src/base/openfpga_naming.h @@ -108,11 +108,19 @@ std::string generate_routing_track_middle_output_port_name( std::string generate_switch_block_module_name( const vtr::Point& coordinate); +std::string generate_switch_block_module_name_using_index( + const size_t& index); + std::string generate_connection_block_module_name( const t_rr_type& cb_type, const vtr::Point& coordinate); +std::string generate_connection_block_module_name_using_index( + const t_rr_type& cb_type, const size_t& index); + std::string generate_tile_module_name(const vtr::Point& tile_coord); +std::string generate_tile_module_name_using_index(const size_t& index); + std::string generate_tile_module_port_name(const std::string& prefix, const std::string& port_name); diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index eec3731cb..060a67a47 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -23,6 +23,7 @@ #include "build_wire_modules.h" #include "command_exit_codes.h" #include "openfpga_naming.h" +#include "rename_modules.h" /* begin namespace openfpga */ namespace openfpga { @@ -155,13 +156,13 @@ int build_device_module_graph( openfpga_ctx.arch().circuit_lib); /* Collect module names and initialize module name mapping */ - status = init_fabric_module_map_name(module_manager, module_name_map); + status = init_fabric_module_name_map(module_name_map, module_manager, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } if (name_module_using_index) { /* Update module name data */ - status = update_module_map_name_with_indexing_names(module_name_map, device_rr_gsb, fabric_tile); + status = update_module_map_name_with_indexing_names(module_name_map, device_rr_gsb, fabric_tile, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga/src/fabric/rename_modules.cpp b/openfpga/src/fabric/rename_modules.cpp new file mode 100644 index 000000000..5f216ed52 --- /dev/null +++ b/openfpga/src/fabric/rename_modules.cpp @@ -0,0 +1,93 @@ +/* Headers from vtrutil library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +#include "command_exit_codes.h" +#include "openfpga_naming.h" +#include "rename_modules.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/** @brief Initialize a module name map with the existing module names from a module manager. In this case, all the built-in names are the same as customized names */ +int init_fabric_module_name_map( + ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + /* the module name map should be empty! */ + module_name_map.clear(); + size_t cnt = 0; + for (ModuleId curr_module : module_manager.modules()) { + status = module_name_map.set_tag_to_name_pair(module_manager.module_name(curr_module), module_manager.module_name(curr_module)); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + cnt++; + } + VTR_LOGV(verbose, "Initialized module name map for '%lu' modules\n", cnt); + return CMD_EXEC_SUCCESS; +} + +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + /* Walk through the device rr gsb on the unique routing modules */ + for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { + const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); + vtr::Point gsb_coordinate(unique_mirror.get_sb_x(), unique_mirror.get_sb_y()); + std::string name_using_coord = generate_switch_block_module_name(gsb_coordinate); + std::string name_using_index = generate_switch_block_module_name_using_index(isb); + status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + } + for (t_rr_type cb_type : {CHANX, CHANY}) { + for (size_t icb = 0; icb < device_rr_gsb.get_num_cb_unique_module(cb_type); + ++icb) { + const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(cb_type, icb); + vtr::Point gsb_coordinate(unique_mirror.get_cb_x(cb_type), + unique_mirror.get_cb_y(cb_type)); + std::string name_using_coord = generate_connection_block_module_name(cb_type, gsb_coordinate); + std::string name_using_index = generate_connection_block_module_name_using_index(cb_type, icb); + status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + } + } + /* Walk through the fabric tile on the unique routing modules */ + for (size_t itile = 0; itile < fabric_tile.unique_tiles().size(); ++itile) { + FabricTileId fabric_tile_id = fabric_tile.unique_tiles()[itile]; + vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); + std::string name_using_coord = generate_tile_module_name(tile_coord); + std::string name_using_index = generate_tile_module_name_using_index(tile_coord, itile); + status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + } + return CMD_EXEC_SUCCESS; +} + +int rename_fabric_modules(ModuleManager& module_manager, const ModuleNameMap& module_name_map, const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + size_t cnt = 0; + for (ModuleId curr_module : module_manager.modules()) { + std::string new_name = module_name_map.name(module_manager.module_name(curr_module)); + if (new_name != module_manager.module_name()) { + VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", module_manager.module_name(curr_module).c_str(), new_name.c_str()); + module_manager.set_module_name(curr_module, new_name); + } + cnt++; + } + VTR_LOG("Renamed %lu modules\n", cnt); + return status; +} + + +} /* end namespace openfpga */ diff --git a/openfpga/src/fabric/rename_modules.h b/openfpga/src/fabric/rename_modules.h new file mode 100644 index 000000000..deef21b41 --- /dev/null +++ b/openfpga/src/fabric/rename_modules.h @@ -0,0 +1,30 @@ +#ifndef RENAME_MODULES_H +#define RENAME_MODULES_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "fabric_tile.h" +#include "device_rr_gsb.h" +#include "module_name_map.h" +#include "module_manager.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int init_fabric_module_name_map( + ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose); + +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, const bool& verbose); + +int rename_fabric_modules(ModuleManager& module_manager, const ModuleNameMap& module_name_map, const bool& verbose); + +} /* end namespace openfpga */ + +#endif From c85c64eb5a01b2d26afc5ef544500425d17f1cb6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 23:30:34 -0700 Subject: [PATCH 012/174] [core] syntax --- openfpga/src/base/openfpga_build_fabric_template.h | 2 +- openfpga/src/base/openfpga_setup_command_template.h | 2 +- openfpga/src/fabric/build_device_module.cpp | 2 +- openfpga/src/fabric/build_device_module.h | 3 +++ openfpga/src/fabric/rename_modules.cpp | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 9c897d2f3..0fdb26674 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -346,7 +346,7 @@ int add_fpga_core_to_fabric_template(T& openfpga_ctx, const Command& cmd, * Rename modules in module graph with a set of given rules *******************************************************************/ template -int rename_modules_template(const T& openfpga_ctx, const Command& cmd, +int rename_modules_template(T& openfpga_ctx, const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_verbose = cmd.option("verbose"); diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index b2e18a839..0a6938fb8 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -812,7 +812,7 @@ ShellCommandId add_rename_modules_command_template( ShellCommandId shell_cmd_id = shell.add_command( shell_cmd, "Rename modules with a set of given rules", hidden); shell.set_command_class(shell_cmd_id, cmd_class_id); - shell.set_command_const_execute_function(shell_cmd_id, + shell.set_command_execute_function(shell_cmd_id, rename_modules_template); /* Add command dependency to the Shell */ diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 060a67a47..e759dba03 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -162,7 +162,7 @@ int build_device_module_graph( } if (name_module_using_index) { /* Update module name data */ - status = update_module_map_name_with_indexing_names(module_name_map, device_rr_gsb, fabric_tile, verbose); + status = update_module_map_name_with_indexing_names(module_name_map, openfpga_ctx.device_rr_gsb(), fabric_tile, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga/src/fabric/build_device_module.h b/openfpga/src/fabric/build_device_module.h index fb4178cc8..98db557bd 100644 --- a/openfpga/src/fabric/build_device_module.h +++ b/openfpga/src/fabric/build_device_module.h @@ -7,6 +7,7 @@ #include "fabric_key.h" #include "fabric_tile.h" #include "io_name_map.h" +#include "module_name_map.h" #include "openfpga_context.h" #include "tile_config.h" #include "vpr_context.h" @@ -21,10 +22,12 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, const bool& frame_view, const bool& compress_routing, const bool& duplicate_grid_pin, const FabricKey& fabric_key, const TileConfig& tile_config, const bool& group_config_block, + const bool& name_module_using_index, const bool& generate_random_fabric_key, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/rename_modules.cpp b/openfpga/src/fabric/rename_modules.cpp index 5f216ed52..53f9bbdcb 100644 --- a/openfpga/src/fabric/rename_modules.cpp +++ b/openfpga/src/fabric/rename_modules.cpp @@ -64,7 +64,7 @@ int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, c FabricTileId fabric_tile_id = fabric_tile.unique_tiles()[itile]; vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); std::string name_using_coord = generate_tile_module_name(tile_coord); - std::string name_using_index = generate_tile_module_name_using_index(tile_coord, itile); + std::string name_using_index = generate_tile_module_name_using_index(itile); status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_SUCCESS; @@ -79,7 +79,7 @@ int rename_fabric_modules(ModuleManager& module_manager, const ModuleNameMap& mo size_t cnt = 0; for (ModuleId curr_module : module_manager.modules()) { std::string new_name = module_name_map.name(module_manager.module_name(curr_module)); - if (new_name != module_manager.module_name()) { + if (new_name != module_manager.module_name(curr_module)) { VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", module_manager.module_name(curr_module).c_str(), new_name.c_str()); module_manager.set_module_name(curr_module, new_name); } From 37573abc22b44d57f1a0b582fab5f5de4a1554f5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 15 Sep 2023 23:32:40 -0700 Subject: [PATCH 013/174] [core] code format --- .../src/base/module_name_map.cpp | 15 ++-- .../libnamemanager/src/base/module_name_map.h | 12 ++- .../src/io/read_xml_module_name_map.cpp | 10 ++- .../src/io/write_xml_module_name_map.cpp | 17 ++-- .../src/io/write_xml_module_name_map.h | 3 +- .../src/base/openfpga_build_fabric_template.h | 20 +++-- openfpga/src/base/openfpga_context.h | 10 ++- openfpga/src/base/openfpga_naming.cpp | 9 +-- openfpga/src/base/openfpga_naming.h | 3 +- .../base/openfpga_setup_command_template.h | 16 ++-- openfpga/src/fabric/build_device_module.cpp | 22 +++--- openfpga/src/fabric/build_device_module.h | 11 ++- openfpga/src/fabric/rename_modules.cpp | 78 ++++++++++++------- openfpga/src/fabric/rename_modules.h | 20 +++-- 14 files changed, 144 insertions(+), 102 deletions(-) diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp index bfcc02046..2a163191c 100644 --- a/libs/libnamemanager/src/base/module_name_map.cpp +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -20,7 +20,8 @@ namespace openfpga { std::string ModuleNameMap::name(const std::string& tag) const { auto result = tag2names_.find(tag); if (result == tag2names_.end()) { - VTR_LOG_ERROR("The given built-in name '%s' does not exist!\n", tag.c_str()); + VTR_LOG_ERROR("The given built-in name '%s' does not exist!\n", + tag.c_str()); return std::string(); } return result->second; @@ -34,9 +35,10 @@ std::vector ModuleNameMap::tags() const { return keys; } -int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::string& name) { +int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, + const std::string& name) { /* tagA <--x--> nameA - * | + * | * +----> nameB * tagB <--x--> nameB * Scenarios to be considered: @@ -45,7 +47,10 @@ int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::strin */ auto result = name2tags_.find(name); if (result != name2tags_.end() && result->second != tag) { - VTR_LOG_ERROR("The customized name '%s' has already been mapped to a built-in name '%s'! Fail to bind it to a new built-in name '%s'\n", name.c_str(), result->second.c_str(), tag.c_str()); + VTR_LOG_ERROR( + "The customized name '%s' has already been mapped to a built-in name " + "'%s'! Fail to bind it to a new built-in name '%s'\n", + name.c_str(), result->second.c_str(), tag.c_str()); return CMD_EXEC_FATAL_ERROR; } /* Clean up */ @@ -54,7 +59,7 @@ int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, const std::strin name2tags_[name] = tag; tag2names_[tag] = name; return CMD_EXEC_SUCCESS; -} +} void ModuleNameMap::clear() { tag2names_.clear(); diff --git a/libs/libnamemanager/src/base/module_name_map.h b/libs/libnamemanager/src/base/module_name_map.h index 0d2c5301e..e18359f0e 100644 --- a/libs/libnamemanager/src/base/module_name_map.h +++ b/libs/libnamemanager/src/base/module_name_map.h @@ -4,15 +4,16 @@ /******************************************************************** * Include header files required by the data structure definition *******************************************************************/ +#include #include #include -#include /* Begin namespace openfpga */ namespace openfpga { /** - * @brief Module name map is a data structure to show mapping between a tag (built-in name) and customized names (may be given by users) + * @brief Module name map is a data structure to show mapping between a tag + * (built-in name) and customized names (may be given by users) */ class ModuleNameMap { public: /* Public accessors */ @@ -22,13 +23,16 @@ class ModuleNameMap { std::vector tags() const; public: /* Public mutators */ - /** @brief Create the one-on-one mapping between an built-in name and a customized name. Return 0 for success, return 1 for fail */ + /** @brief Create the one-on-one mapping between an built-in name and a + * customized name. Return 0 for success, return 1 for fail */ int set_tag_to_name_pair(const std::string& tag, const std::string& name); /** @brief Reset to empty status. Clear all the storage */ void clear(); + private: /* Internal Data */ /* built-in name -> customized_name - * Create a double link to check any customized name is mapped to more than 1 built-in name! + * Create a double link to check any customized name is mapped to more than 1 + * built-in name! */ std::map tag2names_; std::map name2tags_; diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp index 3b1f76ed2..111ce871c 100644 --- a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp @@ -27,8 +27,8 @@ namespace openfpga { // Begin namespace openfpga * Parse XML codes of a to an object of I/O naming *******************************************************************/ static int read_xml_module_name_binding(pugi::xml_node& xml_binding, - const pugiutil::loc_data& loc_data, - ModuleNameMap& module_name_map) { + const pugiutil::loc_data& loc_data, + ModuleNameMap& module_name_map) { std::string default_name = get_attribute(xml_binding, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, loc_data) .as_string(); @@ -42,7 +42,8 @@ static int read_xml_module_name_binding(pugi::xml_node& xml_binding, /******************************************************************** * Parse XML codes about to an object of ClockNetwork *******************************************************************/ -int read_xml_module_name_map(const char* fname, ModuleNameMap& module_name_map) { +int read_xml_module_name_map(const char* fname, + ModuleNameMap& module_name_map) { vtr::ScopedStartFinishTimer timer("Read module rename rules"); int status = CMD_EXEC_SUCCESS; @@ -62,7 +63,8 @@ int read_xml_module_name_map(const char* fname, ModuleNameMap& module_name_map) if (xml_binding.name() != std::string(XML_MODULE_NAME_NODE_NAME)) { bad_tag(xml_binding, loc_data, xml_root, {XML_MODULE_NAME_NODE_NAME}); } - status = read_xml_module_name_binding(xml_binding, loc_data, module_name_map); + status = + read_xml_module_name_binding(xml_binding, loc_data, module_name_map); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp index 90b529316..4b07111da 100644 --- a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp @@ -30,8 +30,9 @@ namespace openfpga { // Begin namespace openfpga * Return 1 if there are more serious bugs in the architecture * Return 2 if fail when creating files *******************************************************************/ -static int write_xml_module_name_binding(std::fstream& fp, const ModuleNameMap& module_name_map, - const std::string& built_in_name) { +static int write_xml_module_name_binding(std::fstream& fp, + const ModuleNameMap& module_name_map, + const std::string& built_in_name) { /* Validate the file stream */ if (false == openfpga::valid_file_stream(fp)) { return 2; @@ -44,11 +45,11 @@ static int write_xml_module_name_binding(std::fstream& fp, const ModuleNameMap& std::string given_name = module_name_map.name(built_in_name); if (given_name.empty()) { - VTR_LOG_ERROR("Default name '%s' is not mapped to any given name!\n", built_in_name.c_str()); + VTR_LOG_ERROR("Default name '%s' is not mapped to any given name!\n", + built_in_name.c_str()); return 1; } - write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_GIVEN, - given_name.c_str()); + write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_GIVEN, given_name.c_str()); fp << ">" << "\n"; @@ -62,7 +63,8 @@ static int write_xml_module_name_binding(std::fstream& fp, const ModuleNameMap& * Return 1 if there are more serious bugs in the architecture * Return 2 if fail when creating files *******************************************************************/ -int write_xml_module_name_map(const char* fname, const ModuleNameMap& module_name_map) { +int write_xml_module_name_map(const char* fname, + const ModuleNameMap& module_name_map) { vtr::ScopedStartFinishTimer timer("Write module renaming rules"); /* Create a file handler */ @@ -83,7 +85,8 @@ int write_xml_module_name_map(const char* fname, const ModuleNameMap& module_nam /* Write each port */ for (std::string built_in_name : module_name_map.tags()) { /* Write bus */ - err_code = write_xml_module_name_binding(fp, module_name_map, built_in_name); + err_code = + write_xml_module_name_binding(fp, module_name_map, built_in_name); if (0 != err_code) { return err_code; } diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.h b/libs/libnamemanager/src/io/write_xml_module_name_map.h index ae47c70d3..fb9b95953 100644 --- a/libs/libnamemanager/src/io/write_xml_module_name_map.h +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.h @@ -13,7 +13,8 @@ *******************************************************************/ namespace openfpga { // Begin namespace openfpga -int write_xml_module_name_map(const char* fname, const ModuleNameMap& module_name_map); +int write_xml_module_name_map(const char* fname, + const ModuleNameMap& module_name_map); } // End of namespace openfpga diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 0fdb26674..d1b9c1e96 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -20,9 +20,9 @@ #include "read_xml_io_name_map.h" #include "read_xml_module_name_map.h" #include "read_xml_tile_config.h" +#include "rename_modules.h" #include "vtr_log.h" #include "vtr_time.h" -#include "rename_modules.h" /* begin namespace openfpga */ namespace openfpga { @@ -105,7 +105,8 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, CommandOptionId opt_load_fabric_key = cmd.option("load_fabric_key"); CommandOptionId opt_group_tile = cmd.option("group_tile"); CommandOptionId opt_group_config_block = cmd.option("group_config_block"); - CommandOptionId opt_name_module_using_index = cmd.option("name_module_using_index"); + CommandOptionId opt_name_module_using_index = + cmd.option("name_module_using_index"); CommandOptionId opt_verbose = cmd.option("verbose"); /* Report conflicts with options: @@ -176,10 +177,9 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, curr_status = build_device_module_graph( openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_decoder_lib(), openfpga_ctx.mutable_blwl_shift_register_banks(), - openfpga_ctx.mutable_fabric_tile(), - openfpga_ctx.mutable_module_name_map(), - const_cast(openfpga_ctx), - g_vpr_ctx.device(), cmd_context.option_enable(cmd, opt_frame_view), + openfpga_ctx.mutable_fabric_tile(), openfpga_ctx.mutable_module_name_map(), + const_cast(openfpga_ctx), g_vpr_ctx.device(), + cmd_context.option_enable(cmd, opt_frame_view), cmd_context.option_enable(cmd, opt_compress_routing), cmd_context.option_enable(cmd, opt_duplicate_grid_pin), predefined_fabric_key, tile_config, @@ -360,12 +360,16 @@ int rename_modules_template(T& openfpga_ctx, const Command& cmd, std::string file_name = cmd_context.option_value(cmd, opt_file); - if (CMD_EXEC_SUCCESS != read_xml_module_name_map(file_name.c_str(), openfpga_ctx.mutable_module_name_map())) { + if (CMD_EXEC_SUCCESS != + read_xml_module_name_map(file_name.c_str(), + openfpga_ctx.mutable_module_name_map())) { return CMD_EXEC_FATAL_ERROR; } /* Write hierarchy to a file */ - return rename_fabric_modules(openfpga_ctx.mutable_module_graph(), openfpga_ctx.module_name_map(), cmd_context.option_enable(cmd, opt_verbose)); + return rename_fabric_modules(openfpga_ctx.mutable_module_graph(), + openfpga_ctx.module_name_map(), + cmd_context.option_enable(cmd, opt_verbose)); } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index b67b2a572..a334b183e 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -13,9 +13,9 @@ #include "fabric_tile.h" #include "io_location_map.h" #include "io_name_map.h" -#include "module_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "openfpga_arch.h" @@ -108,7 +108,9 @@ class OpenfpgaContext : public Context { return io_location_map_; } const openfpga::IoNameMap& io_name_map() const { return io_name_map_; } - const openfpga::ModuleNameMap& module_name_map() const { return module_name_map_; } + const openfpga::ModuleNameMap& module_name_map() const { + return module_name_map_; + } const openfpga::FabricTile& fabric_tile() const { return fabric_tile_; } const openfpga::FabricGlobalPortInfo& fabric_global_port_info() const { return fabric_global_port_info_; @@ -169,7 +171,9 @@ class OpenfpgaContext : public Context { return io_location_map_; } openfpga::IoNameMap& mutable_io_name_map() { return io_name_map_; } - openfpga::ModuleNameMap& mutable_module_name_map() { return module_name_map_; } + openfpga::ModuleNameMap& mutable_module_name_map() { + return module_name_map_; + } openfpga::FabricTile& mutable_fabric_tile() { return fabric_tile_; } openfpga::FabricGlobalPortInfo& mutable_fabric_global_port_info() { return fabric_global_port_info_; diff --git a/openfpga/src/base/openfpga_naming.cpp b/openfpga/src/base/openfpga_naming.cpp index 81b057a09..b80c3ba36 100644 --- a/openfpga/src/base/openfpga_naming.cpp +++ b/openfpga/src/base/openfpga_naming.cpp @@ -506,10 +506,8 @@ std::string generate_switch_block_module_name( /********************************************************************* * Generate the module name for a switch block with a given index *********************************************************************/ -std::string generate_switch_block_module_name_using_index( - const size_t& index) { - return std::string("sb_" + std::to_string(index) + - std::string("_")); +std::string generate_switch_block_module_name_using_index(const size_t& index) { + return std::string("sb_" + std::to_string(index) + std::string("_")); } /********************************************************************* @@ -594,8 +592,7 @@ std::string generate_connection_block_module_name_using_index( exit(1); } - return std::string(prefix + std::to_string(index) + - std::string("_")); + return std::string(prefix + std::to_string(index) + std::string("_")); } /********************************************************************* diff --git a/openfpga/src/base/openfpga_naming.h b/openfpga/src/base/openfpga_naming.h index b415231c2..378a2836a 100644 --- a/openfpga/src/base/openfpga_naming.h +++ b/openfpga/src/base/openfpga_naming.h @@ -108,8 +108,7 @@ std::string generate_routing_track_middle_output_port_name( std::string generate_switch_block_module_name( const vtr::Point& coordinate); -std::string generate_switch_block_module_name_using_index( - const size_t& index); +std::string generate_switch_block_module_name_using_index(const size_t& index); std::string generate_connection_block_module_name( const t_rr_type& cb_type, const vtr::Point& coordinate); diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index 0a6938fb8..fb34c925f 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -397,7 +397,8 @@ ShellCommandId add_build_fabric_command_template( /* Add an option '--name_module_using_index' */ shell_cmd.add_option("name_module_using_index", false, - "Use index to name modules, such as cbx_0_, rather than coordinates, such as cbx_1__0_"); + "Use index to name modules, such as cbx_0_, rather than " + "coordinates, such as cbx_1__0_"); /* Add an option '--load_fabric_key' */ CommandOptionId opt_load_fkey = shell_cmd.add_option( @@ -801,8 +802,8 @@ ShellCommandId add_rename_modules_command_template( const std::vector& dependent_cmds, const bool& hidden) { Command shell_cmd("rename_modules"); /* Add an option '--file' in short '-f'*/ - CommandOptionId opt_file = - shell_cmd.add_option("file", true, "file path to the XML file that contains renaming rules"); + CommandOptionId opt_file = shell_cmd.add_option( + "file", true, "file path to the XML file that contains renaming rules"); shell_cmd.set_option_short_name(opt_file, "f"); shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); @@ -812,8 +813,7 @@ ShellCommandId add_rename_modules_command_template( ShellCommandId shell_cmd_id = shell.add_command( shell_cmd, "Rename modules with a set of given rules", hidden); shell.set_command_class(shell_cmd_id, cmd_class_id); - shell.set_command_execute_function(shell_cmd_id, - rename_modules_template); + shell.set_command_execute_function(shell_cmd_id, rename_modules_template); /* Add command dependency to the Shell */ shell.set_command_dependency(shell_cmd_id, dependent_cmds); @@ -1048,10 +1048,8 @@ void add_setup_command_templates(openfpga::Shell& shell, * 'build_fabric' */ std::vector cmd_dependency_rename_modules; cmd_dependency_rename_modules.push_back(build_fabric_cmd_id); - add_rename_modules_command_template( - shell, openfpga_setup_cmd_class, cmd_dependency_rename_modules, - hidden); - + add_rename_modules_command_template(shell, openfpga_setup_cmd_class, + cmd_dependency_rename_modules, hidden); } } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index e759dba03..45c53ac92 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -35,14 +35,12 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, - ModuleNameMap& module_name_map, - const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, - const bool& frame_view, const bool& compress_routing, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const TileConfig& tile_config, const bool& group_config_block, - const bool& name_module_using_index, - const bool& generate_random_fabric_key, - const bool& verbose) { + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, + const DeviceContext& vpr_device_ctx, const bool& frame_view, + const bool& compress_routing, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const TileConfig& tile_config, + const bool& group_config_block, const bool& name_module_using_index, + const bool& generate_random_fabric_key, const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build fabric module graph"); int status = CMD_EXEC_SUCCESS; @@ -156,18 +154,20 @@ int build_device_module_graph( openfpga_ctx.arch().circuit_lib); /* Collect module names and initialize module name mapping */ - status = init_fabric_module_name_map(module_name_map, module_manager, verbose); + status = + init_fabric_module_name_map(module_name_map, module_manager, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } if (name_module_using_index) { /* Update module name data */ - status = update_module_map_name_with_indexing_names(module_name_map, openfpga_ctx.device_rr_gsb(), fabric_tile, verbose); + status = update_module_map_name_with_indexing_names( + module_name_map, openfpga_ctx.device_rr_gsb(), fabric_tile, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } /* Apply module naming */ - status = rename_fabric_modules(module_manager, module_name_map, verbose); + status = rename_fabric_modules(module_manager, module_name_map, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga/src/fabric/build_device_module.h b/openfpga/src/fabric/build_device_module.h index 98db557bd..7221d202c 100644 --- a/openfpga/src/fabric/build_device_module.h +++ b/openfpga/src/fabric/build_device_module.h @@ -22,12 +22,11 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, - ModuleNameMap& module_name_map, - const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, - const bool& frame_view, const bool& compress_routing, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const TileConfig& tile_config, const bool& group_config_block, - const bool& name_module_using_index, + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, + const DeviceContext& vpr_device_ctx, const bool& frame_view, + const bool& compress_routing, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const TileConfig& tile_config, + const bool& group_config_block, const bool& name_module_using_index, const bool& generate_random_fabric_key, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/rename_modules.cpp b/openfpga/src/fabric/rename_modules.cpp index 53f9bbdcb..c1c98e7ce 100644 --- a/openfpga/src/fabric/rename_modules.cpp +++ b/openfpga/src/fabric/rename_modules.cpp @@ -1,26 +1,29 @@ /* Headers from vtrutil library */ +#include "rename_modules.h" + +#include "command_exit_codes.h" +#include "openfpga_naming.h" #include "vtr_assert.h" #include "vtr_log.h" #include "vtr_time.h" -#include "command_exit_codes.h" -#include "openfpga_naming.h" -#include "rename_modules.h" - /* begin namespace openfpga */ namespace openfpga { -/** @brief Initialize a module name map with the existing module names from a module manager. In this case, all the built-in names are the same as customized names */ -int init_fabric_module_name_map( - ModuleNameMap& module_name_map, - const ModuleManager& module_manager, - const bool& verbose) { +/** @brief Initialize a module name map with the existing module names from a + * module manager. In this case, all the built-in names are the same as + * customized names */ +int init_fabric_module_name_map(ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; /* the module name map should be empty! */ module_name_map.clear(); size_t cnt = 0; for (ModuleId curr_module : module_manager.modules()) { - status = module_name_map.set_tag_to_name_pair(module_manager.module_name(curr_module), module_manager.module_name(curr_module)); + status = module_name_map.set_tag_to_name_pair( + module_manager.module_name(curr_module), + module_manager.module_name(curr_module)); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_SUCCESS; } @@ -30,33 +33,46 @@ int init_fabric_module_name_map( return CMD_EXEC_SUCCESS; } -int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, const bool& verbose) { +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, + const DeviceRRGSB& device_rr_gsb, + const FabricTile& fabric_tile, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; /* Walk through the device rr gsb on the unique routing modules */ for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); - vtr::Point gsb_coordinate(unique_mirror.get_sb_x(), unique_mirror.get_sb_y()); - std::string name_using_coord = generate_switch_block_module_name(gsb_coordinate); - std::string name_using_index = generate_switch_block_module_name_using_index(isb); - status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + vtr::Point gsb_coordinate(unique_mirror.get_sb_x(), + unique_mirror.get_sb_y()); + std::string name_using_coord = + generate_switch_block_module_name(gsb_coordinate); + std::string name_using_index = + generate_switch_block_module_name_using_index(isb); + status = + module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_SUCCESS; } - VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); } for (t_rr_type cb_type : {CHANX, CHANY}) { for (size_t icb = 0; icb < device_rr_gsb.get_num_cb_unique_module(cb_type); ++icb) { - const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(cb_type, icb); + const RRGSB& unique_mirror = + device_rr_gsb.get_cb_unique_module(cb_type, icb); vtr::Point gsb_coordinate(unique_mirror.get_cb_x(cb_type), unique_mirror.get_cb_y(cb_type)); - std::string name_using_coord = generate_connection_block_module_name(cb_type, gsb_coordinate); - std::string name_using_index = generate_connection_block_module_name_using_index(cb_type, icb); - status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + std::string name_using_coord = + generate_connection_block_module_name(cb_type, gsb_coordinate); + std::string name_using_index = + generate_connection_block_module_name_using_index(cb_type, icb); + status = module_name_map.set_tag_to_name_pair(name_using_coord, + name_using_index); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_SUCCESS; } - VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); } } /* Walk through the fabric tile on the unique routing modules */ @@ -65,29 +81,35 @@ int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, c vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); std::string name_using_coord = generate_tile_module_name(tile_coord); std::string name_using_index = generate_tile_module_name_using_index(itile); - status = module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + status = + module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_SUCCESS; } - VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", name_using_index.c_str(), name_using_coord.c_str()); + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); } return CMD_EXEC_SUCCESS; } -int rename_fabric_modules(ModuleManager& module_manager, const ModuleNameMap& module_name_map, const bool& verbose) { +int rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; size_t cnt = 0; for (ModuleId curr_module : module_manager.modules()) { - std::string new_name = module_name_map.name(module_manager.module_name(curr_module)); + std::string new_name = + module_name_map.name(module_manager.module_name(curr_module)); if (new_name != module_manager.module_name(curr_module)) { - VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", module_manager.module_name(curr_module).c_str(), new_name.c_str()); + VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", + module_manager.module_name(curr_module).c_str(), + new_name.c_str()); module_manager.set_module_name(curr_module, new_name); } cnt++; } VTR_LOG("Renamed %lu modules\n", cnt); return status; -} - +} } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/rename_modules.h b/openfpga/src/fabric/rename_modules.h index deef21b41..2dc029b0f 100644 --- a/openfpga/src/fabric/rename_modules.h +++ b/openfpga/src/fabric/rename_modules.h @@ -4,10 +4,10 @@ /******************************************************************** * Include header files that are required by function declaration *******************************************************************/ -#include "fabric_tile.h" #include "device_rr_gsb.h" -#include "module_name_map.h" +#include "fabric_tile.h" #include "module_manager.h" +#include "module_name_map.h" /******************************************************************** * Function declaration @@ -16,14 +16,18 @@ /* begin namespace openfpga */ namespace openfpga { -int init_fabric_module_name_map( - ModuleNameMap& module_name_map, - const ModuleManager& module_manager, - const bool& verbose); +int init_fabric_module_name_map(ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose); -int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, const bool& verbose); +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, + const DeviceRRGSB& device_rr_gsb, + const FabricTile& fabric_tile, + const bool& verbose); -int rename_fabric_modules(ModuleManager& module_manager, const ModuleNameMap& module_name_map, const bool& verbose); +int rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose); } /* end namespace openfpga */ From 559fa45d89c3d1fb611f542dd09811eb2d115a0a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 17:55:52 -0700 Subject: [PATCH 014/174] [test] add a new test to validate module renaming using index --- ...ame_full_testbench_example_script.openfpga | 74 +++++++++++++++++++ .../regression_test_scripts/basic_reg_test.sh | 3 + .../using_index/config/task.conf | 39 ++++++++++ .../using_index/config/tile_config.xml | 1 + 4 files changed, 117 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga create mode 100644 openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf create mode 100644 openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml diff --git a/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga new file mode 100644 index 000000000..18a919cd2 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga @@ -0,0 +1,74 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --clock_modeling ideal + +# 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 --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 --group_config_block ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} ${OPENFPGA_FABRIC_MODULE_NAME_OPTIONS} #--verbose +# Add a fpga core between fpga top and the underlying modules +${OPENFPGA_ADD_FPGA_CORE_MODULE} + +# 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 + +# Write the SDC files for PnR backend +# - Turn on every options here +# FIXME: Not supported yet. +#write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +#write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +#write_analysis_sdc --file ./SDC_analysis + +# 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 749765a33..93ce47b1d 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -202,6 +202,9 @@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile $@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape $@ run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile $@ +echo -e "Module naming"; +run-task basic_tests/module_naming/using_index $@ + 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 $@ diff --git a/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf new file mode 100644 index 000000000..8781d4fc5 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf @@ -0,0 +1,39 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/module_rename_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_add_fpga_core_module= +openfpga_vpr_device=auto +openfpga_vpr_route_chan_width=20 +openfpga_fabric_module_name_options=--name_module_using_index + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_TileOrgzTl_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = or2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml @@ -0,0 +1 @@ + From d61d88f12e01188b7b99db3e6b9932bf7760b384 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 18:13:22 -0700 Subject: [PATCH 015/174] [core] fixed some bugs in verilog writer due to renaming --- openfpga/src/fpga_verilog/verilog_api.cpp | 7 +++--- openfpga/src/fpga_verilog/verilog_api.h | 2 ++ openfpga/src/fpga_verilog/verilog_routing.cpp | 23 +++++++++++-------- openfpga/src/fpga_verilog/verilog_routing.h | 3 +++ openfpga/src/fpga_verilog/verilog_tile.cpp | 6 +++-- openfpga/src/fpga_verilog/verilog_tile.h | 2 ++ 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 1dbf64dc9..42ba377ed 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -61,6 +61,7 @@ int fpga_fabric_verilog( const DecoderLibrary &decoder_lib, const DeviceContext &device_ctx, const VprDeviceAnnotation &device_annotation, const DeviceRRGSB &device_rr_gsb, const FabricTile &fabric_tile, + const ModuleNameMap& module_name_map, const FabricVerilogOption &options) { vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n"); @@ -111,12 +112,12 @@ int fpga_fabric_verilog( /* Generate routing blocks */ if (true == options.compress_routing()) { print_verilog_unique_routing_modules( - netlist_manager, const_cast(module_manager), + netlist_manager, const_cast(module_manager), module_name_map, device_rr_gsb, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); } else { VTR_ASSERT(false == options.compress_routing()); print_verilog_flatten_routing_modules( - netlist_manager, const_cast(module_manager), + netlist_manager, const_cast(module_manager), module_name_map, device_rr_gsb, device_ctx.rr_graph, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); } @@ -130,7 +131,7 @@ int fpga_fabric_verilog( /* Generate tiles */ if (!fabric_tile.empty()) { status_code = print_verilog_tiles( - netlist_manager, const_cast(module_manager), + netlist_manager, const_cast(module_manager), module_name_map, tile_dir_path, fabric_tile, std::string(DEFAULT_TILE_DIR_NAME), options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index bea3ba4d7..28c848be2 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -20,6 +20,7 @@ #include "fabric_verilog_options.h" #include "io_location_map.h" #include "io_name_map.h" +#include "module_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" #include "mux_library.h" @@ -45,6 +46,7 @@ int fpga_fabric_verilog( const DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, + const ModuleNameMap& module_name_map, const FabricVerilogOption& options); int fpga_verilog_full_testbench( diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index 1cf57dabb..4b990d283 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -77,6 +77,7 @@ namespace openfpga { ********************************************************************/ static void print_verilog_routing_connection_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& subckt_dir, const std::string& subckt_dir_name, const RRGSB& rr_gsb, const t_rr_type& cb_type, const FabricVerilogOption& options) { @@ -102,8 +103,8 @@ static void print_verilog_routing_connection_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId cb_module = module_manager.find_module( - generate_connection_block_module_name(cb_type, gsb_coordinate)); + std::string cb_module_name = module_name_map.name(generate_connection_block_module_name(cb_type, gsb_coordinate)); + ModuleId cb_module = module_manager.find_module(cb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Write the verilog module */ @@ -191,6 +192,7 @@ static void print_verilog_routing_connection_box_unique_module( ********************************************************************/ static void print_verilog_routing_switch_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& subckt_dir, const std::string& subckt_dir_name, const RRGSB& rr_gsb, const FabricVerilogOption& options) { /* Create the netlist */ @@ -215,8 +217,9 @@ static void print_verilog_routing_switch_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ + std::string sb_module_name = module_name_map.name(generate_switch_block_module_name(gsb_coordinate)); ModuleId sb_module = module_manager.find_module( - generate_switch_block_module_name(gsb_coordinate)); + sb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Write the verilog module */ @@ -279,6 +282,7 @@ static void print_verilog_flatten_connection_block_modules( *******************************************************************/ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph, const std::string& subckt_dir, @@ -298,17 +302,17 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, continue; } print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, rr_gsb, + netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, rr_gsb, options); } } print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, device_rr_gsb, subckt_dir, subckt_dir_name, + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, subckt_dir_name, CHANX, options); print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, device_rr_gsb, subckt_dir, subckt_dir_name, + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, subckt_dir_name, CHANY, options); } @@ -324,6 +328,7 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, *******************************************************************/ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const std::string& subckt_dir_name, @@ -336,7 +341,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, + netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, unique_mirror, options); } @@ -346,7 +351,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANX, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, + netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, unique_mirror, CHANX, options); } @@ -356,7 +361,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANY, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, + netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, unique_mirror, CHANY, options); } diff --git a/openfpga/src/fpga_verilog/verilog_routing.h b/openfpga/src/fpga_verilog/verilog_routing.h index 2766c1b2a..15baa3ebb 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.h +++ b/openfpga/src/fpga_verilog/verilog_routing.h @@ -8,6 +8,7 @@ #include "device_rr_gsb.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "rr_graph_view.h" @@ -21,6 +22,7 @@ namespace openfpga { void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph, const std::string& subckt_dir, @@ -29,6 +31,7 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const std::string& subckt_dir_name, diff --git a/openfpga/src/fpga_verilog/verilog_tile.cpp b/openfpga/src/fpga_verilog/verilog_tile.cpp index 400695554..e66b9c317 100644 --- a/openfpga/src/fpga_verilog/verilog_tile.cpp +++ b/openfpga/src/fpga_verilog/verilog_tile.cpp @@ -26,13 +26,14 @@ namespace openfpga { *******************************************************************/ static int print_verilog_tile_module_netlist( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, const std::string& subckt_dir_name, const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); - std::string tile_module_name = generate_tile_module_name(tile_coord); + std::string tile_module_name = module_name_map.name(generate_tile_module_name(tile_coord)); ModuleId tile_module = module_manager.find_module(tile_module_name); if (!module_manager.valid_module_id(tile_module)) { return CMD_EXEC_FATAL_ERROR; @@ -89,6 +90,7 @@ static int print_verilog_tile_module_netlist( *******************************************************************/ int print_verilog_tiles(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricTile& fabric_tile, const std::string& subckt_dir_name, @@ -100,7 +102,7 @@ int print_verilog_tiles(NetlistManager& netlist_manager, /* Build a module for each unique tile */ for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) { status_code = print_verilog_tile_module_netlist( - netlist_manager, module_manager, verilog_dir, fabric_tile, fabric_tile_id, + netlist_manager, module_manager, module_name_map, verilog_dir, fabric_tile, fabric_tile_id, subckt_dir_name, options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; diff --git a/openfpga/src/fpga_verilog/verilog_tile.h b/openfpga/src/fpga_verilog/verilog_tile.h index 03dac11ae..6fb6c63ef 100644 --- a/openfpga/src/fpga_verilog/verilog_tile.h +++ b/openfpga/src/fpga_verilog/verilog_tile.h @@ -9,6 +9,7 @@ #include "fabric_tile.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" /******************************************************************** @@ -20,6 +21,7 @@ namespace openfpga { int print_verilog_tiles(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricTile& fabric_tile, const std::string& subckt_dir_name, From 6fc29244381ee3f4db1caeb9a70e0ab77178f919 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 18:16:30 -0700 Subject: [PATCH 016/174] [core] syntax --- openfpga/src/base/openfpga_verilog_template.h | 2 +- openfpga/src/fpga_verilog/verilog_routing.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog_template.h b/openfpga/src/base/openfpga_verilog_template.h index 32cb09ee0..7a8db67ea 100644 --- a/openfpga/src/base/openfpga_verilog_template.h +++ b/openfpga/src/base/openfpga_verilog_template.h @@ -63,7 +63,7 @@ int write_fabric_verilog_template(T& openfpga_ctx, const Command& cmd, openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), openfpga_ctx.decoder_lib(), g_vpr_ctx.device(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(), - openfpga_ctx.fabric_tile(), options); + openfpga_ctx.fabric_tile(), openfpga_ctx.module_name_map(), options); } /******************************************************************** diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index 4b990d283..830b3add1 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -248,6 +248,7 @@ static void print_verilog_routing_switch_box_unique_module( *******************************************************************/ static void print_verilog_flatten_connection_block_modules( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const std::string& subckt_dir_name, const t_rr_type& cb_type, const FabricVerilogOption& options) { @@ -265,7 +266,7 @@ static void print_verilog_flatten_connection_block_modules( continue; } print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, rr_gsb, + netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, rr_gsb, cb_type, options); } } From 058bb1ef51f94846f98eb19bdd0cc89b203547d6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 18:24:38 -0700 Subject: [PATCH 017/174] [core] code format --- openfpga/src/fpga_verilog/verilog_api.cpp | 17 ++--- openfpga/src/fpga_verilog/verilog_api.h | 5 +- openfpga/src/fpga_verilog/verilog_routing.cpp | 70 +++++++++---------- openfpga/src/fpga_verilog/verilog_routing.h | 13 ++-- openfpga/src/fpga_verilog/verilog_tile.cpp | 14 ++-- 5 files changed, 56 insertions(+), 63 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 42ba377ed..70551659a 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -61,8 +61,7 @@ int fpga_fabric_verilog( const DecoderLibrary &decoder_lib, const DeviceContext &device_ctx, const VprDeviceAnnotation &device_annotation, const DeviceRRGSB &device_rr_gsb, const FabricTile &fabric_tile, - const ModuleNameMap& module_name_map, - const FabricVerilogOption &options) { + const ModuleNameMap &module_name_map, const FabricVerilogOption &options) { vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n"); int status_code = CMD_EXEC_SUCCESS; @@ -112,13 +111,14 @@ int fpga_fabric_verilog( /* Generate routing blocks */ if (true == options.compress_routing()) { print_verilog_unique_routing_modules( - netlist_manager, const_cast(module_manager), module_name_map, - device_rr_gsb, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); + netlist_manager, const_cast(module_manager), + module_name_map, device_rr_gsb, rr_dir_path, + std::string(DEFAULT_RR_DIR_NAME), options); } else { VTR_ASSERT(false == options.compress_routing()); print_verilog_flatten_routing_modules( - netlist_manager, const_cast(module_manager), module_name_map, - device_rr_gsb, device_ctx.rr_graph, rr_dir_path, + netlist_manager, const_cast(module_manager), + module_name_map, device_rr_gsb, device_ctx.rr_graph, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); } @@ -131,8 +131,9 @@ int fpga_fabric_verilog( /* Generate tiles */ if (!fabric_tile.empty()) { status_code = print_verilog_tiles( - netlist_manager, const_cast(module_manager), module_name_map, - tile_dir_path, fabric_tile, std::string(DEFAULT_TILE_DIR_NAME), options); + netlist_manager, const_cast(module_manager), + module_name_map, tile_dir_path, fabric_tile, + std::string(DEFAULT_TILE_DIR_NAME), options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index 28c848be2..c1ea1565e 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -20,9 +20,9 @@ #include "fabric_verilog_options.h" #include "io_location_map.h" #include "io_name_map.h" -#include "module_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "pin_constraints.h" @@ -46,8 +46,7 @@ int fpga_fabric_verilog( const DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, - const ModuleNameMap& module_name_map, - const FabricVerilogOption& options); + const ModuleNameMap& module_name_map, const FabricVerilogOption& options); int fpga_verilog_full_testbench( const ModuleManager& module_manager, diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index 830b3add1..820b1ba90 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -77,10 +77,9 @@ namespace openfpga { ********************************************************************/ static void print_verilog_routing_connection_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const RRGSB& rr_gsb, const t_rr_type& cb_type, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, const RRGSB& rr_gsb, + const t_rr_type& cb_type, const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); @@ -103,7 +102,8 @@ static void print_verilog_routing_connection_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - std::string cb_module_name = module_name_map.name(generate_connection_block_module_name(cb_type, gsb_coordinate)); + std::string cb_module_name = module_name_map.name( + generate_connection_block_module_name(cb_type, gsb_coordinate)); ModuleId cb_module = module_manager.find_module(cb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); @@ -192,9 +192,9 @@ static void print_verilog_routing_connection_box_unique_module( ********************************************************************/ static void print_verilog_routing_switch_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const RRGSB& rr_gsb, const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, const RRGSB& rr_gsb, + const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); std::string verilog_fname(generate_routing_block_netlist_name( @@ -217,9 +217,9 @@ static void print_verilog_routing_switch_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - std::string sb_module_name = module_name_map.name(generate_switch_block_module_name(gsb_coordinate)); - ModuleId sb_module = module_manager.find_module( - sb_module_name); + std::string sb_module_name = + module_name_map.name(generate_switch_block_module_name(gsb_coordinate)); + ModuleId sb_module = module_manager.find_module(sb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Write the verilog module */ @@ -248,10 +248,9 @@ static void print_verilog_routing_switch_box_unique_module( *******************************************************************/ static void print_verilog_flatten_connection_block_modules( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const std::string& subckt_dir_name, const t_rr_type& cb_type, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const std::string& subckt_dir, const std::string& subckt_dir_name, + const t_rr_type& cb_type, const FabricVerilogOption& options) { /* Build unique X-direction connection block modules */ vtr::Point cb_range = device_rr_gsb.get_gsb_range(); @@ -266,8 +265,8 @@ static void print_verilog_flatten_connection_block_modules( continue; } print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, rr_gsb, - cb_type, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, rr_gsb, cb_type, options); } } } @@ -281,14 +280,11 @@ static void print_verilog_flatten_connection_block_modules( * 1. Connection blocks * 2. Switch blocks *******************************************************************/ -void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, - const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const DeviceRRGSB& device_rr_gsb, - const RRGraphView& rr_graph, - const std::string& subckt_dir, - const std::string& subckt_dir_name, - const FabricVerilogOption& options) { +void print_verilog_flatten_routing_modules( + NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const RRGraphView& rr_graph, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options) { /* Create a vector to contain all the Verilog netlist names that have been * generated in this function */ std::vector netlist_names; @@ -303,18 +299,18 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, continue; } print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, rr_gsb, - options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, rr_gsb, options); } } print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, subckt_dir_name, - CHANX, options); + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, + subckt_dir_name, CHANX, options); print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, subckt_dir_name, - CHANY, options); + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, + subckt_dir_name, CHANY, options); } /******************************************************************** @@ -342,8 +338,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, - unique_mirror, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, options); } /* Build unique X-direction connection block modules */ @@ -352,8 +348,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANX, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, - unique_mirror, CHANX, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, CHANX, options); } /* Build unique X-direction connection block modules */ @@ -362,8 +358,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANY, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, module_name_map, subckt_dir, subckt_dir_name, - unique_mirror, CHANY, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, CHANY, options); } VTR_LOG("\n"); diff --git a/openfpga/src/fpga_verilog/verilog_routing.h b/openfpga/src/fpga_verilog/verilog_routing.h index 15baa3ebb..2450db35e 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.h +++ b/openfpga/src/fpga_verilog/verilog_routing.h @@ -20,14 +20,11 @@ /* begin namespace openfpga */ namespace openfpga { -void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, - const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const DeviceRRGSB& device_rr_gsb, - const RRGraphView& rr_graph, - const std::string& subckt_dir, - const std::string& subckt_dir_name, - const FabricVerilogOption& options); +void print_verilog_flatten_routing_modules( + NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const RRGraphView& rr_graph, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options); void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, diff --git a/openfpga/src/fpga_verilog/verilog_tile.cpp b/openfpga/src/fpga_verilog/verilog_tile.cpp index e66b9c317..da32fc58c 100644 --- a/openfpga/src/fpga_verilog/verilog_tile.cpp +++ b/openfpga/src/fpga_verilog/verilog_tile.cpp @@ -26,14 +26,14 @@ namespace openfpga { *******************************************************************/ static int print_verilog_tile_module_netlist( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const ModuleNameMap& module_name_map, - const std::string& verilog_dir, const FabricTile& fabric_tile, - const FabricTileId& fabric_tile_id, const std::string& subckt_dir_name, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& verilog_dir, + const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, + const std::string& subckt_dir_name, const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); - std::string tile_module_name = module_name_map.name(generate_tile_module_name(tile_coord)); + std::string tile_module_name = + module_name_map.name(generate_tile_module_name(tile_coord)); ModuleId tile_module = module_manager.find_module(tile_module_name); if (!module_manager.valid_module_id(tile_module)) { return CMD_EXEC_FATAL_ERROR; @@ -102,8 +102,8 @@ int print_verilog_tiles(NetlistManager& netlist_manager, /* Build a module for each unique tile */ for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) { status_code = print_verilog_tile_module_netlist( - netlist_manager, module_manager, module_name_map, verilog_dir, fabric_tile, fabric_tile_id, - subckt_dir_name, options); + netlist_manager, module_manager, module_name_map, verilog_dir, + fabric_tile, fabric_tile_id, subckt_dir_name, options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } From 200ecad74ad2d1b48c1dae1eca7b6dbdf4b97822 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 18:34:55 -0700 Subject: [PATCH 018/174] [core] fixed bugs in bitgen --- .../src/fpga_bitstream/build_device_bitstream.cpp | 1 + .../src/fpga_bitstream/build_routing_bitstream.cpp | 12 ++++++------ .../src/fpga_bitstream/build_routing_bitstream.h | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp index 69e723f05..10a85baf8 100644 --- a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp @@ -220,6 +220,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, VTR_LOGV(verbose, "Building routing bitstream...\n"); build_routing_bitstream( bitstream_manager, top_block, openfpga_ctx.module_graph(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_tile(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), vpr_ctx.atom(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(), diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp index 0c1d7c31e..c35eebce1 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp @@ -452,7 +452,7 @@ static void build_connection_block_bitstream( static void build_connection_block_bitstreams( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, @@ -501,7 +501,7 @@ static void build_connection_block_bitstreams( cb_module_name = generate_connection_block_module_name(cb_type, unique_cb_coord); } - ModuleId cb_module = module_manager.find_module(cb_module_name); + ModuleId cb_module = module_manager.find_module(module_name_map.name(cb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Bypass empty blocks which have none configurable children */ @@ -596,7 +596,7 @@ static void build_connection_block_bitstreams( void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, @@ -636,7 +636,7 @@ void build_routing_bitstream( unique_sb_coord.set_y(unique_mirror.get_sb_y()); sb_module_name = generate_switch_block_module_name(unique_sb_coord); } - ModuleId sb_module = module_manager.find_module(sb_module_name); + ModuleId sb_module = module_manager.find_module(module_name_map.name(sb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Bypass empty blocks which have none configurable children */ @@ -725,7 +725,7 @@ void build_routing_bitstream( VTR_LOG("Generating bitstream for X-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, fabric_tile, + bitstream_manager, top_configurable_block, module_manager, module_name_map, fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANX, verbose); VTR_LOG("Done\n"); @@ -733,7 +733,7 @@ void build_routing_bitstream( VTR_LOG("Generating bitstream for Y-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, fabric_tile, + bitstream_manager, top_configurable_block, module_manager, module_name_map, fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANY, verbose); VTR_LOG("Done\n"); diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.h b/openfpga/src/fpga_bitstream/build_routing_bitstream.h index b268acd79..97f2553c2 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.h @@ -14,6 +14,7 @@ #include "device_rr_gsb.h" #include "fabric_tile.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "vpr_context.h" #include "vpr_device_annotation.h" @@ -29,7 +30,7 @@ namespace openfpga { void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, From 32df673d728d7935734f8b154ae1128295041909 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 18:35:33 -0700 Subject: [PATCH 019/174] [core] code format --- .../fpga_bitstream/build_device_bitstream.cpp | 5 ++- .../build_routing_bitstream.cpp | 34 +++++++++++-------- .../fpga_bitstream/build_routing_bitstream.h | 7 ++-- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp index 10a85baf8..2a589aebc 100644 --- a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp @@ -220,9 +220,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, VTR_LOGV(verbose, "Building routing bitstream...\n"); build_routing_bitstream( bitstream_manager, top_block, openfpga_ctx.module_graph(), - openfpga_ctx.module_name_map(), - openfpga_ctx.fabric_tile(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.mux_lib(), vpr_ctx.atom(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_tile(), + openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), vpr_ctx.atom(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(), vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(), openfpga_ctx.flow_manager().compress_routing(), verbose); diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp index c35eebce1..2daf50108 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp @@ -452,9 +452,10 @@ static void build_connection_block_bitstream( static void build_connection_block_bitstreams( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const t_rr_type& cb_type, const bool& verbose) { @@ -501,7 +502,8 @@ static void build_connection_block_bitstreams( cb_module_name = generate_connection_block_module_name(cb_type, unique_cb_coord); } - ModuleId cb_module = module_manager.find_module(module_name_map.name(cb_module_name)); + ModuleId cb_module = + module_manager.find_module(module_name_map.name(cb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Bypass empty blocks which have none configurable children */ @@ -596,9 +598,10 @@ static void build_connection_block_bitstreams( void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const bool& verbose) { @@ -636,7 +639,8 @@ void build_routing_bitstream( unique_sb_coord.set_y(unique_mirror.get_sb_y()); sb_module_name = generate_switch_block_module_name(unique_sb_coord); } - ModuleId sb_module = module_manager.find_module(module_name_map.name(sb_module_name)); + ModuleId sb_module = + module_manager.find_module(module_name_map.name(sb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Bypass empty blocks which have none configurable children */ @@ -725,17 +729,19 @@ void build_routing_bitstream( VTR_LOG("Generating bitstream for X-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, module_name_map, fabric_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, - rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANX, verbose); + bitstream_manager, top_configurable_block, module_manager, module_name_map, + fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, + CHANX, verbose); VTR_LOG("Done\n"); VTR_LOG("Generating bitstream for Y-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, module_name_map, fabric_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, - rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANY, verbose); + bitstream_manager, top_configurable_block, module_manager, module_name_map, + fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, + CHANY, verbose); VTR_LOG("Done\n"); } diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.h b/openfpga/src/fpga_bitstream/build_routing_bitstream.h index 97f2553c2..c3af671bd 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.h @@ -30,9 +30,10 @@ namespace openfpga { void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const bool& verbose); From 9e303e9529a80855b2459cdb5f5f138208c2a522 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 19:19:53 -0700 Subject: [PATCH 020/174] [doc] update for renaming modules --- docs/source/manual/file_formats/index.rst | 2 + .../file_formats/module_naming_file.rst | 42 +++++++++++++++++++ .../openfpga_commands/setup_commands.rst | 37 ++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 docs/source/manual/file_formats/module_naming_file.rst diff --git a/docs/source/manual/file_formats/index.rst b/docs/source/manual/file_formats/index.rst index 6a30c2b8b..6ec94c3b9 100644 --- a/docs/source/manual/file_formats/index.rst +++ b/docs/source/manual/file_formats/index.rst @@ -38,4 +38,6 @@ OpenFPGA widely uses XML format for interchangeable files io_naming_file + module_naming_file + tile_config_file diff --git a/docs/source/manual/file_formats/module_naming_file.rst b/docs/source/manual/file_formats/module_naming_file.rst new file mode 100644 index 000000000..17d2646cd --- /dev/null +++ b/docs/source/manual/file_formats/module_naming_file.rst @@ -0,0 +1,42 @@ +.. _file_formats_module_naming_file: + +Fabric Module Naming (.xml) +--------------------------- + +The XML-based description language is used to describe module names for an FPGA fabric, including: + +- the built-in name or default name for each module when building an FPGA fabric +- the customized name which is given by users for each module, in place of the built-in names + +Using the description language, users can customize the name for each module in an FPGA fabric, including testbenches. + +Under the root node ````, naming rules can be defined line-by-line through syntax ````. + +.. code-block:: xml + + + + + +.. note:: If you do not need to rename a module of an FPGA fabric, there is no need to define it explicitly in the naming rules. OpenFPGA can infer it. + +Syntax +`````` + +Detailed syntax are presented as follows. + +.. option:: default="" + + Define the default or built-in name of a module. This follows fixed naming rules of OpenFPGA. Suggest to run command :ref:`openfpga_setup_commands_write_module_naming_rules` to obtain an initial version for your fabric. For example, + + .. code-block:: xml + + default="cbx_1__2_" + +.. option:: given="" + + Define the customized name of a module, this is the final name will appear in netlists. For example, + + .. code-block:: xml + + given="cbx_corner_left_bottom" diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst index 62ec61e21..9ea4b2145 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst @@ -279,6 +279,9 @@ build_fabric Netlist hierarchy on grouped configuable blocks + .. option:: --name_module_using_index + + Use index in module names, e.g., ``cbx_2_``. This is applied to routing modules, as well as tile modules when option ``--group_tile`` is enabled. If disabled, the module name consist of coordinates, e.g., ``cbx_1__2_``. .. option:: --duplicate_grid_pin @@ -435,3 +438,37 @@ pcf2place .. option:: --verbose Show verbose log + +.. _openfpga_setup_commands_rename_modules: + +rename_modules +~~~~~~~~~~~~~~ + + Rename modules of an FPGA fabric with a given set of naming rules + + .. option:: --file + + Specify the file path which contain the naming rules. See details in :ref:`file_formats_module_naming_file`. + + .. option:: --verbose + + Show verbose log + +.. _openfpga_setup_commands_write_module_naming_rules: + +write_module_naming_rules +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Output the naming rules for each module of an FPGA fabric to a given file + + .. option:: --file + + Specify the file path to be written to + + .. option:: --no_time_stamp + + Do not print time stamp in bitstream files + + .. option:: --verbose + + Show verbose log From ccd4c1861bd1a24a7d595035c98f27bf0332f531 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 16 Sep 2023 19:37:06 -0700 Subject: [PATCH 021/174] [core] developing new command to write module naming rules --- .../src/io/write_xml_module_name_map.cpp | 35 +++++++++++++- .../src/io/write_xml_module_name_map.h | 4 +- .../test/xml_io_module_name_map.cpp | 2 +- .../src/base/openfpga_build_fabric_template.h | 27 +++++++++++ .../base/openfpga_setup_command_template.h | 46 +++++++++++++++++++ 5 files changed, 111 insertions(+), 3 deletions(-) diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp index 4b07111da..d8349ba46 100644 --- a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp @@ -5,6 +5,8 @@ /* Headers from system goes first */ #include #include +#include +#include /* Headers from vtr util library */ #include "vtr_assert.h" @@ -23,6 +25,29 @@ namespace openfpga { // Begin namespace openfpga +/******************************************************************** + * This function write header information to a bitstream file + *******************************************************************/ +static void write_xml_module_name_map_file_head(std::fstream& fp, + const bool& include_time_stamp) { + valid_file_stream(fp); + + fp << "" << std::endl; + fp << std::endl; +} + + /******************************************************************** * A writer to output a I/O name mapping to XML format * @@ -64,7 +89,9 @@ static int write_xml_module_name_binding(std::fstream& fp, * Return 2 if fail when creating files *******************************************************************/ int write_xml_module_name_map(const char* fname, - const ModuleNameMap& module_name_map) { + const ModuleNameMap& module_name_map, + const bool& include_time_stamp, + const bool& verbose) { vtr::ScopedStartFinishTimer timer("Write module renaming rules"); /* Create a file handler */ @@ -75,6 +102,8 @@ int write_xml_module_name_map(const char* fname, /* Validate the file stream */ openfpga::check_file_stream(fname, fp); + write_xml_module_name_map_file_head(fp, include_time_stamp); + /* Write the root node */ fp << "<" << XML_MODULE_NAMES_ROOT_NAME; fp << ">" @@ -83,6 +112,7 @@ int write_xml_module_name_map(const char* fname, int err_code = 0; /* Write each port */ + size_t cnt = 0; for (std::string built_in_name : module_name_map.tags()) { /* Write bus */ err_code = @@ -90,6 +120,7 @@ int write_xml_module_name_map(const char* fname, if (0 != err_code) { return err_code; } + cnt++; } /* Finish writing the root node */ @@ -99,6 +130,8 @@ int write_xml_module_name_map(const char* fname, /* Close the file stream */ fp.close(); + VTR_LOGV(verbose, "Outputted %lu naming rules.\n", cnt); + return err_code; } diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.h b/libs/libnamemanager/src/io/write_xml_module_name_map.h index fb9b95953..f0725df16 100644 --- a/libs/libnamemanager/src/io/write_xml_module_name_map.h +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.h @@ -14,7 +14,9 @@ namespace openfpga { // Begin namespace openfpga int write_xml_module_name_map(const char* fname, - const ModuleNameMap& module_name_map); + const ModuleNameMap& module_name_map, + const bool& include_time_stamp, + const bool& verbose); } // End of namespace openfpga diff --git a/libs/libnamemanager/test/xml_io_module_name_map.cpp b/libs/libnamemanager/test/xml_io_module_name_map.cpp index bf8b364a6..6dadd08c1 100644 --- a/libs/libnamemanager/test/xml_io_module_name_map.cpp +++ b/libs/libnamemanager/test/xml_io_module_name_map.cpp @@ -30,7 +30,7 @@ int main(int argc, const char** argv) { * This is optional only used when there is a second argument */ if (3 <= argc) { - status = openfpga::write_xml_module_name_map(argv[2], module_name_map); + status = openfpga::write_xml_module_name_map(argv[2], module_name_map, true, true); VTR_LOG("Write the module name mapping to an XML file: %s.\n", argv[2]); } diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index d1b9c1e96..bd8102045 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -19,6 +19,7 @@ #include "read_xml_fabric_key.h" #include "read_xml_io_name_map.h" #include "read_xml_module_name_map.h" +#include "write_xml_module_name_map.h" #include "read_xml_tile_config.h" #include "rename_modules.h" #include "vtr_log.h" @@ -372,6 +373,32 @@ int rename_modules_template(T& openfpga_ctx, const Command& cmd, cmd_context.option_enable(cmd, opt_verbose)); } +/******************************************************************** + * Write module naming rules to a file + *******************************************************************/ +template +int write_module_naming_rules_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + CommandOptionId opt_file = cmd.option("file"); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + + /* Write hierarchy to a file */ + return write_xml_module_name_map(file_name.c_str(), openfpga_ctx.module_name_map(), + !cmd_context.option_enable(cmd, opt_no_time_stamp), + cmd_context.option_enable(cmd, opt_verbose)); +} + + } /* end namespace openfpga */ #endif diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index fb34c925f..5c73f3eb8 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -821,6 +821,41 @@ ShellCommandId add_rename_modules_command_template( return shell_cmd_id; } +/******************************************************************** + * - Add a command to Shell environment: write_module_naming_rules + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_write_module_naming_rules_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_module_naming_rules"); + /* Add an option '--file' in short '-f'*/ + CommandOptionId opt_file = shell_cmd.add_option( + "file", true, "file path to the XML file that contains renaming rules"); + shell_cmd.set_option_short_name(opt_file, "f"); + shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print time stamp in output files"); + + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "Output the naming rules for each module of an FPGA fabric to a given file", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_const_execute_function(shell_cmd_id, write_module_naming_rules_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + + template void add_setup_command_templates(openfpga::Shell& shell, const bool& hidden = false) { @@ -1050,6 +1085,17 @@ void add_setup_command_templates(openfpga::Shell& shell, cmd_dependency_rename_modules.push_back(build_fabric_cmd_id); add_rename_modules_command_template(shell, openfpga_setup_cmd_class, cmd_dependency_rename_modules, hidden); + + /******************************** + * Command 'write_module_naming_rules' + */ + /* The 'write_module_naming_rules' command should NOT be executed before + * 'build_fabric' */ + std::vector cmd_dependency_write_module_naming_rules; + cmd_dependency_write_module_naming_rules.push_back(build_fabric_cmd_id); + add_write_module_naming_rules_command_template(shell, openfpga_setup_cmd_class, + cmd_dependency_write_module_naming_rules, hidden); + } } /* end namespace openfpga */ From 0ef1e0bde5e2b2df09ea804a13b3c4c929ceec8a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 17 Sep 2023 13:29:12 -0700 Subject: [PATCH 022/174] [test] add a new test to validate renaming rules --- ...reconfig_testbench_example_script.openfpga | 84 +++++++++++++++++++ .../regression_test_scripts/basic_reg_test.sh | 1 + .../renaming_rules/config/module_names.xml | 4 + .../renaming_rules/config/task.conf | 51 +++++++++++ .../renaming_rules/config/tile_config.xml | 1 + 5 files changed, 141 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga create mode 100644 openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml create mode 100644 openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf create mode 100644 openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml diff --git a/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga new file mode 100644 index 000000000..d087939c5 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga @@ -0,0 +1,84 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --clock_modeling ideal ${OPENFPGA_VPR_EXTRA_OPTIONS} + +# 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 --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 + +# Optionally pb pin fixup +${OPENFPGA_PB_PIN_FIXUP_COMMAND} + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing ${OPENFPGA_FABRIC_MODULE_NAME_OPTIONS} ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} #--verbose +# Add a fpga core between fpga top and the underlying modules +${OPENFPGA_ADD_FPGA_CORE_MODULE} +# Output module naming for debugging. Comment it if not required +write_module_naming_rules --file module_names_before_renaming.xml +# Rename modules with a given rule +rename_modules --file ${OPENFPGA_RENAME_MODULE_FILE} +# Output module naming for debugging. Comment it if not required +write_module_naming_rules --file module_names_after_renaming.xml + +# 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_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS} +write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS} + +# Write the SDC files for PnR backend +# - Turn on every options here +# FIXME: Not supported yet. +#write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +#write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +#write_analysis_sdc --file ./SDC_analysis + +# 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 93ce47b1d..010f8ba8c 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -204,6 +204,7 @@ run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_glob echo -e "Module naming"; run-task basic_tests/module_naming/using_index $@ +run-task basic_tests/module_naming/renaming_rules $@ echo -e "Testing global port definition from tiles"; run-task basic_tests/global_tile_ports/global_tile_clock $@ diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml new file mode 100644 index 000000000..3cdf37fcb --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml @@ -0,0 +1,4 @@ + + + + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf new file mode 100644 index 000000000..33318738a --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/module_rename_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_module_name_options= +openfpga_rename_module_file = ${PATH:TASK_DIR}/config/module_names.xml + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml @@ -0,0 +1 @@ + From 72a3c05747f120eade1776ed0f900aaf0691df0b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 17 Sep 2023 13:29:30 -0700 Subject: [PATCH 023/174] [core] code format --- .../src/io/write_xml_module_name_map.cpp | 7 +++---- .../test/xml_io_module_name_map.cpp | 3 ++- .../src/base/openfpga_build_fabric_template.h | 15 ++++++++------- .../src/base/openfpga_setup_command_template.h | 14 ++++++++------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp index d8349ba46..74bdfa9e8 100644 --- a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp @@ -4,9 +4,9 @@ *******************************************************************/ /* Headers from system goes first */ #include -#include #include #include +#include /* Headers from vtr util library */ #include "vtr_assert.h" @@ -28,8 +28,8 @@ namespace openfpga { // Begin namespace openfpga /******************************************************************** * This function write header information to a bitstream file *******************************************************************/ -static void write_xml_module_name_map_file_head(std::fstream& fp, - const bool& include_time_stamp) { +static void write_xml_module_name_map_file_head( + std::fstream& fp, const bool& include_time_stamp) { valid_file_stream(fp); fp << " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 4835a66cd..c7d0b31a8 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -211,6 +211,7 @@ 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_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= From a4f53c64c6bfb62df27753720413cbd54cfb2b10 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 19:28:19 -0700 Subject: [PATCH 074/174] [test] fixed a bug --- ...lobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index c820eb762..a7c1a8bfa 100644 --- 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 @@ -179,7 +179,7 @@ - + From 76f446caece8f43071c7b2ca36b84b5802d830d6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 21:13:11 -0700 Subject: [PATCH 075/174] [core] fixed a bug --- libs/libarchopenfpga/src/tile_annotation.cpp | 2 +- .../build_grid_module_duplicated_pins.cpp | 18 +++++++++++------- .../src/fabric/build_grid_module_utils.cpp | 9 ++++++--- openfpga/src/fabric/build_grid_modules.cpp | 17 ++++++++++------- .../build_top_module_child_tile_instance.cpp | 13 ++++++++----- .../src/fabric/build_top_module_connection.cpp | 14 +++++++++----- 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/libs/libarchopenfpga/src/tile_annotation.cpp b/libs/libarchopenfpga/src/tile_annotation.cpp index fd5bd25d4..2ffacd1d0 100644 --- a/libs/libarchopenfpga/src/tile_annotation.cpp +++ b/libs/libarchopenfpga/src/tile_annotation.cpp @@ -108,7 +108,7 @@ bool TileAnnotation::is_tile_port_to_merge(const std::string& tile_name, if (result == tile_ports_to_merge_.end()) { return false; } - return result->second.end() == + return result->second.end() != std::find(result->second.begin(), result->second.end(), port_name); } diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp index 5a633eb0f..a8b2b8fd4 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp @@ -99,13 +99,6 @@ void add_grid_module_duplicated_pb_type_ports( grid_type_descriptor, ipin); VTR_ASSERT(OPEN != subtile_index && subtile_index < grid_type_descriptor->capacity); - /* 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()) && - subtile_index != 0) { - continue; - } /* Generate the pin name * For each RECEIVER PIN or DRIVER PIN for direct connection, * we do not duplicate in these cases */ @@ -117,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, diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index 8c3dfe5ac..eacab5321 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -90,14 +90,17 @@ void add_grid_module_net_connect_pb_graph_pin( grid_type_descriptor, grid_pin_index); VTR_ASSERT(OPEN != subtile_index && 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())) { - subtile_index = 0; + /* Exception: use top side for these merged ports */ + grid_port_name = generate_grid_port_name( + 0, 0, 0, TOP, pin_info); + VTR_LOG("Use source pin '%s'\n", grid_port_name.c_str()); } - std::string grid_port_name = generate_grid_port_name( - pin_width, pin_height, subtile_index, side, 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_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index 72f0df1a0..ad49cc63c 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -87,17 +87,20 @@ static void add_grid_module_pb_type_ports( int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index( grid_type_descriptor, ipin); - /* 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()) && - subtile_index != 0) { - continue; - } VTR_ASSERT(OPEN != subtile_index && 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, 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 8cf04a36d..9b59019cb 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -1398,17 +1398,20 @@ static int build_top_module_global_net_for_given_tile_module( vpr_device_annotation.physical_tile_pin_port_info(physical_tile, grid_pin_index); VTR_ASSERT(true == grid_pin_info.is_valid()); - if (tile_annotation.is_tile_port_to_merge( - std::string(physical_tile->name), grid_pin_info.get_name()) && - subtile_index != 0) { - continue; - } /* Build nets */ for (const e_side& pin_side : pin_sides) { 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 48b5f1cd6..49eeee658 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -944,17 +944,21 @@ static int build_top_module_global_net_for_given_grid_module( vpr_device_annotation.physical_tile_pin_port_info(physical_tile, grid_pin_index); VTR_ASSERT(true == grid_pin_info.is_valid()); - if (tile_annotation.is_tile_port_to_merge( - std::string(physical_tile->name), grid_pin_info.get_name()) && - subtile_index != 0) { - continue; - } /* Build nets */ for (const e_side& pin_side : pin_sides) { 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, From 1624dc9764e817c1c3f8aebe9f1175d02cc063b1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 21:13:50 -0700 Subject: [PATCH 076/174] [core] code format --- openfpga/src/fabric/build_grid_module_duplicated_pins.cpp | 6 +++--- openfpga/src/fabric/build_grid_module_utils.cpp | 3 +-- .../src/fabric/build_top_module_child_tile_instance.cpp | 3 ++- openfpga/src/fabric/build_top_module_connection.cpp | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp index a8b2b8fd4..cae215259 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp @@ -113,10 +113,10 @@ void add_grid_module_duplicated_pb_type_ports( /* 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())) { + 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); + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); } else { continue; } diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index eacab5321..e1477db10 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -97,8 +97,7 @@ void add_grid_module_net_connect_pb_graph_pin( 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); + grid_port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); VTR_LOG("Use source pin '%s'\n", grid_port_name.c_str()); } ModulePortId grid_module_port_id = 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 9b59019cb..a9ee52917 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -1407,7 +1407,8 @@ static int build_top_module_global_net_for_given_tile_module( 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); + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); } else { continue; } diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index 49eeee658..be9983aae 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -953,7 +953,8 @@ static int build_top_module_global_net_for_given_grid_module( 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); + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); } else { continue; } From 60b8c396dc16afcba739d4c4b5d33ef02042ba02 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 21:25:21 -0700 Subject: [PATCH 077/174] [test] add a new test --- ...ins_full_testbench_example_script.openfpga | 73 +++++++++++++++++++ .../regression_test_scripts/basic_reg_test.sh | 1 + .../config/task.conf | 35 +++++++++ 3 files changed, 109 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga create mode 100644 openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_duplicate_pin/config/task.conf diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga new file mode 100644 index 000000000..54d2706b8 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga @@ -0,0 +1,73 @@ +# 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 --duplicate_grid_pin #--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 + +# Write the SDC files for PnR backend +# - Turn on every options here +write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +write_analysis_sdc --file ./SDC_analysis + +# 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 c7d0b31a8..125825631 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -212,6 +212,7 @@ 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_duplicate_pin $@ 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_duplicate_pin/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_duplicate_pin/config/task.conf new file mode 100644 index 000000000..8b93cb1f5 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_duplicate_pin/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_duplicated_pins_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= From 5aa206e6161409f8b2c60c5a0a0014429521dafd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 22:27:24 -0700 Subject: [PATCH 078/174] [core] fixed some bugs --- openfpga/src/fabric/build_device_module.cpp | 4 +++- .../src/fabric/build_grid_module_utils.cpp | 1 - openfpga/src/fabric/build_tile_modules.cpp | 19 ++++++++++++++++--- openfpga/src/fabric/build_tile_modules.h | 2 ++ .../build_top_module_child_tile_instance.cpp | 2 +- .../fabric/build_top_module_connection.cpp | 2 +- ...ns_full_testbench_example_script.openfpga} | 12 +----------- .../regression_test_scripts/basic_reg_test.sh | 2 +- .../config/task.conf | 4 +++- .../config/tile_config.xml | 1 + 10 files changed, 29 insertions(+), 20 deletions(-) rename openfpga_flow/openfpga_shell_scripts/{global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga => global_tile_clock_options_full_testbench_example_script.openfpga} (87%) rename openfpga_flow/tasks/basic_tests/global_tile_ports/{global_tile_clock_subtile_port_merge_duplicate_pin => global_tile_clock_subtile_port_merge_fabric_tile_group_config}/config/task.conf (86%) create mode 100644 openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 8c343f44f..b17c40c67 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -125,7 +125,9 @@ int build_device_module_graph( 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().tile_annotations, + openfpga_ctx.arch().circuit_lib, + sram_model, openfpga_ctx.arch().config_protocol.type(), name_module_using_index, frame_view, verbose); } diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index e1477db10..3b3f14203 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -98,7 +98,6 @@ void add_grid_module_net_connect_pb_graph_pin( 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); - VTR_LOG("Use source pin '%s'\n", grid_port_name.c_str()); } ModulePortId grid_module_port_id = module_manager.find_module_port(grid_module, grid_port_name); diff --git a/openfpga/src/fabric/build_tile_modules.cpp b/openfpga/src/fabric/build_tile_modules.cpp index 6fafbcf3d..7044346f1 100644 --- a/openfpga/src/fabric/build_tile_modules.cpp +++ b/openfpga/src/fabric/build_tile_modules.cpp @@ -1004,6 +1004,7 @@ 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 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) { @@ -1065,6 +1066,15 @@ 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,6 +1203,7 @@ 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 TileAnnotation& tile_annotation, const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, const std::vector& pb_instances, const std::map>& cb_instances, @@ -1259,7 +1270,7 @@ 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, + 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,6 +1314,7 @@ 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 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, @@ -1451,7 +1463,7 @@ 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, + 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: @@ -1521,6 +1533,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,7 +1549,7 @@ 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, + 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..5f18aec71 100644 --- a/openfpga/src/fabric/build_tile_modules.h +++ b/openfpga/src/fabric/build_tile_modules.h @@ -16,6 +16,7 @@ #include "module_manager.h" #include "rr_graph_view.h" #include "vpr_device_annotation.h" +#include "tile_annotation.h" /******************************************************************** * Function declaration @@ -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 a9ee52917..3c1c86c1c 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -1406,7 +1406,7 @@ static int build_top_module_global_net_for_given_tile_module( 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) { + if (subtile_index == 0) { grid_port_name = generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); } else { diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index be9983aae..98b256fe0 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -952,7 +952,7 @@ static int build_top_module_global_net_for_given_grid_module( 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) { + if (subtile_index == 0) { grid_port_name = generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); } else { diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga similarity index 87% rename from openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga rename to openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga index 54d2706b8..956451380 100644 --- a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_duplicated_pins_full_testbench_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga @@ -23,7 +23,7 @@ lut_truth_table_fixup # Build the module graph # - Enabled compression on routing architecture modules # - Enable pin duplication on grid modules -build_fabric --compress_routing --duplicate_grid_pin #--verbose +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 @@ -56,16 +56,6 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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 -# Write the SDC files for PnR backend -# - Turn on every options here -write_pnr_sdc --file ./SDC - -# Write SDC to disable timing for configure ports -write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc - -# Write the SDC to run timing analysis for a mapped FPGA fabric -write_analysis_sdc --file ./SDC_analysis - # Finish and exit OpenFPGA exit diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 125825631..dd945b427 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -212,7 +212,7 @@ 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_duplicate_pin $@ +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_duplicate_pin/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 similarity index 86% rename from openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_duplicate_pin/config/task.conf rename to openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf index 8b93cb1f5..dc9eacdb7 100644 --- a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_duplicate_pin/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 @@ -16,10 +16,12 @@ 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_duplicated_pins_full_testbench_example_script.openfpga +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 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 @@ + From 262e47a92215db20284a45ab1433fb7781033e05 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 22:34:10 -0700 Subject: [PATCH 079/174] [doc] update --- docs/source/manual/arch_lang/annotate_vpr_arch.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index a23b4f0c6..1871d491e 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -62,12 +62,25 @@ Here is an example: .. code-block:: xml + ... +For subtile port merge support: + +- ``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 + +.. 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. + +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. From c4bce834e4208aa9f2565eed7d22fdbc22d02b4c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Sep 2023 22:34:39 -0700 Subject: [PATCH 080/174] [core] code format --- openfpga/src/fabric/build_device_module.cpp | 16 ++++----- openfpga/src/fabric/build_tile_modules.cpp | 36 ++++++++++----------- openfpga/src/fabric/build_tile_modules.h | 2 +- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index b17c40c67..012e3a529 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -121,15 +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().tile_annotations, - 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_tile_modules.cpp b/openfpga/src/fabric/build_tile_modules.cpp index 7044346f1..caf82f075 100644 --- a/openfpga/src/fabric/build_tile_modules.cpp +++ b/openfpga/src/fabric/build_tile_modules.cpp @@ -1004,10 +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 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) { + 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)); @@ -1066,9 +1066,8 @@ 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 (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 { @@ -1203,9 +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 TileAnnotation& tile_annotation, - 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) { @@ -1270,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, tile_annotation, 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; } @@ -1314,8 +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 TileAnnotation& tile_annotation, - 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) { @@ -1463,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, tile_annotation, 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), @@ -1549,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, tile_annotation, 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 5f18aec71..83f219610 100644 --- a/openfpga/src/fabric/build_tile_modules.h +++ b/openfpga/src/fabric/build_tile_modules.h @@ -15,8 +15,8 @@ #include "fabric_tile.h" #include "module_manager.h" #include "rr_graph_view.h" -#include "vpr_device_annotation.h" #include "tile_annotation.h" +#include "vpr_device_annotation.h" /******************************************************************** * Function declaration From ea91182216b3ea86d650053750090c9dea7e9d43 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 26 Sep 2023 11:40:42 -0700 Subject: [PATCH 081/174] [core] check option conflicts --- openfpga/src/base/openfpga_build_fabric_template.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index d3d94c3e7..c2bb2c08c 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -130,6 +130,15 @@ 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( From a15db832674a1c6813abf171028b70f57691fe5b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 26 Sep 2023 11:41:11 -0700 Subject: [PATCH 082/174] [core] code format --- openfpga/src/base/openfpga_build_fabric_template.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index c2bb2c08c..63e623398 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -132,7 +132,8 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, } /* 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) { + 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()); From b56609d210052f164f723f930f79a1e84abbadb4 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 26 Sep 2023 15:11:26 -0700 Subject: [PATCH 083/174] [doc] more details --- .../manual/arch_lang/annotate_vpr_arch.rst | 14 +++++++++++++- .../arch_lang/figures/subtile_port_merge.png | Bin 0 -> 124778 bytes 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 docs/source/manual/arch_lang/figures/subtile_port_merge.png diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index 1871d491e..a12e49556 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -69,16 +69,28 @@ Here is an example: -For subtile port merge support: +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 + :scale: 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. 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 0000000000000000000000000000000000000000..16f7c6021d10dc662a9150f135ae424ff5ba5636 GIT binary patch literal 124778 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 literal 0 HcmV?d00001 From 517be141ba6d7746e3cea5c4fd0624debcc16f37 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 26 Sep 2023 18:37:49 -0700 Subject: [PATCH 084/174] [doc] format --- docs/source/manual/arch_lang/annotate_vpr_arch.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index a12e49556..9fd1024a7 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -85,7 +85,7 @@ For subtile port merge support (see an illustrative example in :numref:`fig_subt .. _fig_subtile_port_merge: .. figure:: ./figures/subtile_port_merge.png - :scale: 100% + :width: 100% :alt: Difference in netlists with and without subtile port merging Difference in netlists with and without subtile port merging @@ -136,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 From 49057372cf18299966af40a12af159c9ed2df28e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 04:20:43 +0000 Subject: [PATCH 085/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index d4ffd153c..a6da2665b 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1614 +1.2.1635 From 3055df134e89475b2b4cd69a8dfdc2474ba8cd04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 06:46:10 +0000 Subject: [PATCH 086/174] Bump yosys from `934c822` to `076c5ce` Bumps [yosys](https://github.com/YosysHQ/yosys) from `934c822` to `076c5ce`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/934c82254d8abd33ee8827b200ff005868737f74...076c5ceb714bc8f20136a83cc9818b96e6a542b4) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 934c82254..076c5ceb7 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 934c82254d8abd33ee8827b200ff005868737f74 +Subproject commit 076c5ceb714bc8f20136a83cc9818b96e6a542b4 From 56cf22cb124d39b2a59987efa6526edb0ee69713 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:43:57 +0000 Subject: [PATCH 087/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index a6da2665b..5b1005c4c 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1635 +1.2.1639 From e944e9e161395f38b28f3ea30a3c2f10ca68db8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:18:58 +0000 Subject: [PATCH 088/174] Bump yosys from `076c5ce` to `11ffd7d` Bumps [yosys](https://github.com/YosysHQ/yosys) from `076c5ce` to `11ffd7d`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/076c5ceb714bc8f20136a83cc9818b96e6a542b4...11ffd7df40260f782c82b43be190a48ec88214a1) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 076c5ceb7..11ffd7df4 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 076c5ceb714bc8f20136a83cc9818b96e6a542b4 +Subproject commit 11ffd7df40260f782c82b43be190a48ec88214a1 From 9f4505574fabe6b37cdc47517d942bba1d6f037d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 06:02:51 +0000 Subject: [PATCH 089/174] Bump yosys from `11ffd7d` to `8367f06` Bumps [yosys](https://github.com/YosysHQ/yosys) from `11ffd7d` to `8367f06`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/11ffd7df40260f782c82b43be190a48ec88214a1...8367f06188edf750b32bd603552ba9d75995baf5) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 11ffd7df4..8367f0618 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 11ffd7df40260f782c82b43be190a48ec88214a1 +Subproject commit 8367f06188edf750b32bd603552ba9d75995baf5 From 059e08ae73a57f453a9d6f4108ad092e7ad47f31 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 11:00:21 -0700 Subject: [PATCH 090/174] [doc] add missing packages --- docs/requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8e64ef952..732f30a96 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,6 +8,9 @@ Jinja2<3.1 # Support Markdown #recommonmark +# Theme +sphinx-rtd-theme + #Handle references in bibtex format sphinxcontrib-bibtex From 80856f1b70a0fb86102459270f29319c6e1f633c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 13:54:29 -0700 Subject: [PATCH 091/174] [core] adding new options and rewrite options for bitfile writer --- .../openfpga_bitstream_command_template.h | 17 ++ .../src/base/openfpga_bitstream_template.h | 3 + .../bitstream_writer_options.cpp | 172 ++++++++++++++++++ .../fpga_bitstream/bitstream_writer_options.h | 99 ++++++++++ 4 files changed, 291 insertions(+) create mode 100644 openfpga/src/fpga_bitstream/bitstream_writer_options.cpp create mode 100644 openfpga/src/fpga_bitstream/bitstream_writer_options.h diff --git a/openfpga/src/base/openfpga_bitstream_command_template.h b/openfpga/src/base/openfpga_bitstream_command_template.h index bc781dcdc..0ebf5cb2b 100644 --- a/openfpga/src/base/openfpga_bitstream_command_template.h +++ b/openfpga/src/base/openfpga_bitstream_command_template.h @@ -190,6 +190,23 @@ ShellCommandId add_write_fabric_bitstream_command_template( "file format of fabric bitstream [plain_text|xml]. Default: plain_text"); shell_cmd.set_option_require_value(opt_file_format, openfpga::OPT_STRING); + CommandOptionId opt_filter_value = shell_cmd.add_option( + "filter_value", false, + "Specify what values should be written out in the resulting fabric bitstream [0|1|none]. Only applicable to XML file format. Default: none"); + shell_cmd.set_option_require_value(opt_filter_value, openfpga::OPT_STRING); + + shell_cmd.add_option( + "path_only", false, + "Only paths will be written out in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + + shell_cmd.add_option( + "value_only", false, + "Only values will be written out in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + + shell_cmd.add_option( + "trim_path", false, + "Trim the path by a level of 1 in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + /* Add an option '--fast_configuration' */ shell_cmd.add_option("fast_configuration", false, "Reduce the size of bitstream to be downloaded"); diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index 85edafd9c..58750d23c 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -94,6 +94,9 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, CommandOptionId opt_keep_dont_care_bits = cmd.option("keep_dont_care_bits"); CommandOptionId opt_wl_decremental_order = cmd.option("wl_decremental_order"); CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_filter_value = cmd.option("filter_value"); + CommandOptionId opt_path_only = cmd.option("path_only"); + CommandOptionId opt_value_only = cmd.option("value_only"); /* Write fabric bitstream if required */ int status = CMD_EXEC_SUCCESS; diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp new file mode 100644 index 000000000..f789e9884 --- /dev/null +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -0,0 +1,172 @@ +/****************************************************************************** + * Memember functions for data structure BitstreamWriterOption + ******************************************************************************/ +#include "bitstream_writer_options.h" + +#include "vtr_assert.h" +#include "vtr_log.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/************************************************** + * Public Constructors + *************************************************/ +BitstreamWriterOption::BitstreamWriterOption() { + file_type_ = BitstreamWriterOption::e_bitfile_type::NUM_TYPES; + BITFILE_TYPE_STRING_ = {"plain_text", "xml"}; + output_file_.clear(); + time_stamp_ = true; + verbose_output_ = false; + + filter_value_ = ""; + trim_path_ = false; + path_only_ = false; + value_only_ = false; + + fast_config_ = false; + keep_dont_care_bits_ = false; + wl_decremental_order_ = false; +} + +/************************************************** + * Public Accessors + *************************************************/ +BitstreamWriterOption::e_bitfile_type output_file_type() const { + return file_type_; +} + +std::string BitstreamWriterOption::output_file_name() const { + return output_file_; +} + +bool BitstreamWriterOption::time_stamp() const { return time_stamp_; } + +bool BitstreamWriterOption::verbose_output() const { return verbose_output_; } + +bool BitstreamWriterOption:filter_value() const { + return !filter_value_.empty(); +} + +bool BitstreamWriterOption:value_to_skip(const size_t& val) const { + return std::to_string(val) == filter_value_; +} + +bool trim_path() const { return trim_path_; } +bool output_path() const { return path_only_; } +bool output_value() const { return value_only_; } + +bool fast_configuration() const { return fast_config_; } +bool keep_dont_care_bits() const { return keep_dont_care_bits_; } +bool wl_decremental_order() const { return wl_decremental_order_; } + +/****************************************************************************** + * Private Mutators + ******************************************************************************/ +void BitstreamWriterOption::set_output_file_type(const std::string& val) { + file_type_ = str2bitfile_type(val); +} + +void BitstreamWriterOption::set_output_file_name(const std::string& output_file) { + output_file_ = output_file; +} + +void BitstreamWriterOption::set_time_stamp(const bool& enabled) { + time_stamp_ = enabled; +} + +void BitstreamWriterOption::set_verbose_output(const bool& enabled) { + verbose_output_ = enabled; +} + +void BitstreamWriterOption::set_filter_value(const std::string& val) { + filter_value_ = val; +} + +void BitstreamWriterOption::set_trim_path(const bool& enabled) { + trim_path_ = enabled; +} + +void BitstreamWriterOption::set_path_only(const bool& enabled) { + path_only_ = enabled; +} + +void BitstreamWriterOption::set_value_only(const bool& enabled) { + value_only_ = enabled; +} + +void BitstreamWriterOption::set_fast_configuration(const bool& enabled) { + fast_config_ = enabled; +} + +void BitstreamWriterOption::set_keep_dont_care_bits(const bool& enabled) { + keep_dont_care_bits_ = enabled; +} + +void BitstreamWriterOption::set_wl_decremental_order(const bool& enabled) { + wl_decremental_order_ = enabled; +} + +bool BitstreamWriterOption::validate(bool show_err_msg) const { + /* Check file type */ + if (!valid_file_type(file_type_)) { + VTR_LOGV_ERROR(show_err_msg, "Invalid file type!\n"); + return false; + } + if (output_file_.empty()) { + VTR_LOGV_ERROR(show_err_msg, "Empty file name!\n"); + return false; + } + if (file_type_ == BitstreamWriterOption::e_bitfile_type::XML) { + /* All the options in the XML format should be off */ + if (path_only_ && value_only) { + VTR_LOGV_ERROR(show_err_msg, "Both path and value are specifed as only inputs! If specified, please define one of them\n"); + return false; + } + if (!filter_value_.empty() && (filter_value_ != std::to_string(0) || filter_value_ != std::to_string(1))) { + VTR_LOGV_ERROR(show_err_msg, "Invalid value '%s' for filter values. Expect [0|1]!\n", filter_value_); + return false; + } + } + return true; +} + +e_bitfile_type BitstreamWriterOption::str2bitfile_type(const std::string& type_str, const bool& verbose) const { + for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { + if (type_str == std::string(BITFILE_TYPE_STRING_[itype])) { + return static_cast(itype); + } + } + VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", + bitfile_type_all2str().c_str()); + return BitstreamWriterOption::e_bitfile_type::NUM_TYPES; +} + +std::string BitstreamWriterOption::bitfile_type2str(const BitstreamWriterOption::e_bitfile_type& type, + const bool& verbose) const { + if (!valid_file_type(type)) { + VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", + file_type_all2str().c_str()); + return std::string(); + } + return std::string(BITFILE_TYPE_STRING_[size_t(type)]); +} + +std::string BitstreamWriterOption::file_type_all2str() const { + std::string full_types = "["; + for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { + full_types += std::string(BITFILE_TYPE_STRING_[itype]) + std::string("|"); + } + full_types.pop_back(); + full_types += "]"; + return full_types; +} + + +bool BitstreamWriterOption::valid_file_type(const BitstreamWriterOption::e_bitfile_type bitfile_type) const { + return bitfile_type != BitstreamWriterOption::e_bitfile_type::NUM_TYPES; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.h b/openfpga/src/fpga_bitstream/bitstream_writer_options.h new file mode 100644 index 000000000..a9a159093 --- /dev/null +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.h @@ -0,0 +1,99 @@ +#ifndef BITSTREAM_WRITER_OPTIONS_H +#define BITSTREAM_WRITER_OPTIONS_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include + +/* Begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Options for Bitstream Writer + *******************************************************************/ +class BitstreamWriterOption { + public: /* Private data structures */ + /* A type to define the bitstream file format */ + enum class e_bitfile_type { + TEXT, + XML, + NUM_TYPES + }; + public: /* Public constructor */ + /* Set default options */ + BitstreamWriterOption(); + + public: /* Public accessors */ + e_bitfile_type output_file_type() const; + std::string output_file_name() const; + bool time_stamp() const; + bool verbose_output() const; + + /* Check if a filter on value is applied */ + bool filter_value() const; + /* Check if a given value should be skipped */ + bool value_to_skip(const size_t& val) const; + /* Check if path trimming should be applied or not */ + bool trim_path() const; + /* Check if path should be outputted in the resulting file */ + bool output_path() const; + /* Check if value should be outputted in the resulting file */ + bool output_value() const; + + bool fast_configuration() const; + bool keep_dont_care_bits() const; + bool wl_decremental_order() const; + + public: /* Public mutators */ + void set_output_file_type(const std::string& val); + void set_output_file_name(const std::string& output_file); + void set_time_stamp(const bool& enabled); + void set_verbose_output(const bool& enabled); + + void set_filter_value(const std::string& val); + + public: /* Public validator */ + bool validate(bool show_err_msg = false) const; + + public: /* Internal utility */ + /** @brief Parse the file type from string to valid type. Parser + * error can be turned on */ + e_bitfile_type str2bitfile_type(const std::string& type_str, + const bool& verbose = false) const; + + /** @brief Output the string representing file_type */ + std::string bitfile_type2str(const e_bitfile_type& type, + const bool& verbose = false) const; + /** @brief Validate the file_type */ + bool valid_file_type(const e_bitfile_type& bitfile_type) const; + + /* Generate a string include all the valid style + * Useful for printing debugging messages */ + std::string file_type_all2str() const; + + private: /* Internal Data */ + /* Universal options */ + e_bitfile_type file_type_; + std::string output_file_; + bool time_stamp_; + bool verbose_output_; + + /* XML-specific options */ + std::string filter_value_; + bool trim_path_; + bool path_only_; + bool value_only_; + + /* Plain-text options */ + bool fast_config_; + bool keep_dont_care_bits_; + bool wl_decremental_order_; + + /* Constants */ + std::array BITFILE_TYPE_STRING_; +}; + +} /* End namespace openfpga*/ + +#endif From 108bbad8d460be1756062db36bed9cfd85ffb9f7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 14:07:44 -0700 Subject: [PATCH 092/174] [core] syntax --- .../bitstream_writer_options.cpp | 30 +++++++++---------- .../fpga_bitstream/bitstream_writer_options.h | 9 +++++- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp index f789e9884..087adee54 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -32,7 +32,7 @@ BitstreamWriterOption::BitstreamWriterOption() { /************************************************** * Public Accessors *************************************************/ -BitstreamWriterOption::e_bitfile_type output_file_type() const { +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::output_file_type() const { return file_type_; } @@ -44,21 +44,21 @@ bool BitstreamWriterOption::time_stamp() const { return time_stamp_; } bool BitstreamWriterOption::verbose_output() const { return verbose_output_; } -bool BitstreamWriterOption:filter_value() const { +bool BitstreamWriterOption::filter_value() const { return !filter_value_.empty(); } -bool BitstreamWriterOption:value_to_skip(const size_t& val) const { +bool BitstreamWriterOption::value_to_skip(const size_t& val) const { return std::to_string(val) == filter_value_; } -bool trim_path() const { return trim_path_; } -bool output_path() const { return path_only_; } -bool output_value() const { return value_only_; } +bool BitstreamWriterOption::trim_path() const { return trim_path_; } +bool BitstreamWriterOption::output_path() const { return path_only_; } +bool BitstreamWriterOption::output_value() const { return value_only_; } -bool fast_configuration() const { return fast_config_; } -bool keep_dont_care_bits() const { return keep_dont_care_bits_; } -bool wl_decremental_order() const { return wl_decremental_order_; } +bool BitstreamWriterOption::fast_configuration() const { return fast_config_; } +bool BitstreamWriterOption::keep_dont_care_bits() const { return keep_dont_care_bits_; } +bool BitstreamWriterOption::wl_decremental_order() const { return wl_decremental_order_; } /****************************************************************************** * Private Mutators @@ -119,7 +119,7 @@ bool BitstreamWriterOption::validate(bool show_err_msg) const { } if (file_type_ == BitstreamWriterOption::e_bitfile_type::XML) { /* All the options in the XML format should be off */ - if (path_only_ && value_only) { + if (path_only_ && value_only_) { VTR_LOGV_ERROR(show_err_msg, "Both path and value are specifed as only inputs! If specified, please define one of them\n"); return false; } @@ -131,11 +131,11 @@ bool BitstreamWriterOption::validate(bool show_err_msg) const { return true; } -e_bitfile_type BitstreamWriterOption::str2bitfile_type(const std::string& type_str, const bool& verbose) const { +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::str2bitfile_type(const std::string& type_str, const bool& verbose) const { for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { if (type_str == std::string(BITFILE_TYPE_STRING_[itype])) { - return static_cast(itype); + return static_cast(itype); } } VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", @@ -147,13 +147,13 @@ std::string BitstreamWriterOption::bitfile_type2str(const BitstreamWriterOption: const bool& verbose) const { if (!valid_file_type(type)) { VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", - file_type_all2str().c_str()); + bitfile_type_all2str().c_str()); return std::string(); } return std::string(BITFILE_TYPE_STRING_[size_t(type)]); } -std::string BitstreamWriterOption::file_type_all2str() const { +std::string BitstreamWriterOption::bitfile_type_all2str() const { std::string full_types = "["; for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { @@ -165,7 +165,7 @@ std::string BitstreamWriterOption::file_type_all2str() const { } -bool BitstreamWriterOption::valid_file_type(const BitstreamWriterOption::e_bitfile_type bitfile_type) const { +bool BitstreamWriterOption::valid_file_type(const BitstreamWriterOption::e_bitfile_type& bitfile_type) const { return bitfile_type != BitstreamWriterOption::e_bitfile_type::NUM_TYPES; } diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.h b/openfpga/src/fpga_bitstream/bitstream_writer_options.h index a9a159093..4a5dd39b8 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.h +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.h @@ -5,6 +5,7 @@ * Include header files required by the data structure definition *******************************************************************/ #include +#include /* Begin namespace openfpga */ namespace openfpga { @@ -50,6 +51,12 @@ class BitstreamWriterOption { void set_output_file_name(const std::string& output_file); void set_time_stamp(const bool& enabled); void set_verbose_output(const bool& enabled); + void set_trim_path(const bool& enabled); + void set_path_only(const bool& enabled); + void set_value_only(const bool& enabled); + void set_fast_configuration(const bool& enabled); + void set_keep_dont_care_bits(const bool& enabled); + void set_wl_decremental_order(const bool& enabled); void set_filter_value(const std::string& val); @@ -70,7 +77,7 @@ class BitstreamWriterOption { /* Generate a string include all the valid style * Useful for printing debugging messages */ - std::string file_type_all2str() const; + std::string bitfile_type_all2str() const; private: /* Internal Data */ /* Universal options */ From f30663f7084b56f5b5ec7bdb1c79adb5ba4e62f5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 14:08:09 -0700 Subject: [PATCH 093/174] [core] code format --- .../openfpga_bitstream_command_template.h | 12 ++++-- .../bitstream_writer_options.cpp | 43 +++++++++++++------ .../fpga_bitstream/bitstream_writer_options.h | 16 +++---- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/openfpga/src/base/openfpga_bitstream_command_template.h b/openfpga/src/base/openfpga_bitstream_command_template.h index 0ebf5cb2b..f80176514 100644 --- a/openfpga/src/base/openfpga_bitstream_command_template.h +++ b/openfpga/src/base/openfpga_bitstream_command_template.h @@ -192,20 +192,24 @@ ShellCommandId add_write_fabric_bitstream_command_template( CommandOptionId opt_filter_value = shell_cmd.add_option( "filter_value", false, - "Specify what values should be written out in the resulting fabric bitstream [0|1|none]. Only applicable to XML file format. Default: none"); + "Specify what values should be written out in the resulting fabric " + "bitstream [0|1|none]. Only applicable to XML file format. Default: none"); shell_cmd.set_option_require_value(opt_filter_value, openfpga::OPT_STRING); shell_cmd.add_option( "path_only", false, - "Only paths will be written out in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + "Only paths will be written out in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); shell_cmd.add_option( "value_only", false, - "Only values will be written out in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + "Only values will be written out in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); shell_cmd.add_option( "trim_path", false, - "Trim the path by a level of 1 in the resulting fabric bitstream. Only applicable to XML file format. Default: off"); + "Trim the path by a level of 1 in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); /* Add an option '--fast_configuration' */ shell_cmd.add_option("fast_configuration", false, diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp index 087adee54..62fcac30e 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -32,7 +32,8 @@ BitstreamWriterOption::BitstreamWriterOption() { /************************************************** * Public Accessors *************************************************/ -BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::output_file_type() const { +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::output_file_type() + const { return file_type_; } @@ -57,8 +58,12 @@ bool BitstreamWriterOption::output_path() const { return path_only_; } bool BitstreamWriterOption::output_value() const { return value_only_; } bool BitstreamWriterOption::fast_configuration() const { return fast_config_; } -bool BitstreamWriterOption::keep_dont_care_bits() const { return keep_dont_care_bits_; } -bool BitstreamWriterOption::wl_decremental_order() const { return wl_decremental_order_; } +bool BitstreamWriterOption::keep_dont_care_bits() const { + return keep_dont_care_bits_; +} +bool BitstreamWriterOption::wl_decremental_order() const { + return wl_decremental_order_; +} /****************************************************************************** * Private Mutators @@ -67,7 +72,8 @@ void BitstreamWriterOption::set_output_file_type(const std::string& val) { file_type_ = str2bitfile_type(val); } -void BitstreamWriterOption::set_output_file_name(const std::string& output_file) { +void BitstreamWriterOption::set_output_file_name( + const std::string& output_file) { output_file_ = output_file; } @@ -120,20 +126,27 @@ bool BitstreamWriterOption::validate(bool show_err_msg) const { if (file_type_ == BitstreamWriterOption::e_bitfile_type::XML) { /* All the options in the XML format should be off */ if (path_only_ && value_only_) { - VTR_LOGV_ERROR(show_err_msg, "Both path and value are specifed as only inputs! If specified, please define one of them\n"); + VTR_LOGV_ERROR(show_err_msg, + "Both path and value are specifed as only inputs! If " + "specified, please define one of them\n"); return false; } - if (!filter_value_.empty() && (filter_value_ != std::to_string(0) || filter_value_ != std::to_string(1))) { - VTR_LOGV_ERROR(show_err_msg, "Invalid value '%s' for filter values. Expect [0|1]!\n", filter_value_); + if (!filter_value_.empty() && (filter_value_ != std::to_string(0) || + filter_value_ != std::to_string(1))) { + VTR_LOGV_ERROR(show_err_msg, + "Invalid value '%s' for filter values. Expect [0|1]!\n", + filter_value_); return false; } } return true; } -BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::str2bitfile_type(const std::string& type_str, const bool& verbose) const { +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::str2bitfile_type( + const std::string& type_str, const bool& verbose) const { for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); - itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); + ++itype) { if (type_str == std::string(BITFILE_TYPE_STRING_[itype])) { return static_cast(itype); } @@ -143,8 +156,9 @@ BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::str2bitfile_type(co return BitstreamWriterOption::e_bitfile_type::NUM_TYPES; } -std::string BitstreamWriterOption::bitfile_type2str(const BitstreamWriterOption::e_bitfile_type& type, - const bool& verbose) const { +std::string BitstreamWriterOption::bitfile_type2str( + const BitstreamWriterOption::e_bitfile_type& type, + const bool& verbose) const { if (!valid_file_type(type)) { VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", bitfile_type_all2str().c_str()); @@ -156,7 +170,8 @@ std::string BitstreamWriterOption::bitfile_type2str(const BitstreamWriterOption: std::string BitstreamWriterOption::bitfile_type_all2str() const { std::string full_types = "["; for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); - itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); ++itype) { + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); + ++itype) { full_types += std::string(BITFILE_TYPE_STRING_[itype]) + std::string("|"); } full_types.pop_back(); @@ -164,8 +179,8 @@ std::string BitstreamWriterOption::bitfile_type_all2str() const { return full_types; } - -bool BitstreamWriterOption::valid_file_type(const BitstreamWriterOption::e_bitfile_type& bitfile_type) const { +bool BitstreamWriterOption::valid_file_type( + const BitstreamWriterOption::e_bitfile_type& bitfile_type) const { return bitfile_type != BitstreamWriterOption::e_bitfile_type::NUM_TYPES; } diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.h b/openfpga/src/fpga_bitstream/bitstream_writer_options.h index 4a5dd39b8..9a23aefbd 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.h +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.h @@ -4,8 +4,8 @@ /******************************************************************** * Include header files required by the data structure definition *******************************************************************/ -#include #include +#include /* Begin namespace openfpga */ namespace openfpga { @@ -16,11 +16,8 @@ namespace openfpga { class BitstreamWriterOption { public: /* Private data structures */ /* A type to define the bitstream file format */ - enum class e_bitfile_type { - TEXT, - XML, - NUM_TYPES - }; + enum class e_bitfile_type { TEXT, XML, NUM_TYPES }; + public: /* Public constructor */ /* Set default options */ BitstreamWriterOption(); @@ -67,11 +64,11 @@ class BitstreamWriterOption { /** @brief Parse the file type from string to valid type. Parser * error can be turned on */ e_bitfile_type str2bitfile_type(const std::string& type_str, - const bool& verbose = false) const; + const bool& verbose = false) const; /** @brief Output the string representing file_type */ std::string bitfile_type2str(const e_bitfile_type& type, - const bool& verbose = false) const; + const bool& verbose = false) const; /** @brief Validate the file_type */ bool valid_file_type(const e_bitfile_type& bitfile_type) const; @@ -98,7 +95,8 @@ class BitstreamWriterOption { bool wl_decremental_order_; /* Constants */ - std::array BITFILE_TYPE_STRING_; + std::array + BITFILE_TYPE_STRING_; }; } /* End namespace openfpga*/ From 2b04034aa27345bf7aefde65fdefa8d944b71e80 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 7 Oct 2023 00:02:24 +0000 Subject: [PATCH 094/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 5b1005c4c..27a9b20c0 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1639 +1.2.1647 From 1e8bf1ceceefdaf5c5a93339e82658656a5b659e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 17:28:02 -0700 Subject: [PATCH 095/174] [core] deploy options --- .../src/base/openfpga_bitstream_template.h | 36 +++++++++++++------ .../write_text_fabric_bitstream.cpp | 23 ++++++------ .../write_text_fabric_bitstream.h | 7 ++-- .../write_xml_fabric_bitstream.cpp | 10 +++--- .../write_xml_fabric_bitstream.h | 5 +-- 5 files changed, 49 insertions(+), 32 deletions(-) diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index 58750d23c..0de196e7d 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -22,6 +22,7 @@ #include "write_xml_arch_bitstream.h" #include "write_xml_fabric_bitstream.h" #include "write_xml_io_mapping.h" +#include "bitstream_writer_options.h" /* begin namespace openfpga */ namespace openfpga { @@ -97,6 +98,7 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, CommandOptionId opt_filter_value = cmd.option("filter_value"); CommandOptionId opt_path_only = cmd.option("path_only"); CommandOptionId opt_value_only = cmd.option("value_only"); + CommandOptionId opt_trim_path = cmd.option("trim_path"); /* Write fabric bitstream if required */ int status = CMD_EXEC_SUCCESS; @@ -115,26 +117,40 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, file_format = cmd_context.option_value(cmd, opt_file_format); } - if (std::string("xml") == file_format) { + /* Validate options */ + BitstreamWriterOption bitfile_writer_opt; + bitfile_writer_opt.set_output_file_type(file_format); + bitfile_writer_opt.set_output_file_name(cmd_context.option_value(cmd, opt_file)); + bitfile_writer_opt.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); + bitfile_writer_opt.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + bitfile_writer_opt.set_trim_path(cmd_context.option_enable(cmd, opt_trim_path)); + bitfile_writer_opt.set_path_only(cmd_context.option_enable(cmd, opt_path_only)); + bitfile_writer_opt.set_value_only(cmd_context.option_enable(cmd, opt_value_only)); + bitfile_writer_opt.set_fast_configuration(cmd_context.option_enable(cmd, opt_fast_config)); + bitfile_writer_opt.set_keep_dont_care_bits(cmd_context.option_enable(cmd, opt_keep_dont_care_bits)); + bitfile_writer_opt.set_wl_decremental_order(cmd_context.option_enable(cmd, opt_wl_decremental_order)); + if (cmd_context.option_enable(cmd, opt_filter_value)) { + bitfile_writer_opt.set_filter_value(cmd_context.option_value(cmd, opt_filter_value)); + } + if (!bitfile_writer_opt.validate(true)) { + VTR_LOG_ERROR("Conflicts detected in options for bitstream writer!\n"); + return CMD_EXEC_FATAL_ERROR; + } + + if (bitfile_writer_opt.output_file_type() == BitstreamWriterOption::e_bitfile_type::XML) { status = write_fabric_bitstream_to_xml_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), openfpga_ctx.arch().config_protocol, - cmd_context.option_value(cmd, opt_file), - !cmd_context.option_enable(cmd, opt_no_time_stamp), - cmd_context.option_enable(cmd, opt_verbose)); + bitfile_writer_opt); } else { + VTR_ASSERT_SAFE(bitfile_writer_opt.output_file_type() == BitstreamWriterOption::e_bitfile_type::TEXT); /* By default, output in plain text format */ status = write_fabric_bitstream_to_text_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().config_protocol, openfpga_ctx.fabric_global_port_info(), - cmd_context.option_value(cmd, opt_file), - cmd_context.option_enable(cmd, opt_fast_config), - cmd_context.option_enable(cmd, opt_keep_dont_care_bits), - !cmd_context.option_enable(cmd, opt_wl_decremental_order), - !cmd_context.option_enable(cmd, opt_no_time_stamp), - cmd_context.option_enable(cmd, opt_verbose)); + bitfile_writer_opt); } return status; diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp index 4cde144d5..5d958a01e 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp @@ -579,10 +579,10 @@ int write_fabric_bitstream_to_text_file( const FabricBitstream& fabric_bitstream, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const ConfigProtocol& config_protocol, - const FabricGlobalPortInfo& global_ports, const std::string& fname, - const bool& fast_configuration, const bool& keep_dont_care_bits, - const bool& wl_incremental_order, const bool& include_time_stamp, - const bool& verbose) { + const FabricGlobalPortInfo& global_ports, + const BitstreamWriterOption& options) { + VTR_ASSERT(options.output_file_type() == BitstreamWriterOption::e_bitfile_type::TEXT); + std::string fname = options.output_file_name(); /* Ensure that we have a valid file name */ if (true == fname.empty()) { VTR_LOG_ERROR( @@ -603,8 +603,8 @@ int write_fabric_bitstream_to_text_file( check_file_stream(fname.c_str(), fp); bool apply_fast_configuration = - is_fast_configuration_applicable(global_ports) && fast_configuration; - if (fast_configuration && apply_fast_configuration != fast_configuration) { + is_fast_configuration_applicable(global_ports) && options.fast_configuration(); + if (options.fast_configuration() && apply_fast_configuration != options.fast_configuration()) { VTR_LOG_WARN("Disable fast configuration even it is enabled by user\n"); } @@ -616,7 +616,7 @@ int write_fabric_bitstream_to_text_file( } /* Write file head */ - write_fabric_bitstream_text_file_head(fp, include_time_stamp); + write_fabric_bitstream_text_file_head(fp, options.time_stamp()); /* Output fabric bitstream to the file */ int status = 0; @@ -649,19 +649,18 @@ int write_fabric_bitstream_to_text_file( // bitstream status = fast_write_memory_bank_flatten_fabric_bitstream_to_text_file( fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, - keep_dont_care_bits, wl_incremental_order); + options.keep_dont_care_bits(), options.wl_decremental_order()); } else if (BLWL_PROTOCOL_FLATTEN == config_protocol.bl_protocol_type()) { status = write_memory_bank_flatten_fabric_bitstream_to_text_file( fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, - keep_dont_care_bits); + options.keep_dont_care_bits()); } else { VTR_ASSERT(BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type()); status = write_memory_bank_shift_register_fabric_bitstream_to_text_file( fp, apply_fast_configuration, bit_value_to_skip, - - fabric_bitstream, blwl_sr_banks, keep_dont_care_bits); + fabric_bitstream, blwl_sr_banks, options.keep_dont_care_bits()); } break; } @@ -685,7 +684,7 @@ int write_fabric_bitstream_to_text_file( /* Close file handler */ fp.close(); - VTR_LOGV(verbose, "Outputted %lu configuration bits to plain text file: %s\n", + VTR_LOGV(options.verbose_output(), "Outputted %lu configuration bits to plain text file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h index 59f4774de..e8fa34dcd 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h @@ -12,6 +12,7 @@ #include "fabric_bitstream.h" #include "fabric_global_port_info.h" #include "memory_bank_shift_register_banks.h" +#include "bitstream_writer_options.h" /******************************************************************** * Function declaration @@ -25,10 +26,8 @@ int write_fabric_bitstream_to_text_file( const FabricBitstream& fabric_bitstream, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const ConfigProtocol& config_protocol, - const FabricGlobalPortInfo& global_ports, const std::string& fname, - const bool& fast_configuration, const bool& keep_dont_care_bits, - const bool& wl_incremental_order, const bool& include_time_stamp, - const bool& verbose); + const FabricGlobalPortInfo& global_ports, + const BitstreamWriterOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 06f0c079e..8e2e75205 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -261,9 +261,11 @@ static int write_fabric_regional_config_bit_to_xml_file( int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, const std::string& fname, - const bool& include_time_stamp, const bool& verbose) { + const ConfigProtocol& config_protocol, + const BitstreamWriterOption& options) { + VTR_ASSERT(options.output_file_type() == BitstreamWriterOption::e_bitfile_type::XML); /* Ensure that we have a valid file name */ + std::string fname = options.output_file_name(); if (true == fname.empty()) { VTR_LOG_ERROR( "Received empty file name to output bitstream!\n\tPlease specify a valid " @@ -282,7 +284,7 @@ int write_fabric_bitstream_to_xml_file( check_file_stream(fname.c_str(), fp); /* Write XML head */ - write_fabric_bitstream_xml_file_head(fp, include_time_stamp); + write_fabric_bitstream_xml_file_head(fp, options.time_stamp()); int xml_hierarchy_depth = 0; fp << "\n"; @@ -306,7 +308,7 @@ int write_fabric_bitstream_to_xml_file( /* Close file handler */ fp.close(); - VTR_LOGV(verbose, "Outputted %lu configuration bits to XML file: %s\n", + VTR_LOGV(options.verbose_output(), "Outputted %lu configuration bits to XML file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h index ce5b3a384..1dfab557b 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h @@ -10,6 +10,7 @@ #include "bitstream_manager.h" #include "config_protocol.h" #include "fabric_bitstream.h" +#include "bitstream_writer_options.h" /******************************************************************** * Function declaration @@ -21,8 +22,8 @@ namespace openfpga { int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, const std::string& fname, - const bool& include_time_stamp, const bool& verbose); + const ConfigProtocol& config_protocol, + const BitstreamWriterOption& options); } /* end namespace openfpga */ From ae63c9d441f5bfe1c60fa4628edefad16236dbc6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 17:28:25 -0700 Subject: [PATCH 096/174] [core] code format --- .../src/base/openfpga_bitstream_template.h | 46 +++++++++++-------- .../write_text_fabric_bitstream.cpp | 16 ++++--- .../write_text_fabric_bitstream.h | 2 +- .../write_xml_fabric_bitstream.cpp | 9 ++-- .../write_xml_fabric_bitstream.h | 5 +- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index 0de196e7d..8821c8392 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -4,6 +4,7 @@ /******************************************************************** * This file includes functions to build bitstream database *******************************************************************/ +#include "bitstream_writer_options.h" #include "build_device_bitstream.h" #include "build_fabric_bitstream.h" #include "build_io_mapping_info.h" @@ -22,7 +23,6 @@ #include "write_xml_arch_bitstream.h" #include "write_xml_fabric_bitstream.h" #include "write_xml_io_mapping.h" -#include "bitstream_writer_options.h" /* begin namespace openfpga */ namespace openfpga { @@ -120,37 +120,47 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, /* Validate options */ BitstreamWriterOption bitfile_writer_opt; bitfile_writer_opt.set_output_file_type(file_format); - bitfile_writer_opt.set_output_file_name(cmd_context.option_value(cmd, opt_file)); - bitfile_writer_opt.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); - bitfile_writer_opt.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); - bitfile_writer_opt.set_trim_path(cmd_context.option_enable(cmd, opt_trim_path)); - bitfile_writer_opt.set_path_only(cmd_context.option_enable(cmd, opt_path_only)); - bitfile_writer_opt.set_value_only(cmd_context.option_enable(cmd, opt_value_only)); - bitfile_writer_opt.set_fast_configuration(cmd_context.option_enable(cmd, opt_fast_config)); - bitfile_writer_opt.set_keep_dont_care_bits(cmd_context.option_enable(cmd, opt_keep_dont_care_bits)); - bitfile_writer_opt.set_wl_decremental_order(cmd_context.option_enable(cmd, opt_wl_decremental_order)); + bitfile_writer_opt.set_output_file_name( + cmd_context.option_value(cmd, opt_file)); + bitfile_writer_opt.set_time_stamp( + !cmd_context.option_enable(cmd, opt_no_time_stamp)); + bitfile_writer_opt.set_verbose_output( + cmd_context.option_enable(cmd, opt_verbose)); + bitfile_writer_opt.set_trim_path( + cmd_context.option_enable(cmd, opt_trim_path)); + bitfile_writer_opt.set_path_only( + cmd_context.option_enable(cmd, opt_path_only)); + bitfile_writer_opt.set_value_only( + cmd_context.option_enable(cmd, opt_value_only)); + bitfile_writer_opt.set_fast_configuration( + cmd_context.option_enable(cmd, opt_fast_config)); + bitfile_writer_opt.set_keep_dont_care_bits( + cmd_context.option_enable(cmd, opt_keep_dont_care_bits)); + bitfile_writer_opt.set_wl_decremental_order( + cmd_context.option_enable(cmd, opt_wl_decremental_order)); if (cmd_context.option_enable(cmd, opt_filter_value)) { - bitfile_writer_opt.set_filter_value(cmd_context.option_value(cmd, opt_filter_value)); + bitfile_writer_opt.set_filter_value( + cmd_context.option_value(cmd, opt_filter_value)); } if (!bitfile_writer_opt.validate(true)) { VTR_LOG_ERROR("Conflicts detected in options for bitstream writer!\n"); - return CMD_EXEC_FATAL_ERROR; + return CMD_EXEC_FATAL_ERROR; } - if (bitfile_writer_opt.output_file_type() == BitstreamWriterOption::e_bitfile_type::XML) { + if (bitfile_writer_opt.output_file_type() == + BitstreamWriterOption::e_bitfile_type::XML) { status = write_fabric_bitstream_to_xml_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), - openfpga_ctx.arch().config_protocol, - bitfile_writer_opt); + openfpga_ctx.arch().config_protocol, bitfile_writer_opt); } else { - VTR_ASSERT_SAFE(bitfile_writer_opt.output_file_type() == BitstreamWriterOption::e_bitfile_type::TEXT); + VTR_ASSERT_SAFE(bitfile_writer_opt.output_file_type() == + BitstreamWriterOption::e_bitfile_type::TEXT); /* By default, output in plain text format */ status = write_fabric_bitstream_to_text_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().config_protocol, - openfpga_ctx.fabric_global_port_info(), - bitfile_writer_opt); + openfpga_ctx.fabric_global_port_info(), bitfile_writer_opt); } return status; diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp index 5d958a01e..1f83f7a57 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp @@ -581,7 +581,8 @@ int write_fabric_bitstream_to_text_file( const ConfigProtocol& config_protocol, const FabricGlobalPortInfo& global_ports, const BitstreamWriterOption& options) { - VTR_ASSERT(options.output_file_type() == BitstreamWriterOption::e_bitfile_type::TEXT); + VTR_ASSERT(options.output_file_type() == + BitstreamWriterOption::e_bitfile_type::TEXT); std::string fname = options.output_file_name(); /* Ensure that we have a valid file name */ if (true == fname.empty()) { @@ -603,8 +604,10 @@ int write_fabric_bitstream_to_text_file( check_file_stream(fname.c_str(), fp); bool apply_fast_configuration = - is_fast_configuration_applicable(global_ports) && options.fast_configuration(); - if (options.fast_configuration() && apply_fast_configuration != options.fast_configuration()) { + is_fast_configuration_applicable(global_ports) && + options.fast_configuration(); + if (options.fast_configuration() && + apply_fast_configuration != options.fast_configuration()) { VTR_LOG_WARN("Disable fast configuration even it is enabled by user\n"); } @@ -659,8 +662,8 @@ int write_fabric_bitstream_to_text_file( VTR_ASSERT(BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type()); status = write_memory_bank_shift_register_fabric_bitstream_to_text_file( - fp, apply_fast_configuration, bit_value_to_skip, - fabric_bitstream, blwl_sr_banks, options.keep_dont_care_bits()); + fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, + blwl_sr_banks, options.keep_dont_care_bits()); } break; } @@ -684,7 +687,8 @@ int write_fabric_bitstream_to_text_file( /* Close file handler */ fp.close(); - VTR_LOGV(options.verbose_output(), "Outputted %lu configuration bits to plain text file: %s\n", + VTR_LOGV(options.verbose_output(), + "Outputted %lu configuration bits to plain text file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h index e8fa34dcd..48d542ddf 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h @@ -8,11 +8,11 @@ #include #include "bitstream_manager.h" +#include "bitstream_writer_options.h" #include "config_protocol.h" #include "fabric_bitstream.h" #include "fabric_global_port_info.h" #include "memory_bank_shift_register_banks.h" -#include "bitstream_writer_options.h" /******************************************************************** * Function declaration diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 8e2e75205..5e554bb31 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -261,9 +261,9 @@ static int write_fabric_regional_config_bit_to_xml_file( int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, - const BitstreamWriterOption& options) { - VTR_ASSERT(options.output_file_type() == BitstreamWriterOption::e_bitfile_type::XML); + const ConfigProtocol& config_protocol, const BitstreamWriterOption& options) { + VTR_ASSERT(options.output_file_type() == + BitstreamWriterOption::e_bitfile_type::XML); /* Ensure that we have a valid file name */ std::string fname = options.output_file_name(); if (true == fname.empty()) { @@ -308,7 +308,8 @@ int write_fabric_bitstream_to_xml_file( /* Close file handler */ fp.close(); - VTR_LOGV(options.verbose_output(), "Outputted %lu configuration bits to XML file: %s\n", + VTR_LOGV(options.verbose_output(), + "Outputted %lu configuration bits to XML file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h index 1dfab557b..8e40a8d36 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h @@ -8,9 +8,9 @@ #include #include "bitstream_manager.h" +#include "bitstream_writer_options.h" #include "config_protocol.h" #include "fabric_bitstream.h" -#include "bitstream_writer_options.h" /******************************************************************** * Function declaration @@ -22,8 +22,7 @@ namespace openfpga { int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, - const BitstreamWriterOption& options); + const ConfigProtocol& config_protocol, const BitstreamWriterOption& options); } /* end namespace openfpga */ From b07111497c96e968bfd52d7461ea731e72e476f3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:20:17 -0700 Subject: [PATCH 097/174] [core] enable options in xml writers --- .../src/bitstream_manager_utils.cpp | 22 +++++++ .../src/bitstream_manager_utils.h | 3 + .../write_xml_fabric_bitstream.cpp | 58 ++++++++++++------- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp index 9a2ef1277..d6575327f 100644 --- a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp +++ b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp @@ -81,6 +81,28 @@ size_t find_bitstream_manager_config_bit_index_in_parent_block( return curr_index; } +/******************************************************************** + * Find the index of a configuration bit in the children bits of its grandparent + *block. We count the index from the parent of current parent block + *******************************************************************/ +size_t find_bitstream_manager_config_bit_index_in_grandparent_block( + const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id) { + size_t curr_index = 0; + ConfigBlockId parent_blk = bitstream_manager.bit_parent_block(bit_id); + ConfigBlockId grandparent_blk = bitstream_manager.block_parent(parent_blk); + for (const ConfigBlockId& cand_blk : bitstream_manager.block_children(grandparent_blk)) { + if (cand_blk != parent_blk) { + curr_index += bitstream_manager.block_bits(cand_blk).size(); + } else { + curr_index += find_bitstream_manager_config_bit_index_in_parent_block(bitstream_manager, bit_id); + break; + } + } + + return curr_index; +} + + /******************************************************************** * Find the total number of configuration bits under a block * As configuration bits are stored only under the leaf blocks, diff --git a/libs/libfpgabitstream/src/bitstream_manager_utils.h b/libs/libfpgabitstream/src/bitstream_manager_utils.h index e427f834c..26d6f35b8 100644 --- a/libs/libfpgabitstream/src/bitstream_manager_utils.h +++ b/libs/libfpgabitstream/src/bitstream_manager_utils.h @@ -25,6 +25,9 @@ std::vector find_bitstream_manager_top_blocks( size_t find_bitstream_manager_config_bit_index_in_parent_block( const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id); +size_t find_bitstream_manager_config_bit_index_in_grandparent_block( + const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id); + size_t rec_find_bitstream_manager_block_sum_of_bits( const BitstreamManager& bitstream_manager, const ConfigBlockId& block); diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 5e554bb31..4bc60ea42 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -72,36 +72,51 @@ static int write_fabric_config_bit_to_xml_file( std::fstream& fp, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, const FabricBitId& fabric_bit, const e_config_protocol_type& config_type, bool fast_xml, - const int& xml_hierarchy_depth, std::string& bl_addr, std::string& wl_addr) { + const int& xml_hierarchy_depth, std::string& bl_addr, std::string& wl_addr, + const BitstreamWriterOption& options) { if (false == valid_file_stream(fp)) { return 1; } write_tab_to_file(fp, xml_hierarchy_depth); fp << " block_hierarchy = - find_bitstream_manager_block_hierarchy(bitstream_manager, config_block); - std::string hie_path; - for (const ConfigBlockId& temp_block : block_hierarchy) { - hie_path += bitstream_manager.block_name(temp_block); - hie_path += std::string("."); - } - hie_path += generate_configurable_memory_data_out_name(); - hie_path += std::string("["); - hie_path += - std::to_string(find_bitstream_manager_config_bit_index_in_parent_block( - bitstream_manager, config_bit)); - hie_path += std::string("]"); - fp << " path=\"" << hie_path << "\">\n"; + if (options.output_path()) { + std::vector block_hierarchy = + find_bitstream_manager_block_hierarchy(bitstream_manager, config_block); + std::string hie_path; + for (size_t iblk = 0; iblk < block_hierarchy.size(); ++iblk) { + /* If enabled, pop the last block name */ + if (options.trim_path() && iblk == block_hierarchy.size() - 1) { + break; + } + hie_path += bitstream_manager.block_name(block_hierarchy[iblk]); + hie_path += std::string("."); + } + hie_path += generate_configurable_memory_data_out_name(); + hie_path += std::string("["); + size_t bit_idx_in_parent_block = find_bitstream_manager_config_bit_index_in_parent_block( + bitstream_manager, config_bit); + if (options.trim_path()) { + bit_idx_in_parent_block = find_bitstream_manager_config_bit_index_in_grandparent_block( + bitstream_manager, config_bit); + } + hie_path += + std::to_string(bit_idx_in_parent_block); + hie_path += std::string("]"); + + fp << " path=\"" << hie_path << "\">\n"; + } switch (config_type) { case CONFIG_MEM_STANDALONE: @@ -196,7 +211,8 @@ static int write_fabric_regional_config_bit_to_xml_file( const FabricBitstream& fabric_bitstream, const FabricBitRegionId& fabric_region, const e_config_protocol_type& config_type, bool fast_xml, - const int& xml_hierarchy_depth) { + const int& xml_hierarchy_depth, + const BitstreamWriterOption& options) { if (false == valid_file_stream(fp)) { return 1; } @@ -228,7 +244,7 @@ static int write_fabric_regional_config_bit_to_xml_file( fabric_bitstream.region_bits(fabric_region)) { status = write_fabric_config_bit_to_xml_file( fp, bitstream_manager, fabric_bitstream, fabric_bit, config_type, - fast_xml, xml_hierarchy_depth + 1, bl_addr, wl_addr); + fast_xml, xml_hierarchy_depth + 1, bl_addr, wl_addr, options); if (1 == status) { return status; } @@ -296,7 +312,7 @@ int write_fabric_bitstream_to_xml_file( fp, bitstream_manager, fabric_bitstream, region, config_protocol.type(), BLWL_PROTOCOL_FLATTEN == config_protocol.bl_protocol_type() && BLWL_PROTOCOL_FLATTEN == config_protocol.wl_protocol_type(), - xml_hierarchy_depth + 1); + xml_hierarchy_depth + 1, options); if (1 == status) { break; } From 93cbbf204546ac27c7fb951a7fa7e3f42e3d4eac Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:20:55 -0700 Subject: [PATCH 098/174] [core] code format --- .../src/bitstream_manager_utils.cpp | 7 ++++--- .../write_xml_fabric_bitstream.cpp | 20 ++++++++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp index d6575327f..13ef85bbd 100644 --- a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp +++ b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp @@ -90,11 +90,13 @@ size_t find_bitstream_manager_config_bit_index_in_grandparent_block( size_t curr_index = 0; ConfigBlockId parent_blk = bitstream_manager.bit_parent_block(bit_id); ConfigBlockId grandparent_blk = bitstream_manager.block_parent(parent_blk); - for (const ConfigBlockId& cand_blk : bitstream_manager.block_children(grandparent_blk)) { + for (const ConfigBlockId& cand_blk : + bitstream_manager.block_children(grandparent_blk)) { if (cand_blk != parent_blk) { curr_index += bitstream_manager.block_bits(cand_blk).size(); } else { - curr_index += find_bitstream_manager_config_bit_index_in_parent_block(bitstream_manager, bit_id); + curr_index += find_bitstream_manager_config_bit_index_in_parent_block( + bitstream_manager, bit_id); break; } } @@ -102,7 +104,6 @@ size_t find_bitstream_manager_config_bit_index_in_grandparent_block( return curr_index; } - /******************************************************************** * Find the total number of configuration bits under a block * As configuration bits are stored only under the leaf blocks, diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 4bc60ea42..acbd95d0b 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -80,7 +80,9 @@ static int write_fabric_config_bit_to_xml_file( write_tab_to_file(fp, xml_hierarchy_depth); fp << "\n"; @@ -211,8 +214,7 @@ static int write_fabric_regional_config_bit_to_xml_file( const FabricBitstream& fabric_bitstream, const FabricBitRegionId& fabric_region, const e_config_protocol_type& config_type, bool fast_xml, - const int& xml_hierarchy_depth, - const BitstreamWriterOption& options) { + const int& xml_hierarchy_depth, const BitstreamWriterOption& options) { if (false == valid_file_stream(fp)) { return 1; } From 7d83fc914c63c14b59c20ceddd2752cd25368d98 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:31:54 -0700 Subject: [PATCH 099/174] [core] ad a new test case --- ...reconfig_testbench_example_script.openfpga | 2 +- .../fpga_bitstream_reg_test.sh | 3 + .../config/task.conf | 1 + .../config/task.conf | 1 + .../config/task.conf | 1 + .../fpga_bitstream/trim_path/config/task.conf | 56 +++++++++++++++++++ .../trim_path/config/tile_config.xml | 1 + 7 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf create mode 100644 openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml diff --git a/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga index 978feaa56..cdb981da2 100644 --- a/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga @@ -45,7 +45,7 @@ build_architecture_bitstream --verbose --write_file fabric_independent_bitstream build_fabric_bitstream --verbose # Write fabric-dependent bitstream -write_fabric_bitstream --file fabric_bitstream.bit --format plain_text +write_fabric_bitstream --file fabric_bitstream.xml --format xml ${OPENFPGA_FABRIC_BITSTREAM_OPTIONS} # Write the Verilog netlist for FPGA fabric # - Enable the use of explicit port mapping in Verilog netlist diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh index f5bb9a78f..c27475b04 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -45,3 +45,6 @@ run-task fpga_bitstream/report_bitstream_distribution/custom_depth $@ echo -e "Testing bitstream file with don't care bits"; run-task fpga_bitstream/dont_care_bits/ql_memory_bank_flatten $@ run-task fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register $@ + +echo -e "Testing bitstream file with selective contents"; +run-task fpga_bitstream/trim_path $@ diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf index c8f54dda0..2da309cac 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=60 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options= openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf index 8967adc33..8eb945a23 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=60 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options= openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileableL_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf index a04c046d9..06aaf0e87 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=20 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options=--explicit_port_mapping openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml diff --git a/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf new file mode 100644 index 000000000..a9032b322 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--trim_path + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml @@ -0,0 +1 @@ + From e102c9bddcf5d5cb94cbd3afd221eb5f6e6f2b03 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:37:28 -0700 Subject: [PATCH 100/174] [core] fixed a bug --- .../fpga_bitstream/bitstream_writer_options.cpp | 14 ++++++++++++-- .../fpga_bitstream/write_xml_fabric_bitstream.cpp | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp index 62fcac30e..74ded2737 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -54,8 +54,18 @@ bool BitstreamWriterOption::value_to_skip(const size_t& val) const { } bool BitstreamWriterOption::trim_path() const { return trim_path_; } -bool BitstreamWriterOption::output_path() const { return path_only_; } -bool BitstreamWriterOption::output_value() const { return value_only_; } +bool BitstreamWriterOption::output_path() const { + if (!path_only_ && !value_only_) { + return true; + } + return path_only_; +} +bool BitstreamWriterOption::output_value() const { + if (!path_only_ && !value_only_) { + return true; + } + return value_only_; +} bool BitstreamWriterOption::fast_configuration() const { return fast_config_; } bool BitstreamWriterOption::keep_dont_care_bits() const { diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index acbd95d0b..4f942c4f5 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -118,8 +118,9 @@ static int write_fabric_config_bit_to_xml_file( hie_path += std::to_string(bit_idx_in_parent_block); hie_path += std::string("]"); - fp << " path=\"" << hie_path << "\">\n"; + fp << " path=\"" << hie_path; } + fp << "\">\n"; switch (config_type) { case CONFIG_MEM_STANDALONE: From 3440768840e2468753efe4d7097867e1c6d68ffd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:37:54 -0700 Subject: [PATCH 101/174] [core] code format --- openfpga/src/fpga_bitstream/bitstream_writer_options.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp index 74ded2737..a4a83fbeb 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -54,13 +54,13 @@ bool BitstreamWriterOption::value_to_skip(const size_t& val) const { } bool BitstreamWriterOption::trim_path() const { return trim_path_; } -bool BitstreamWriterOption::output_path() const { +bool BitstreamWriterOption::output_path() const { if (!path_only_ && !value_only_) { return true; } return path_only_; } -bool BitstreamWriterOption::output_value() const { +bool BitstreamWriterOption::output_value() const { if (!path_only_ && !value_only_) { return true; } From c6f33bcd7f4b88037553dbbbfba87ee4d7e0444f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:41:57 -0700 Subject: [PATCH 102/174] [test] add new tests to cover the new features --- .../fpga_bitstream_reg_test.sh | 4 ++ .../filter_value0/config/task.conf | 56 +++++++++++++++++++ .../filter_value0/config/tile_config.xml | 1 + .../filter_value1/config/task.conf | 56 +++++++++++++++++++ .../filter_value1/config/tile_config.xml | 1 + .../fpga_bitstream/path_only/config/task.conf | 56 +++++++++++++++++++ .../path_only/config/tile_config.xml | 1 + .../value_only/config/task.conf | 56 +++++++++++++++++++ .../value_only/config/tile_config.xml | 1 + 9 files changed, 232 insertions(+) create mode 100644 openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf create mode 100644 openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml create mode 100644 openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf create mode 100644 openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml create mode 100644 openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf create mode 100644 openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml create mode 100644 openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf create mode 100644 openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh index c27475b04..184eceee9 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -48,3 +48,7 @@ run-task fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register $@ echo -e "Testing bitstream file with selective contents"; run-task fpga_bitstream/trim_path $@ +run-task fpga_bitstream/filter_value0 $@ +run-task fpga_bitstream/filter_value1 $@ +run-task fpga_bitstream/path_only $@ +run-task fpga_bitstream/value_only $@ diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf new file mode 100644 index 000000000..2d68176e0 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--filter_value 0 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf new file mode 100644 index 000000000..56d0f79e2 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--filter_value 1 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf new file mode 100644 index 000000000..ce8eb7c70 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--path_only + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf new file mode 100644 index 000000000..16f68f62c --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--value_only + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml @@ -0,0 +1 @@ + From 83ef35b2da9c8fe5caabe58737651f7c0600db69 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:47:20 -0700 Subject: [PATCH 103/174] [core] fixed a bug --- openfpga/src/fpga_bitstream/bitstream_writer_options.cpp | 4 ++-- openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp index a4a83fbeb..28f94a6ed 100644 --- a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -141,11 +141,11 @@ bool BitstreamWriterOption::validate(bool show_err_msg) const { "specified, please define one of them\n"); return false; } - if (!filter_value_.empty() && (filter_value_ != std::to_string(0) || + if (!filter_value_.empty() && (filter_value_ != std::to_string(0) && filter_value_ != std::to_string(1))) { VTR_LOGV_ERROR(show_err_msg, "Invalid value '%s' for filter values. Expect [0|1]!\n", - filter_value_); + filter_value_.c_str()); return false; } } diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 4f942c4f5..156c0186e 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -118,9 +118,9 @@ static int write_fabric_config_bit_to_xml_file( hie_path += std::to_string(bit_idx_in_parent_block); hie_path += std::string("]"); - fp << " path=\"" << hie_path; + fp << " path=\"" << hie_path << "\""; } - fp << "\">\n"; + fp << ">\n"; switch (config_type) { case CONFIG_MEM_STANDALONE: From 7ba6795fe2b950fc3e02aa6c9ddba9bec37b7403 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 6 Oct 2023 18:50:26 -0700 Subject: [PATCH 104/174] [core] fixed a bug --- .../src/fpga_bitstream/write_xml_fabric_bitstream.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 156c0186e..9bd3287e1 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -77,12 +77,14 @@ static int write_fabric_config_bit_to_xml_file( if (false == valid_file_stream(fp)) { return 1; } + if (options.value_to_skip( + bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit)))) { + return 0; + } write_tab_to_file(fp, xml_hierarchy_depth); fp << " Date: Fri, 6 Oct 2023 19:32:42 -0700 Subject: [PATCH 105/174] [doc] update for new options that are added to ``write_fabric_bitstream`` --- .../fpga_bitstream_commands.rst | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst index 56032a5e0..ffd6d8087 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst @@ -81,6 +81,40 @@ write_fabric_bitstream Specify the file format [``plain_text`` | ``xml``]. By default is ``plain_text``. See file formats in :ref:`file_formats_fabric_bitstream_xml` and :ref:`file_formats_fabric_bitstream_plain_text`. + .. option:: --filter_value + + .. warning:: Value filter is only applicable to XML file format! + + Specify the value to be keep in the bitstream file. Can be [``0`` | ``1`` ]. By default is ``none``, which means no filter is applied. + When specified, only the bit with the filter value is written to the file. + See file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --path_only + + .. warning:: This is only applicable to XML file format! + + Specify that only the ``path`` attribute is kept in the bitstream file. By default is ``off``. + When specified, only the ``path`` attribute is written to the file. + Regarding the ``path`` attribute, See file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --value_only + + .. warning:: This is only applicable to XML file format! + + Specify that only the ``value`` attribute is kept in the bitstream file. By default is ``off``. + When specified, only the ``value`` attribute is written to the file. + Regarding the ``value`` attribute, see file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --trim_path + + .. warning:: This is only applicable to XML file format! + + .. warning:: This is an option for power user! Suggest only to use when you enable the ``--group_config_block`` option when building a fabric (See details in :ref:`cmd_build_fabric`). + + Specify that the ``path`` will be trimed by 1 level in resulting bitstream file. By default is ``off``. + When specified, the hierarchy of ``path`` will be reduced by 1. For example, the original path is ``fpga_top.tile_1__1_.config_block.sub_mem.mem_out[0]``, the path after trimming is ``fpga_top.tile_1__1_.config_block.mem_out[0]``. + Regarding the ``path`` attribute, see file formats in :ref:`file_formats_fabric_bitstream_xml`. + .. option:: --fast_configuration Reduce the bitstream size when outputing by skipping dummy configuration bits. It is applicable to configuration chain, memory bank and frame-based configuration protocols. For configuration chain, when enabled, the zeros at the head of the bitstream will be skipped. For memory bank and frame-based, when enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal. From 5d53948da298b3946d5256379558599d2c219301 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 7 Oct 2023 05:54:00 +0000 Subject: [PATCH 106/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 27a9b20c0..31b2c8ba3 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1647 +1.2.1667 From 8b075c2f7c31761f41e2e923854876f343bb2e76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 06:35:05 +0000 Subject: [PATCH 107/174] Bump yosys from `8367f06` to `11b9deb` Bumps [yosys](https://github.com/YosysHQ/yosys) from `8367f06` to `11b9deb`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/8367f06188edf750b32bd603552ba9d75995baf5...11b9deba9f05a107c70f66139fc988be46567719) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 8367f0618..11b9deba9 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 8367f06188edf750b32bd603552ba9d75995baf5 +Subproject commit 11b9deba9f05a107c70f66139fc988be46567719 From 21ff3448960d15baebc45ba70f4173b42479485a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 00:02:18 +0000 Subject: [PATCH 108/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 31b2c8ba3..3f6e0aa75 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1667 +1.2.1671 From 1730be33422bab6dc1397f3b2912fb14c5779575 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 06:29:53 +0000 Subject: [PATCH 109/174] Bump yosys from `11b9deb` to `3e22791` Bumps [yosys](https://github.com/YosysHQ/yosys) from `11b9deb` to `3e22791`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/11b9deba9f05a107c70f66139fc988be46567719...3e227918105384dd955ce8b9908a0ebe36f8640f) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 11b9deba9..3e2279181 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 11b9deba9f05a107c70f66139fc988be46567719 +Subproject commit 3e227918105384dd955ce8b9908a0ebe36f8640f From 83aacf6739df96de5d2f896556c8ab0cae7d5174 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 00:02:26 +0000 Subject: [PATCH 110/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 3f6e0aa75..c8776420f 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1671 +1.2.1675 From fc0ecaba4dc936c94b32d9725cd0db7498e8bb60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 06:47:55 +0000 Subject: [PATCH 111/174] Bump yosys from `3e22791` to `59fbee4` Bumps [yosys](https://github.com/YosysHQ/yosys) from `3e22791` to `59fbee4`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/3e227918105384dd955ce8b9908a0ebe36f8640f...59fbee4009f02f807d3b60888ff5eca6670e3a7f) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 3e2279181..59fbee400 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 3e227918105384dd955ce8b9908a0ebe36f8640f +Subproject commit 59fbee4009f02f807d3b60888ff5eca6670e3a7f From ffdb24cb7476ce3cdc38bbe593d40d5f3ebf14e9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 00:02:21 +0000 Subject: [PATCH 112/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index c8776420f..286c7097a 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1675 +1.2.1679 From 761d810a54b19c0bd76cb2454ea54ef957581369 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 06:26:33 +0000 Subject: [PATCH 113/174] Bump yosys from `59fbee4` to `7d30f71` Bumps [yosys](https://github.com/YosysHQ/yosys) from `59fbee4` to `7d30f71`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/59fbee4009f02f807d3b60888ff5eca6670e3a7f...7d30f716e82ff4782b653cb2c448062f7878c308) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 59fbee400..7d30f716e 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 59fbee4009f02f807d3b60888ff5eca6670e3a7f +Subproject commit 7d30f716e82ff4782b653cb2c448062f7878c308 From cb65ae011e90461cfb87c936d0f85dc1b2bfe71a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 00:02:26 +0000 Subject: [PATCH 114/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 286c7097a..4f499c0e3 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1679 +1.2.1683 From a2648cffb7941e5afa7bd24c0a475152dfae8e48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 06:27:21 +0000 Subject: [PATCH 115/174] Bump yosys from `7d30f71` to `d21c464` Bumps [yosys](https://github.com/YosysHQ/yosys) from `7d30f71` to `d21c464`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/7d30f716e82ff4782b653cb2c448062f7878c308...d21c464ae4212abc8a413ecd12c3c1bdc04fb100) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 7d30f716e..d21c464ae 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 7d30f716e82ff4782b653cb2c448062f7878c308 +Subproject commit d21c464ae4212abc8a413ecd12c3c1bdc04fb100 From 9c71e2d21402101ed6fb1a4ff7fcbec9a6aea067 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 00:02:14 +0000 Subject: [PATCH 116/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 4f499c0e3..d75c7207a 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1683 +1.2.1687 From 4b00651a467da7d722a02b58c36f68368bc3efeb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 19 Oct 2023 23:03:48 -0700 Subject: [PATCH 117/174] [core] now name indexing is applied to netlist names --- openfpga/src/fpga_verilog/verilog_routing.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index 820b1ba90..de4753ae6 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -85,6 +85,11 @@ static void print_verilog_routing_connection_box_unique_module( rr_gsb.get_cb_y(cb_type)); std::string verilog_fname(generate_connection_block_netlist_name( cb_type, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); + std::string orig_module_name = generate_connection_block_module_name(cb_type, gsb_coordinate); + if (module_name_map.name_exist(orig_module_name)) { + verilog_fname = generate_tile_module_netlist_name(module_name_map.name(orig_module_name), std::string(VERILOG_NETLIST_FILE_POSTFIX)); + } + std::string verilog_fpath(subckt_dir + verilog_fname); /* Create the file stream */ @@ -102,8 +107,7 @@ static void print_verilog_routing_connection_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - std::string cb_module_name = module_name_map.name( - generate_connection_block_module_name(cb_type, gsb_coordinate)); + std::string cb_module_name = module_name_map.name(orig_module_name); ModuleId cb_module = module_manager.find_module(cb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); @@ -200,6 +204,10 @@ static void print_verilog_routing_switch_box_unique_module( std::string verilog_fname(generate_routing_block_netlist_name( SB_VERILOG_FILE_NAME_PREFIX, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); + std::string orig_module_name = generate_switch_block_module_name(gsb_coordinate); + if (module_name_map.name_exist(orig_module_name)) { + verilog_fname = generate_tile_module_netlist_name(module_name_map.name(orig_module_name), std::string(VERILOG_NETLIST_FILE_POSTFIX)); + } std::string verilog_fpath(subckt_dir + verilog_fname); /* Create the file stream */ @@ -218,7 +226,7 @@ static void print_verilog_routing_switch_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ std::string sb_module_name = - module_name_map.name(generate_switch_block_module_name(gsb_coordinate)); + module_name_map.name(orig_module_name); ModuleId sb_module = module_manager.find_module(sb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); From 5bae2bf54d48b162f6478b5b7a6687176957e21f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 19 Oct 2023 23:05:49 -0700 Subject: [PATCH 118/174] [core] code format --- openfpga/src/fpga_verilog/verilog_routing.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index de4753ae6..dbe59e935 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -85,9 +85,12 @@ static void print_verilog_routing_connection_box_unique_module( rr_gsb.get_cb_y(cb_type)); std::string verilog_fname(generate_connection_block_netlist_name( cb_type, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); - std::string orig_module_name = generate_connection_block_module_name(cb_type, gsb_coordinate); + std::string orig_module_name = + generate_connection_block_module_name(cb_type, gsb_coordinate); if (module_name_map.name_exist(orig_module_name)) { - verilog_fname = generate_tile_module_netlist_name(module_name_map.name(orig_module_name), std::string(VERILOG_NETLIST_FILE_POSTFIX)); + verilog_fname = generate_tile_module_netlist_name( + module_name_map.name(orig_module_name), + std::string(VERILOG_NETLIST_FILE_POSTFIX)); } std::string verilog_fpath(subckt_dir + verilog_fname); @@ -204,9 +207,12 @@ static void print_verilog_routing_switch_box_unique_module( std::string verilog_fname(generate_routing_block_netlist_name( SB_VERILOG_FILE_NAME_PREFIX, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); - std::string orig_module_name = generate_switch_block_module_name(gsb_coordinate); + std::string orig_module_name = + generate_switch_block_module_name(gsb_coordinate); if (module_name_map.name_exist(orig_module_name)) { - verilog_fname = generate_tile_module_netlist_name(module_name_map.name(orig_module_name), std::string(VERILOG_NETLIST_FILE_POSTFIX)); + verilog_fname = generate_tile_module_netlist_name( + module_name_map.name(orig_module_name), + std::string(VERILOG_NETLIST_FILE_POSTFIX)); } std::string verilog_fpath(subckt_dir + verilog_fname); @@ -225,8 +231,7 @@ static void print_verilog_routing_switch_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - std::string sb_module_name = - module_name_map.name(orig_module_name); + std::string sb_module_name = module_name_map.name(orig_module_name); ModuleId sb_module = module_manager.find_module(sb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); From 76a4b8a82ba97d94d4040f14e3c6aa16e01e5b38 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 20 Oct 2023 21:13:37 -0700 Subject: [PATCH 119/174] [core] remove the prefix of grouped memory blocks --- openfpga/src/fabric/build_memory_modules.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index 80899a04c..a5977b5a8 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -1510,7 +1510,7 @@ int add_physical_memory_module(ModuleManager& module_manager, return CMD_EXEC_SUCCESS; } std::string phy_mem_module_name = generate_physical_memory_module_name( - module_manager.module_name(curr_module), module_num_config_bits); + std::string(), module_num_config_bits); VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n", phy_mem_module_name.c_str(), module_manager.module_name(curr_module).c_str()); From e4b204f2e4c3940d61da6938255df72cd0e5ac85 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 20 Oct 2023 21:14:07 -0700 Subject: [PATCH 120/174] [core] code format --- openfpga/src/fabric/build_memory_modules.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index a5977b5a8..75da54a5d 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -1509,8 +1509,8 @@ int add_physical_memory_module(ModuleManager& module_manager, if (module_num_config_bits == 0) { return CMD_EXEC_SUCCESS; } - std::string phy_mem_module_name = generate_physical_memory_module_name( - std::string(), module_num_config_bits); + std::string phy_mem_module_name = + generate_physical_memory_module_name(std::string(), module_num_config_bits); VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n", phy_mem_module_name.c_str(), module_manager.module_name(curr_module).c_str()); From 66c3226fade47cd57018ed98273fc153c7c20c98 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 20 Oct 2023 22:01:19 -0700 Subject: [PATCH 121/174] [core] now follow module unique index when naming grouped configuration memories --- openfpga/src/fabric/build_grid_modules.cpp | 2 +- openfpga/src/fabric/build_memory_modules.cpp | 7 +++++- openfpga/src/fabric/build_memory_modules.h | 1 + openfpga/src/fabric/build_routing_modules.cpp | 22 +++++++++++-------- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index ad49cc63c..94b9d884c 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -1232,7 +1232,7 @@ static int build_physical_tile_module( /* TODO: Add a physical memory block */ if (group_config_block) { status = add_physical_memory_module(module_manager, decoder_lib, - grid_module, circuit_lib, + grid_module, std::string(), circuit_lib, sram_orgz_type, sram_model, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index 75da54a5d..2694314d3 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -1486,6 +1486,7 @@ int build_memory_group_module( int add_physical_memory_module(ModuleManager& module_manager, DecoderLibrary& decoder_lib, const ModuleId& curr_module, + const std::string& suggested_module_name_prefix, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, @@ -1509,8 +1510,12 @@ int add_physical_memory_module(ModuleManager& module_manager, if (module_num_config_bits == 0) { return CMD_EXEC_SUCCESS; } + std::string module_name_prefix = module_manager.module_name(curr_module); + if (!suggested_module_name_prefix.empty()) { + module_name_prefix = suggested_module_name_prefix; + } std::string phy_mem_module_name = - generate_physical_memory_module_name(std::string(), module_num_config_bits); + generate_physical_memory_module_name(module_name_prefix, module_num_config_bits); VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n", phy_mem_module_name.c_str(), module_manager.module_name(curr_module).c_str()); diff --git a/openfpga/src/fabric/build_memory_modules.h b/openfpga/src/fabric/build_memory_modules.h index b79fd4b90..e66a70656 100644 --- a/openfpga/src/fabric/build_memory_modules.h +++ b/openfpga/src/fabric/build_memory_modules.h @@ -41,6 +41,7 @@ int build_memory_group_module( int add_physical_memory_module(ModuleManager& module_manager, DecoderLibrary& decoder_lib, const ModuleId& curr_module, + const std::string& suggested_module_name_prefix, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp index 1f12774c5..08194f39d 100644 --- a/openfpga/src/fabric/build_routing_modules.cpp +++ b/openfpga/src/fabric/build_routing_modules.cpp @@ -384,7 +384,7 @@ static void build_switch_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const RRGSB& rr_gsb, + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, const RRGSB& rr_gsb, const bool& group_config_block, const bool& verbose) { /* Create a Module of Switch Block and add to module manager */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); @@ -494,7 +494,9 @@ static void build_switch_block_module( /* Build a physical memory block */ if (group_config_block) { - add_physical_memory_module(module_manager, decoder_lib, sb_module, + std::string mem_module_name_prefix = + generate_switch_block_module_name_using_index(device_rr_gsb.get_sb_unique_module_index(gsb_coordinate)); + add_physical_memory_module(module_manager, decoder_lib, sb_module, mem_module_name_prefix, circuit_lib, sram_orgz_type, sram_model, verbose); } @@ -891,7 +893,7 @@ static void build_connection_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const RRGSB& rr_gsb, + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, const RRGSB& rr_gsb, const t_rr_type& cb_type, const bool& group_config_block, const bool& verbose) { /* Create the netlist */ @@ -1022,7 +1024,9 @@ static void build_connection_block_module( /* Build a physical memory block */ if (group_config_block) { - add_physical_memory_module(module_manager, decoder_lib, cb_module, + std::string mem_module_name_prefix = + generate_connection_block_module_name_using_index(cb_type, device_rr_gsb.get_cb_unique_module_index(cb_type, gsb_coordinate)); + add_physical_memory_module(module_manager, decoder_lib, cb_module, mem_module_name_prefix, circuit_lib, sram_orgz_type, sram_model, verbose); } @@ -1105,7 +1109,7 @@ static void build_flatten_connection_block_modules( } build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, - device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, rr_gsb, + device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, device_rr_gsb, rr_gsb, cb_type, group_config_block, verbose); } } @@ -1140,7 +1144,7 @@ void build_flatten_routing_modules( } build_switch_block_module(module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, - circuit_lib, sram_orgz_type, sram_model, rr_gsb, + circuit_lib, sram_orgz_type, sram_model, device_rr_gsb, rr_gsb, group_config_block, verbose); } } @@ -1181,7 +1185,7 @@ void build_unique_routing_modules( const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); build_switch_block_module(module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, - sram_orgz_type, sram_model, unique_mirror, + sram_orgz_type, sram_model, device_rr_gsb, unique_mirror, group_config_block, verbose); } @@ -1193,7 +1197,7 @@ void build_unique_routing_modules( build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, - unique_mirror, CHANX, group_config_block, verbose); + device_rr_gsb, unique_mirror, CHANX, group_config_block, verbose); } /* Build unique X-direction connection block modules */ @@ -1204,7 +1208,7 @@ void build_unique_routing_modules( build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, - unique_mirror, CHANY, group_config_block, verbose); + device_rr_gsb, unique_mirror, CHANY, group_config_block, verbose); } } From 3d4f1505b69b5c352cbcc3c58ef6d7cdcffa0997 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 20 Oct 2023 22:02:56 -0700 Subject: [PATCH 122/174] [core] code format --- openfpga/src/fabric/build_memory_modules.cpp | 4 +- openfpga/src/fabric/build_routing_modules.cpp | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index 2694314d3..6ac58ba21 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -1514,8 +1514,8 @@ int add_physical_memory_module(ModuleManager& module_manager, if (!suggested_module_name_prefix.empty()) { module_name_prefix = suggested_module_name_prefix; } - std::string phy_mem_module_name = - generate_physical_memory_module_name(module_name_prefix, module_num_config_bits); + std::string phy_mem_module_name = generate_physical_memory_module_name( + module_name_prefix, module_num_config_bits); VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n", phy_mem_module_name.c_str(), module_manager.module_name(curr_module).c_str()); diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp index 08194f39d..d552a611c 100644 --- a/openfpga/src/fabric/build_routing_modules.cpp +++ b/openfpga/src/fabric/build_routing_modules.cpp @@ -384,8 +384,8 @@ static void build_switch_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, const RRGSB& rr_gsb, - const bool& group_config_block, const bool& verbose) { + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, + const RRGSB& rr_gsb, const bool& group_config_block, const bool& verbose) { /* Create a Module of Switch Block and add to module manager */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); ModuleId sb_module = module_manager.add_module( @@ -494,11 +494,12 @@ static void build_switch_block_module( /* Build a physical memory block */ if (group_config_block) { - std::string mem_module_name_prefix = - generate_switch_block_module_name_using_index(device_rr_gsb.get_sb_unique_module_index(gsb_coordinate)); - add_physical_memory_module(module_manager, decoder_lib, sb_module, mem_module_name_prefix, - circuit_lib, sram_orgz_type, sram_model, - verbose); + std::string mem_module_name_prefix = + generate_switch_block_module_name_using_index( + device_rr_gsb.get_sb_unique_module_index(gsb_coordinate)); + add_physical_memory_module(module_manager, decoder_lib, sb_module, + mem_module_name_prefix, circuit_lib, + sram_orgz_type, sram_model, verbose); } /* Add global ports to the pb_module: @@ -893,8 +894,8 @@ static void build_connection_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, const RRGSB& rr_gsb, - const t_rr_type& cb_type, const bool& group_config_block, + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, + const RRGSB& rr_gsb, const t_rr_type& cb_type, const bool& group_config_block, const bool& verbose) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), @@ -1024,11 +1025,13 @@ static void build_connection_block_module( /* Build a physical memory block */ if (group_config_block) { - std::string mem_module_name_prefix = - generate_connection_block_module_name_using_index(cb_type, device_rr_gsb.get_cb_unique_module_index(cb_type, gsb_coordinate)); - add_physical_memory_module(module_manager, decoder_lib, cb_module, mem_module_name_prefix, - circuit_lib, sram_orgz_type, sram_model, - verbose); + std::string mem_module_name_prefix = + generate_connection_block_module_name_using_index( + cb_type, + device_rr_gsb.get_cb_unique_module_index(cb_type, gsb_coordinate)); + add_physical_memory_module(module_manager, decoder_lib, cb_module, + mem_module_name_prefix, circuit_lib, + sram_orgz_type, sram_model, verbose); } /* Add global ports to the pb_module: @@ -1109,8 +1112,8 @@ static void build_flatten_connection_block_modules( } build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, - device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, device_rr_gsb, rr_gsb, - cb_type, group_config_block, verbose); + device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, + device_rr_gsb, rr_gsb, cb_type, group_config_block, verbose); } } } @@ -1142,10 +1145,10 @@ void build_flatten_routing_modules( if (false == rr_gsb.is_sb_exist(device_ctx.rr_graph)) { continue; } - build_switch_block_module(module_manager, decoder_lib, device_annotation, - device_ctx.grid, device_ctx.rr_graph, - circuit_lib, sram_orgz_type, sram_model, device_rr_gsb, rr_gsb, - group_config_block, verbose); + build_switch_block_module( + module_manager, decoder_lib, device_annotation, device_ctx.grid, + device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, + device_rr_gsb, rr_gsb, group_config_block, verbose); } } @@ -1185,8 +1188,8 @@ void build_unique_routing_modules( const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); build_switch_block_module(module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, - sram_orgz_type, sram_model, device_rr_gsb, unique_mirror, - group_config_block, verbose); + sram_orgz_type, sram_model, device_rr_gsb, + unique_mirror, group_config_block, verbose); } /* Build unique X-direction connection block modules */ From 171c7c6fc016c6342c1d8657b53337380d8dafdd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 20:36:09 +0000 Subject: [PATCH 123/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index d75c7207a..b015c920e 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1687 +1.2.1696 From d0ad312999125ff7b27769456dd3442c55af70d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 06:24:52 +0000 Subject: [PATCH 124/174] Bump yosys from `d21c464` to `672375e` Bumps [yosys](https://github.com/YosysHQ/yosys) from `d21c464` to `672375e`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/d21c464ae4212abc8a413ecd12c3c1bdc04fb100...672375ed02be68733856e616a5f4fbf281fe7733) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index d21c464ae..672375ed0 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit d21c464ae4212abc8a413ecd12c3c1bdc04fb100 +Subproject commit 672375ed02be68733856e616a5f4fbf281fe7733 From 6912adaa0cedb1b406f34193727225fba12b81fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:02:25 +0000 Subject: [PATCH 125/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index b015c920e..9524fcbd9 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1696 +1.2.1700 From 75e9e98e5d1ca20f66dba364a8f92d6c9b0c79cd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 16:06:48 -0700 Subject: [PATCH 126/174] [core] add two new commands to output testbench parts --- .../base/openfpga_verilog_command_template.h | 140 +++++++++++++ openfpga/src/base/openfpga_verilog_template.h | 94 +++++++++ openfpga/src/fpga_verilog/verilog_api.cpp | 44 ++++ .../verilog_preconfig_top_module.cpp | 175 +--------------- .../verilog_preconfig_top_module.h | 4 +- .../verilog_preconfig_top_module_utils.cpp | 194 ++++++++++++++++++ .../verilog_preconfig_top_module_utils.h | 44 ++++ .../verilog_template_testbench.cpp | 138 +++++++++++++ .../fpga_verilog/verilog_template_testbench.h | 45 ++++ .../verilog_testbench_options.cpp | 16 ++ .../fpga_verilog/verilog_testbench_options.h | 3 + 11 files changed, 724 insertions(+), 173 deletions(-) create mode 100644 openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp create mode 100644 openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h create mode 100644 openfpga/src/fpga_verilog/verilog_template_testbench.cpp create mode 100644 openfpga/src/fpga_verilog/verilog_template_testbench.h diff --git a/openfpga/src/base/openfpga_verilog_command_template.h b/openfpga/src/base/openfpga_verilog_command_template.h index fa40faff9..160ce809f 100644 --- a/openfpga/src/base/openfpga_verilog_command_template.h +++ b/openfpga/src/base/openfpga_verilog_command_template.h @@ -265,6 +265,124 @@ ShellCommandId add_write_preconfigured_fabric_wrapper_command_template( return shell_cmd_id; } +/******************************************************************** + * - add a command to shell environment: write a template of testbench + * - add associated options + * - add command dependency + *******************************************************************/ +template +ShellCommandId add_write_testbench_template_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_testbench_template"); + + /* add an option '--file' in short '-f'*/ + CommandOptionId output_opt = shell_cmd.add_option( + "file", true, "specify the file path to output the content"); + shell_cmd.set_option_short_name(output_opt, "f"); + shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); + + /* add an option '--top_module'*/ + CommandOptionId top_module_opt = shell_cmd.add_option( + "top_module", false, + "specify the top-level module name to be used in the testbench. Please avoid reserved words, i.e., fpga_top or fpga_core. By default, it is top_tb."); + shell_cmd.set_option_require_value(top_module_opt, openfpga::OPT_STRING); + + /* add an option '--dut_module'*/ + CommandOptionId dut_module_opt = shell_cmd.add_option( + "dut_module", false, + "specify the module name of DUT to be used in the testbench. Can be either " + "fpga_top or fpga_core. By default, it is fpga_top."); + shell_cmd.set_option_require_value(dut_module_opt, openfpga::OPT_STRING); + + /* add an option '--explicit_port_mapping' */ + shell_cmd.add_option("explicit_port_mapping", false, + "use explicit port mapping in verilog netlists"); + + /* Add an option '--default_net_type' */ + CommandOptionId default_net_type_opt = shell_cmd.add_option( + "default_net_type", false, + "Set the default net type for Verilog netlists. Default value is 'none'"); + shell_cmd.set_option_require_value(default_net_type_opt, + openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print a time stamp in the output files"); + + /* add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "enable verbose output"); + + /* add command to the shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "generate a template of testbench for a pre-configured fpga fabric", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function( + shell_cmd_id, write_testbench_template_template); + + /* add command dependency to the shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + +/******************************************************************** + * - add a command to shell environment: write testbench io connection + * - add associated options + * - add command dependency + *******************************************************************/ +template +ShellCommandId add_write_testbench_io_connection_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_testbench_io_connection"); + + /* add an option '--file' in short '-f'*/ + CommandOptionId output_opt = shell_cmd.add_option( + "file", true, "specify the file path to output the content"); + shell_cmd.set_option_short_name(output_opt, "f"); + shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); + + /* add an option '--dut_module'*/ + CommandOptionId dut_module_opt = shell_cmd.add_option( + "dut_module", false, + "specify the module name of DUT to be used in the testbench. Can be either " + "fpga_top or fpga_core. By default, it is fpga_top."); + shell_cmd.set_option_require_value(dut_module_opt, openfpga::OPT_STRING); + + /* add an option '--pin_constraints_file in short '-pcf' */ + CommandOptionId pcf_opt = + shell_cmd.add_option("pin_constraints_file", false, + "specify the file path to the pin constraints"); + shell_cmd.set_option_short_name(pcf_opt, "pcf"); + shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); + + /* add an option '--bus_group_file in short '-bgf' */ + CommandOptionId bgf_opt = shell_cmd.add_option( + "bus_group_file", false, "specify the file path to the group pins to bus"); + shell_cmd.set_option_short_name(bgf_opt, "bgf"); + shell_cmd.set_option_require_value(bgf_opt, openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print a time stamp in the output files"); + + /* add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "enable verbose output"); + + /* add command to the shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "generate a file to describe the connection to I/Os of a pre-configured fpga fabric", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function( + shell_cmd_id, write_testbench_io_connection_template); + + /* add command dependency to the shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + /******************************************************************** * - add a command to shell environment: write mock fpga wrapper * - add associated options @@ -525,6 +643,28 @@ void add_verilog_command_templates(openfpga::Shell& shell, shell, openfpga_verilog_cmd_class, preconfig_wrapper_dependent_cmds, hidden); + /******************************** + * Command 'write_testbench_template' + */ + /* The command 'write_testbench_template' should NOT be executed + * before 'build_fabric' */ + std::vector testbench_template_dependent_cmds; + testbench_template_dependent_cmds.push_back(build_fabric_cmd_id); + add_write_testbench_template_command_template( + shell, openfpga_verilog_cmd_class, testbench_template_dependent_cmds, + hidden); + + /******************************** + * Command 'write_testbench_io_connection' + */ + /* The command 'write_testbench_io_connection' should NOT be executed + * before 'build_fabric' */ + std::vector testbench_io_conkt_dependent_cmds; + testbench_io_conkt_dependent_cmds.push_back(build_fabric_cmd_id); + add_write_testbench_io_connection_command_template( + shell, openfpga_verilog_cmd_class, testbench_io_conkt_dependent_cmds, + hidden); + /******************************** * Command 'write_mock_fpga_wrapper' */ diff --git a/openfpga/src/base/openfpga_verilog_template.h b/openfpga/src/base/openfpga_verilog_template.h index 783ab7f7d..0f5923948 100644 --- a/openfpga/src/base/openfpga_verilog_template.h +++ b/openfpga/src/base/openfpga_verilog_template.h @@ -217,6 +217,100 @@ int write_preconfigured_fabric_wrapper_template( openfpga_ctx.arch().config_protocol, options); } +/******************************************************************** + * A wrapper function to call the testbench template generator of + *FPGA-Verilog + *******************************************************************/ +template +int write_testbench_template_template( + const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_output_dir = cmd.option("file"); + CommandOptionId opt_top_module = cmd.option("top_module"); + CommandOptionId opt_dut_module = cmd.option("dut_module"); + CommandOptionId opt_explicit_port_mapping = + cmd.option("explicit_port_mapping"); + CommandOptionId opt_default_net_type = cmd.option("default_net_type"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* This is an intermediate data structure which is designed to modularize the + * FPGA-Verilog Keep it independent from any other outside data structures + */ + VerilogTestbenchOption options; + options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir)); + options.set_explicit_port_mapping( + cmd_context.option_enable(cmd, opt_explicit_port_mapping)); + options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); + options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + + if (true == cmd_context.option_enable(cmd, opt_dut_module)) { + options.set_dut_module(cmd_context.option_value(cmd, opt_dut_module)); + } + + if (true == cmd_context.option_enable(cmd, opt_top_module)) { + options.set_top_module(cmd_context.option_value(cmd, opt_top_module)); + } + + return fpga_verilog_template_testbench( + openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), + g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, + openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, + openfpga_ctx.arch().config_protocol, options); +} + +/******************************************************************** + * A wrapper function to call the testbench I/O connection generator of + *FPGA-Verilog + *******************************************************************/ +template +int write_testbench_io_connection_template( + const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_output_dir = cmd.option("file"); + CommandOptionId opt_dut_module = cmd.option("dut_module"); + CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); + CommandOptionId opt_bgf = cmd.option("bus_group_file"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* This is an intermediate data structure which is designed to modularize the + * FPGA-Verilog Keep it independent from any other outside data structures + */ + VerilogTestbenchOption options; + options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir)); + options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); + options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + + if (true == cmd_context.option_enable(cmd, opt_dut_module)) { + options.set_dut_module(cmd_context.option_value(cmd, opt_dut_module)); + } + + /* If pin constraints are enabled by command options, read the file */ + PinConstraints pin_constraints; + if (true == cmd_context.option_enable(cmd, opt_pcf)) { + pin_constraints = + read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); + } + + /* If bug group file are enabled by command options, read the file */ + BusGroup bus_group; + if (true == cmd_context.option_enable(cmd, opt_bgf)) { + bus_group = + read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str()); + } + + return fpga_verilog_testbench_io_connection( + openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), + g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, + openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, + openfpga_ctx.arch().config_protocol, options); +} + /******************************************************************** * A wrapper function to call the mock fpga wrapper generator of *FPGA-Verilog diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index d7c266b79..c8282893e 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -20,6 +20,7 @@ #include "verilog_grid.h" #include "verilog_mock_fpga_wrapper.h" #include "verilog_preconfig_top_module.h" +#include "verilog_template_testbench.h" #include "verilog_routing.h" #include "verilog_simulation_info_writer.h" #include "verilog_submodule.h" @@ -256,6 +257,49 @@ int fpga_verilog_preconfigured_fabric_wrapper( return status; } +/******************************************************************** + * A top-level function of FPGA-Verilog which focuses on template testbench + *generation This function will generate + * - A wrapper module, which encapsulate the FPGA module in a Verilog module + *which have the same port as the input benchmark + ********************************************************************/ +int fpga_verilog_template_testbench( + const ModuleManager &module_manager, + const BitstreamManager &bitstream_manager, const AtomContext &atom_ctx, + const PlacementContext &place_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const IoLocationMap &io_location_map, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, + const FabricGlobalPortInfo &fabric_global_port_info, + const VprNetlistAnnotation &netlist_annotation, + const CircuitLibrary &circuit_lib, const ConfigProtocol &config_protocol, + const VerilogTestbenchOption &options) { + vtr::ScopedStartFinishTimer timer( + "Write a template testbench for a preconfigured FPGA fabric\n"); + + std::string src_dir_path = format_dir_path(options.output_directory()); + + std::string netlist_name = atom_ctx.nlist.netlist_name(); + + int status = CMD_EXEC_SUCCESS; + + /* Create directories */ + create_directory(src_dir_path); + + /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and + * pre-configured testbench for verification */ + std::string testbench_file_path = + src_dir_path + options.top_module_name() + + std::string(VERILOG_NETLIST_FILE_POSTFIX); + status = print_verilog_template_testbench( + module_manager, bitstream_manager, config_protocol, circuit_lib, + fabric_global_port_info, atom_ctx, place_ctx, pin_constraints, bus_group, + io_location_map, io_name_map, module_name_map, netlist_annotation, + netlist_name, testbench_file_path, options); + + return status; +} + + /******************************************************************** * A top-level function of FPGA-Verilog which focuses on a wrapper module, * which encapsulate the application HDL into a mock FPGA module diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 490697d95..10a0c2877 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -18,6 +18,7 @@ #include "openfpga_port.h" #include "openfpga_reserved_words.h" #include "verilog_constants.h" +#include "verilog_preconfig_top_module_utils.h" #include "verilog_preconfig_top_module.h" #include "verilog_testbench_utils.h" #include "verilog_writer_utils.h" @@ -130,176 +131,6 @@ static void print_verilog_preconfig_top_module_ports( fp << std::endl; } -/******************************************************************** - * Print internal wires for the pre-configured FPGA top module - * The internal wires are tailored for the ports of FPGA top module - * which will be different in various configuration protocols - *******************************************************************/ -static void print_verilog_preconfig_top_module_internal_wires( - std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module) { - /* Validate the file stream */ - valid_file_stream(fp); - - /* Global ports of top-level module */ - print_verilog_comment(fp, - std::string("----- Local wires for FPGA fabric -----")); - for (const ModulePortId &module_port_id : - module_manager.module_ports(top_module)) { - BasicPort module_port = - module_manager.module_port(top_module, module_port_id); - /* Add a postfix to the internal wires to be different from other reserved - * ports */ - module_port.set_name( - module_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); - fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" - << std::endl; - } - /* Add an empty line as a splitter */ - fp << std::endl; -} - -/******************************************************************** - * Connect global ports of FPGA top module to constants except: - * 1. operating clock, which should be wired to the clock port of - * this pre-configured FPGA top module - *******************************************************************/ -static int print_verilog_preconfig_top_module_connect_global_ports( - std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module, const PinConstraints &pin_constraints, - const FabricGlobalPortInfo &fabric_global_ports, - const std::vector &benchmark_clock_port_names) { - /* Validate the file stream */ - valid_file_stream(fp); - - print_verilog_comment( - fp, - std::string("----- Begin Connect Global ports of FPGA top module -----")); - - for (const FabricGlobalPortId &global_port_id : - fabric_global_ports.global_ports()) { - ModulePortId module_global_port_id = - fabric_global_ports.global_module_port(global_port_id); - VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == - module_manager.port_type(top_module, module_global_port_id)); - BasicPort module_global_port = - module_manager.module_port(top_module, module_global_port_id); - /* Now, for operating clock port, we should wire it to the clock of - * benchmark! */ - if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) && - (false == fabric_global_ports.global_port_is_prog(global_port_id))) { - /* Wiring to each pin of the global port: benchmark clock is always 1-bit - */ - for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); - ++pin_id) { - BasicPort module_clock_pin( - module_global_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), - module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]); - - /* If the clock port name is in the pin constraints, we should wire it - * to the constrained pin */ - std::string constrained_net_name = pin_constraints.pin_net(BasicPort( - module_global_port.get_name(), module_global_port.pins()[pin_id], - module_global_port.pins()[pin_id])); - - /* If constrained to an open net or there is no clock in the benchmark, - * we assign it to a default value */ - if ((true == pin_constraints.unmapped_net(constrained_net_name)) || - (true == benchmark_clock_port_names.empty())) { - std::vector default_values( - 1, fabric_global_ports.global_port_default_value(global_port_id)); - print_verilog_wire_constant_values(fp, module_clock_pin, - default_values); - continue; - } - - std::string clock_name_to_connect; - if (!pin_constraints.unconstrained_net(constrained_net_name)) { - clock_name_to_connect = constrained_net_name; - } else { - /* Otherwise, we must have a clear one-to-one clock net - * corresponding!!! */ - if (benchmark_clock_port_names.size() != - module_global_port.get_width()) { - VTR_LOG_ERROR( - "Unable to map %lu benchmark clocks to %lu clock pins of " - "FPGA!\nRequire clear pin constraints!\n", - benchmark_clock_port_names.size(), - module_global_port.get_width()); - return CMD_EXEC_FATAL_ERROR; - } - clock_name_to_connect = benchmark_clock_port_names[pin_id]; - } - - BasicPort benchmark_clock_pin(clock_name_to_connect, 1); - print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, - false); - } - /* Finish, go to the next */ - continue; - } - - /* For other ports, give an default value */ - for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); - ++pin_id) { - BasicPort module_global_pin(module_global_port.get_name(), - module_global_port.pins()[pin_id], - module_global_port.pins()[pin_id]); - - /* If the global port name is in the pin constraints, we should wire it to - * the constrained pin */ - std::string constrained_net_name = - pin_constraints.pin_net(module_global_pin); - - module_global_pin.set_name( - module_global_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); - - /* - If constrained to a given net in the benchmark, we connect the global - * pin to the net - * - If constrained to an open net in the benchmark, we assign it to a - * default value - */ - if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && - (false == pin_constraints.unmapped_net(constrained_net_name))) { - BasicPort benchmark_pin(constrained_net_name, 1); - print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, - false); - } else { - VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == - constrained_net_name); - std::vector default_values( - module_global_pin.get_width(), - fabric_global_ports.global_port_default_value(global_port_id)); - /* For configuration done signals, we should enable them in - * preconfigured wrapper */ - if (fabric_global_ports.global_port_is_config_enable(global_port_id)) { - VTR_LOG( - "Config-enable port '%s' is detected with default value '%ld'", - module_global_pin.get_name().c_str(), - fabric_global_ports.global_port_default_value(global_port_id)); - default_values.clear(); - default_values.resize( - module_global_pin.get_width(), - 1 - fabric_global_ports.global_port_default_value(global_port_id)); - } - print_verilog_wire_constant_values(fp, module_global_pin, - default_values); - } - } - } - - print_verilog_comment( - fp, std::string("----- End Connect Global ports of FPGA top module -----")); - - /* Add an empty line as a splitter */ - fp << std::endl; - - return CMD_EXEC_SUCCESS; -} - /******************************************************************** * Impose the bitstream on the configuration memories * This function uses 'assign' syntax to impost the bitstream at mem port @@ -597,7 +428,7 @@ int print_verilog_preconfig_top_module( /* Print internal wires */ print_verilog_preconfig_top_module_internal_wires(fp, module_manager, - core_module); + core_module, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); /* Instanciate FPGA top-level module */ print_verilog_testbench_fpga_instance( @@ -614,7 +445,7 @@ int print_verilog_preconfig_top_module( * signals! */ status = print_verilog_preconfig_top_module_connect_global_ports( fp, module_manager, core_module, pin_constraints, global_ports, - benchmark_clock_port_names); + benchmark_clock_port_names, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index 0d7f3edac..7cf187b29 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -28,7 +28,8 @@ /* begin namespace openfpga */ namespace openfpga { -int print_verilog_preconfig_top_module( + +int print_verilog_testbench_io_connection( const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, const ConfigProtocol& config_protocol, const CircuitLibrary& circuit_lib, @@ -40,6 +41,7 @@ int print_verilog_preconfig_top_module( const std::string& circuit_name, const std::string& verilog_fname, const VerilogTestbenchOption& options); + } /* end namespace openfpga */ #endif diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp new file mode 100644 index 000000000..f3081ed37 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp @@ -0,0 +1,194 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Print internal wires for the pre-configured FPGA top module + * The internal wires are tailored for the ports of FPGA top module + * which will be different in various configuration protocols + *******************************************************************/ +void print_verilog_preconfig_top_module_internal_wires( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const std::string& port_postfix) { + /* Validate the file stream */ + valid_file_stream(fp); + + /* Global ports of top-level module */ + print_verilog_comment(fp, + std::string("----- Local wires for FPGA fabric -----")); + for (const ModulePortId &module_port_id : + module_manager.module_ports(top_module)) { + BasicPort module_port = + module_manager.module_port(top_module, module_port_id); + /* Add a postfix to the internal wires to be different from other reserved + * ports */ + module_port.set_name( + module_port.get_name() + port_postfix); + fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" + << std::endl; + } + /* Add an empty line as a splitter */ + fp << std::endl; +} + +/******************************************************************** + * Connect global ports of FPGA top module to constants except: + * 1. operating clock, which should be wired to the clock port of + * this pre-configured FPGA top module + *******************************************************************/ +int print_verilog_preconfig_top_module_connect_global_ports( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const PinConstraints &pin_constraints, + const FabricGlobalPortInfo &fabric_global_ports, + const std::vector &benchmark_clock_port_names, + const std::string& port_postfix) { + /* Validate the file stream */ + valid_file_stream(fp); + + print_verilog_comment( + fp, + std::string("----- Begin Connect Global ports of FPGA top module -----")); + + for (const FabricGlobalPortId &global_port_id : + fabric_global_ports.global_ports()) { + ModulePortId module_global_port_id = + fabric_global_ports.global_module_port(global_port_id); + VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == + module_manager.port_type(top_module, module_global_port_id)); + BasicPort module_global_port = + module_manager.module_port(top_module, module_global_port_id); + /* Now, for operating clock port, we should wire it to the clock of + * benchmark! */ + if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) && + (false == fabric_global_ports.global_port_is_prog(global_port_id))) { + /* Wiring to each pin of the global port: benchmark clock is always 1-bit + */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_clock_pin( + module_global_port.get_name() + + port_postfix, + module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]); + + /* If the clock port name is in the pin constraints, we should wire it + * to the constrained pin */ + std::string constrained_net_name = pin_constraints.pin_net(BasicPort( + module_global_port.get_name(), module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id])); + + /* If constrained to an open net or there is no clock in the benchmark, + * we assign it to a default value */ + if ((true == pin_constraints.unmapped_net(constrained_net_name)) || + (true == benchmark_clock_port_names.empty())) { + std::vector default_values( + 1, fabric_global_ports.global_port_default_value(global_port_id)); + print_verilog_wire_constant_values(fp, module_clock_pin, + default_values); + continue; + } + + std::string clock_name_to_connect; + if (!pin_constraints.unconstrained_net(constrained_net_name)) { + clock_name_to_connect = constrained_net_name; + } else { + /* Otherwise, we must have a clear one-to-one clock net + * corresponding!!! */ + if (benchmark_clock_port_names.size() != + module_global_port.get_width()) { + VTR_LOG_ERROR( + "Unable to map %lu benchmark clocks to %lu clock pins of " + "FPGA!\nRequire clear pin constraints!\n", + benchmark_clock_port_names.size(), + module_global_port.get_width()); + return CMD_EXEC_FATAL_ERROR; + } + clock_name_to_connect = benchmark_clock_port_names[pin_id]; + } + + BasicPort benchmark_clock_pin(clock_name_to_connect, 1); + print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, + false); + } + /* Finish, go to the next */ + continue; + } + + /* For other ports, give an default value */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_global_pin(module_global_port.get_name(), + module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id]); + + /* If the global port name is in the pin constraints, we should wire it to + * the constrained pin */ + std::string constrained_net_name = + pin_constraints.pin_net(module_global_pin); + + module_global_pin.set_name( + module_global_port.get_name() + + port_postfix); + + /* - If constrained to a given net in the benchmark, we connect the global + * pin to the net + * - If constrained to an open net in the benchmark, we assign it to a + * default value + */ + if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && + (false == pin_constraints.unmapped_net(constrained_net_name))) { + BasicPort benchmark_pin(constrained_net_name, 1); + print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, + false); + } else { + VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == + constrained_net_name); + std::vector default_values( + module_global_pin.get_width(), + fabric_global_ports.global_port_default_value(global_port_id)); + /* For configuration done signals, we should enable them in + * preconfigured wrapper */ + if (fabric_global_ports.global_port_is_config_enable(global_port_id)) { + VTR_LOG( + "Config-enable port '%s' is detected with default value '%ld'", + module_global_pin.get_name().c_str(), + fabric_global_ports.global_port_default_value(global_port_id)); + default_values.clear(); + default_values.resize( + module_global_pin.get_width(), + 1 - fabric_global_ports.global_port_default_value(global_port_id)); + } + print_verilog_wire_constant_values(fp, module_global_pin, + default_values); + } + } + } + + print_verilog_comment( + fp, std::string("----- End Connect Global ports of FPGA top module -----")); + + /* Add an empty line as a splitter */ + fp << std::endl; + + return CMD_EXEC_SUCCESS; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h new file mode 100644 index 000000000..0a14663ca --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h @@ -0,0 +1,44 @@ +#ifndef VERILOG_PRECONFIG_TOP_MODULE_UTILS_H +#define VERILOG_PRECONFIG_TOP_MODULE_UTILS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "bitstream_manager.h" +#include "bus_group.h" +#include "circuit_library.h" +#include "config_protocol.h" +#include "fabric_global_port_info.h" +#include "io_location_map.h" +#include "io_name_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "pin_constraints.h" +#include "verilog_testbench_options.h" +#include "vpr_context.h" +#include "vpr_netlist_annotation.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void print_verilog_preconfig_top_module_internal_wires( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const std::string& port_postfix); + +int print_verilog_preconfig_top_module_connect_global_ports( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const PinConstraints &pin_constraints, + const FabricGlobalPortInfo &fabric_global_ports, + const std::vector &benchmark_clock_port_names, const std::string& port_postfix); + + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp new file mode 100644 index 000000000..3dbdadaab --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp @@ -0,0 +1,138 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "bitstream_manager_utils.h" +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "openfpga_reserved_words.h" +#include "verilog_constants.h" +#include "verilog_template_testbench.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_testbench_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Top-level function to generate a template testbench for a FPGA fabric. + * + * Testbench + * +-------------------------------------------- + * | + * | FPGA fabric + * | +-------------------------------+ + * | | | + * | 0/1---->|FPGA global ports | + * | | | + * |--------->|FPGA_clock | + * | | | + * |--------->|FPGA mapped I/Os | + * | | | + * |<---------|FPGA mapped I/Os | + * | | | + * | 0/1---->|FPGA unmapped I/Os | + * | | | + * |--------->|Internal_configuration_ports | + * | +-------------------------------+ + * | + * +------------------------------------------- + *******************************************************************/ +int print_verilog_template_testbench( + const ModuleManager &module_manager, + const BitstreamManager &bitstream_manager, + const ConfigProtocol &config_protocol, const CircuitLibrary &circuit_lib, + const FabricGlobalPortInfo &global_ports, const AtomContext &atom_ctx, + const PlacementContext &place_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const IoLocationMap &io_location_map, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, + const VprNetlistAnnotation &netlist_annotation, + const std::string &circuit_name, const std::string &verilog_fname, + const VerilogTestbenchOption &options) { + std::string timer_message = + std::string( + "Write a template Verilog testbench for pre-configured FPGA top-level netlist"); + + int status = CMD_EXEC_SUCCESS; + + /* Start time count */ + vtr::ScopedStartFinishTimer timer(timer_message); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(verilog_fname.c_str(), fp); + + /* Generate a brief description on the Verilog file*/ + std::string title = + std::string("A template Verilog testbench for pre-configured FPGA fabric") + print_verilog_file_header(fp, title, options.time_stamp()); + + print_verilog_comment(fp, std::string("Require an adaption to your needs before used for design verification!!!")); + + print_verilog_default_net_type_declaration(fp, options.default_net_type()); + + /* Module declaration */ + fp << "module " << options.top_module(); + fp << ";" << std::endl; + + /* Spot the dut module */ + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); + if (!module_manager.valid_module_id(top_module)) { + VTR_LOG_ERROR( + "Unable to find the DUT module '%s'. Please check if you create " + "dedicated module when building the fabric!\n", + options.dut_module().c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Note that we always need the core module as it contains the original port + * names before possible renaming at top-level module. If there is no core + * module, it means that the current top module is the core module */ + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); + if (!module_manager.valid_module_id(core_module)) { + core_module = top_module; + } + + /* Print internal wires */ + print_verilog_preconfig_top_module_internal_wires(fp, module_manager, + core_module, std::string()); + + /* Instanciate FPGA top-level module */ + print_verilog_testbench_fpga_instance( + fp, module_manager, top_module, core_module, + std::string(FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME), + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), io_name_map, + options.explicit_port_mapping()); + + /* Testbench ends*/ + print_verilog_module_end( + fp, + options.top_module(), + options.default_net_type()); + + /* Close the file stream */ + fp.close(); + + return status; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.h b/openfpga/src/fpga_verilog/verilog_template_testbench.h new file mode 100644 index 000000000..3bd459975 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.h @@ -0,0 +1,45 @@ +#ifndef VERILOG_TEMPLATE_TESTBENCH_H +#define VERILOG_TEMPLATE_TESTBENCH_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "bitstream_manager.h" +#include "bus_group.h" +#include "circuit_library.h" +#include "config_protocol.h" +#include "fabric_global_port_info.h" +#include "io_location_map.h" +#include "io_name_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "pin_constraints.h" +#include "verilog_testbench_options.h" +#include "vpr_context.h" +#include "vpr_netlist_annotation.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int print_verilog_template_testbench( + const ModuleManager& module_manager, + const BitstreamManager& bitstream_manager, + const ConfigProtocol& config_protocol, const CircuitLibrary& circuit_lib, + const FabricGlobalPortInfo& global_ports, const AtomContext& atom_ctx, + const PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const IoLocationMap& io_location_map, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, + const VprNetlistAnnotation& netlist_annotation, + const std::string& circuit_name, const std::string& verilog_fname, + const VerilogTestbenchOption& options); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp index 5e4709419..a6db0353b 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp @@ -15,6 +15,7 @@ namespace openfpga { *************************************************/ VerilogTestbenchOption::VerilogTestbenchOption() { output_directory_.clear(); + top_module_ = "top_tb"; dut_module_ = "fpga_top"; fabric_netlist_file_path_.clear(); reference_benchmark_file_path_.clear(); @@ -41,6 +42,8 @@ std::string VerilogTestbenchOption::output_directory() const { std::string VerilogTestbenchOption::dut_module() const { return dut_module_; } +std::string VerilogTestbenchOption::top_module() const { return top_module_; } + std::string VerilogTestbenchOption::fabric_netlist_file_path() const { return fabric_netlist_file_path_; } @@ -112,6 +115,19 @@ void VerilogTestbenchOption::set_output_directory( output_directory_ = output_dir; } +void VerilogTestbenchOption::set_top_module(const std::string& top_module) { + /* Precheck: avoid naming conflicts */ + if (top_module == generate_fpga_top_module_name() || + top_module == generate_fpga_core_module_name()) { + VTR_LOG_ERROR( + "Conflicted module name '%s' as top-levle module! Please avoid [%s|%s]\n", + top_module.c_str(), generate_fpga_top_module_name().c_str(), + generate_fpga_core_module_name().c_str()); + exit(1); + } + top_module_ = top_module; +} + void VerilogTestbenchOption::set_dut_module(const std::string& dut_module) { /* Precheck: only accept two legal names */ if (dut_module != generate_fpga_top_module_name() && diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.h b/openfpga/src/fpga_verilog/verilog_testbench_options.h index aafa15d71..97d2e27fd 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.h @@ -37,6 +37,7 @@ class VerilogTestbenchOption { public: /* Public accessors */ std::string output_directory() const; + std::string top_module() const; std::string dut_module() const; std::string fabric_netlist_file_path() const; std::string reference_benchmark_file_path() const; @@ -61,6 +62,7 @@ class VerilogTestbenchOption { public: /* Public mutators */ void set_output_directory(const std::string& output_dir); + void set_top_module(const std::string& top_module); void set_dut_module(const std::string& dut_module); /* The reference verilog file path is the key parameters that will have an * impact on other options: @@ -95,6 +97,7 @@ class VerilogTestbenchOption { private: /* Internal Data */ std::string output_directory_; + std::string top_module_; std::string dut_module_; std::string fabric_netlist_file_path_; std::string reference_benchmark_file_path_; From 36fa020c156317a84634eaf72526461d586c57da Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 16:33:19 -0700 Subject: [PATCH 127/174] [core] syntax --- openfpga/src/base/openfpga_verilog_template.h | 20 ++++---- openfpga/src/fpga_verilog/verilog_api.cpp | 51 ++++++++++++++----- openfpga/src/fpga_verilog/verilog_api.h | 16 ++++++ .../verilog_preconfig_top_module.h | 2 +- .../verilog_template_testbench.cpp | 10 +--- .../fpga_verilog/verilog_template_testbench.h | 23 ++------- 6 files changed, 71 insertions(+), 51 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog_template.h b/openfpga/src/base/openfpga_verilog_template.h index 0f5923948..93ee4be7a 100644 --- a/openfpga/src/base/openfpga_verilog_template.h +++ b/openfpga/src/base/openfpga_verilog_template.h @@ -244,6 +244,11 @@ int write_testbench_template_template( options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { + options.set_default_net_type( + cmd_context.option_value(cmd, opt_default_net_type)); + } + if (true == cmd_context.option_enable(cmd, opt_dut_module)) { options.set_dut_module(cmd_context.option_value(cmd, opt_dut_module)); } @@ -253,12 +258,8 @@ int write_testbench_template_template( } return fpga_verilog_template_testbench( - openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), - g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, - openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), - openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), - openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.arch().config_protocol, options); + openfpga_ctx.module_graph(), openfpga_ctx.io_name_map(), + openfpga_ctx.module_name_map(), options); } /******************************************************************** @@ -303,12 +304,11 @@ int write_testbench_io_connection_template( } return fpga_verilog_testbench_io_connection( - openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), + openfpga_ctx.module_graph(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, - openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), + openfpga_ctx.io_location_map(), openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), - openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.arch().config_protocol, options); + openfpga_ctx.vpr_netlist_annotation(), options); } /******************************************************************** diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index c8282893e..c18220cba 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -21,6 +21,7 @@ #include "verilog_mock_fpga_wrapper.h" #include "verilog_preconfig_top_module.h" #include "verilog_template_testbench.h" +#include "verilog_testbench_io_connection.h" #include "verilog_routing.h" #include "verilog_simulation_info_writer.h" #include "verilog_submodule.h" @@ -265,18 +266,45 @@ int fpga_verilog_preconfigured_fabric_wrapper( ********************************************************************/ int fpga_verilog_template_testbench( const ModuleManager &module_manager, - const BitstreamManager &bitstream_manager, const AtomContext &atom_ctx, - const PlacementContext &place_ctx, const PinConstraints &pin_constraints, - const BusGroup &bus_group, const IoLocationMap &io_location_map, const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const FabricGlobalPortInfo &fabric_global_port_info, - const VprNetlistAnnotation &netlist_annotation, - const CircuitLibrary &circuit_lib, const ConfigProtocol &config_protocol, const VerilogTestbenchOption &options) { vtr::ScopedStartFinishTimer timer( "Write a template testbench for a preconfigured FPGA fabric\n"); - std::string src_dir_path = format_dir_path(options.output_directory()); + std::string src_dir_path = format_dir_path(find_path_dir_name(options.output_directory())); + std::string testbench_file_path = options.output_directory(); + + int status = CMD_EXEC_SUCCESS; + + /* Create directories */ + create_directory(src_dir_path); + + /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and + * pre-configured testbench for verification */ + status = print_verilog_template_testbench( + module_manager, io_name_map, module_name_map, + testbench_file_path, options); + + return status; +} + +/******************************************************************** + * A top-level function of FPGA-Verilog which focuses on generating I/O connection part of testbenches + ********************************************************************/ +int fpga_verilog_testbench_io_connection( + const ModuleManager &module_manager, + const AtomContext &atom_ctx, + const PlacementContext &place_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const IoLocationMap &io_location_map, + const ModuleNameMap &module_name_map, + const FabricGlobalPortInfo &fabric_global_port_info, + const VprNetlistAnnotation &netlist_annotation, + const VerilogTestbenchOption &options) { + vtr::ScopedStartFinishTimer timer( + "Write a template testbench for a preconfigured FPGA fabric\n"); + + std::string src_dir_path = format_dir_path(find_path_dir_name(options.output_directory())); + std::string testbench_file_path = options.output_directory(); std::string netlist_name = atom_ctx.nlist.netlist_name(); @@ -287,13 +315,10 @@ int fpga_verilog_template_testbench( /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and * pre-configured testbench for verification */ - std::string testbench_file_path = - src_dir_path + options.top_module_name() + - std::string(VERILOG_NETLIST_FILE_POSTFIX); - status = print_verilog_template_testbench( - module_manager, bitstream_manager, config_protocol, circuit_lib, + status = print_verilog_testbench_io_connection( + module_manager, fabric_global_port_info, atom_ctx, place_ctx, pin_constraints, bus_group, - io_location_map, io_name_map, module_name_map, netlist_annotation, + io_location_map, module_name_map, netlist_annotation, netlist_name, testbench_file_path, options); return status; diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index bef74daad..be1c7f91c 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -74,6 +74,22 @@ int fpga_verilog_preconfigured_fabric_wrapper( const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, const VerilogTestbenchOption& options); +int fpga_verilog_template_testbench( + const ModuleManager &module_manager, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, + const VerilogTestbenchOption &options); + +int fpga_verilog_testbench_io_connection( + const ModuleManager &module_manager, + const AtomContext &atom_ctx, + const PlacementContext &place_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const IoLocationMap &io_location_map, + const ModuleNameMap &module_name_map, + const FabricGlobalPortInfo &fabric_global_port_info, + const VprNetlistAnnotation &netlist_annotation, + const VerilogTestbenchOption &options); + + int fpga_verilog_mock_fpga_wrapper( const ModuleManager& module_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index 7cf187b29..bb5ec6138 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -29,7 +29,7 @@ namespace openfpga { -int print_verilog_testbench_io_connection( +int print_verilog_preconfig_top_module( const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, const ConfigProtocol& config_protocol, const CircuitLibrary& circuit_lib, diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp index 3dbdadaab..5b10bfcac 100644 --- a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp @@ -52,14 +52,8 @@ namespace openfpga { *******************************************************************/ int print_verilog_template_testbench( const ModuleManager &module_manager, - const BitstreamManager &bitstream_manager, - const ConfigProtocol &config_protocol, const CircuitLibrary &circuit_lib, - const FabricGlobalPortInfo &global_ports, const AtomContext &atom_ctx, - const PlacementContext &place_ctx, const PinConstraints &pin_constraints, - const BusGroup &bus_group, const IoLocationMap &io_location_map, const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const VprNetlistAnnotation &netlist_annotation, - const std::string &circuit_name, const std::string &verilog_fname, + const std::string &verilog_fname, const VerilogTestbenchOption &options) { std::string timer_message = std::string( @@ -79,7 +73,7 @@ int print_verilog_template_testbench( /* Generate a brief description on the Verilog file*/ std::string title = - std::string("A template Verilog testbench for pre-configured FPGA fabric") + std::string("A template Verilog testbench for pre-configured FPGA fabric"); print_verilog_file_header(fp, title, options.time_stamp()); print_verilog_comment(fp, std::string("Require an adaption to your needs before used for design verification!!!")); diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.h b/openfpga/src/fpga_verilog/verilog_template_testbench.h index 3bd459975..6b4ea2283 100644 --- a/openfpga/src/fpga_verilog/verilog_template_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.h @@ -7,19 +7,10 @@ #include #include -#include "bitstream_manager.h" -#include "bus_group.h" -#include "circuit_library.h" -#include "config_protocol.h" -#include "fabric_global_port_info.h" -#include "io_location_map.h" #include "io_name_map.h" #include "module_manager.h" #include "module_name_map.h" -#include "pin_constraints.h" #include "verilog_testbench_options.h" -#include "vpr_context.h" -#include "vpr_netlist_annotation.h" /******************************************************************** * Function declaration @@ -29,16 +20,10 @@ namespace openfpga { int print_verilog_template_testbench( - const ModuleManager& module_manager, - const BitstreamManager& bitstream_manager, - const ConfigProtocol& config_protocol, const CircuitLibrary& circuit_lib, - const FabricGlobalPortInfo& global_ports, const AtomContext& atom_ctx, - const PlacementContext& place_ctx, const PinConstraints& pin_constraints, - const BusGroup& bus_group, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, - const VprNetlistAnnotation& netlist_annotation, - const std::string& circuit_name, const std::string& verilog_fname, - const VerilogTestbenchOption& options); + const ModuleManager &module_manager, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, + const std::string &verilog_fname, + const VerilogTestbenchOption &options); } /* end namespace openfpga */ From 649d44b2d864223e09e4d471d49452735ea402c0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 16:33:55 -0700 Subject: [PATCH 128/174] [core] code format --- .../base/openfpga_verilog_command_template.h | 27 ++++++++------ openfpga/src/base/openfpga_verilog_template.h | 16 ++++----- openfpga/src/fpga_verilog/verilog_api.cpp | 35 +++++++++---------- openfpga/src/fpga_verilog/verilog_api.h | 24 ++++++------- .../verilog_preconfig_top_module.cpp | 10 +++--- .../verilog_preconfig_top_module.h | 2 -- .../verilog_preconfig_top_module_utils.cpp | 18 ++++------ .../verilog_preconfig_top_module_utils.h | 6 ++-- .../verilog_template_testbench.cpp | 30 ++++++++-------- .../fpga_verilog/verilog_template_testbench.h | 10 +++--- 10 files changed, 88 insertions(+), 90 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog_command_template.h b/openfpga/src/base/openfpga_verilog_command_template.h index 160ce809f..6b27dd5e1 100644 --- a/openfpga/src/base/openfpga_verilog_command_template.h +++ b/openfpga/src/base/openfpga_verilog_command_template.h @@ -283,9 +283,11 @@ ShellCommandId add_write_testbench_template_command_template( shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); /* add an option '--top_module'*/ - CommandOptionId top_module_opt = shell_cmd.add_option( - "top_module", false, - "specify the top-level module name to be used in the testbench. Please avoid reserved words, i.e., fpga_top or fpga_core. By default, it is top_tb."); + CommandOptionId top_module_opt = + shell_cmd.add_option("top_module", false, + "specify the top-level module name to be used in the " + "testbench. Please avoid reserved words, i.e., " + "fpga_top or fpga_core. By default, it is top_tb."); shell_cmd.set_option_require_value(top_module_opt, openfpga::OPT_STRING); /* add an option '--dut_module'*/ @@ -315,10 +317,12 @@ ShellCommandId add_write_testbench_template_command_template( /* add command to the shell */ ShellCommandId shell_cmd_id = shell.add_command( - shell_cmd, "generate a template of testbench for a pre-configured fpga fabric", hidden); + shell_cmd, + "generate a template of testbench for a pre-configured fpga fabric", + hidden); shell.set_command_class(shell_cmd_id, cmd_class_id); - shell.set_command_execute_function( - shell_cmd_id, write_testbench_template_template); + shell.set_command_execute_function(shell_cmd_id, + write_testbench_template_template); /* add command dependency to the shell */ shell.set_command_dependency(shell_cmd_id, dependent_cmds); @@ -371,11 +375,14 @@ ShellCommandId add_write_testbench_io_connection_command_template( shell_cmd.add_option("verbose", false, "enable verbose output"); /* add command to the shell */ - ShellCommandId shell_cmd_id = shell.add_command( - shell_cmd, "generate a file to describe the connection to I/Os of a pre-configured fpga fabric", hidden); + ShellCommandId shell_cmd_id = + shell.add_command(shell_cmd, + "generate a file to describe the connection to I/Os of a " + "pre-configured fpga fabric", + hidden); shell.set_command_class(shell_cmd_id, cmd_class_id); - shell.set_command_execute_function( - shell_cmd_id, write_testbench_io_connection_template); + shell.set_command_execute_function(shell_cmd_id, + write_testbench_io_connection_template); /* add command dependency to the shell */ shell.set_command_dependency(shell_cmd_id, dependent_cmds); diff --git a/openfpga/src/base/openfpga_verilog_template.h b/openfpga/src/base/openfpga_verilog_template.h index 93ee4be7a..66070a777 100644 --- a/openfpga/src/base/openfpga_verilog_template.h +++ b/openfpga/src/base/openfpga_verilog_template.h @@ -222,9 +222,8 @@ int write_preconfigured_fabric_wrapper_template( *FPGA-Verilog *******************************************************************/ template -int write_testbench_template_template( - const T& openfpga_ctx, const Command& cmd, - const CommandContext& cmd_context) { +int write_testbench_template_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_top_module = cmd.option("top_module"); CommandOptionId opt_dut_module = cmd.option("dut_module"); @@ -267,9 +266,9 @@ int write_testbench_template_template( *FPGA-Verilog *******************************************************************/ template -int write_testbench_io_connection_template( - const T& openfpga_ctx, const Command& cmd, - const CommandContext& cmd_context) { +int write_testbench_io_connection_template(const T& openfpga_ctx, + const Command& cmd, + const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_dut_module = cmd.option("dut_module"); CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); @@ -304,9 +303,8 @@ int write_testbench_io_connection_template( } return fpga_verilog_testbench_io_connection( - openfpga_ctx.module_graph(), - g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, - openfpga_ctx.io_location_map(), + openfpga_ctx.module_graph(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), + pin_constraints, bus_group, openfpga_ctx.io_location_map(), openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), options); } diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index c18220cba..a8d2f78b2 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -20,11 +20,11 @@ #include "verilog_grid.h" #include "verilog_mock_fpga_wrapper.h" #include "verilog_preconfig_top_module.h" -#include "verilog_template_testbench.h" -#include "verilog_testbench_io_connection.h" #include "verilog_routing.h" #include "verilog_simulation_info_writer.h" #include "verilog_submodule.h" +#include "verilog_template_testbench.h" +#include "verilog_testbench_io_connection.h" #include "verilog_tile.h" #include "verilog_top_module.h" #include "verilog_top_testbench.h" @@ -264,14 +264,15 @@ int fpga_verilog_preconfigured_fabric_wrapper( * - A wrapper module, which encapsulate the FPGA module in a Verilog module *which have the same port as the input benchmark ********************************************************************/ -int fpga_verilog_template_testbench( - const ModuleManager &module_manager, - const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const VerilogTestbenchOption &options) { +int fpga_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const VerilogTestbenchOption &options) { vtr::ScopedStartFinishTimer timer( "Write a template testbench for a preconfigured FPGA fabric\n"); - std::string src_dir_path = format_dir_path(find_path_dir_name(options.output_directory())); + std::string src_dir_path = + format_dir_path(find_path_dir_name(options.output_directory())); std::string testbench_file_path = options.output_directory(); int status = CMD_EXEC_SUCCESS; @@ -282,18 +283,17 @@ int fpga_verilog_template_testbench( /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and * pre-configured testbench for verification */ status = print_verilog_template_testbench( - module_manager, io_name_map, module_name_map, - testbench_file_path, options); + module_manager, io_name_map, module_name_map, testbench_file_path, options); return status; } /******************************************************************** - * A top-level function of FPGA-Verilog which focuses on generating I/O connection part of testbenches + * A top-level function of FPGA-Verilog which focuses on generating I/O + *connection part of testbenches ********************************************************************/ int fpga_verilog_testbench_io_connection( - const ModuleManager &module_manager, - const AtomContext &atom_ctx, + const ModuleManager &module_manager, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints &pin_constraints, const BusGroup &bus_group, const IoLocationMap &io_location_map, const ModuleNameMap &module_name_map, @@ -303,7 +303,8 @@ int fpga_verilog_testbench_io_connection( vtr::ScopedStartFinishTimer timer( "Write a template testbench for a preconfigured FPGA fabric\n"); - std::string src_dir_path = format_dir_path(find_path_dir_name(options.output_directory())); + std::string src_dir_path = + format_dir_path(find_path_dir_name(options.output_directory())); std::string testbench_file_path = options.output_directory(); std::string netlist_name = atom_ctx.nlist.netlist_name(); @@ -316,15 +317,13 @@ int fpga_verilog_testbench_io_connection( /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and * pre-configured testbench for verification */ status = print_verilog_testbench_io_connection( - module_manager, - fabric_global_port_info, atom_ctx, place_ctx, pin_constraints, bus_group, - io_location_map, module_name_map, netlist_annotation, - netlist_name, testbench_file_path, options); + module_manager, fabric_global_port_info, atom_ctx, place_ctx, + pin_constraints, bus_group, io_location_map, module_name_map, + netlist_annotation, netlist_name, testbench_file_path, options); return status; } - /******************************************************************** * A top-level function of FPGA-Verilog which focuses on a wrapper module, * which encapsulate the application HDL into a mock FPGA module diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index be1c7f91c..5030288d0 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -74,21 +74,19 @@ int fpga_verilog_preconfigured_fabric_wrapper( const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, const VerilogTestbenchOption& options); -int fpga_verilog_template_testbench( - const ModuleManager &module_manager, - const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const VerilogTestbenchOption &options); +int fpga_verilog_template_testbench(const ModuleManager& module_manager, + const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, + const VerilogTestbenchOption& options); int fpga_verilog_testbench_io_connection( - const ModuleManager &module_manager, - const AtomContext &atom_ctx, - const PlacementContext &place_ctx, const PinConstraints &pin_constraints, - const BusGroup &bus_group, const IoLocationMap &io_location_map, - const ModuleNameMap &module_name_map, - const FabricGlobalPortInfo &fabric_global_port_info, - const VprNetlistAnnotation &netlist_annotation, - const VerilogTestbenchOption &options); - + const ModuleManager& module_manager, const AtomContext& atom_ctx, + const PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const IoLocationMap& io_location_map, + const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& fabric_global_port_info, + const VprNetlistAnnotation& netlist_annotation, + const VerilogTestbenchOption& options); int fpga_verilog_mock_fpga_wrapper( const ModuleManager& module_manager, const AtomContext& atom_ctx, diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 10a0c2877..e278ff9fa 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -18,8 +18,8 @@ #include "openfpga_port.h" #include "openfpga_reserved_words.h" #include "verilog_constants.h" -#include "verilog_preconfig_top_module_utils.h" #include "verilog_preconfig_top_module.h" +#include "verilog_preconfig_top_module_utils.h" #include "verilog_testbench_utils.h" #include "verilog_writer_utils.h" @@ -427,8 +427,9 @@ int print_verilog_preconfig_top_module( } /* Print internal wires */ - print_verilog_preconfig_top_module_internal_wires(fp, module_manager, - core_module, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); + print_verilog_preconfig_top_module_internal_wires( + fp, module_manager, core_module, + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); /* Instanciate FPGA top-level module */ print_verilog_testbench_fpga_instance( @@ -445,7 +446,8 @@ int print_verilog_preconfig_top_module( * signals! */ status = print_verilog_preconfig_top_module_connect_global_ports( fp, module_manager, core_module, pin_constraints, global_ports, - benchmark_clock_port_names, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); + benchmark_clock_port_names, + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index bb5ec6138..0d7f3edac 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -28,7 +28,6 @@ /* begin namespace openfpga */ namespace openfpga { - int print_verilog_preconfig_top_module( const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, @@ -41,7 +40,6 @@ int print_verilog_preconfig_top_module( const std::string& circuit_name, const std::string& verilog_fname, const VerilogTestbenchOption& options); - } /* end namespace openfpga */ #endif diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp index f3081ed37..944506c89 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp @@ -28,7 +28,7 @@ namespace openfpga { *******************************************************************/ void print_verilog_preconfig_top_module_internal_wires( std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module, const std::string& port_postfix) { + const ModuleId &top_module, const std::string &port_postfix) { /* Validate the file stream */ valid_file_stream(fp); @@ -41,8 +41,7 @@ void print_verilog_preconfig_top_module_internal_wires( module_manager.module_port(top_module, module_port_id); /* Add a postfix to the internal wires to be different from other reserved * ports */ - module_port.set_name( - module_port.get_name() + port_postfix); + module_port.set_name(module_port.get_name() + port_postfix); fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" << std::endl; } @@ -60,7 +59,7 @@ int print_verilog_preconfig_top_module_connect_global_ports( const ModuleId &top_module, const PinConstraints &pin_constraints, const FabricGlobalPortInfo &fabric_global_ports, const std::vector &benchmark_clock_port_names, - const std::string& port_postfix) { + const std::string &port_postfix) { /* Validate the file stream */ valid_file_stream(fp); @@ -84,10 +83,9 @@ int print_verilog_preconfig_top_module_connect_global_ports( */ for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); ++pin_id) { - BasicPort module_clock_pin( - module_global_port.get_name() + - port_postfix, - module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]); + BasicPort module_clock_pin(module_global_port.get_name() + port_postfix, + module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id]); /* If the clock port name is in the pin constraints, we should wire it * to the constrained pin */ @@ -144,9 +142,7 @@ int print_verilog_preconfig_top_module_connect_global_ports( std::string constrained_net_name = pin_constraints.pin_net(module_global_pin); - module_global_pin.set_name( - module_global_port.get_name() + - port_postfix); + module_global_pin.set_name(module_global_port.get_name() + port_postfix); /* - If constrained to a given net in the benchmark, we connect the global * pin to the net diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h index 0a14663ca..55c85eadd 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h @@ -30,14 +30,14 @@ namespace openfpga { void print_verilog_preconfig_top_module_internal_wires( std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module, const std::string& port_postfix); + const ModuleId &top_module, const std::string &port_postfix); int print_verilog_preconfig_top_module_connect_global_ports( std::fstream &fp, const ModuleManager &module_manager, const ModuleId &top_module, const PinConstraints &pin_constraints, const FabricGlobalPortInfo &fabric_global_ports, - const std::vector &benchmark_clock_port_names, const std::string& port_postfix); - + const std::vector &benchmark_clock_port_names, + const std::string &port_postfix); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp index 5b10bfcac..3f48d2a6c 100644 --- a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp @@ -18,8 +18,8 @@ #include "openfpga_port.h" #include "openfpga_reserved_words.h" #include "verilog_constants.h" -#include "verilog_template_testbench.h" #include "verilog_preconfig_top_module_utils.h" +#include "verilog_template_testbench.h" #include "verilog_testbench_utils.h" #include "verilog_writer_utils.h" @@ -29,7 +29,7 @@ namespace openfpga { /******************************************************************** * Top-level function to generate a template testbench for a FPGA fabric. * - * Testbench + * Testbench * +-------------------------------------------- * | * | FPGA fabric @@ -50,14 +50,14 @@ namespace openfpga { * | * +------------------------------------------- *******************************************************************/ -int print_verilog_template_testbench( - const ModuleManager &module_manager, - const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const std::string &verilog_fname, - const VerilogTestbenchOption &options) { - std::string timer_message = - std::string( - "Write a template Verilog testbench for pre-configured FPGA top-level netlist"); +int print_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const std::string &verilog_fname, + const VerilogTestbenchOption &options) { + std::string timer_message = std::string( + "Write a template Verilog testbench for pre-configured FPGA top-level " + "netlist"); int status = CMD_EXEC_SUCCESS; @@ -76,7 +76,9 @@ int print_verilog_template_testbench( std::string("A template Verilog testbench for pre-configured FPGA fabric"); print_verilog_file_header(fp, title, options.time_stamp()); - print_verilog_comment(fp, std::string("Require an adaption to your needs before used for design verification!!!")); + print_verilog_comment(fp, + std::string("Require an adaption to your needs before " + "used for design verification!!!")); print_verilog_default_net_type_declaration(fp, options.default_net_type()); @@ -118,10 +120,8 @@ int print_verilog_template_testbench( options.explicit_port_mapping()); /* Testbench ends*/ - print_verilog_module_end( - fp, - options.top_module(), - options.default_net_type()); + print_verilog_module_end(fp, options.top_module(), + options.default_net_type()); /* Close the file stream */ fp.close(); diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.h b/openfpga/src/fpga_verilog/verilog_template_testbench.h index 6b4ea2283..baa07cbc7 100644 --- a/openfpga/src/fpga_verilog/verilog_template_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.h @@ -19,11 +19,11 @@ /* begin namespace openfpga */ namespace openfpga { -int print_verilog_template_testbench( - const ModuleManager &module_manager, - const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, - const std::string &verilog_fname, - const VerilogTestbenchOption &options); +int print_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const std::string &verilog_fname, + const VerilogTestbenchOption &options); } /* end namespace openfpga */ From 8bee65853c9b14d1361a759327a4fb973ef2925f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 19:01:25 -0700 Subject: [PATCH 129/174] [core] add missing files --- .../verilog_testbench_io_connection.cpp | 111 ++++++++++++++++++ .../verilog_testbench_io_connection.h | 38 ++++++ 2 files changed, 149 insertions(+) create mode 100644 openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp create mode 100644 openfpga/src/fpga_verilog/verilog_testbench_io_connection.h diff --git a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp new file mode 100644 index 000000000..30018e400 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp @@ -0,0 +1,111 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "openfpga_reserved_words.h" +#include "verilog_constants.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_testbench_io_connection.h" +#include "verilog_testbench_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Top-level function to generate the I/O connections for a pre-configured FPGA + *fabric. + *******************************************************************/ +int print_verilog_testbench_io_connection( + const ModuleManager &module_manager, const FabricGlobalPortInfo &global_ports, + const AtomContext &atom_ctx, const PlacementContext &place_ctx, + const PinConstraints &pin_constraints, const BusGroup &bus_group, + const IoLocationMap &io_location_map, const ModuleNameMap &module_name_map, + const VprNetlistAnnotation &netlist_annotation, + const std::string &circuit_name, const std::string &verilog_fname, + const VerilogTestbenchOption &options) { + std::string timer_message = std::string( + "Write I/O connections for pre-configured FPGA " + "fabric mapped to design '") + + circuit_name + std::string("'"); + + int status = CMD_EXEC_SUCCESS; + + /* Start time count */ + vtr::ScopedStartFinishTimer timer(timer_message); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(verilog_fname.c_str(), fp); + + /* Generate a brief description on the Verilog file*/ + std::string title = + std::string( + "I/O connections for a pre-configured FPGA fabric mapped to design: ") + + circuit_name; + print_verilog_file_header(fp, title, options.time_stamp()); + + /* Spot the dut module */ + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); + if (!module_manager.valid_module_id(top_module)) { + VTR_LOG_ERROR( + "Unable to find the DUT module '%s'. Please check if you create " + "dedicated module when building the fabric!\n", + options.dut_module().c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Note that we always need the core module as it contains the original port + * names before possible renaming at top-level module. If there is no core + * module, it means that the current top module is the core module */ + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); + if (!module_manager.valid_module_id(core_module)) { + core_module = top_module; + } + + /* Find clock ports in benchmark */ + std::vector benchmark_clock_port_names = + find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation); + + /* Connect FPGA top module global ports to constant or benchmark global + * signals! */ + status = print_verilog_preconfig_top_module_connect_global_ports( + fp, module_manager, core_module, pin_constraints, global_ports, + benchmark_clock_port_names, std::string()); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + + /* Connect I/Os to benchmark I/Os or constant driver */ + print_verilog_testbench_connect_fpga_ios( + fp, module_manager, core_module, atom_ctx, place_ctx, io_location_map, + netlist_annotation, bus_group, std::string(), std::string(), std::string(), + std::vector(), (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); + + /* Close the file stream */ + fp.close(); + + return status; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h new file mode 100644 index 000000000..9875c4d61 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h @@ -0,0 +1,38 @@ +#ifndef VERILOG_TESTBENCH_IO_CONNECTION_H +#define VERILOG_TESTBENCH_IO_CONNECTION_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "bus_group.h" +#include "fabric_global_port_info.h" +#include "io_location_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "pin_constraints.h" +#include "verilog_testbench_options.h" +#include "vpr_context.h" +#include "vpr_netlist_annotation.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int print_verilog_testbench_io_connection( + const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const AtomContext& atom_ctx, const PlacementContext& place_ctx, + const PinConstraints& pin_constraints, const BusGroup& bus_group, + const IoLocationMap& io_location_map, const ModuleNameMap& module_name_map, + const VprNetlistAnnotation& netlist_annotation, + const std::string& circuit_name, const std::string& verilog_fname, + const VerilogTestbenchOption& options); + +} /* end namespace openfpga */ + +#endif From 8e875f34533f94a78f437391e27077e30754f4f5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 21:08:36 -0700 Subject: [PATCH 130/174] [test] add a new test case to validate the new feature --- ...testbench_template_example_script.openfpga | 57 +++++++++++++++++++ .../regression_test_scripts/basic_reg_test.sh | 1 + .../config/counter8_bus_group.xml | 12 ++++ .../config/mac4_bus_group.xml | 26 +++++++++ .../config/pin_constraints_dummy.xml | 5 ++ .../config/pin_constraints_reset.xml | 7 +++ .../config/task.conf | 51 +++++++++++++++++ 7 files changed, 159 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga create mode 100644 openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml create mode 100644 openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf diff --git a/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga new file mode 100644 index 000000000..7f0f8eeaf --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga @@ -0,0 +1,57 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal + +# 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 --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 #--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 --verbose + +# Write template testbenches +write_testbench_template --file ./TESTBENCH/template_testbench.v --top_module template_top_tb ${OPENFPGA_VERILOG_PORT_MAPPING} +write_testbench_io_connection --file ./TESTBENCH/io_connections.v --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bus_group_file ${OPENFPGA_BUS_GROUP_FILE} + +# 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 dd945b427..e240b64dd 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -99,6 +99,7 @@ run-task basic_tests/generate_fabric $@ echo -e "Testing Verilog testbench generation only"; run-task basic_tests/generate_testbench $@ +run-task basic_tests/generate_template_testbench $@ echo -e "Testing separated Verilog fabric netlists and testbench locations"; run-task basic_tests/custom_fabric_netlist_location $@ diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml new file mode 100644 index 000000000..a0fd22f77 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml new file mode 100644 index 000000000..50a42a566 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml new file mode 100644 index 000000000..9d692672b --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml @@ -0,0 +1,5 @@ + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf new file mode 100644 index 000000000..e869ac5a1 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/write_testbench_template_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_verilog_port_mapping=--explicit_port_mapping + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v +bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt +bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys + +bench0_top = counter +bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml +bench0_openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml + +bench1_top = mac_4 +bench1_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_dummy.xml +bench1_openfpga_bus_group_file=${PATH:TASK_DIR}/config/mac4_bus_group.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] From 16f4e2938f8fc2d8429043e1a4b5d2ca5e249ec4 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 21:22:37 -0700 Subject: [PATCH 131/174] [doc] add new comand --- .../fpga_verilog_commands.rst | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index d8337a9ce..16db7cf8c 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -180,6 +180,83 @@ __ iverilog_website_ Show verbose log + +.. _cmd_write_testbench_template: + +write_testbench_template +~~~~~~~~~~~~~~~~~~~~~~~~ + + Write a template of testbench for a preconfigured FPGA fabric. See details in :ref:`fpga_verilog_testbench`. + +.. warning:: The template testbench only contains an instance of FPGA fabric. Please do **NOT** directly use it in design verification without a proper modification!!! + + .. option:: --file or -f + + The file path to output the testbench file. For example, ``--file /temp/testbench_template.v`` + + .. option:: --top_module + + Specify the name of top-level module to be considered in the testbench. Please avoid reserved words, i.e., ``fpga_top`` or ``fpga_core. By default, it is ``top_tb``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --dut_module + + Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --explicit_port_mapping + + Use explicit port mapping when writing the Verilog netlists + + .. option:: --default_net_type + + Specify the default net type for the Verilog netlists. Currently, supported types are ``none`` and ``wire``. Default value: ``none``. + + .. option:: --no_time_stamp + + Do not print time stamp in Verilog netlists + + .. option:: --verbose + + Show verbose log + +write_testbench_io_connection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Write the I/O connection statements in Verilog for a preconfigured FPGA fabric mapped to a given design. See details in :ref:`fpga_verilog_testbench`. + +.. warning:: The netlist may be included by the template testbench (see details in :ref:`cmd_write_testbench_template`). Please do **NOT** directly use it in design verification without a proper modification!!! + + .. option:: --file or -f + + The file path to output the netlist file. For example, ``--file /temp/testbench_io_conkt.v`` + + .. option:: --dut_module + + Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --pin_constraints_file or -pcf + + Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` + Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. + + .. option:: --bus_group_file or -bgf + + Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml`` + Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`. + + .. option:: --no_time_stamp + + Do not print time stamp in Verilog netlists + + .. option:: --verbose + + Show verbose log + write_mock_fpga_wrapper ~~~~~~~~~~~~~~~~~~~~~~~ From 442dc9ddec2e2441daf20ee48a5345cfdda4401f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Nov 2023 21:27:12 -0700 Subject: [PATCH 132/174] [doc] format --- .../openfpga_commands/fpga_verilog_commands.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index 16db7cf8c..d3497cd98 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -188,7 +188,7 @@ write_testbench_template Write a template of testbench for a preconfigured FPGA fabric. See details in :ref:`fpga_verilog_testbench`. -.. warning:: The template testbench only contains an instance of FPGA fabric. Please do **NOT** directly use it in design verification without a proper modification!!! + .. warning:: The template testbench only contains an instance of FPGA fabric. Please do **NOT** directly use it in design verification without a proper modification!!! .. option:: --file or -f @@ -227,7 +227,7 @@ write_testbench_io_connection Write the I/O connection statements in Verilog for a preconfigured FPGA fabric mapped to a given design. See details in :ref:`fpga_verilog_testbench`. -.. warning:: The netlist may be included by the template testbench (see details in :ref:`cmd_write_testbench_template`). Please do **NOT** directly use it in design verification without a proper modification!!! + .. warning:: The netlist may be included by the template testbench (see details in :ref:`cmd_write_testbench_template`). Please do **NOT** directly use it in design verification without a proper modification!!! .. option:: --file or -f From 2cd3453629ae467fd5154cd5d7a8d45fcad42b99 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Nov 2023 10:25:12 -0700 Subject: [PATCH 133/174] [core] fixed the bug in ccff v2 on config enable signal drivers --- openfpga/src/fpga_verilog/verilog_top_testbench.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 617dcd952..5ae917b42 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -398,7 +398,7 @@ static void print_verilog_top_testbench_global_config_done_ports_stimuli( module_global_port)); BasicPort stimuli_config_done_port( - std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1); + std::string(TOP_TB_CONFIG_ALL_DONE_PORT_NAME), 1); /* Wire the port to the input stimuli: * The wiring will be inverted if the default value of the global port is 1 * Otherwise, the wiring will not be inverted! From 21813eb59faa860d09d2cd562ba56a2ca5296036 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Nov 2023 13:48:21 -0700 Subject: [PATCH 134/174] [core] now full testbench uses bitstream in different sizes --- .../src/fpga_verilog/verilog_top_testbench.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 5ae917b42..f10a065a0 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -1623,12 +1623,23 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( /* Additional constants for multiple programming clock */ if (num_prog_clocks > 1) { for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { + std::vector curr_clk_ctrl_regions = + config_protocol.prog_clock_pin_ccff_head_indices( + config_protocol.prog_clock_pins()[iclk]); + size_t curr_regional_bitstream_max_size = + find_fabric_regional_bitstream_max_size(fabric_bitstream, curr_clk_ctrl_regions); + size_t curr_num_bits_to_skip = 0; + if (true == fast_configuration) { + curr_num_bits_to_skip = + find_configuration_chain_fabric_bitstream_size_to_be_skipped( + fabric_bitstream, bitstream_manager, bit_value_to_skip, curr_clk_ctrl_regions); + } /* TODO: Try to apply different length as the bitstream size for ccffs are * different driven by differnt clocks! Tried but no luck yet. */ print_verilog_define_flag( fp, std::string(TOP_TB_BITSTREAM_LENGTH_VARIABLE) + std::to_string(iclk), - regional_bitstream_max_size - num_bits_to_skip); + curr_regional_bitstream_max_size - curr_num_bits_to_skip); } } @@ -1905,9 +1916,12 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( } else { VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { + BasicPort curr_prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME) + + std::string(TOP_TB_CLOCK_REG_POSTFIX), + iclk, iclk); fp << "always"; fp << " @(negedge " - << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ")"; + << generate_verilog_port(VERILOG_PORT_CONKT, curr_prog_clock_port) << ")"; fp << " begin"; fp << std::endl; From b2e1eb30c726979ab91fcd77ea2be05b9b6874a2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Nov 2023 13:50:04 -0700 Subject: [PATCH 135/174] [core] code format --- .../src/fpga_verilog/verilog_top_testbench.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index f10a065a0..d62b3f143 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -1627,12 +1627,14 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( config_protocol.prog_clock_pin_ccff_head_indices( config_protocol.prog_clock_pins()[iclk]); size_t curr_regional_bitstream_max_size = - find_fabric_regional_bitstream_max_size(fabric_bitstream, curr_clk_ctrl_regions); + find_fabric_regional_bitstream_max_size(fabric_bitstream, + curr_clk_ctrl_regions); size_t curr_num_bits_to_skip = 0; if (true == fast_configuration) { - curr_num_bits_to_skip = + curr_num_bits_to_skip = find_configuration_chain_fabric_bitstream_size_to_be_skipped( - fabric_bitstream, bitstream_manager, bit_value_to_skip, curr_clk_ctrl_regions); + fabric_bitstream, bitstream_manager, bit_value_to_skip, + curr_clk_ctrl_regions); } /* TODO: Try to apply different length as the bitstream size for ccffs are * different driven by differnt clocks! Tried but no luck yet. */ @@ -1917,11 +1919,12 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { BasicPort curr_prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME) + - std::string(TOP_TB_CLOCK_REG_POSTFIX), - iclk, iclk); + std::string(TOP_TB_CLOCK_REG_POSTFIX), + iclk, iclk); fp << "always"; fp << " @(negedge " - << generate_verilog_port(VERILOG_PORT_CONKT, curr_prog_clock_port) << ")"; + << generate_verilog_port(VERILOG_PORT_CONKT, curr_prog_clock_port) + << ")"; fp << " begin"; fp << std::endl; From e48de682edbd1fca3f85759a160010b5af2bbd0f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Nov 2023 14:39:28 -0700 Subject: [PATCH 136/174] [core] fixed som ebugs --- .../fpga_verilog/verilog_top_testbench.cpp | 26 +++++++------------ openfpga/src/utils/fabric_bitstream_utils.cpp | 4 +-- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index d62b3f143..0e6901fca 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -1623,25 +1623,12 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( /* Additional constants for multiple programming clock */ if (num_prog_clocks > 1) { for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { - std::vector curr_clk_ctrl_regions = - config_protocol.prog_clock_pin_ccff_head_indices( - config_protocol.prog_clock_pins()[iclk]); - size_t curr_regional_bitstream_max_size = - find_fabric_regional_bitstream_max_size(fabric_bitstream, - curr_clk_ctrl_regions); - size_t curr_num_bits_to_skip = 0; - if (true == fast_configuration) { - curr_num_bits_to_skip = - find_configuration_chain_fabric_bitstream_size_to_be_skipped( - fabric_bitstream, bitstream_manager, bit_value_to_skip, - curr_clk_ctrl_regions); - } /* TODO: Try to apply different length as the bitstream size for ccffs are * different driven by differnt clocks! Tried but no luck yet. */ print_verilog_define_flag( fp, std::string(TOP_TB_BITSTREAM_LENGTH_VARIABLE) + std::to_string(iclk), - curr_regional_bitstream_max_size - curr_num_bits_to_skip); + regional_bitstream_max_size - num_bits_to_skip); } } @@ -1708,8 +1695,14 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( } else { VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { + std::vector curr_clk_ctrl_regions = + config_protocol.prog_clock_pin_ccff_head_indices( + config_protocol.prog_clock_pins()[iclk]); + size_t curr_regional_bitstream_max_size = + find_fabric_regional_bitstream_max_size(fabric_bitstream, + curr_clk_ctrl_regions); fp << "\t"; - fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= 0"; + fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= " << regional_bitstream_max_size - curr_regional_bitstream_max_size; fp << ";"; fp << std::endl; } @@ -1918,8 +1911,7 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( } else { VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { - BasicPort curr_prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME) + - std::string(TOP_TB_CLOCK_REG_POSTFIX), + BasicPort curr_prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), iclk, iclk); fp << "always"; fp << " @(negedge " diff --git a/openfpga/src/utils/fabric_bitstream_utils.cpp b/openfpga/src/utils/fabric_bitstream_utils.cpp index d26eff686..eab11cb23 100644 --- a/openfpga/src/utils/fabric_bitstream_utils.cpp +++ b/openfpga/src/utils/fabric_bitstream_utils.cpp @@ -33,7 +33,7 @@ size_t find_fabric_regional_bitstream_max_size( for (const auto& region : fabric_bitstream.regions()) { if (!region_whitelist.empty() && (std::find(region_whitelist.begin(), region_whitelist.end(), - size_t(region)) != region_whitelist.end())) { + size_t(region)) == region_whitelist.end())) { continue; } if (regional_bitstream_max_size < @@ -65,7 +65,7 @@ size_t find_configuration_chain_fabric_bitstream_size_to_be_skipped( for (const auto& region : fabric_bitstream.regions()) { if (!region_whitelist.empty() && (std::find(region_whitelist.begin(), region_whitelist.end(), - size_t(region)) != region_whitelist.end())) { + size_t(region)) == region_whitelist.end())) { continue; } size_t curr_region_num_bits_to_skip = 0; From b780f0a5528693735f43fafdd51e78876cdfdf6c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Nov 2023 14:39:49 -0700 Subject: [PATCH 137/174] [core] code format --- openfpga/src/fpga_verilog/verilog_top_testbench.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 0e6901fca..2443abf5c 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -1702,7 +1702,8 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( find_fabric_regional_bitstream_max_size(fabric_bitstream, curr_clk_ctrl_regions); fp << "\t"; - fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= " << regional_bitstream_max_size - curr_regional_bitstream_max_size; + fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= " + << regional_bitstream_max_size - curr_regional_bitstream_max_size; fp << ";"; fp << std::endl; } From 767461221d7ef89cb7b9847ae205d173c08fcd3e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 5 Nov 2023 00:02:21 +0000 Subject: [PATCH 138/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 9524fcbd9..eacd5e196 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1700 +1.2.1716 From 44730bf4fa8f02f60f862c70d4159a3e2b66b4cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:41:54 +0000 Subject: [PATCH 139/174] Bump yosys from `672375e` to `6f1ca68` Bumps [yosys](https://github.com/YosysHQ/yosys) from `672375e` to `6f1ca68`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/672375ed02be68733856e616a5f4fbf281fe7733...6f1ca68712e7713952440a36b25a9b6848f1a749) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 672375ed0..6f1ca6871 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 672375ed02be68733856e616a5f4fbf281fe7733 +Subproject commit 6f1ca68712e7713952440a36b25a9b6848f1a749 From e293a564b3705668af9e9ea223d7d4d2808777dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 00:02:13 +0000 Subject: [PATCH 140/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index eacd5e196..1fe622a45 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1716 +1.2.1720 From 39885135c6a1489ee8eb5422a702ad6ac7214739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 07:25:44 +0000 Subject: [PATCH 141/174] Bump yosys from `6f1ca68` to `93a426c` Bumps [yosys](https://github.com/YosysHQ/yosys) from `6f1ca68` to `93a426c`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/6f1ca68712e7713952440a36b25a9b6848f1a749...93a426cbbf7da47279154ce9ef113885546ceb4e) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 6f1ca6871..93a426cbb 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 6f1ca68712e7713952440a36b25a9b6848f1a749 +Subproject commit 93a426cbbf7da47279154ce9ef113885546ceb4e From 67bc5b0eb537455ed7557ef216ee20f3c135bd3c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:02:19 +0000 Subject: [PATCH 142/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 1fe622a45..eeaf6f10b 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1720 +1.2.1724 From 64b502290123ec0703b37024d615823caf5f343f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 07:15:40 +0000 Subject: [PATCH 143/174] Bump yosys from `93a426c` to `5691cd0` Bumps [yosys](https://github.com/YosysHQ/yosys) from `93a426c` to `5691cd0`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/93a426cbbf7da47279154ce9ef113885546ceb4e...5691cd095848f89f9f84a29f267fdebe95bae832) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 93a426cbb..5691cd095 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 93a426cbbf7da47279154ce9ef113885546ceb4e +Subproject commit 5691cd095848f89f9f84a29f267fdebe95bae832 From f4ab9de98287e9e526c68820e297e31e42f36d33 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 00:02:20 +0000 Subject: [PATCH 144/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index eeaf6f10b..b3d60d613 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1724 +1.2.1728 From 2ea08a0f46d9867ecaacaedcbb90fa57dca60257 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 13:59:16 -0800 Subject: [PATCH 145/174] [lib] update vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 254d38faa..5d41e33cc 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 254d38faa02884c9b48d6a82e18fd54d9b567d44 +Subproject commit 5d41e33cc89a34d0481550728f855252a63ac704 From 0b83ca3902200e485cf578ab07a23f96af384b03 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 14:00:42 -0800 Subject: [PATCH 146/174] [script] now use submodule checkout for github --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e3d23b82a..23c2cdab6 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ help: checkout: # Update all the submodules git submodule init - git submodule update --init --depth 1 + git submodule update --init --recursive prebuild: # Run cmake to generate Makefile under the build directory, before compilation From d78f18d235e8d0671d7529ef766bef4e5c055e18 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 14:11:34 -0800 Subject: [PATCH 147/174] [test] add new testcase --- .../fpga_verilog_reg_test.sh | 3 + .../rr_concat_wire/config/bus_group_gen.py | 173 +++ .../config/counter8_bus_group_task.yaml | 5 + .../config/pin_constraints_reset.xml | 7 + .../rr_concat_wire/config/task.conf | 48 + openfpga_flow/vpr_arch/README.md | 3 +- ..._adder_chain_dpram8K_dsp36_fracff_40nm.xml | 1239 +++++++++++++++++ 7 files changed, 1477 insertions(+), 1 deletion(-) create mode 100644 openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py create mode 100644 openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml create mode 100644 openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf create mode 100644 openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml diff --git a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh index 3cad92b31..46bf5cba9 100755 --- a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh @@ -140,6 +140,9 @@ echo -e "Testing through channels in tileable routing"; run-task fpga_verilog/thru_channel/thru_narrow_tile $@ run-task fpga_verilog/thru_channel/thru_wide_tile $@ +echo -e "Testing wire concatation in tileable routing"; +run-task fpga_verilog/rr_concat_wire $@ + echo -e "Testing the generation of preconfigured fabric wrapper for different HDL simulators"; run-task fpga_verilog/verilog_netlist_formats/embed_bitstream_none $@ run-task fpga_verilog/verilog_netlist_formats/embed_bitstream_modelsim $@ diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py new file mode 100644 index 000000000..3303aaf0a --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py @@ -0,0 +1,173 @@ +##################################################################### +# A script to create a bus group file based on an input verilog file +# The bug group file is an input required by OpenFPGA +##################################################################### +import os +from os.path import dirname, abspath +import argparse +import logging +import subprocess +import hashlib +import yaml +import pyverilog +from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer +from xml.dom import minidom + +##################################################################### +# Error codes +##################################################################### +error_codes = { + "SUCCESS": 0, + "MD5_ERROR": 1, + "OPTION_ERROR": 2, + "FILE_ERROR": 3 +} + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO); + +##################################################################### +# Generate the string for a Verilog port +##################################################################### +def gen_verilog_port_str(port_name, msb, lsb): + port_str = str(port_name) + "[" + str(msb) + ":" + str(lsb) + "]" + return port_str + +##################################################################### +# Generate the string for a flatten Verilog port +##################################################################### +def gen_flatten_verilog_port_str(port_name, pin_id): + port_str = str(port_name) + "_" + str(pin_id) + "_" + return port_str + +##################################################################### +# Parse a verilog file and collect bus port information +##################################################################### +def parse_verilog_file_bus_ports(verilog_files, top_module): + # Check if verilog file exists + verilog_file_list = [] + for verilog_f in verilog_files: + print(verilog_f) + verilog_f_abspath = os.path.abspath(verilog_f["name"]) + if not os.path.exists(verilog_f_abspath): + raise IOError("file not found: " + verilog_f_abspath) + + verilog_file_list.append(verilog_f_abspath) + + # Parse verilog file + analyzer = VerilogDataflowAnalyzer(verilog_file_list, top_module) + analyzer.generate() + # Get port information + terms = analyzer.getTerms() + # Create XML tree + xml = minidom.Document() + bus_group = xml.createElement("bus_group") + xml.appendChild(bus_group) + for tk, tv in sorted(terms.items(), key=lambda x: str(x[0])): + logging.debug(tv.name) + logging.debug(tv.termtype) + logging.debug("[" + str(tv.lsb) + ":" + str(tv.msb) + "]") + for tk, tv in sorted(terms.items(), key=lambda x: str(x[0])): + # Skip ports that do not belong to top module + if (top_module != str(tv.name).split(".")[-2]): + continue + port_name = str(tv.name).split(".")[-1] + + # Skip minus lsb or msb, which are in don't care set + if (("Minus" == str(tv.lsb)) or ("Minus" == str(tv.msb))): + continue + port_lsb = int(str(tv.lsb)) + port_msb = int(str(tv.msb)) + # Only care input and outports + if ((not ("Input" in tv.termtype)) and (not ("Output" in tv.termtype))): + continue + # Only care bus (msb - lsb > 0) + if (abs(port_lsb - port_msb) == 0): + continue + # Reaching here, this is a bus port we need + # Get the second part of the name, which is the port name + cur_bus = xml.createElement("bus") + cur_bus.setAttribute("name", gen_verilog_port_str(port_name, port_msb, port_lsb)) + # Get if this is little endian or not + cur_bus.setAttribute("big_endian", "false") + if (port_lsb > port_msb): + cur_bus.setAttribute("big_endian", "true") + bus_group.appendChild(cur_bus) + # Add all the pins + for ipin in range(min([port_msb, port_lsb]), max([port_msb, port_lsb]) + 1): + cur_pin = xml.createElement("pin") + cur_pin.setAttribute('id', str(ipin)) + cur_pin.setAttribute('name', gen_flatten_verilog_port_str(port_name, ipin)) + cur_bus.appendChild(cur_pin) + + return xml, bus_group + +##################################################################### +# Generate bus group files with a given task list +##################################################################### +def generate_bus_group_files(task_db): + # Iterate over all the tasks + for verilog_fname in task_db.keys(): + space_limit = 120 + log_str = "Parsing verilog file: " + top_module_name = task_db[verilog_fname]["top_module"] + logging_space = "." * (space_limit - len(log_str) - len(top_module_name)) + logging.info(log_str + top_module_name) + xml, bus_group_data = parse_verilog_file_bus_ports(task_db[verilog_fname]["source"], top_module_name) + logging.info(log_str + top_module_name + logging_space + "Done") + # Write bus ports to an XML file + bus_group_frelname = task_db[verilog_fname]["bus_group_file"] + bus_group_fname = os.path.abspath(bus_group_frelname) + log_str = "Writing bus group file:" + logging_space = "." * (space_limit - len(log_str) - len(bus_group_frelname)) + logging.info(log_str + bus_group_frelname) + xml_str = xml.toprettyxml(indent="\t") + with open(bus_group_fname, "w") as bus_group_f: + bus_group_f.write(xml_str) + logging.info(log_str + bus_group_frelname + logging_space + "Done") + +##################################################################### +# Read task list from a yaml file +##################################################################### +def read_yaml_to_task_database(yaml_filename): + task_db = {} + with open(yaml_filename, 'r') as stream: + try: + task_db = yaml.load(stream, Loader=yaml.FullLoader) + logging.info("Found " + str(len(task_db)) + " tasks to create symbolic links") + except yaml.YAMLError as exc: + logging.error(exc) + exit(error_codes["FILE_ERROR"]); + + return task_db + +##################################################################### +# Write result database to a yaml file +##################################################################### +def write_result_database_to_yaml(result_db, yaml_filename): + with open(yaml_filename, 'w') as yaml_file: + yaml.dump(result_db, yaml_file, default_flow_style=False) + +##################################################################### +# Main function +##################################################################### +if __name__ == '__main__': + # Execute when the module is not initialized from an import statement + + # Parse the options and apply sanity checks + parser = argparse.ArgumentParser(description='Create bus group files for Verilog inputs') + parser.add_argument('--task_list', + required=True, + help='Configuration file in YAML format which contains a list of input Verilog and output bus group files') + args = parser.parse_args() + + # Create a database for tasks + task_db = {} + task_db = read_yaml_to_task_database(args.task_list) + + # Generate links based on the task list in database + generate_bus_group_files(task_db) + logging.info("Created " + str(len(task_db)) + " bus group files") + exit(error_codes["SUCCESS"]) diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml new file mode 100644 index 000000000..2c0a81258 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml @@ -0,0 +1,5 @@ +counter8: + source: + - name: counter_output_verilog.v + top_module: counter + bus_group_file: bus_group.xml diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf new file mode 100644 index 000000000..39335966e --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf @@ -0,0 +1,48 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +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/auto_bus_group_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_verilog_port_mapping=--explicit_port_mapping + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v +bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt +bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys + +bench0_top = counter +bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml +bench0_openfpga_bus_group_file=bus_group.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/vpr_arch/README.md b/openfpga_flow/vpr_arch/README.md index cbec4f286..65f3c3d55 100644 --- a/openfpga_flow/vpr_arch/README.md +++ b/openfpga_flow/vpr_arch/README.md @@ -5,8 +5,9 @@ Please reveal the following architecture features in the names to help quickly s * The keyword 'frac' is to specify if fracturable LUT is used or not. * The keyword 'Native' is to specify if fracturable LUT design is a native one (without mode switch) or a standard one (with mode switch). - N: Number of logic elements for a CLB. If you have multiple CLB architectures, this should be largest number. -- tileable: If the routing architecture is tileable or not. +- tileable: If the routing architecture is tileable or not. * The keyword 'IO' specifies if the I/O tile is tileable or not + * The keyword 'ConcatWire' specifies if the routing wires can be continued in the same direction or not. For example, L4 -> L1 - fracff<2edge>: Use multi-mode flip-flop model, where reset/set polarity is configurable. When 2edge is specified, clock polarity can be switched between postive edge triggered and negative edge triggered - adder\_chain: If hard adder/carry chain is used inside CLBs - register\_chain: If shift register chain is used inside CLBs diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml new file mode 100644 index 000000000..c9dc5e65e --- /dev/null +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml @@ -0,0 +1,1239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + io.outpad io.inpad + io.outpad io.inpad + io.outpad io.inpad + io.outpad io.inpad + + + + + + + + + + + + + + + + + + + + + + + + + + clb.clk clb.reset clb.set + clb.cin + clb.O[9:0] clb.I[19:0] + clb.cout clb.O[19:10] clb.I[39:20] + + + + + + + + + + + + + + + + + + + + + memory.clk + + memory.waddr[4:0] memory.raddr[4:0] memory.data_in[3:0] memory.wen memory.data_out[3:0] + memory.waddr[9:5] memory.raddr[9:5] memory.data_in[7:4] memory.ren memory.data_out[7:4] + + + + + + + + + + + + + + + + mult_36.b[0:9] mult_36.b[10:35] mult_36.out[36:71] + + mult_36.a[0:9] mult_36.a[10:35] mult_36.out[0:35] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 235e-12 + 235e-12 + 235e-12 + 235e-12 + 235e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 195e-12 + 195e-12 + 195e-12 + 195e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 261e-12 + 261e-12 + 261e-12 + 261e-12 + 261e-12 + 261e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 1b8748abb491750037375e187c3c26ea419481d8 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 14:21:34 -0800 Subject: [PATCH 148/174] [core] update vtr --- ...tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml | 2 +- vtr-verilog-to-routing | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml index c9dc5e65e..370341554 100644 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml @@ -302,7 +302,7 @@ - + diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 5d41e33cc..229e43e30 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 5d41e33cc89a34d0481550728f855252a63ac704 +Subproject commit 229e43e30bd7a99bf34239179ad957ca6e00f8da From 59a5db5f26b6b195bb73506d3e1fe4168b326f77 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:02:04 -0800 Subject: [PATCH 149/174] [lib] update vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 229e43e30..a668e3938 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 229e43e30bd7a99bf34239179ad957ca6e00f8da +Subproject commit a668e393859ecbc85a113d54800f0ffd2272bbca From 2006a33a4960f069cfdfc93841a7ce7f5539a7bb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:11:52 -0800 Subject: [PATCH 150/174] [lib] upgrade vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index a668e3938..320ab25a5 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit a668e393859ecbc85a113d54800f0ffd2272bbca +Subproject commit 320ab25a5a8f8f7559f27cb87f8feafa8dca0903 From a014a99e75a8137e26030ee61fb37e77174a4656 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:31:38 -0800 Subject: [PATCH 151/174] [lib] upgrade vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 320ab25a5..7b5d47bd1 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 320ab25a5a8f8f7559f27cb87f8feafa8dca0903 +Subproject commit 7b5d47bd1ddbb3843c6638f89f2faa531bd31dad From 70d502d09486f3c843c2c367ff430d824fcb6c0c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:34:20 -0800 Subject: [PATCH 152/174] [lib] upgrade vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 7b5d47bd1..d65c0546a 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 7b5d47bd1ddbb3843c6638f89f2faa531bd31dad +Subproject commit d65c0546ac34f53f0713d841004a003aa1131e9f From f2f66028e30f75eb997324e60dedbb4f91261e4f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:37:35 -0800 Subject: [PATCH 153/174] [lib] upgrade vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index d65c0546a..2818f1b0c 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit d65c0546ac34f53f0713d841004a003aa1131e9f +Subproject commit 2818f1b0c64d206826d57a6b32d234a81d0c6fdd From 5a80250aa36277cd9e7c5aa4c9b7e6c719bf460a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 15:38:39 -0800 Subject: [PATCH 154/174] [lib] upgrade vtr --- vtr-verilog-to-routing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 2818f1b0c..eb9722851 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 2818f1b0c64d206826d57a6b32d234a81d0c6fdd +Subproject commit eb9722851bd3de03df7fb9ace5bdfb9cb078ca83 From 32772d1bd980fa6ce1a11d0264f9772bcb66de25 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 16:13:09 -0800 Subject: [PATCH 155/174] [ci] remove gcc-7 support --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0cd7bc71..360870213 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,9 +76,6 @@ jobs: fail-fast: false matrix: config: - - name: "Build Compatibility: GCC-7 (Ubuntu 20.04)" - cc: gcc-7 - cxx: g++-7 - name: "Build Compatibility: GCC-8 (Ubuntu 20.04)" cc: gcc-8 cxx: g++-8 From e94e7c7c75a4294a21ff601bbb95d2eacb706826 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 21:13:42 -0800 Subject: [PATCH 156/174] [ci] now change to use gcc-11 build image --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 360870213..01d945a01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,7 +134,7 @@ jobs: run: ccache -s - name: Upload artifact uses: actions/upload-artifact@v2 - if: ${{ matrix.config.cc == 'gcc-8'}} + if: ${{ matrix.config.cc == 'gcc-11'}} with: name: openfpga path: | @@ -438,7 +438,7 @@ jobs: chmod +x build/yosys/bin/yosys-config chmod +x build/yosys/bin/yosys-filterlib chmod +x build/yosys/bin/yosys-smtbmc - - name: ${{matrix.config.name}}_GCC-8_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-11_(Ubuntu 20.04) shell: bash run: source openfpga.sh && source openfpga_flow/regression_test_scripts/${{matrix.config.name}}.sh --debug --show_thread_logs - name: Upload artifact @@ -482,7 +482,7 @@ jobs: - name: Checkout OpenFPGA repo uses: actions/checkout@v3 - - name: ${{matrix.config.name}}_GCC-8_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-11_(Ubuntu 20.04) shell: bash run: | bash .github/workflows/install_dependencies_run.sh From 5cbe698dd1f19bd71fc27afa9bf1223df8ed26e8 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 13 Nov 2023 22:59:27 -0800 Subject: [PATCH 157/174] [ci] switch to use gcc-9 when running reg tests --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 01d945a01..2e8a8246c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,7 +134,7 @@ jobs: run: ccache -s - name: Upload artifact uses: actions/upload-artifact@v2 - if: ${{ matrix.config.cc == 'gcc-11'}} + if: ${{ matrix.config.cc == 'gcc-9'}} with: name: openfpga path: | @@ -438,7 +438,7 @@ jobs: chmod +x build/yosys/bin/yosys-config chmod +x build/yosys/bin/yosys-filterlib chmod +x build/yosys/bin/yosys-smtbmc - - name: ${{matrix.config.name}}_GCC-11_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-9_(Ubuntu 20.04) shell: bash run: source openfpga.sh && source openfpga_flow/regression_test_scripts/${{matrix.config.name}}.sh --debug --show_thread_logs - name: Upload artifact @@ -482,7 +482,7 @@ jobs: - name: Checkout OpenFPGA repo uses: actions/checkout@v3 - - name: ${{matrix.config.name}}_GCC-11_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-9_(Ubuntu 20.04) shell: bash run: | bash .github/workflows/install_dependencies_run.sh From 658db1fdff32f51a2875ae4b8338afa603eb52ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 07:26:41 +0000 Subject: [PATCH 158/174] Bump yosys from `5691cd0` to `c11744b` Bumps [yosys](https://github.com/YosysHQ/yosys) from `5691cd0` to `c11744b`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/5691cd095848f89f9f84a29f267fdebe95bae832...c11744b4efb5fd372efeb90af1c8f5801047f445) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 5691cd095..c11744b4e 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 5691cd095848f89f9f84a29f267fdebe95bae832 +Subproject commit c11744b4efb5fd372efeb90af1c8f5801047f445 From 59d086a27ff904d3be8cf8348a949de2d5e45538 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:25:45 -0800 Subject: [PATCH 159/174] [test] try to keep the golden inputs --- openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml index 3c32dbc99..7a354232c 100644 --- a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -67,7 +67,7 @@ - + From 913434b70d91e6d2d74b07f74f8209d5681271d3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:28:57 -0800 Subject: [PATCH 160/174] [test] fixed the bug that golden netlists are modified --- openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml index 7a354232c..33a4f4e56 100644 --- a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -67,7 +67,7 @@ - + From d1082841053154fd73e1c03a6115ee1535ff6e4c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:31:07 -0800 Subject: [PATCH 161/174] [test] update arch to keep golden outputs --- openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml index b3b4110a3..2946ce80a 100644 --- a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml @@ -103,7 +103,7 @@ - + From 0b473e345452e655c26b4275c12cb7a6f31b440c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:35:26 -0800 Subject: [PATCH 162/174] [test] fixed the bug in single-mode lut testcase --- .../tasks/fpga_verilog/lut_design/single_mode/config/task.conf | 2 +- openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf b/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf index 989f8e09a..ae5896549 100644 --- a/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf @@ -19,7 +19,7 @@ fpga_flow=vpr_blif openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_N10_40nm_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml -openfpga_vpr_device_layout=2x2 +openfpga_vpr_device_layout=auto [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml diff --git a/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml b/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml index 4706bb30f..634dacd64 100644 --- a/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml @@ -67,7 +67,7 @@ - + From dff03e7993f1f70aa1ec4c8b4e5eac4cd0d53aae Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:45:02 -0800 Subject: [PATCH 163/174] [test] enable missing options in the arch used by benchmark sweeping tests --- .../k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml | 2 +- ..._frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml | 2 +- ...frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml index b2eea07af..d0750f9ac 100644 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml @@ -234,7 +234,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml index 0ae64adda..428a0e617 100644 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml @@ -302,7 +302,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml index 1190e3624..1b6f2760b 100755 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml @@ -146,7 +146,7 @@ - + From e9673916b2ae875efc5412cdcdf58afca28c94e4 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 09:56:57 -0800 Subject: [PATCH 164/174] [doc] add figures for new options in tileable rr graph --- .../arch_lang/figures/concat_pass_wire.svg | 574 +++++++++++++++++ .../manual/arch_lang/figures/concat_wire.svg | 580 +++++++++++++++++ .../arch_lang/figures/opin2all_sides.svg | 592 ++++++++++++++++++ 3 files changed, 1746 insertions(+) create mode 100644 docs/source/manual/arch_lang/figures/concat_pass_wire.svg create mode 100644 docs/source/manual/arch_lang/figures/concat_wire.svg create mode 100644 docs/source/manual/arch_lang/figures/opin2all_sides.svg diff --git a/docs/source/manual/arch_lang/figures/concat_pass_wire.svg b/docs/source/manual/arch_lang/figures/concat_pass_wire.svg new file mode 100644 index 000000000..ccebac06b --- /dev/null +++ b/docs/source/manual/arch_lang/figures/concat_pass_wire.svg @@ -0,0 +1,574 @@ + + + + + + + + + + + + + + + + + concat_pass_wire + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + diff --git a/docs/source/manual/arch_lang/figures/concat_wire.svg b/docs/source/manual/arch_lang/figures/concat_wire.svg new file mode 100644 index 000000000..bb01dd6d5 --- /dev/null +++ b/docs/source/manual/arch_lang/figures/concat_wire.svg @@ -0,0 +1,580 @@ + + + + + + + + + + + + + + + + + concat_wire + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + diff --git a/docs/source/manual/arch_lang/figures/opin2all_sides.svg b/docs/source/manual/arch_lang/figures/opin2all_sides.svg new file mode 100644 index 000000000..dff4b1222 --- /dev/null +++ b/docs/source/manual/arch_lang/figures/opin2all_sides.svg @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + opin2all_sides + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + From b79703fc8bdb6d7fed5d6599eb4817cfde8c1148 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 14 Nov 2023 10:10:41 -0800 Subject: [PATCH 165/174] [doc] comment on new options --- .../manual/arch_lang/addon_vpr_syntax.rst | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/source/manual/arch_lang/addon_vpr_syntax.rst b/docs/source/manual/arch_lang/addon_vpr_syntax.rst index ef93be938..b2c88992c 100644 --- a/docs/source/manual/arch_lang/addon_vpr_syntax.rst +++ b/docs/source/manual/arch_lang/addon_vpr_syntax.rst @@ -88,11 +88,58 @@ Layout .. warning:: Do NOT enable ``shrink_boundary`` if you are not using the tileable routing resource graph generator! +.. option:: opin2all_sides="" + + Allow each output pin of a programmable block to drive the routing tracks on all the sides of its adjacent switch block (see an illustrative example in :numref:`fig_opin2all_sides`). This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. _fig_opin2all_sides: + + .. figure:: ./figures/opin2all_sides.svg + :width: 100% + :alt: Impact of opin2all_sides + + Impact on routing architecture when the opin-to-all-sides: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``opin2all_sides`` if you are not using the tileable routing resource graph generator! + +.. option:: concat_wire="" + + In each switch block, allow each routing track which ends to drive another routing track on the opposite side, as such a wire can be continued in the same direction (see an illustrative example in :numref:`fig_concat_wire`). In other words, routing wires can be concatenated in the same direction across an FPGA fabric. This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. _fig_concat_wire: + + .. figure:: ./figures/concat_wire.svg + :width: 100% + :alt: Impact of concat_wire + + Impact on routing architecture when the wire concatenation: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``concat_wire`` if you are not using the tileable routing resource graph generator! + +.. option:: concat_pass_wire="" + + In each switch block, allow each routing track which passes to drive another routing track on the opposite side, as such a pass wire can be continued in the same direction (see an illustrative example in :numref:`fig_concat_pass_wire`). This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. warning:: Please enable this option if you are looking for device support which is created by any release which is before v1.1.541!!! + + .. _fig_concat_wire: + + .. figure:: ./figures/concat_pass_wire.svg + :width: 100% + :alt: Impact of concat_pass_wire + + Impact on routing architecture when the pass wire concatenation: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``concat_pass_wire`` if you are not using the tileable routing resource graph generator! + A quick example to show tileable routing is enabled, other options, e.g., through channels are disabled: .. code-block:: xml - + Switch Block From 9ea2587618e99eb2db3c05b0394e08af7688f56a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 20:31:52 +0000 Subject: [PATCH 166/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index b3d60d613..cc82ea8a1 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1728 +1.2.1753 From 7504268b6638e93cedec45fbec362928a3eb73cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 07:04:16 +0000 Subject: [PATCH 167/174] Bump yosys from `c11744b` to `7eea047` Bumps [yosys](https://github.com/YosysHQ/yosys) from `c11744b` to `7eea047`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/c11744b4efb5fd372efeb90af1c8f5801047f445...7eea047793afcfafe7507d828aeec574f56f8901) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index c11744b4e..7eea04779 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit c11744b4efb5fd372efeb90af1c8f5801047f445 +Subproject commit 7eea047793afcfafe7507d828aeec574f56f8901 From 5f966e6f64cfd8c2e19d3eef3ff39dd1a79c4a65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 00:02:17 +0000 Subject: [PATCH 168/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index cc82ea8a1..bb5da25d9 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1753 +1.2.1757 From c80e72d55972db6b99d4591c83c42668052bb39b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 07:54:16 +0000 Subject: [PATCH 169/174] Bump yosys from `7eea047` to `032fab1` Bumps [yosys](https://github.com/YosysHQ/yosys) from `7eea047` to `032fab1`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/7eea047793afcfafe7507d828aeec574f56f8901...032fab1f541a9a09faa5a7bda29ac6ae0597a4bc) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 7eea04779..032fab1f5 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 7eea047793afcfafe7507d828aeec574f56f8901 +Subproject commit 032fab1f541a9a09faa5a7bda29ac6ae0597a4bc From 0030ba9033f8884fc458f72a9bc89b198c43e151 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 00:02:20 +0000 Subject: [PATCH 170/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index bb5da25d9..016e7a71a 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1757 +1.2.1761 From 7cf6b9193c12a3ed8f0def0e923b5b9c3a4ac4f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 07:33:52 +0000 Subject: [PATCH 171/174] Bump yosys from `032fab1` to `ab6c1d3` Bumps [yosys](https://github.com/YosysHQ/yosys) from `032fab1` to `ab6c1d3`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/032fab1f541a9a09faa5a7bda29ac6ae0597a4bc...ab6c1d368b103addae8cc658659e2f7cfd166d94) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index 032fab1f5..ab6c1d368 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 032fab1f541a9a09faa5a7bda29ac6ae0597a4bc +Subproject commit ab6c1d368b103addae8cc658659e2f7cfd166d94 From 35149d9de0eb4e6efb36132402d0f92547a7a358 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 00:02:33 +0000 Subject: [PATCH 172/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 016e7a71a..9d1917807 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1761 +1.2.1765 From e0cea074d4bf4ad91660282828904994383d8c79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 07:41:03 +0000 Subject: [PATCH 173/174] Bump yosys from `ab6c1d3` to `c952982` Bumps [yosys](https://github.com/YosysHQ/yosys) from `ab6c1d3` to `c952982`. - [Release notes](https://github.com/YosysHQ/yosys/releases) - [Commits](https://github.com/YosysHQ/yosys/compare/ab6c1d368b103addae8cc658659e2f7cfd166d94...c95298225ddb5d5f7e193d5ab23aa969aa9628ff) --- updated-dependencies: - dependency-name: yosys dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yosys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yosys b/yosys index ab6c1d368..c95298225 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit ab6c1d368b103addae8cc658659e2f7cfd166d94 +Subproject commit c95298225ddb5d5f7e193d5ab23aa969aa9628ff From 9e9f831bb108fd06075b0830da5183819d09d147 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:02:35 +0000 Subject: [PATCH 174/174] Updated Patch Count --- VERSION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.md b/VERSION.md index 9d1917807..1983ccf3d 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1765 +1.2.1769