[Tool] Add bitstream setting file to openfpga library

This commit is contained in:
tangxifan 2021-02-01 17:43:46 -07:00
parent 04594cb7ab
commit f102e84497
12 changed files with 415 additions and 1 deletions

View File

@ -0,0 +1,80 @@
#include "vtr_assert.h"
#include "bitstream_setting.h"
/* namespace openfpga begins */
namespace openfpga {
/************************************************************************
* Member functions for class BitstreamSetting
***********************************************************************/
/************************************************************************
* Public Accessors : aggregates
***********************************************************************/
BitstreamSetting::bitstream_pb_type_setting_range BitstreamSetting::pb_type_settings() const {
return vtr::make_range(pb_type_setting_ids_.begin(), pb_type_setting_ids_.end());
}
/************************************************************************
* Constructors
***********************************************************************/
BitstreamSetting::BitstreamSetting() {
return;
}
/************************************************************************
* Public Accessors
***********************************************************************/
std::string BitstreamSetting::pb_type_name(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id));
return pb_type_names_[pb_type_setting_id];
}
std::vector<std::string> BitstreamSetting::parent_pb_type_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id));
return parent_pb_type_names_[pb_type_setting_id];
}
std::vector<std::string> BitstreamSetting::parent_mode_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id));
return parent_mode_names_[pb_type_setting_id];
}
std::string BitstreamSetting::pb_type_bitstream_source(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id));
return pb_type_bitstream_sources_[pb_type_setting_id];
}
std::string BitstreamSetting::pb_type_bitstream_content(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id));
return pb_type_bitstream_contents_[pb_type_setting_id];
}
/************************************************************************
* Public Mutators
***********************************************************************/
BitstreamPbTypeSettingId BitstreamSetting::add_bitstream_pb_type_setting(const std::string& pb_type_name,
const std::vector<std::string>& parent_pb_type_names,
const std::vector<std::string>& parent_mode_names,
const std::string& bitstream_source,
const std::string& bitstream_content) {
BitstreamPbTypeSettingId pb_type_setting_id = BitstreamPbTypeSettingId(pb_type_setting_ids_.size());
pb_type_setting_ids_.push_back(pb_type_setting_id);
pb_type_names_.push_back(pb_type_name);
parent_pb_type_names_.push_back(parent_pb_type_names);
parent_mode_names_.push_back(parent_mode_names);
pb_type_bitstream_sources_.push_back(bitstream_source);
pb_type_bitstream_contents_.push_back(bitstream_content);
return pb_type_setting_id;
}
/************************************************************************
* Public Validators
***********************************************************************/
bool BitstreamSetting::valid_bitstream_pb_type_setting_id(const BitstreamPbTypeSettingId& pb_type_setting_id) const {
return ( size_t(pb_type_setting_id) < pb_type_setting_ids_.size() ) && ( pb_type_setting_id == pb_type_setting_ids_[pb_type_setting_id] );
}
} /* namespace openfpga ends */

View File

