[Tool] Update bitstream setting parser/writer to support interconnect-related syntax

This commit is contained in:
tangxifan 2021-04-19 13:42:12 -06:00
parent e85402eaaa
commit 5364b94cf8
5 changed files with 157 additions and 5 deletions

View File

@ -16,6 +16,10 @@ BitstreamSetting::bitstream_pb_type_setting_range BitstreamSetting::pb_type_sett
return vtr::make_range(pb_type_setting_ids_.begin(), pb_type_setting_ids_.end());
}
BitstreamSetting::bitstream_interconnect_setting_range BitstreamSetting::interconnect_settings() const {
return vtr::make_range(interconnect_setting_ids_.begin(), interconnect_setting_ids_.end());
}
/************************************************************************
* Constructors
***********************************************************************/
@ -61,6 +65,25 @@ size_t BitstreamSetting::bitstream_offset(const BitstreamPbTypeSettingId& pb_typ
return bitstream_offsets_[pb_type_setting_id];
}
std::string BitstreamSetting::interconnect_name(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
return interconnect_names_[interconnect_setting_id];
}
std::vector<std::string> BitstreamSetting::parent_pb_type_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
return interconnect_parent_pb_type_names_[interconnect_setting_id];
}
std::vector<std::string> BitstreamSetting::parent_mode_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
return interconnect_parent_mode_names_[interconnect_setting_id];
}
std::string BitstreamSetting::default_path(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
return interconnect_default_paths_[interconnect_setting_id];
}
/************************************************************************
* Public Mutators
@ -95,6 +118,20 @@ void BitstreamSetting::set_bitstream_offset(const BitstreamPbTypeSettingId& pb_t
bitstream_offsets_[pb_type_setting_id] = offset;
}
BitstreamInterconnectSettingId BitstreamSetting::add_bitstream_interconnect_setting(const std::string& interconnect_name,
const std::vector<std::string>& parent_pb_type_names,
const std::vector<std::string>& parent_mode_names,
const std::string& default_path) {
BitstreamInterconnectSettingId interc_setting_id = BitstreamInterconnectSettingId(interconnect_setting_ids_.size());
interconnect_setting_ids_.push_back(interc_setting_id);
interconnect_names_.push_back(interconnect_name);
interconnect_parent_pb_type_names_.push_back(parent_pb_type_names);
interconnect_parent_mode_names_.push_back(parent_mode_names);
interconnect_default_paths_.push_back(default_path);
return interc_setting_id;
}
/************************************************************************
* Public Validators
***********************************************************************/
@ -102,4 +139,8 @@ bool BitstreamSetting::valid_bitstream_pb_type_setting_id(const BitstreamPbTypeS
return ( size_t(pb_type_setting_id) < pb_type_setting_ids_.size() ) && ( pb_type_setting_id == pb_type_setting_ids_[pb_type_setting_id] );
}
bool BitstreamSetting::valid_bitstream_interconnect_setting_id(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
return ( size_t(interconnect_setting_id) < interconnect_setting_ids_.size() ) && ( interconnect_setting_id == interconnect_setting_ids_[interconnect_setting_id] );
}
} /* namespace openfpga ends */

View File

