add pb parser and support XML parsing for pb type name in full hiearchy

This commit is contained in:
tangxifan 2020-01-26 11:52:58 -07:00
parent cd3565cf53
commit 1cba141dd0
3 changed files with 199 additions and 3 deletions

View File

@ -14,6 +14,7 @@
/* Headers from openfpga util library */
#include "openfpga_port_parser.h"
#include "openfpga_pb_parser.h"
/* Headers from libarchfpga */
#include "arch_error.h"
@ -80,14 +81,36 @@ void read_xml_pb_type_annotation(pugi::xml_node& xml_pb_type,
if ( (false == name_attr.empty())
&& (false == physical_name_attr.empty()) ) {
/* Parse the attributes for operating pb_type */
pb_type_annotation.set_operating_pb_type_name(name_attr);
pb_type_annotation.set_physical_pb_type_name(physical_name_attr);
openfpga::PbParser operating_pb_parser(name_attr);
pb_type_annotation.set_operating_pb_type_name(operating_pb_parser.leaf());
if (0 < operating_pb_parser.parents().size()) {
pb_type_annotation.set_operating_parent_pb_type_names(operating_pb_parser.parents());
}
if (0 < operating_pb_parser.modes().size()) {
pb_type_annotation.set_operating_parent_mode_names(operating_pb_parser.modes());
}
openfpga::PbParser physical_pb_parser(physical_name_attr);
pb_type_annotation.set_physical_pb_type_name(physical_pb_parser.leaf());
if (0 < physical_pb_parser.parents().size()) {
pb_type_annotation.set_physical_parent_pb_type_names(physical_pb_parser.parents());
}
if (0 < physical_pb_parser.modes().size()) {
pb_type_annotation.set_physical_parent_mode_names(physical_pb_parser.modes());
}
}
/* If there is only a name, this is a physical pb_type */
if ( (false == name_attr.empty())
&& (true == physical_name_attr.empty()) ) {
pb_type_annotation.set_physical_pb_type_name(name_attr);
openfpga::PbParser physical_pb_parser(name_attr);
pb_type_annotation.set_physical_pb_type_name(physical_pb_parser.leaf());
if (0 < physical_pb_parser.parents().size()) {
pb_type_annotation.set_physical_parent_pb_type_names(physical_pb_parser.parents());
}
if (0 < physical_pb_parser.modes().size()) {
pb_type_annotation.set_physical_parent_mode_names(physical_pb_parser.modes());
}
}
/* Parse physical mode name which are applied to both pb_types */

View File

@ -0,0 +1,117 @@
/************************************************************************
* Member functions for Pb parsers
***********************************************************************/
#include <cstring>
#include "vtr_assert.h"
#include "openfpga_tokenizer.h"
#include "openfpga_pb_parser.h"
/* namespace openfpga begins */
namespace openfpga {
/************************************************************************
* Member functions for PbParser class
***********************************************************************/
/************************************************************************
* Constructors
***********************************************************************/
PbParser::PbParser (const std::string& data) {
set_default_bracket();
set_default_delim();
set_data(data);
}
/************************************************************************
* Public Accessors
***********************************************************************/
/* Get the data string */
std::string PbParser::data() const {
return data_;
}
std::string PbParser::leaf() const {
return leaf_;
}
std::vector<std::string> PbParser::parents() const {
return parents_;
}
std::vector<std::string> PbParser::modes() const {
return modes_;
}
/************************************************************************
* Public Mutators
***********************************************************************/
void PbParser::set_data(const std::string& data) {
data_ = data;
parse();
}
/************************************************************************
* Internal Mutators
***********************************************************************/
/* Parse the data */
void PbParser::parse() {
/* Create a tokenizer */
StringToken tokenizer(data_);
/* Split the data into <pb_type>[<mode>] */
std::vector<std::string> pb_tokens = tokenizer.split(delim_);
/* The last pb is the leaf node.
* It should NOT be empty and should NOT contain any brackets!
*/
VTR_ASSERT(false == pb_tokens.back().empty());
VTR_ASSERT(pb_tokens.back().find(bracket_.x()) == std::string::npos);
VTR_ASSERT(pb_tokens.back().find(bracket_.y()) == std::string::npos);
/* Pass the check, we assign the value */
leaf_ = pb_tokens.back();
/* Split the rest of pb_tokens, split the pb_type and mode_name */
for (size_t itok = 0; itok < pb_tokens.size() - 1; ++itok) {
/* Create a tokenizer */
StringToken pb_tokenizer(pb_tokens[itok]);
std::vector<std::string> tokens = pb_tokenizer.split(bracket_.x());
/* Make sure we have a port name! */
VTR_ASSERT_SAFE ((1 == tokens.size()) || (2 == tokens.size()));
/* Store the pb_type name */
parents_.push_back(tokens[0]);
/* If we only have one token, the mode name is the default mode
* Here we use the default keyword 'default'
* from VPR function ProcessMode() in libarchfpga
*/
if (1 == tokens.size()) {
modes_.push_back(std::string("default"));
continue; /* We can finish here */
}
/* If there is a mode name, extract it */
VTR_ASSERT_SAFE (2 == tokens.size());
/* Chomp the ']' */
pb_tokenizer.set_data(tokens[1]);
std::vector<std::string> mode_tokens = pb_tokenizer.split(bracket_.y());
/* Make sure we have only one mode name inside */
VTR_ASSERT(1 == mode_tokens.size());
modes_.push_back(mode_tokens[0]);
}
}
void PbParser::set_default_bracket() {
bracket_.set_x('[');
bracket_.set_y(']');
}
void PbParser::set_default_delim() {
delim_ = '.';
}
} /* namespace openfpga ends */

View File

@ -0,0 +1,56 @@
#ifndef OPENFPGA_PB_PARSER_H
#define OPENFPGA_PB_PARSER_H
/********************************************************************
* Include header files that are required by data structure declaration
*******************************************************************/
#include <string>
#include <vector>
#include "vtr_geometry.h"
#include "openfpga_tokenizer.h"
/************************************************************************
* This file includes parsers for pb_type definition in the architecture XML
* language.
***********************************************************************/
/* namespace openfpga begins */
namespace openfpga {
/************************************************************************
* Class PbParser: pb_type name with full hierarchy parser
* Supported pb_type definition:
* 1. <pb_type>[<mode>].<sub_pb_type>[<mode>] ... .<leaf_pb_type>
* 2. <pb_type>.<sub_pb_type> ... .<leaf_pb_type>
* where each pb_type may be specified by a mode or use the default mode
* (mode name not given)
***********************************************************************/
class PbParser{
public : /* Constructors*/
PbParser (const std::string& data);
public : /* Public Accessors */
std::string data() const;
std::string leaf() const;
std::vector<std::string> parents() const;
std::vector<std::string> modes() const;
public : /* Public Mutators */
void set_data(const std::string& data);
private : /* Private Mutators */
void parse();
void set_default_bracket();
void set_default_delim();
private: /* Internal data */
std::string data_; /* Lines to be splited */
vtr::Point<char> bracket_;
char delim_;
std::vector<std::string> parents_;
std::vector<std::string> modes_;
std::string leaf_;
};
} /* namespace openfpga ends */
#endif