From 491433fae2291e57592c4aedc041dec512763e8b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 27 Sep 2020 20:41:01 -0600 Subject: [PATCH] [OpenFPGA Tool] Update XML parser for fabric regions --- .../libfabrickey/src/read_xml_fabric_key.cpp | 74 ++++++++++++++++--- .../libfabrickey/src/write_xml_fabric_key.cpp | 24 ++++-- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp index 7bc42b54e..f509ddc79 100644 --- a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp @@ -23,17 +23,19 @@ * Parse XML codes of a 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 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(), diff --git a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp index 33e345fb9..ea12d75a1 100644 --- a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp @@ -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" << "\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 << "" << "\n"; } /* Finish writing the root node */