diff --git a/libopenfpga/libarchopenfpga/arch/sample_arch.xml b/libopenfpga/libarchopenfpga/arch/sample_arch.xml
index aaadd04ad..dafaa83dd 100644
--- a/libopenfpga/libarchopenfpga/arch/sample_arch.xml
+++ b/libopenfpga/libarchopenfpga/arch/sample_arch.xml
@@ -293,21 +293,21 @@
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp
index 806a76c44..98fad3dd0 100644
--- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp
+++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp
@@ -146,12 +146,12 @@ void PbTypeAnnotation::set_circuit_model_name(const std::string& name) {
circuit_model_name_ = name;
}
-void PbTypeAnnotation::physical_pb_type_index_factor(const int& value) {
+void PbTypeAnnotation::set_physical_pb_type_index_factor(const int& value) {
VTR_ASSERT(true == is_operating_pb_type());
physical_pb_type_index_factor_ = value;
}
-void PbTypeAnnotation::physical_pb_type_index_offset(const int& value) {
+void PbTypeAnnotation::set_physical_pb_type_index_offset(const int& value) {
VTR_ASSERT(true == is_operating_pb_type());
physical_pb_type_index_offset_ = value;
}
diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h
index 8bf4480a8..8849ef273 100644
--- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h
+++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h
@@ -61,8 +61,8 @@ class PbTypeAnnotation {
void set_idle_mode_name(const std::string& name);
void set_mode_bits(const std::string& mode_bits);
void set_circuit_model_name(const std::string& name);
- void physical_pb_type_index_factor(const int& value);
- void physical_pb_type_index_offset(const int& value);
+ void set_physical_pb_type_index_factor(const int& value);
+ void set_physical_pb_type_index_offset(const int& value);
void add_pb_type_port_pair(const std::string& operating_pb_port_name,
const BasicPort& physical_pb_port);
void set_physical_pin_rotate_offset(const std::string& operating_pb_port_name,
diff --git a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp
index 7ac685436..160c3183a 100644
--- a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp
+++ b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp
@@ -12,12 +12,56 @@
/* Headers from vtr util library */
#include "vtr_assert.h"
+/* Headers from openfpga util library */
+#include "openfpga_port_parser.h"
+
/* Headers from libarchfpga */
#include "arch_error.h"
#include "read_xml_util.h"
#include "read_xml_pb_type_annotation.h"
+/********************************************************************
+ * Parse XML description for an interconnection annotation
+ * under a XML node
+ *******************************************************************/
+static
+void read_xml_interc_annotation(pugi::xml_node& xml_interc,
+ const pugiutil::loc_data& loc_data,
+ openfpga::PbTypeAnnotation& pb_type_annotation) {
+ /* We have two mandatory XML attribute
+ * 1. name of the interconnect
+ * 2. circuit model name of the interconnect
+ */
+ const std::string& name_attr = get_attribute(xml_interc, "name", loc_data).as_string();
+ const std::string& circuit_model_name_attr = get_attribute(xml_interc, "circuit_model_name", loc_data).as_string();
+
+ pb_type_annotation.add_interconnect_circuit_model_pair(name_attr, circuit_model_name_attr);
+}
+
+/********************************************************************
+ * Parse XML description for a pb_type port annotation
+ * under a XML node
+ *******************************************************************/
+static
+void read_xml_pb_port_annotation(pugi::xml_node& xml_port,
+ const pugiutil::loc_data& loc_data,
+ openfpga::PbTypeAnnotation& pb_type_annotation) {
+ /* We have two mandatory XML attribute
+ * 1. name of the port
+ * 2. name of the port to be binded in physical mode
+ */
+ const std::string& name_attr = get_attribute(xml_port, "name", loc_data).as_string();
+ const std::string& physical_mode_port_attr = get_attribute(xml_port, "physical_mode_port", loc_data).as_string();
+
+ /* Parse the mode port using openfpga port parser */
+ openfpga::PortParser port_parser(physical_mode_port_attr);
+ pb_type_annotation.add_pb_type_port_pair(name_attr, port_parser.port());
+
+ /* We have an optional attribute: physical_mode_pin_rotate_offset */
+ pb_type_annotation.set_physical_pin_rotate_offset(name_attr, get_attribute(xml_port, "physical_mode_pin_rotate_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0));
+}
+
/********************************************************************
* Parse XML description for a pb_type annotation under a XML node
*******************************************************************/
@@ -60,6 +104,39 @@ void read_xml_pb_type_annotation(pugi::xml_node& xml_pb_type,
pb_type_annotation.set_circuit_model_name(get_attribute(xml_pb_type, "circuit_model_name", loc_data).as_string());
}
+ /* If this is an operating pb_type, index factor and offset may be optional needed */
+ if (true == pb_type_annotation.is_operating_pb_type()) {
+ pb_type_annotation.set_physical_pb_type_index_factor(get_attribute(xml_pb_type, "physical_pb_type_index_factor", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(1));
+ pb_type_annotation.set_physical_pb_type_index_offset(get_attribute(xml_pb_type, "physical_pb_type_index_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0));
+ }
+
+ /* Parse all the interconnect-to-circuit binding under this node
+ * All the bindings are defined in child node
+ */
+ size_t num_intercs = count_children(xml_pb_type, "interconnect", loc_data, pugiutil::ReqOpt::OPTIONAL);
+ if (0 < num_intercs) {
+ pugi::xml_node xml_interc = get_first_child(xml_pb_type, "interconnect", loc_data);
+ while (xml_interc) {
+ read_xml_interc_annotation(xml_interc, loc_data, pb_type_annotation);
+ xml_interc = xml_interc.next_sibling(xml_interc.name());
+ }
+ }
+
+ /* Parse all the port-to-port binding from operating pb_type to physical pb_type under this node
+ * All the bindings are defined in child node
+ * This is only applicable to operating pb_type
+ */
+ if (true == pb_type_annotation.is_operating_pb_type()) {
+ size_t num_ports = count_children(xml_pb_type, "port", loc_data, pugiutil::ReqOpt::OPTIONAL);
+ if (0 < num_ports) {
+ pugi::xml_node xml_port = get_first_child(xml_pb_type, "port", loc_data);
+ while (xml_port) {
+ read_xml_pb_port_annotation(xml_port, loc_data, pb_type_annotation);
+ xml_port = xml_port.next_sibling(xml_port.name());
+ }
+ }
+ }
+
/* Finish parsing and add it to the vector */
pb_type_annotations.push_back(pb_type_annotation);
}