@ -0,0 +1,61 @@
#ifndef BITSTREAM_SETTING_H
#define BITSTREAM_SETTING_H
/********************************************************************
* This file include the declaration of simulation settings
* which are used by OpenFPGA
*******************************************************************/
#include <string>
#include "vtr_vector.h"
#include "bitstream_setting_fwd.h"
/* namespace openfpga begins */
namespace openfpga {
/********************************************************************
* A data structure to describe bitstream settings
*
* Typical usage:
* --------------
* // Create an empty bitstream setting
* BitstreamSetting bitstream_setting;
* // call your builder for bitstream_setting
*
*******************************************************************/
class BitstreamSetting {
public: /* Types */
typedef vtr::vector<BitstreamPbTypeSettingId, BitstreamPbTypeSettingId>::const_iterator bitstream_pb_type_setting_iterator;
/* Create range */
typedef vtr::Range<bitstream_pb_type_setting_iterator> bitstream_pb_type_setting_range;
public: /* Constructors */
BitstreamSetting();
public: /* Accessors: aggregates */
bitstream_pb_type_setting_range pb_type_settings() const;
public: /* Public Accessors */
std::string pb_type_name(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
std::vector<std::string> parent_pb_type_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
std::vector<std::string> parent_mode_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
std::string pb_type_bitstream_source(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
std::string pb_type_bitstream_content(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
public: /* Public Mutators */
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(const std::string& pb_type_name,
const std::vector<std::string>& parent_pb_type_names,
const std::vector<std::string>& parent_mode_names,
const std::string& bitstream_source,
const std::string& bitstream_content);
public: /* Public Validators */
bool valid_bitstream_pb_type_setting_id(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
private: /* Internal data */
vtr::vector<BitstreamPbTypeSettingId, BitstreamPbTypeSettingId> pb_type_setting_ids_;
vtr::vector<BitstreamPbTypeSettingId, std::string> pb_type_names_;
vtr::vector<BitstreamPbTypeSettingId, std::vector<std::string>> parent_pb_type_names_;
vtr::vector<BitstreamPbTypeSettingId, std::vector<std::string>> parent_mode_names_;
vtr::vector<BitstreamPbTypeSettingId, std::string> pb_type_bitstream_sources_;
vtr::vector<BitstreamPbTypeSettingId, std::string> pb_type_bitstream_contents_;
};
} /* namespace openfpga ends */
#endif

View File

@ -0,0 +1,22 @@
/************************************************************************
* A header file for BitstreamSetting class, including critical data declaration
* Please include this file only for using any BitstreamSetting data structure
* Refer to bitstream_setting.h for more details
***********************************************************************/
/************************************************************************
* Create strong id for the pb_type annotation in Bitstream setting to avoid illegal type casting
***********************************************************************/
#ifndef BITSTREAM_SETTING_FWD_H
#define BITSTREAM_SETTING_FWD_H
#include "vtr_strong_id.h"
struct bitstream_pb_type_setting_id_tag;
typedef vtr::StrongId<bitstream_pb_type_setting_id_tag> BitstreamPbTypeSettingId;
/* Short declaration of class */
class BitstreamSetting;
#endif

View File

@ -6,7 +6,6 @@
#include "circuit_library.h"
#include "technology_library.h"
#include "simulation_setting.h"
#include "config_protocol.h"
#include "arch_direct.h"
#include "tile_annotation.h"

View File

@ -0,0 +1,65 @@
/********************************************************************
* This file includes the top-level function of this library
* which reads an XML modeling OpenFPGA architecture to the associated
* data structures
*******************************************************************/
#include <string>
/* Headers from pugi XML library */
#include "pugixml.hpp"
#include "pugixml_util.hpp"
/* Headers from vtr util library */
#include "vtr_assert.h"
/* Headers from openfpga util library */
#include "openfpga_pb_parser.h"
/* Headers from libarchfpga */
#include "arch_error.h"
#include "read_xml_util.h"
#include "read_xml_bitstream_setting.h"
/********************************************************************
* Parse XML description for a pb_type annotation under a <pb_type> XML node
*******************************************************************/
static
void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type,
const pugiutil::loc_data& loc_data,
openfpga::BitstreamSetting& bitstream_setting) {
const std::string& name_attr = get_attribute(xml_pb_type, "name", loc_data).as_string();
const std::string& source_attr = get_attribute(xml_pb_type, "source", loc_data).as_string();
const std::string& content_attr = get_attribute(xml_pb_type, "content", loc_data).as_string();
/* Parse the attributes for operating pb_type */
openfpga::PbParser operating_pb_parser(name_attr);
/* Add to bitstream setting */
bitstream_setting.add_bitstream_pb_type_setting(operating_pb_parser.leaf(),
operating_pb_parser.parents(),
operating_pb_parser.modes(),
source_attr,
content_attr);
}
/********************************************************************
* Parse XML codes about <openfpga_bitstream_setting> to an object
*******************************************************************/
openfpga::BitstreamSetting read_xml_bitstream_setting(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data) {
openfpga::BitstreamSetting bitstream_setting;
/* Iterate over the children under this node,
* each child should be named after <pb_type>
*/
for (pugi::xml_node xml_pb_type : Node.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_pb_type.name() != std::string("pb_type")) {
bad_tag(xml_pb_type, loc_data, Node, {"pb_type"});
}
read_xml_bitstream_pb_type_setting(xml_pb_type, loc_data, bitstream_setting);
}
return bitstream_setting;
}

View File

@ -0,0 +1,18 @@
#ifndef READ_XML_BITSTREAM_SETTING_H
#define READ_XML_BITSTREAM_SETTING_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "pugixml_util.hpp"
#include "pugixml.hpp"
#include "bitstream_setting.h"
/********************************************************************
* Function declaration
*******************************************************************/
openfpga::BitstreamSetting read_xml_bitstream_setting(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data);
#endif

View File

@ -23,6 +23,7 @@
#include "read_xml_routing_circuit.h"
#include "read_xml_tile_annotation.h"
#include "read_xml_pb_type_annotation.h"
#include "read_xml_bitstream_setting.h"
#include "read_xml_openfpga_arch.h"
#include "openfpga_arch_linker.h"
@ -149,3 +150,34 @@ openfpga::SimulationSetting read_xml_openfpga_simulation_settings(const char* si
return openfpga_sim_setting;
}
/********************************************************************
* Top-level function to parse an XML file and load data to bitstream settings
*******************************************************************/
openfpga::BitstreamSetting read_xml_openfpga_bitstream_settings(const char* bitstream_setting_file_name) {
vtr::ScopedStartFinishTimer timer("Read OpenFPGA bitstream settings");
openfpga::BitstreamSetting openfpga_bitstream_setting;
pugi::xml_node Next;
/* Parse the file */
pugi::xml_document doc;
pugiutil::loc_data loc_data;
try {
loc_data = pugiutil::load_xml(doc, bitstream_setting_file_name);
/* Second node should be <openfpga_simulation_setting> */
auto xml_bitstream_settings = get_single_child(doc, "openfpga_bitstream_setting", loc_data);
/* Parse simulation settings to data structure */
openfpga_bitstream_setting = read_xml_bitstream_setting(xml_bitstream_settings, loc_data);
} catch (pugiutil::XmlError& e) {
archfpga_throw(bitstream_setting_file_name, e.line(),
"%s", e.what());
}
return openfpga_bitstream_setting;
}

View File

@ -6,6 +6,8 @@
*******************************************************************/
#include <string>
#include "openfpga_arch.h"
#include "simulation_setting.h"
#include "bitstream_setting.h"
/********************************************************************
* Function declaration
@ -14,4 +16,6 @@ openfpga::Arch read_xml_openfpga_arch(const char* arch_file_name);
openfpga::SimulationSetting read_xml_openfpga_simulation_settings(const char* sim_setting_file_name);
openfpga::BitstreamSetting read_xml_openfpga_bitstream_settings(const char* bitstream_setting_file_name);
#endif

View File

@ -0,0 +1,84 @@
/********************************************************************
* This file includes functions that outputs a bitstream setting 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_bitstream_setting.h"
/********************************************************************
* Generate the full hierarchy name for a pb_type in bitstream setting
*******************************************************************/
static
std::string generate_bitstream_setting_pb_type_hierarchy_name(const openfpga::BitstreamSetting& bitstream_setting,
const BitstreamPbTypeSettingId& bitstream_pb_type_setting_id) {
/* Iterate over the parent_pb_type and modes names, they should well match */
VTR_ASSERT_SAFE(bitstream_setting.parent_pb_type_names(bitstream_pb_type_setting_id).size() == bitstream_setting.parent_mode_names(bitstream_pb_type_setting_id).size());
std::string hie_name;
for (size_t i = 0 ; i < bitstream_setting.parent_pb_type_names(bitstream_pb_type_setting_id).size(); ++i) {
hie_name += bitstream_setting.parent_pb_type_names(bitstream_pb_type_setting_id)[i];
hie_name += std::string("[");
hie_name += bitstream_setting.parent_mode_names(bitstream_pb_type_setting_id)[i];
hie_name += std::string("]");
hie_name += std::string(".");
}
/* Add the leaf pb_type */
hie_name += bitstream_setting.pb_type_name(bitstream_pb_type_setting_id);
return hie_name;
}
/********************************************************************
* A writer to output a bitstream pb_type setting to XML format
*******************************************************************/
static
void write_xml_bitstream_pb_type_setting(std::fstream& fp,
const char* fname,
const openfpga::BitstreamSetting& bitstream_setting,
const BitstreamPbTypeSettingId& bitstream_pb_type_setting_id) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t\t" << "<pb_type";
/* Generate the full hierarchy name of the pb_type */
write_xml_attribute(fp, "name", generate_bitstream_setting_pb_type_hierarchy_name(bitstream_setting, bitstream_pb_type_setting_id).c_str());
write_xml_attribute(fp, "source", bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id).c_str());
write_xml_attribute(fp, "content", bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id).c_str());
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output a bitstream setting to XML format
*******************************************************************/
void write_xml_bitstream_setting(std::fstream& fp,
const char* fname,
const openfpga::BitstreamSetting& bitstream_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node <openfpga_bitstream_setting>
*/
fp << "<openfpga_bitstream_setting>" << "\n";
/* Write clock settings */
for (const auto& bitstream_pb_type_setting_id : bitstream_setting.pb_type_settings()) {
write_xml_bitstream_pb_type_setting(fp, fname, bitstream_setting, bitstream_pb_type_setting_id);
}
/* Write the root node <openfpga_bitstream_setting> */
fp << "</openfpga_bitstream_setting>" << "\n";
}

