finish XML parser and writer for pb_type annotation
This commit is contained in:
parent
1cba141dd0
commit
7d4b07421d
|
@ -31,7 +31,8 @@ std::vector<std::string> PbTypeAnnotation::operating_parent_mode_names() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PbTypeAnnotation::is_operating_pb_type() const {
|
bool PbTypeAnnotation::is_operating_pb_type() const {
|
||||||
return true == operating_pb_type_name_.empty();
|
return (false == operating_pb_type_name_.empty())
|
||||||
|
&& (false == physical_pb_type_name_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@ std::vector<std::string> PbTypeAnnotation::physical_parent_mode_names() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PbTypeAnnotation::is_physical_pb_type() const {
|
bool PbTypeAnnotation::is_physical_pb_type() const {
|
||||||
return true == physical_pb_type_name_.empty();
|
return (true == operating_pb_type_name_.empty())
|
||||||
|
&& (false == physical_pb_type_name_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PbTypeAnnotation::physical_mode_name() const {
|
std::string PbTypeAnnotation::physical_mode_name() const {
|
||||||
|
@ -75,7 +77,15 @@ int PbTypeAnnotation::physical_pb_type_index_offset() const {
|
||||||
return physical_pb_type_index_offset_;
|
return physical_pb_type_index_offset_;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicPort PbTypeAnnotation::physical_pb_type_ports(const std::string& port_name) const {
|
std::vector<std::string> PbTypeAnnotation::port_names() const {
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
for (auto const& element : operating_pb_type_ports_) {
|
||||||
|
keys.push_back(element.first);
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicPort PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const {
|
||||||
std::map<std::string, BasicPort>::const_iterator it = operating_pb_type_ports_.find(port_name);
|
std::map<std::string, BasicPort>::const_iterator it = operating_pb_type_ports_.find(port_name);
|
||||||
if (it == operating_pb_type_ports_.end()) {
|
if (it == operating_pb_type_ports_.end()) {
|
||||||
/* Return an empty port */
|
/* Return an empty port */
|
||||||
|
@ -84,7 +94,7 @@ BasicPort PbTypeAnnotation::physical_pb_type_ports(const std::string& port_name)
|
||||||
return operating_pb_type_ports_.at(port_name);
|
return operating_pb_type_ports_.at(port_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PbTypeAnnotation::physical_pin_rotate_offsets(const std::string& port_name) const {
|
int PbTypeAnnotation::physical_pin_rotate_offset(const std::string& port_name) const {
|
||||||
std::map<std::string, int>::const_iterator it = physical_pin_rotate_offsets_.find(port_name);
|
std::map<std::string, int>::const_iterator it = physical_pin_rotate_offsets_.find(port_name);
|
||||||
if (it == physical_pin_rotate_offsets_.end()) {
|
if (it == physical_pin_rotate_offsets_.end()) {
|
||||||
/* Return a zero offset which is default */
|
/* Return a zero offset which is default */
|
||||||
|
@ -93,6 +103,14 @@ int PbTypeAnnotation::physical_pin_rotate_offsets(const std::string& port_name)
|
||||||
return physical_pin_rotate_offsets_.at(port_name);
|
return physical_pin_rotate_offsets_.at(port_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PbTypeAnnotation::interconnect_names() const {
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
for (auto const& element : interconnect_circuit_model_names_) {
|
||||||
|
keys.push_back(element.first);
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PbTypeAnnotation::interconnect_circuit_model_name(const std::string& interc_name) const {
|
std::string PbTypeAnnotation::interconnect_circuit_model_name(const std::string& interc_name) const {
|
||||||
std::map<std::string, std::string>::const_iterator it = interconnect_circuit_model_names_.find(interc_name);
|
std::map<std::string, std::string>::const_iterator it = interconnect_circuit_model_names_.find(interc_name);
|
||||||
if (it == interconnect_circuit_model_names_.end()) {
|
if (it == interconnect_circuit_model_names_.end()) {
|
||||||
|
|
|
@ -47,8 +47,10 @@ class PbTypeAnnotation {
|
||||||
std::string circuit_model_name() const;
|
std::string circuit_model_name() const;
|
||||||
int physical_pb_type_index_factor() const;
|
int physical_pb_type_index_factor() const;
|
||||||
int physical_pb_type_index_offset() const;
|
int physical_pb_type_index_offset() const;
|
||||||
BasicPort physical_pb_type_ports(const std::string& port_name) const;
|
std::vector<std::string> port_names() const;
|
||||||
int physical_pin_rotate_offsets(const std::string& port_name) const;
|
BasicPort physical_pb_type_port(const std::string& port_name) const;
|
||||||
|
int physical_pin_rotate_offset(const std::string& port_name) const;
|
||||||
|
std::vector<std::string> interconnect_names() const;
|
||||||
std::string interconnect_circuit_model_name(const std::string& interc_name) const;
|
std::string interconnect_circuit_model_name(const std::string& interc_name) const;
|
||||||
public: /* Public mutators */
|
public: /* Public mutators */
|
||||||
void set_operating_pb_type_name(const std::string& name);
|
void set_operating_pb_type_name(const std::string& name);
|
||||||
|
|
|
@ -75,7 +75,6 @@ void read_xml_pb_type_annotation(pugi::xml_node& xml_pb_type,
|
||||||
/* Find the name of pb_type */
|
/* Find the name of pb_type */
|
||||||
const std::string& name_attr = get_attribute(xml_pb_type, "name", loc_data).as_string();
|
const std::string& name_attr = get_attribute(xml_pb_type, "name", loc_data).as_string();
|
||||||
const std::string& physical_name_attr = get_attribute(xml_pb_type, "physical_pb_type_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
|
const std::string& physical_name_attr = get_attribute(xml_pb_type, "physical_pb_type_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
|
||||||
const std::string& physical_mode_name_attr = get_attribute(xml_pb_type, "physical_mode_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
|
|
||||||
|
|
||||||
/* If both names are not empty, this is a operating pb_type */
|
/* If both names are not empty, this is a operating pb_type */
|
||||||
if ( (false == name_attr.empty())
|
if ( (false == name_attr.empty())
|
||||||
|
@ -122,9 +121,11 @@ void read_xml_pb_type_annotation(pugi::xml_node& xml_pb_type,
|
||||||
/* Parse mode bits which are applied to both pb_types */
|
/* 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());
|
pb_type_annotation.set_mode_bits(get_attribute(xml_pb_type, "mode_bits", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string());
|
||||||
|
|
||||||
/* If this is a physical pb_type, circuit model name is a mandatory attribute */
|
/* If this is a physical pb_type, circuit model name is an optional attribute,
|
||||||
|
* which is applicable to leaf pb_type in the hierarchy
|
||||||
|
*/
|
||||||
if (true == pb_type_annotation.is_physical_pb_type()) {
|
if (true == pb_type_annotation.is_physical_pb_type()) {
|
||||||
pb_type_annotation.set_circuit_model_name(get_attribute(xml_pb_type, "circuit_model_name", loc_data).as_string());
|
pb_type_annotation.set_circuit_model_name(get_attribute(xml_pb_type, "circuit_model_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is an operating pb_type, index factor and offset may be optional needed */
|
/* If this is an operating pb_type, index factor and offset may be optional needed */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "write_xml_simulation_setting.h"
|
#include "write_xml_simulation_setting.h"
|
||||||
#include "write_xml_config_protocol.h"
|
#include "write_xml_config_protocol.h"
|
||||||
#include "write_xml_routing_circuit.h"
|
#include "write_xml_routing_circuit.h"
|
||||||
|
#include "write_xml_pb_type_annotation.h"
|
||||||
#include "write_xml_openfpga_arch.h"
|
#include "write_xml_openfpga_arch.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -57,6 +58,10 @@ void write_xml_openfpga_arch(const char* fname,
|
||||||
/* Write the direct connection circuit definition */
|
/* Write the direct connection circuit definition */
|
||||||
write_xml_direct_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.direct2circuit);
|
write_xml_direct_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.direct2circuit);
|
||||||
|
|
||||||
|
|
||||||
|
/* Write the pb_type annotations */
|
||||||
|
openfpga::write_xml_pb_type_annotations(fp, fname, openfpga_arch. pb_type_annotations);
|
||||||
|
|
||||||
fp << "</openfpga_architecture>" << "\n";
|
fp << "</openfpga_architecture>" << "\n";
|
||||||
|
|
||||||
/* Write the simulation */
|
/* Write the simulation */
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
/********************************************************************
|
||||||
|
* This file includes functions that outputs pb_type annotations to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
/* Headers from system goes first */
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/* Headers from vtr util library */
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
#include "openfpga_digest.h"
|
||||||
|
|
||||||
|
/* Headers from readarchopenfpga library */
|
||||||
|
#include "write_xml_utils.h"
|
||||||
|
#include "write_xml_pb_type_annotation.h"
|
||||||
|
|
||||||
|
/* namespace openfpga begins */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generate the full hierarchy name for a operating pb_type
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
std::string generate_operating_pb_type_hierarchy_name(const PbTypeAnnotation& pb_type_annotation) {
|
||||||
|
/* Iterate over the parent_pb_type and modes names, they should well match */
|
||||||
|
VTR_ASSERT_SAFE(pb_type_annotation.operating_parent_pb_type_names().size() == pb_type_annotation.operating_parent_mode_names().size());
|
||||||
|
|
||||||
|
std::string hie_name;
|
||||||
|
|
||||||
|
for (size_t i = 0 ; i < pb_type_annotation.operating_parent_pb_type_names().size(); ++i) {
|
||||||
|
hie_name += pb_type_annotation.operating_parent_pb_type_names()[i];
|
||||||
|
hie_name += std::string("[");
|
||||||
|
hie_name += pb_type_annotation.operating_parent_mode_names()[i];
|
||||||
|
hie_name += std::string("]");
|
||||||
|
hie_name += std::string(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the leaf pb_type */
|
||||||
|
hie_name += pb_type_annotation.operating_pb_type_name();
|
||||||
|
|
||||||
|
return hie_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generate the full hierarchy name for a operating pb_type
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
std::string generate_physical_pb_type_hierarchy_name(const PbTypeAnnotation& pb_type_annotation) {
|
||||||
|
/* Iterate over the parent_pb_type and modes names, they should well match */
|
||||||
|
VTR_ASSERT_SAFE(pb_type_annotation.physical_parent_pb_type_names().size() == pb_type_annotation.physical_parent_mode_names().size());
|
||||||
|
|
||||||
|
std::string hie_name;
|
||||||
|
|
||||||
|
for (size_t i = 0 ; i < pb_type_annotation.physical_parent_pb_type_names().size(); ++i) {
|
||||||
|
hie_name += pb_type_annotation.physical_parent_pb_type_names()[i];
|
||||||
|
hie_name += std::string("[");
|
||||||
|
hie_name += pb_type_annotation.physical_parent_mode_names()[i];
|
||||||
|
hie_name += std::string("]");
|
||||||
|
hie_name += std::string(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the leaf pb_type */
|
||||||
|
hie_name += pb_type_annotation.physical_pb_type_name();
|
||||||
|
|
||||||
|
return hie_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generate the full hierarchy name for a operating pb_type
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
std::string generate_physical_pb_port_name(const BasicPort& pb_port) {
|
||||||
|
std::string port_name;
|
||||||
|
|
||||||
|
/* Output format: <port_name>[<LSB>:<MSB>] */
|
||||||
|
port_name += pb_port.get_name();
|
||||||
|
port_name += std::string("[");
|
||||||
|
port_name += std::to_string(pb_port.get_lsb());
|
||||||
|
port_name += std::string(":");
|
||||||
|
port_name += std::to_string(pb_port.get_msb());
|
||||||
|
port_name += std::string("]");
|
||||||
|
|
||||||
|
return port_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output an pb_type interconnection annotation to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void write_xml_interconnect_annotation(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const openfpga::PbTypeAnnotation& pb_type_annotation,
|
||||||
|
const std::string& interc_name) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
fp << "\t\t\t" << "<interconnect";
|
||||||
|
|
||||||
|
write_xml_attribute(fp, "name", interc_name.c_str());
|
||||||
|
write_xml_attribute(fp, "circuit_model_name", pb_type_annotation.interconnect_circuit_model_name(interc_name).c_str());
|
||||||
|
|
||||||
|
fp << "/>" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output an pb_type port annotation to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void write_xml_pb_port_annotation(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const openfpga::PbTypeAnnotation& pb_type_annotation,
|
||||||
|
const std::string& port_name) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
fp << "\t\t\t" << "<port";
|
||||||
|
|
||||||
|
write_xml_attribute(fp, "name", port_name.c_str());
|
||||||
|
write_xml_attribute(fp, "physical_mode_port", generate_physical_pb_port_name(pb_type_annotation.physical_pb_type_port(port_name)).c_str());
|
||||||
|
write_xml_attribute(fp, "physical_mode_pin_rotate_offset", pb_type_annotation.physical_pin_rotate_offset(port_name));
|
||||||
|
|
||||||
|
fp << "/>" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output a device variation in a technology library to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void write_xml_pb_type_annotation(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const openfpga::PbTypeAnnotation& pb_type_annotation) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
fp << "\t\t" << "<pb_type";
|
||||||
|
|
||||||
|
/* Write up name of the pb_type, which is different by the type of pb_type
|
||||||
|
* 1. operating pb_type, we output name, physical_pb_type_name
|
||||||
|
* 1. physical pb_type, we output name
|
||||||
|
*/
|
||||||
|
if (true == pb_type_annotation.is_operating_pb_type()) {
|
||||||
|
write_xml_attribute(fp, "name", generate_operating_pb_type_hierarchy_name(pb_type_annotation).c_str());
|
||||||
|
write_xml_attribute(fp, "physical_pb_type_name", generate_physical_pb_type_hierarchy_name(pb_type_annotation).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true == pb_type_annotation.is_physical_pb_type()) {
|
||||||
|
write_xml_attribute(fp, "name", generate_physical_pb_type_hierarchy_name(pb_type_annotation).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output physical mode name */
|
||||||
|
if (!pb_type_annotation.physical_mode_name().empty()) {
|
||||||
|
write_xml_attribute(fp, "physical_mode_name", pb_type_annotation.physical_mode_name().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output idle mode name */
|
||||||
|
if (!pb_type_annotation.idle_mode_name().empty()) {
|
||||||
|
write_xml_attribute(fp, "idle_mode_name", pb_type_annotation.idle_mode_name().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output mode_bits */
|
||||||
|
if (!pb_type_annotation.mode_bits().empty()) {
|
||||||
|
write_xml_attribute(fp, "mode_bits", pb_type_annotation.mode_bits().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output circuit model name */
|
||||||
|
if (!pb_type_annotation.circuit_model_name().empty()) {
|
||||||
|
write_xml_attribute(fp, "circuit_model_name", pb_type_annotation.circuit_model_name().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output physical mode index factor and offset, only applicable to operating mode */
|
||||||
|
if (true == pb_type_annotation.is_operating_pb_type()) {
|
||||||
|
write_xml_attribute(fp, "physical_pb_type_index_factor", pb_type_annotation.physical_pb_type_index_factor());
|
||||||
|
write_xml_attribute(fp, "physical_pb_type_index_offset", pb_type_annotation.physical_pb_type_index_offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there are interconnect definition or port definition, output them
|
||||||
|
* Otherwise we can finish here
|
||||||
|
*/
|
||||||
|
if ( (0 == pb_type_annotation.interconnect_names().size())
|
||||||
|
&& (0 == pb_type_annotation.port_names().size()) ) {
|
||||||
|
fp << "/>" << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp << ">" << "\n";
|
||||||
|
|
||||||
|
/* Output interconnects if there are any */
|
||||||
|
for (const std::string& interc_name : pb_type_annotation.interconnect_names()) {
|
||||||
|
write_xml_interconnect_annotation(fp, fname, pb_type_annotation, interc_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output pb_type ports if there are any */
|
||||||
|
for (const std::string& port_name : pb_type_annotation.port_names()) {
|
||||||
|
write_xml_pb_port_annotation(fp, fname, pb_type_annotation, port_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fp << "\t\t</pb_type>" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A writer to output a number of pb_type annotations to XML format
|
||||||
|
*******************************************************************/
|
||||||
|
void write_xml_pb_type_annotations(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const std::vector<PbTypeAnnotation>& pb_type_annotations) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::check_file_stream(fname, fp);
|
||||||
|
|
||||||
|
/* Write the root node for pb_type annotations,
|
||||||
|
* we apply a tab becuase pb_type annotations is just a subnode
|
||||||
|
* under the root node <openfpga_arch>
|
||||||
|
*/
|
||||||
|
fp << "\t" << "<pb_type_annotations>" << "\n";
|
||||||
|
|
||||||
|
/* Write device model one by one */
|
||||||
|
for (const PbTypeAnnotation& pb_type_annotation : pb_type_annotations) {
|
||||||
|
write_xml_pb_type_annotation(fp, fname, pb_type_annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the root node for pb_type annotations */
|
||||||
|
fp << "\t" << "</pb_type_annotations>" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace openfpga ends */
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef WRITE_XML_PB_TYPE_ANNOTATION_H
|
||||||
|
#define WRITE_XML_PB_TYPE_ANNOTATION_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files that are required by function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
#include <fstream>
|
||||||
|
#include "pb_type_annotation.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
/* namespace openfpga begins */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
void write_xml_pb_type_annotations(std::fstream& fp,
|
||||||
|
const char* fname,
|
||||||
|
const std::vector<PbTypeAnnotation>& pb_type_annotations);
|
||||||
|
|
||||||
|
} /* namespace openfpga ends */
|
||||||
|
|
||||||
|
#endif
|
|
@ -46,6 +46,21 @@ void write_xml_attribute(std::fstream& fp,
|
||||||
fp << "\"";
|
fp << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* A most utilized function to write an XML attribute to file
|
||||||
|
* This accepts the value as a float
|
||||||
|
*******************************************************************/
|
||||||
|
void write_xml_attribute(std::fstream& fp,
|
||||||
|
const char* attr,
|
||||||
|
const int& value) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
openfpga::valid_file_stream(fp);
|
||||||
|
|
||||||
|
fp << " " << attr << "=\"";
|
||||||
|
fp << value;
|
||||||
|
fp << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* A most utilized function to write an XML attribute to file
|
* A most utilized function to write an XML attribute to file
|
||||||
* This accepts the value as a float
|
* This accepts the value as a float
|
||||||
|
|
|
@ -18,6 +18,10 @@ void write_xml_attribute(std::fstream& fp,
|
||||||
const char* attr,
|
const char* attr,
|
||||||
const bool& value);
|
const bool& value);
|
||||||
|
|
||||||
|
void write_xml_attribute(std::fstream& fp,
|
||||||
|
const char* attr,
|
||||||
|
const int& value);
|
||||||
|
|
||||||
void write_xml_attribute(std::fstream& fp,
|
void write_xml_attribute(std::fstream& fp,
|
||||||
const char* attr,
|
const char* attr,
|
||||||
const float& value);
|
const float& value);
|
||||||
|
|
|
@ -67,6 +67,7 @@ void PbParser::parse() {
|
||||||
/* The last pb is the leaf node.
|
/* The last pb is the leaf node.
|
||||||
* It should NOT be empty and should NOT contain any brackets!
|
* It should NOT be empty and should NOT contain any brackets!
|
||||||
*/
|
*/
|
||||||
|
VTR_ASSERT(0 < pb_tokens.size());
|
||||||
VTR_ASSERT(false == pb_tokens.back().empty());
|
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_.x()) == std::string::npos);
|
||||||
VTR_ASSERT(pb_tokens.back().find(bracket_.y()) == std::string::npos);
|
VTR_ASSERT(pb_tokens.back().find(bracket_.y()) == std::string::npos);
|
||||||
|
|
|
@ -64,7 +64,7 @@ void PortParser::parse() {
|
||||||
|
|
||||||
/* If we only have one token */
|
/* If we only have one token */
|
||||||
if (1 == port_tokens.size()) {
|
if (1 == port_tokens.size()) {
|
||||||
port_.set_width(0);
|
port_.set_width(1);
|
||||||
return; /* We can finish here */
|
return; /* We can finish here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,21 +75,22 @@ void PortParser::parse() {
|
||||||
VTR_ASSERT_SAFE (1 == port_tokens.size());
|
VTR_ASSERT_SAFE (1 == port_tokens.size());
|
||||||
|
|
||||||
/* Split the pin string now */
|
/* Split the pin string now */
|
||||||
tokenizer.set_data(port_tokens[0]);
|
tokenizer.set_data(pin_tokens[0]);
|
||||||
pin_tokens = tokenizer.split(delim_);
|
pin_tokens = tokenizer.split(delim_);
|
||||||
|
|
||||||
/* Check if we have LSB and MSB or just one */
|
/* Check if we have LSB and MSB or just one */
|
||||||
if ( 1 == pin_tokens.size() ) {
|
if ( 1 == pin_tokens.size() ) {
|
||||||
/* Single pin */
|
/* Single pin */
|
||||||
port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[0]));
|
port_.set_width(std::stoi(pin_tokens[0]), std::stoi(pin_tokens[0]));
|
||||||
} else if ( 2 == pin_tokens.size() ) {
|
} else if ( 2 == pin_tokens.size() ) {
|
||||||
/* A number of pin */
|
/* A number of pins.
|
||||||
port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[1]));
|
* Note that we always use the LSB for token[0] and MSB for token[1]
|
||||||
}
|
*/
|
||||||
|
if (std::stoi(pin_tokens[1]) < std::stoi(pin_tokens[0])) {
|
||||||
/* Re-order to ensure LSB <= MSB */
|
port_.set_width(std::stoi(pin_tokens[1]), std::stoi(pin_tokens[0]));
|
||||||
if (false == port_.is_valid()) {
|
} else {
|
||||||
port_.revert();
|
port_.set_width(std::stoi(pin_tokens[0]), std::stoi(pin_tokens[1]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue