[OpenFPGA Tool] Update XML parser for fabric regions

This commit is contained in:
tangxifan 2020-09-27 20:41:01 -06:00
parent e09e5fa6c6
commit 491433fae2
2 changed files with 82 additions and 16 deletions

View File

@ -23,17 +23,19 @@
* Parse XML codes of a <key> to an object of FabricKey
*******************************************************************/
static
void read_xml_component_key(pugi::xml_node& xml_component_key,
const pugiutil::loc_data& loc_data,
FabricKey& fabric_key) {
void read_xml_region_key(pugi::xml_node& xml_component_key,
const pugiutil::loc_data& loc_data,
FabricKey& fabric_key,
const FabricRegionId& fabric_region) {
/* Find the id of component key */
const size_t& id = get_attribute(xml_component_key, "id", loc_data).as_int();
if (false == fabric_key.valid_key_id(FabricKeyId(id))) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key),
"Invalid 'id' attribute '%d'\n",
id);
"Invalid 'id' attribute '%d' (in total %lu keys)!\n",
id,
fabric_key.keys().size());
}
VTR_ASSERT_SAFE(true == fabric_key.valid_key_id(FabricKeyId(id)));
@ -57,6 +59,41 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,
fabric_key.set_key_name(FabricKeyId(id), name);
fabric_key.set_key_value(FabricKeyId(id), value);
fabric_key.add_key_to_region(fabric_region, FabricKeyId(id));
}
/********************************************************************
* Parse XML codes of a <key> to an object of FabricKey
*******************************************************************/
static
void read_xml_fabric_region(pugi::xml_node& xml_region,
const pugiutil::loc_data& loc_data,
FabricKey& fabric_key) {
/* Find the unique id for the region */
const FabricRegionId& region_id = FabricRegionId(get_attribute(xml_region, "id", loc_data).as_int());
if (false == fabric_key.valid_region_id(region_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_region),
"Invalid region id '%lu' (in total %lu regions)!\n",
size_t(region_id),
fabric_key.regions().size());
}
VTR_ASSERT_SAFE(true == fabric_key.valid_region_id(region_id));
/* Reserve memory space for the keys in the region */
size_t num_keys = std::distance(xml_region.children().begin(), xml_region.children().end());
fabric_key.reserve_region_keys(region_id, num_keys);
for (pugi::xml_node xml_key : xml_region.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_key.name() != std::string("key")) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_region),
"Unexpected child '%s' in region '%lu', Region XML node can only contain keys!\n",
xml_key.name(),
size_t(region_id));
}
/* Parse the key for this region */
read_xml_region_key(xml_key, loc_data, fabric_key, region_id);
}
}
/********************************************************************
@ -77,7 +114,24 @@ FabricKey read_xml_fabric_key(const char* key_fname) {
pugi::xml_node xml_root = get_single_child(doc, "fabric_key", loc_data);
size_t num_keys = std::distance(xml_root.children().begin(), xml_root.children().end());
size_t num_regions = std::distance(xml_root.children().begin(), xml_root.children().end());
/* Reserve memory space for the region */
fabric_key.reserve_regions(num_regions);
for (size_t iregion = 0; iregion < num_regions; ++iregion) {
fabric_key.create_region();
}
/* Reserve memory space for the keys */
size_t num_keys = 0;
for (pugi::xml_node xml_region : xml_root.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_region.name() != std::string("region")) {
bad_tag(xml_region, loc_data, xml_root, {"region"});
}
num_keys += std::distance(xml_root.children().begin(), xml_root.children().end());
}
fabric_key.reserve_keys(num_keys);
for (size_t ikey = 0; ikey < num_keys; ++ikey) {
fabric_key.create_key();
@ -86,12 +140,12 @@ FabricKey read_xml_fabric_key(const char* key_fname) {
/* Iterate over the children under this node,
* each child should be named after circuit_model
*/
for (pugi::xml_node xml_key : xml_root.children()) {
for (pugi::xml_node xml_region : xml_root.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_key.name() != std::string("key")) {
bad_tag(xml_key, loc_data, xml_root, {"key"});
if (xml_region.name() != std::string("region")) {
bad_tag(xml_region, loc_data, xml_root, {"region"});
}
read_xml_component_key(xml_key, loc_data, fabric_key);
read_xml_fabric_region(xml_region, loc_data, fabric_key);
}
} catch (pugiutil::XmlError& e) {
archfpga_throw(key_fname, e.line(),

View File

@ -9,6 +9,8 @@
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from openfpga util library */
#include "openfpga_digest.h"
/* Headers from arch openfpga library */
@ -33,7 +35,8 @@ int write_xml_fabric_component_key(std::fstream& fp,
return 2;
}
fp << "\t" << "<key";
openfpga::write_tab_to_file(fp, 2);
fp << "<key";
if (false == fabric_key.valid_key_id(component_key)) {
return 1;
@ -79,12 +82,21 @@ int write_xml_fabric_key(const char* fname,
int err_code = 0;
/* Write component by component */
for (const FabricKeyId& key : fabric_key.keys()) {
err_code = write_xml_fabric_component_key(fp, fabric_key, key);
if (0 != err_code) {
return err_code;
/* Write region by region */
for (const FabricRegionId& region : fabric_key.regions()) {
openfpga::write_tab_to_file(fp, 1);
fp << "<region id=\"" << size_t(region) << "\"" << ">\n";
/* Write component by component */
for (const FabricKeyId& key : fabric_key.region_keys(region)) {
err_code = write_xml_fabric_component_key(fp, fabric_key, key);
if (0 != err_code) {
return err_code;
}
}
openfpga::write_tab_to_file(fp, 1);
fp << "</region>" << "\n";
}
/* Finish writing the root node */