diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp index da494f77f..d04e39b72 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp @@ -61,7 +61,7 @@ std::string PbTypeAnnotation::idle_mode_name() const { return idle_mode_name_; } -std::string PbTypeAnnotation::mode_bits() const { +std::vector PbTypeAnnotation::mode_bits() const { return mode_bits_; } @@ -155,7 +155,7 @@ void PbTypeAnnotation::set_idle_mode_name(const std::string& name) { idle_mode_name_ = name; } -void PbTypeAnnotation::set_mode_bits(const std::string& mode_bits) { +void PbTypeAnnotation::set_mode_bits(const std::vector& mode_bits) { mode_bits_ = mode_bits; } diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h index e03201cde..a969ee93d 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h @@ -43,7 +43,7 @@ class PbTypeAnnotation { bool is_physical_pb_type() const; std::string physical_mode_name() const; std::string idle_mode_name() const; - std::string mode_bits() const; + std::vector mode_bits() const; std::string circuit_model_name() const; int physical_pb_type_index_factor() const; int physical_pb_type_index_offset() const; @@ -61,7 +61,7 @@ class PbTypeAnnotation { void set_physical_parent_mode_names(const std::vector& names); void set_physical_mode_name(const std::string& name); void set_idle_mode_name(const std::string& name); - void set_mode_bits(const std::string& mode_bits); + void set_mode_bits(const std::vector& mode_bits); void set_circuit_model_name(const std::string& name); void set_physical_pb_type_index_factor(const int& value); void set_physical_pb_type_index_offset(const int& value); @@ -102,7 +102,7 @@ class PbTypeAnnotation { std::string idle_mode_name_; /* Configuration bits to select an operting mode for the circuit mode name */ - std::string mode_bits_; + std::vector mode_bits_; /* Circuit mode name linked to a physical pb_type. * This is only applicable to the physical pb_type diff --git a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp index 253053bf5..a17e970b7 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp @@ -63,6 +63,31 @@ void read_xml_pb_port_annotation(pugi::xml_node& xml_port, 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 mode_bits: convert from string to array of digits + * We only allow the bit to either '0' or '1' + *******************************************************************/ +static +std::vector parse_mode_bits(pugi::xml_node& xml_mode_bits, + const pugiutil::loc_data& loc_data, + const std::string& mode_bit_str) { + std::vector mode_bits; + + for (const char& bit_char : mode_bit_str) { + if ('0' == bit_char) { + mode_bits.push_back(0); + } else if ('1' == bit_char) { + mode_bits.push_back(1); + } else { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_mode_bits), + "Unexpected '%c' character found in the mode bit '%s'! Only allow either '0' or '1'\n", + bit_char, mode_bit_str.c_str()); + } + } + + return mode_bits; +} + /******************************************************************** * Parse XML description for a pb_type annotation under a XML node *******************************************************************/ @@ -119,7 +144,8 @@ void read_xml_pb_type_annotation(pugi::xml_node& xml_pb_type, pb_type_annotation.set_idle_mode_name(get_attribute(xml_pb_type, "idle_mode_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string()); /* Parse mode bits which are applied to both pb_types */ - pb_type_annotation.set_mode_bits(get_attribute(xml_pb_type, "mode_bits", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string()); + std::vector mode_bit_data = parse_mode_bits(xml_pb_type, loc_data, get_attribute(xml_pb_type, "mode_bits", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string()); + pb_type_annotation.set_mode_bits(mode_bit_data); /* If this is a physical pb_type, circuit model name is an optional attribute, * which is applicable to leaf pb_type in the hierarchy diff --git a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp index a771c782d..531e117f1 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp @@ -159,7 +159,12 @@ void write_xml_pb_type_annotation(std::fstream& fp, /* Output mode_bits */ if (!pb_type_annotation.mode_bits().empty()) { - write_xml_attribute(fp, "mode_bits", pb_type_annotation.mode_bits().c_str()); + /* Convert the vector of integer to string */ + std::string mode_bits_str; + for (const size_t& bit : pb_type_annotation.mode_bits()) { + mode_bits_str += std::to_string(bit); + } + write_xml_attribute(fp, "mode_bits", mode_bits_str.c_str()); } /* Output circuit model name */