diff --git a/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp new file mode 100644 index 000000000..924e96c0e --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp @@ -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 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 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& parent_pb_type_names, + const std::vector& 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 */ diff --git a/libopenfpga/libarchopenfpga/src/bitstream_setting.h b/libopenfpga/libarchopenfpga/src/bitstream_setting.h new file mode 100644 index 000000000..d42ebe430 --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/bitstream_setting.h @@ -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 + +#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::const_iterator bitstream_pb_type_setting_iterator; + /* Create range */ + typedef vtr::Range 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 parent_pb_type_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const; + std::vector 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& parent_pb_type_names, + const std::vector& 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 pb_type_setting_ids_; + vtr::vector pb_type_names_; + vtr::vector> parent_pb_type_names_; + vtr::vector> parent_mode_names_; + vtr::vector pb_type_bitstream_sources_; + vtr::vector pb_type_bitstream_contents_; +}; + +} /* namespace openfpga ends */ + +#endif diff --git a/libopenfpga/libarchopenfpga/src/bitstream_setting_fwd.h b/libopenfpga/libarchopenfpga/src/bitstream_setting_fwd.h new file mode 100644 index 000000000..009bcbfed --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/bitstream_setting_fwd.h @@ -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 BitstreamPbTypeSettingId; + +/* Short declaration of class */ +class BitstreamSetting; + +#endif diff --git a/libopenfpga/libarchopenfpga/src/openfpga_arch.h b/libopenfpga/libarchopenfpga/src/openfpga_arch.h index 38d920c6e..6867a4bb4 100644 --- a/libopenfpga/libarchopenfpga/src/openfpga_arch.h +++ b/libopenfpga/libarchopenfpga/src/openfpga_arch.h @@ -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" diff --git a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp new file mode 100644 index 000000000..02f257ffe --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -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 + +/* 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 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 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 + */ + 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; +} diff --git a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.h b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.h new file mode 100644 index 000000000..d3b16ec82 --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.h @@ -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 diff --git a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp index bbeb893c0..ad0c88b4d 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp @@ -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 */ + 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; +} + diff --git a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.h b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.h index 660baeec0..920ba20e1 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.h +++ b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.h @@ -6,6 +6,8 @@ *******************************************************************/ #include #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 diff --git a/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp new file mode 100644 index 000000000..8256573dd --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp @@ -0,0 +1,84 @@ +/******************************************************************** + * This file includes functions that outputs a bitstream setting to XML format + *******************************************************************/ +/* Headers from system goes first */ +#include +#include + +/* 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" << "" << "\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 + */ + fp << "" << "\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 */ + fp << "" << "\n"; +} diff --git a/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.h b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.h new file mode 100644 index 000000000..b4eea0d10 --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.h @@ -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 +#include "bitstream_setting.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ +void write_xml_bitstream_setting(std::fstream& fp, + const char* fname, + const openfpga::BitstreamSetting& bitstream_setting); + +#endif diff --git a/libopenfpga/libarchopenfpga/test/read_bitstream_setting_openfpga.cpp b/libopenfpga/libarchopenfpga/test/read_bitstream_setting_openfpga.cpp new file mode 100644 index 000000000..d805eb7f4 --- /dev/null +++ b/libopenfpga/libarchopenfpga/test/read_bitstream_setting_openfpga.cpp @@ -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]); + } +} diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index a6ea28ace..0bff4448e 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -4,6 +4,7 @@ #include #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"