View File

@ -0,0 +1,17 @@
#ifndef WRITE_XML_BITSTREAM_SETTING_H
#define WRITE_XML_BITSTREAM_SETTING_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "bitstream_setting.h"
/********************************************************************
* Function declaration
*******************************************************************/
void write_xml_bitstream_setting(std::fstream& fp,
const char* fname,
const openfpga::BitstreamSetting& bitstream_setting);
#endif

View File

@ -0,0 +1,31 @@
/********************************************************************
* Unit test functions to validate the correctness of
* 1. parser of data structures
* 2. writer of data structures
*******************************************************************/
/* Headers from vtrutils */
#include "vtr_assert.h"
#include "vtr_log.h"
/* Headers from readarchopenfpga */
#include "read_xml_openfpga_arch.h"
#include "write_xml_openfpga_arch.h"
int main(int argc, const char** argv) {
/* Ensure we have only one or two argument */
VTR_ASSERT((2 == argc) || (3 == argc));
/* Parse the simulation settings from an XML file */
const openfpga::BitstreamSetting& openfpga_sim_setting = read_xml_openfpga_bitstream_settings(argv[1]);
VTR_LOG("Parsed bitstream settings from XML %s.\n",
argv[1]);
/* Output the simulation settings to an XML file
* This is optional only used when there is a second argument
*/
if (3 <= argc) {
write_xml_openfpga_bitstream_settings(argv[2], openfpga_bitstream_setting);
VTR_LOG("Echo the OpenFPGA bitstream settings to an XML file: %s.\n",
argv[2]);
}
}

View File

@ -4,6 +4,7 @@
#include <vector>
#include "vpr_context.h"
#include "openfpga_arch.h"
#include "simulation_setting.h"
#include "vpr_netlist_annotation.h"
#include "vpr_device_annotation.h"
#include "vpr_clustering_annotation.h"