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); }