diff --git a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp
index 6b27d0017d..d01b81b64f 100644
--- a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp
+++ b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp
@@ -125,6 +125,22 @@ static void read_xml_tile_global_port_annotation(
}
}
+/********************************************************************
+ * Parse XML description for an interconnection annotation
+ * under a XML node
+ *******************************************************************/
+static void read_xml_tile_merge_port_annotation(
+ pugi::xml_node& xml_tile, const pugiutil::loc_data& loc_data,
+ openfpga::TileAnnotation& tile_annotation) {
+ const std::string& tile_attr =
+ get_attribute(xml_tile, "tile", loc_data).as_string();
+
+ const std::string& port_attr =
+ get_attribute(xml_tile, "port", loc_data).as_string();
+
+ tile_annotation.add_merge_subtile_ports(tile_attr, port_attr);
+}
+
/********************************************************************
* Top function to parse XML description about tile annotation
*******************************************************************/
@@ -146,11 +162,15 @@ openfpga::TileAnnotation read_xml_tile_annotations(
*/
for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) {
/* Error out if the XML child has an invalid name! */
- if (xml_tile_global_port.name() != std::string("global_port")) {
- bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port"});
+ if (xml_tile_global_port.name() == std::string("global_port")) {
+ read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
+ tile_annotations);
+ } else if (xml_tile_global_port.name() == std::string("merge_subtile_ports")) {
+ read_xml_tile_merge_port_annotation(xml_tile_global_port, loc_data,
+ tile_annotations);
+ } else {
+ bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port or merge_subtile_ports"});
}
- read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
- tile_annotations);
}
return tile_annotations;
diff --git a/libs/libarchopenfpga/src/tile_annotation.cpp b/libs/libarchopenfpga/src/tile_annotation.cpp
index 7cf41f02e1..d9ac5c0f56 100644
--- a/libs/libarchopenfpga/src/tile_annotation.cpp
+++ b/libs/libarchopenfpga/src/tile_annotation.cpp
@@ -2,8 +2,11 @@
* Member functions for class TileAnnotation
***********************************************************************/
#include "tile_annotation.h"
+#include "command_exit_codes.h"
+#include
#include "vtr_assert.h"
+#include "vtr_log.h"
/* namespace openfpga begins */
namespace openfpga {
@@ -20,6 +23,24 @@ TileAnnotation::global_port_range TileAnnotation::global_ports() const {
return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end());
}
+std::vector tiles_to_merge_ports() const {
+ std::vector tile_names;
+ for (auto it = tile_ports_to_merge_.begin(); it != tile_ports_to_merge_.end(); it++) {
+ tile_names.push_back(it->first);
+ }
+ return tile_names;
+}
+
+std::vector tile_ports_to_merge(const std::string& tile_name) const {
+ std::vector port_names;
+ const auto& result = tile_ports_to_merge_.find(tile_name);
+ if (result == tile_ports_to_merge.end()) {
+ VTR_LOG_WARN("Tile '%s' does not contain any ports to merge!\n", tile_name.c_str());
+ return port_names;
+ }
+ return result.second;
+}
+
/************************************************************************
* Public Accessors
***********************************************************************/
@@ -178,4 +199,21 @@ bool TileAnnotation::valid_global_port_attributes(
return ((0 == attribute_counter) || (1 == attribute_counter));
}
+int TileAnnotation::add_merge_subtile_ports(const std::string& tile_name, const std::string& port_name) {
+ auto result = tile_ports_to_merge_.find(tile_name);
+ if (result == tile_ports_to_merge_.end()) {
+ /* Empty list: add a new element */
+ tile_ports_to_merge_[tile_name].push_back(port_name);
+ } else {
+ /* Check if the port name is already in the list, if yes, error out */
+ if (result->second.end() == std::find(result->secnd.begin(), result->second.end(), port_name)) {
+ tile_ports_to_merge_[tile_name].push_back(port_name);
+ } else {
+ VTR_LOG_ERROR("Port '%s' has already been defined twice for tile '%s' to be merged!", port_name.c_str(), tile_name.c_str());
+ return CMD_EXEC_FATAL_ERROR;
+ }
+ }
+ return CMD_EXEC_SUCCESS;
+}
+
} // namespace openfpga
diff --git a/libs/libarchopenfpga/src/tile_annotation.h b/libs/libarchopenfpga/src/tile_annotation.h
index ddf9511090..de5a40a082 100644
--- a/libs/libarchopenfpga/src/tile_annotation.h
+++ b/libs/libarchopenfpga/src/tile_annotation.h
@@ -39,6 +39,8 @@ class TileAnnotation {
public: /* Public accessors: aggregators */
global_port_range global_ports() const;
+ std::vector tiles_to_merge_ports() const;
+ std::vector tile_ports_to_merge(const std::string& tile_name) const;
public: /* Public accessors */
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
@@ -77,6 +79,8 @@ class TileAnnotation {
void set_global_port_default_value(const TileGlobalPortId& global_port_id,
const size_t& default_value);
+ int add_merge_subtile_ports(const std::string& tile_name, const std::string& port_name);
+
public: /* Public validator */
bool valid_global_port_id(const TileGlobalPortId& global_port_id) const;
/* Validate attributes of a given global port
@@ -102,6 +106,9 @@ class TileAnnotation {
/* A fast lookup for port names */
std::map global_port_name2ids_;
+
+ /* Merge port information for tiles */
+ std::map> tile_ports_to_merge_; // tile_name -> port_name
};
} // namespace openfpga
diff --git a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp
index af6bab25a5..5bccbc2c69 100644
--- a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp
+++ b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp
@@ -87,6 +87,25 @@ static void write_xml_tile_annotation_global_port(
<< "";
}
+/********************************************************************
+ * A writer to output a device variation in a technology library to XML format
+ *******************************************************************/
+static void write_xml_tile_annotation_subtile_port_to_merge(
+ std::fstream& fp, const char* fname,
+ const std::string& tile_name,
+ const std::string& port_name) {
+ /* Validate the file stream */
+ openfpga::check_file_stream(fname, fp);
+
+ fp << "\t\t"
+ << "";
+}
+
/********************************************************************
* A writer to output tile annotations to XML format
*******************************************************************/
@@ -109,6 +128,11 @@ void write_xml_tile_annotations(std::fstream& fp, const char* fname,
write_xml_tile_annotation_global_port(fp, fname, tile_annotation,
global_port_id);
}
+ for (std::string tile_name : tile_annotation.tiles_to_merge_ports()) {
+ for (std::string port_name : tile_annotation.tile_ports_to_merge(tile_name)) {
+ write_xml_tile_annotation_subtile_port_to_merge(fp, fname, tile_name, port_name);
+ }
+ }
/* Write the root node for pb_type annotations */
fp << "\t"