@ -16,6 +16,10 @@ namespace openfpga {
/********************************************************************
* A data structure to describe bitstream settings
*
* This data structure includes following types of settings:
* - Pb type: include definiting hard coded bitstream for pb_types (LUT or configurable pb_type for mode selection)
* - Interconnect: include defining default paths for routing multiplexers in pb_types
*
* Typical usage:
* --------------
@ -27,12 +31,15 @@ namespace openfpga {
class BitstreamSetting {
public: /* Types */
typedef vtr::vector<BitstreamPbTypeSettingId, BitstreamPbTypeSettingId>::const_iterator bitstream_pb_type_setting_iterator;
typedef vtr::vector<BitstreamInterconnectSettingId, BitstreamInterconnectSettingId>::const_iterator bitstream_interconnect_setting_iterator;
/* Create range */
typedef vtr::Range<bitstream_pb_type_setting_iterator> bitstream_pb_type_setting_range;
typedef vtr::Range<bitstream_interconnect_setting_iterator> bitstream_interconnect_setting_range;
public: /* Constructors */
BitstreamSetting();
public: /* Accessors: aggregates */
bitstream_pb_type_setting_range pb_type_settings() const;
bitstream_interconnect_setting_range interconnect_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;
@ -41,6 +48,10 @@ class BitstreamSetting {
std::string pb_type_bitstream_content(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
bool is_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
size_t bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
std::string interconnect_name(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::vector<std::string> parent_pb_type_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::vector<std::string> parent_mode_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::string default_path(const BitstreamInterconnectSettingId& interconnect_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,
@ -51,9 +62,19 @@ class BitstreamSetting {
const bool& is_mode_select_bitstream);
void set_bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id,
const size_t& offset);
BitstreamInterconnectSettingId add_bitstream_interconnect_setting(const std::string& interconnect_name,
const std::vector<std::string>& parent_pb_type_names,
const std::vector<std::string>& parent_mode_names,
const std::string& default_path);
public: /* Public Validators */
bool valid_bitstream_pb_type_setting_id(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
bool valid_bitstream_interconnect_setting_id(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
private: /* Internal data */
/* Pb type -related settings
* - Paths to a pb_type in the pb_graph
* - Bitstream source, data_type, offsets etc.
*/
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_;
@ -64,6 +85,16 @@ class BitstreamSetting {
vtr::vector<BitstreamPbTypeSettingId, bool> is_mode_select_bitstreams_;
/* The offset that the bitstream is applied to the original bitstream of a pb_type */
vtr::vector<BitstreamPbTypeSettingId, size_t> bitstream_offsets_;
/* Interconnect-related settings:
* - Name of interconnect under a given pb_type
* - The default path to be considered for a given interconnect during bitstream generation
*/
vtr::vector<BitstreamInterconnectSettingId, BitstreamInterconnectSettingId> interconnect_setting_ids_;
vtr::vector<BitstreamInterconnectSettingId, std::string> interconnect_names_;
vtr::vector<BitstreamInterconnectSettingId, std::vector<std::string>> interconnect_parent_pb_type_names_;
vtr::vector<BitstreamInterconnectSettingId, std::vector<std::string>> interconnect_parent_mode_names_;
vtr::vector<BitstreamInterconnectSettingId, std::string> interconnect_default_paths_;
};
} /* namespace openfpga ends */

View File

@ -13,8 +13,10 @@
#include "vtr_strong_id.h"
struct bitstream_pb_type_setting_id_tag;
struct bitstream_interconnect_setting_id_tag;
typedef vtr::StrongId<bitstream_pb_type_setting_id_tag> BitstreamPbTypeSettingId;
typedef vtr::StrongId<bitstream_interconnect_setting_id_tag> BitstreamInterconnectSettingId;
/* Short declaration of class */
class BitstreamSetting;

View File

@ -50,6 +50,26 @@ void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type,
bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset);
}
/********************************************************************
* Parse XML description for a pb_type annotation under a <interconect> XML node
*******************************************************************/
static
void read_xml_bitstream_interconnect_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& default_path_attr = get_attribute(xml_pb_type, "default_path", 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_interconnect_setting(operating_pb_parser.leaf(),
operating_pb_parser.parents(),
operating_pb_parser.modes(),
default_path_attr);
}
/********************************************************************
* Parse XML codes about <openfpga_bitstream_setting> to an object
*******************************************************************/
@ -60,12 +80,19 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(pugi::xml_node& Node,
/* Iterate over the children under this node,
* each child should be named after <pb_type>
*/
for (pugi::xml_node xml_pb_type : Node.children()) {
for (pugi::xml_node xml_child : 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"});
if ( (xml_child.name() != std::string("pb_type"))
&& (xml_child.name() != std::string("interconnect")) ) {
bad_tag(xml_child, loc_data, Node, {"pb_type | interconnect"});
}
if (xml_child.name() == std::string("pb_type")) {
read_xml_bitstream_pb_type_setting(xml_child, loc_data, bitstream_setting);
} else {
VTR_ASSERT_SAFE(xml_child.name() == std::string("interconnect"));
read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting);
}
read_xml_bitstream_pb_type_setting(xml_pb_type, loc_data, bitstream_setting);
}
return bitstream_setting;

View File

@ -39,6 +39,31 @@ std::string generate_bitstream_setting_pb_type_hierarchy_name(const openfpga::Bi
return hie_name;
}
/********************************************************************
* Generate the full hierarchy name for an interconnect in bitstream setting
*******************************************************************/
static
std::string generate_bitstream_setting_interconnect_hierarchy_name(const openfpga::BitstreamSetting& bitstream_setting,
const BitstreamInterconnectSettingId& bitstream_interc_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_interc_setting_id).size() == bitstream_setting.parent_mode_names(bitstream_interc_setting_id).size());
std::string hie_name;
for (size_t i = 0 ; i < bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id).size(); ++i) {
hie_name += bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id)[i];
hie_name += std::string("[");
hie_name += bitstream_setting.parent_mode_names(bitstream_interc_setting_id)[i];
hie_name += std::string("]");
hie_name += std::string(".");
}
/* Add the leaf pb_type */
hie_name += bitstream_setting.interconnect_name(bitstream_interc_setting_id);
return hie_name;
}
/********************************************************************
* A writer to output a bitstream pb_type setting to XML format
*******************************************************************/
@ -63,6 +88,27 @@ void write_xml_bitstream_pb_type_setting(std::fstream& fp,
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output a bitstream interconnect setting to XML format
*******************************************************************/
static
void write_xml_bitstream_interconnect_setting(std::fstream& fp,
const char* fname,
const openfpga::BitstreamSetting& bitstream_setting,
const BitstreamInterconnectSettingId& bitstream_interc_setting_id) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t" << "<pb_type";
/* Generate the full hierarchy name of the pb_type */
write_xml_attribute(fp, "name", generate_bitstream_setting_interconnect_hierarchy_name(bitstream_setting, bitstream_interc_setting_id).c_str());
write_xml_attribute(fp, "default_path", bitstream_setting.default_path(bitstream_interc_setting_id).c_str());
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output a bitstream setting to XML format
*******************************************************************/
@ -76,11 +122,16 @@ void write_xml_bitstream_setting(std::fstream& fp,
*/
fp << "<openfpga_bitstream_setting>" << "\n";
/* Write clock settings */
/* Write pb_type -related 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 interconnect -related settings */
for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) {
write_xml_bitstream_interconnect_setting(fp, fname, bitstream_setting, bitstream_interc_setting_id);
}
/* Write the root node <openfpga_bitstream_setting> */
fp << "</openfpga_bitstream_setting>" << "\n";
}