From ed42c16f87ba643b6689ae82a4e357ecc5e6f3bf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 25 Nov 2024 15:32:00 -0800 Subject: [PATCH] [core] support bitstream setting to overwrite default mode bits --- .../libarchopenfpga/src/bitstream_setting.cpp | 14 +++- libs/libarchopenfpga/src/bitstream_setting.h | 8 +- .../src/read_xml_bitstream_setting.cpp | 4 +- .../src/read_xml_openfpga_arch_utils.cpp | 42 ++++++++++ .../src/read_xml_openfpga_arch_utils.h | 20 +++++ .../src/read_xml_pb_type_annotation.cpp | 26 +----- .../annotation/annotate_bitstream_setting.cpp | 84 ++++++++++++++++++- .../annotation/annotate_bitstream_setting.h | 2 +- openfpga/src/annotation/annotate_pb_types.cpp | 2 +- .../annotation/vpr_bitstream_annotation.cpp | 16 ++++ .../src/annotation/vpr_bitstream_annotation.h | 6 ++ .../src/annotation/vpr_device_annotation.cpp | 14 +++- .../src/annotation/vpr_device_annotation.h | 4 +- .../src/base/openfpga_link_arch_template.h | 2 +- 14 files changed, 206 insertions(+), 38 deletions(-) create mode 100644 libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.cpp create mode 100644 libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.h diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index b5e50d58e..70a35b338 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -104,12 +104,22 @@ std::vector BitstreamSetting::default_mode_parent_mode_names( return default_mode_parent_mode_names_[default_mode_setting_id]; } -std::string BitstreamSetting::default_mode_bits( +std::vector BitstreamSetting::default_mode_bits( const BitstreamDefaultModeSettingId& default_mode_setting_id) const { VTR_ASSERT(true == valid_bitstream_default_mode_setting_id(default_mode_setting_id)); return pb_type_default_mode_bits_[default_mode_setting_id]; } +std::string BitstreamSetting::default_mode_bits_to_string( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const { + VTR_ASSERT(true == valid_bitstream_default_mode_setting_id(default_mode_setting_id)); + std::string mode_bits_str; + for (const size_t& bit : pb_type_default_mode_bits_[default_mode_setting_id]) { + mode_bits_str += std::to_string(bit); + } + return mode_bits_str; +} + std::string BitstreamSetting::interconnect_name( const BitstreamInterconnectSettingId& interconnect_setting_id) const { VTR_ASSERT(true == @@ -193,7 +203,7 @@ BitstreamDefaultModeSettingId BitstreamSetting::add_bitstream_default_mode_setti const std::string& pb_type_name, const std::vector& parent_pb_type_names, const std::vector& parent_mode_names, - const std::string& mode_bits) { + const std::vector& mode_bits) { BitstreamDefaultModeSettingId default_mode_setting_id = BitstreamDefaultModeSettingId(default_mode_setting_ids_.size()); default_mode_setting_ids_.push_back(default_mode_setting_id); diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index 31986c8e9..c49e67af3 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -109,7 +109,9 @@ class BitstreamSetting { const BitstreamDefaultModeSettingId& default_mode_setting_id) const; std::vector default_mode_parent_mode_names( const BitstreamDefaultModeSettingId& default_mode_setting_id) const; - std::string default_mode_bits( + std::vector default_mode_bits( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const; + std::string default_mode_bits_to_string( const BitstreamDefaultModeSettingId& default_mode_setting_id) const; std::string interconnect_name( @@ -140,7 +142,7 @@ class BitstreamSetting { const std::string& pb_type_name, const std::vector& parent_pb_type_names, const std::vector& parent_mode_names, - const std::string& mode_bits); + const std::vector& mode_bits); BitstreamInterconnectSettingId add_bitstream_interconnect_setting( const std::string& interconnect_name, @@ -192,7 +194,7 @@ class BitstreamSetting { default_mode_parent_pb_type_names_; vtr::vector> default_mode_parent_mode_names_; - vtr::vector pb_type_default_mode_bits_; + vtr::vector> pb_type_default_mode_bits_; /* Interconnect-related settings: * - Name of interconnect under a given pb_type diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 3a2b43d6d..4dccc9972 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -18,6 +18,7 @@ /* Headers from libarchfpga */ #include "arch_error.h" #include "read_xml_bitstream_setting.h" +#include "read_xml_openfpga_arch_utils.h" #include "read_xml_util.h" /******************************************************************** @@ -69,11 +70,12 @@ static void read_xml_bitstream_default_mode_setting( const std::string& mode_bits_attr = get_attribute(xml_pb_type, "mode_bits", loc_data).as_string(); + std::vector mode_bits = parse_mode_bits(xml_pb_type, loc_data, mode_bits_attr); /* Add to bitstream setting */ bitstream_setting.add_bitstream_default_mode_setting( operating_pb_parser.leaf(), operating_pb_parser.parents(), - operating_pb_parser.modes(), mode_bits_attr); + operating_pb_parser.modes(), mode_bits); } /******************************************************************** diff --git a/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.cpp b/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.cpp new file mode 100644 index 000000000..7cdf86e93 --- /dev/null +++ b/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.cpp @@ -0,0 +1,42 @@ +/******************************************************************** + * 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 libarchfpga */ +#include "arch_error.h" +#include "read_xml_openfpga_arch_utils.h" + +/******************************************************************** + * Parse mode_bits: convert from string to array of digits + * We only allow the bit to either '0' or '1' + *******************************************************************/ +std::vector parse_mode_bits(pugi::xml_node& xml_mode_bits, + const pugiutil::loc_data& loc_data, + const std::string& mode_bit_str) { + std::vector mode_bits; + + for (const char& bit_char : mode_bit_str) { + if ('0' == bit_char) { + mode_bits.push_back(0); + } else if ('1' == bit_char) { + mode_bits.push_back(1); + } else { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_mode_bits), + "Unexpected '%c' character found in the mode bit '%s'! " + "Only allow either '0' or '1'\n", + bit_char, mode_bit_str.c_str()); + } + } + + return mode_bits; +} diff --git a/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.h b/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.h new file mode 100644 index 000000000..73fadefa5 --- /dev/null +++ b/libs/libarchopenfpga/src/read_xml_openfpga_arch_utils.h @@ -0,0 +1,20 @@ +#ifndef READ_XML_OPENFPGA_ARCH_UTILS_H +#define READ_XML_OPENFPGA_ARCH_UTILS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +#include "bitstream_setting.h" +#include "openfpga_arch.h" +#include "simulation_setting.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ +std::vector parse_mode_bits(pugi::xml_node& xml_mode_bits, + const pugiutil::loc_data& loc_data, + const std::string& mode_bit_str); + +#endif diff --git a/libs/libarchopenfpga/src/read_xml_pb_type_annotation.cpp b/libs/libarchopenfpga/src/read_xml_pb_type_annotation.cpp index 8e2075bb6..ea519ca15 100644 --- a/libs/libarchopenfpga/src/read_xml_pb_type_annotation.cpp +++ b/libs/libarchopenfpga/src/read_xml_pb_type_annotation.cpp @@ -18,6 +18,7 @@ /* Headers from libarchfpga */ #include "arch_error.h" +#include "read_xml_openfpga_arch_utils.h" #include "read_xml_pb_type_annotation.h" #include "read_xml_util.h" @@ -152,31 +153,6 @@ static void read_xml_pb_port_annotation( } } -/******************************************************************** - * Parse mode_bits: convert from string to array of digits - * We only allow the bit to either '0' or '1' - *******************************************************************/ -static std::vector parse_mode_bits(pugi::xml_node& xml_mode_bits, - const pugiutil::loc_data& loc_data, - const std::string& mode_bit_str) { - std::vector mode_bits; - - for (const char& bit_char : mode_bit_str) { - if ('0' == bit_char) { - mode_bits.push_back(0); - } else if ('1' == bit_char) { - mode_bits.push_back(1); - } else { - archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_mode_bits), - "Unexpected '%c' character found in the mode bit '%s'! " - "Only allow either '0' or '1'\n", - bit_char, mode_bit_str.c_str()); - } - } - - return mode_bits; -} - /******************************************************************** * Parse XML description for a pb_type annotation under a XML node *******************************************************************/ diff --git a/openfpga/src/annotation/annotate_bitstream_setting.cpp b/openfpga/src/annotation/annotate_bitstream_setting.cpp index 266202505..b361ac25d 100644 --- a/openfpga/src/annotation/annotate_bitstream_setting.cpp +++ b/openfpga/src/annotation/annotate_bitstream_setting.cpp @@ -128,6 +128,82 @@ static int annotate_bitstream_pb_type_setting( return CMD_EXEC_SUCCESS; } +/******************************************************************** + * Annotate bitstream setting based on VPR device information + * - Find the pb_type and link to the default mode bits + *******************************************************************/ +static int annotate_bitstream_default_mode_setting( + const BitstreamSetting& bitstream_setting, + const DeviceContext& vpr_device_ctx, + VprDeviceAnnotation& vpr_device_annotation) { + for (const auto& bitstream_default_mode_setting_id : + bitstream_setting.default_mode_settings()) { + /* Get the full name of pb_type */ + std::vector target_pb_type_names; + std::vector target_pb_mode_names; + + target_pb_type_names = + bitstream_setting.default_mode_parent_pb_type_names(bitstream_default_mode_setting_id); + target_pb_type_names.push_back( + bitstream_setting.default_mode_pb_type_name(bitstream_default_mode_setting_id)); + target_pb_mode_names = + bitstream_setting.default_mode_parent_mode_names(bitstream_default_mode_setting_id); + + std::vector mode_bits = bitstream_setting.default_mode_bits(bitstream_default_mode_setting_id); + + /* Pb type information are located at the logic_block_types in the device + * context of VPR We iterate over the vectors and find the pb_type matches + * the parent_pb_type_name + */ + bool link_success = false; + + for (const t_logical_block_type& lb_type : + vpr_device_ctx.logical_block_types) { + /* By pass nullptr for pb_type head */ + if (nullptr == lb_type.pb_type) { + continue; + } + /* Check the name of the top-level pb_type, if it does not match, we can + * bypass */ + if (target_pb_type_names[0] != std::string(lb_type.pb_type->name)) { + continue; + } + /* Match the name in the top-level, we go further to search the pb_type in + * the graph */ + t_pb_type* target_pb_type = try_find_pb_type_with_given_path( + lb_type.pb_type, target_pb_type_names, target_pb_mode_names); + if (nullptr == target_pb_type) { + continue; + } + + /* Found one, pre-check and build annotation */ + if (vpr_device_annotation.pb_type_mode_bits(target_pb_type).size() != mode_bits.size()) { + VTR_LOG_ERROR( + "Mismatches in length of default mode bits for a pb_type '%s' which is defined in bitstream setting ('%s') " + "from OpenFPGA architecture description ('%s')\n", + target_pb_type_names[0].c_str(), bitstream_setting.default_mode_bits_to_string(bitstream_default_mode_setting_id).c_str(), + vpr_device_annotation.pb_type_mode_bits_to_string(target_pb_type)); + return CMD_EXEC_FATAL_ERROR; + } + vpr_device_annotation.add_pb_type_mode_bits( + target_pb_type, mode_bits, false); + link_success = true; + } + + /* If fail to link bitstream setting to architecture, error out immediately + */ + if (false == link_success) { + VTR_LOG_ERROR( + "Fail to find a pb_type '%s' which is defined in bitstream setting " + "from VPR architecture description\n", + target_pb_type_names[0].c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } + + return CMD_EXEC_SUCCESS; +} + /******************************************************************** * Annotate bitstream setting based on VPR device information * - Find the interconnect and link to the default path id @@ -259,7 +335,7 @@ static int annotate_bitstream_interconnect_setting( int annotate_bitstream_setting( const BitstreamSetting& bitstream_setting, const DeviceContext& vpr_device_ctx, - const VprDeviceAnnotation& vpr_device_annotation, + VprDeviceAnnotation& vpr_device_annotation, VprBitstreamAnnotation& vpr_bitstream_annotation) { int status = CMD_EXEC_SUCCESS; @@ -269,6 +345,12 @@ int annotate_bitstream_setting( return status; } + status = annotate_bitstream_default_mode_setting(bitstream_setting, vpr_device_ctx, + vpr_device_annotation); + if (status == CMD_EXEC_FATAL_ERROR) { + return status; + } + status = annotate_bitstream_interconnect_setting( bitstream_setting, vpr_device_ctx, vpr_device_annotation, vpr_bitstream_annotation); diff --git a/openfpga/src/annotation/annotate_bitstream_setting.h b/openfpga/src/annotation/annotate_bitstream_setting.h index 3adc17639..947e17897 100644 --- a/openfpga/src/annotation/annotate_bitstream_setting.h +++ b/openfpga/src/annotation/annotate_bitstream_setting.h @@ -17,7 +17,7 @@ namespace openfpga { int annotate_bitstream_setting( const BitstreamSetting& bitstream_setting, const DeviceContext& vpr_device_ctx, - const VprDeviceAnnotation& vpr_device_annotation, + VprDeviceAnnotation& vpr_device_annotation, VprBitstreamAnnotation& vpr_bitstream_annotation); } /* end namespace openfpga */ diff --git a/openfpga/src/annotation/annotate_pb_types.cpp b/openfpga/src/annotation/annotate_pb_types.cpp index 69e1ebc96..bb03f5c94 100644 --- a/openfpga/src/annotation/annotate_pb_types.cpp +++ b/openfpga/src/annotation/annotate_pb_types.cpp @@ -991,7 +991,7 @@ static bool link_primitive_pb_type_to_mode_bits( /* Update the annotation */ vpr_device_annotation.add_pb_type_mode_bits(primitive_pb_type, - pb_type_annotation.mode_bits()); + pb_type_annotation.mode_bits(), true); return true; } diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.cpp b/openfpga/src/annotation/vpr_bitstream_annotation.cpp index 1f7c47cff..000b9c687 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.cpp +++ b/openfpga/src/annotation/vpr_bitstream_annotation.cpp @@ -40,6 +40,17 @@ std::string VprBitstreamAnnotation::pb_type_bitstream_content( return std::string(); } +std::string VprBitstreamAnnotation::pb_type_default_mode_bits( + t_pb_type* pb_type) const { + auto result = default_mode_bits_.find(pb_type); + if (result != default_mode_bits_.end()) { + return result->second; + } + + /* Not found, return an invalid type */ + return std::string(); +} + size_t VprBitstreamAnnotation::pb_type_bitstream_offset( t_pb_type* pb_type) const { auto result = bitstream_offsets_.find(pb_type); @@ -129,6 +140,11 @@ void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset( mode_select_bitstream_offsets_[pb_type] = offset; } +void VprBitstreamAnnotation::set_pb_type_default_mode_bits( + t_pb_type* pb_type, const std::string& default_mode_bits) { + default_mode_bits_[pb_type] = default_mode_bits; +} + void VprBitstreamAnnotation::set_interconnect_default_path_id( t_interconnect* interconnect, const size_t& default_path_id) { interconnect_default_path_ids_[interconnect] = default_path_id; diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.h b/openfpga/src/annotation/vpr_bitstream_annotation.h index 6d99d60e9..3ddb330c0 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.h +++ b/openfpga/src/annotation/vpr_bitstream_annotation.h @@ -36,6 +36,7 @@ class VprBitstreamAnnotation { e_bitstream_source_type pb_type_bitstream_source(t_pb_type* pb_type) const; std::string pb_type_bitstream_content(t_pb_type* pb_type) const; size_t pb_type_bitstream_offset(t_pb_type* pb_type) const; + std::string pb_type_default_mode_bits(t_pb_type* pb_type) const; e_bitstream_source_type pb_type_mode_select_bitstream_source( t_pb_type* pb_type) const; @@ -50,6 +51,9 @@ class VprBitstreamAnnotation { const std::string& bitstream_content); void set_pb_type_bitstream_offset(t_pb_type* pb_type, const size_t& offset); + void set_pb_type_default_mode_bits(t_pb_type* pb_type, + const std::string& default_mode_bits); + void set_pb_type_mode_select_bitstream_source( t_pb_type* pb_type, const e_bitstream_source_type& bitstream_source); void set_pb_type_mode_select_bitstream_content( @@ -67,6 +71,8 @@ class VprBitstreamAnnotation { std::map bitstream_contents_; /* Offset to be applied to bitstream */ std::map bitstream_offsets_; + /* Binding from pb type to default mode bits */ + std::map default_mode_bits_; /* For mode-select bitstreams */ /* A look up for pb type to find bitstream source type */ diff --git a/openfpga/src/annotation/vpr_device_annotation.cpp b/openfpga/src/annotation/vpr_device_annotation.cpp index 07f686302..460a4ac42 100644 --- a/openfpga/src/annotation/vpr_device_annotation.cpp +++ b/openfpga/src/annotation/vpr_device_annotation.cpp @@ -140,6 +140,15 @@ std::vector VprDeviceAnnotation::pb_type_mode_bits( return pb_type_mode_bits_.at(pb_type); } +std::string VprDeviceAnnotation::pb_type_mode_bits_to_string( + t_pb_type* pb_type) const { + std::string mode_bits_str; + for (const size_t& bit : pb_type_mode_bits(pb_type)) { + mode_bits_str += std::to_string(bit); + } + return mode_bits_str; +} + PbGraphNodeId VprDeviceAnnotation::pb_graph_node_unique_index( t_pb_graph_node* pb_graph_node) const { /* Ensure that the pb_type is in the list */ @@ -559,12 +568,13 @@ void VprDeviceAnnotation::add_pb_circuit_port( } void VprDeviceAnnotation::add_pb_type_mode_bits( - t_pb_type* pb_type, const std::vector& mode_bits) { + t_pb_type* pb_type, const std::vector& mode_bits, + const bool& verbose) { /* Warn any override attempt */ std::map>::const_iterator it = pb_type_mode_bits_.find(pb_type); if (it != pb_type_mode_bits_.end()) { - VTR_LOG_WARN("Override the mode bits mapping for pb_type '%s'!\n", + VTR_LOGV_WARN(verbose, "Override the mode bits mapping for pb_type '%s'!\n", pb_type->name); } diff --git a/openfpga/src/annotation/vpr_device_annotation.h b/openfpga/src/annotation/vpr_device_annotation.h index d5330d737..43d386d08 100644 --- a/openfpga/src/annotation/vpr_device_annotation.h +++ b/openfpga/src/annotation/vpr_device_annotation.h @@ -53,6 +53,7 @@ class VprDeviceAnnotation { t_interconnect* pb_interconnect) const; CircuitPortId pb_circuit_port(t_port* pb_port) const; std::vector pb_type_mode_bits(t_pb_type* pb_type) const; + std::string pb_type_mode_bits_to_string(t_pb_type* pb_type) const; /* Get the unique index of a pb_graph_node */ PbGraphNodeId pb_graph_node_unique_index( t_pb_graph_node* pb_graph_node) const; @@ -115,7 +116,8 @@ class VprDeviceAnnotation { const e_interconnect& physical_type); void add_pb_circuit_port(t_port* pb_port, const CircuitPortId& circuit_port); void add_pb_type_mode_bits(t_pb_type* pb_type, - const std::vector& mode_bits); + const std::vector& mode_bits, + const bool& verbose); void add_pb_graph_node_unique_index(t_pb_graph_node* pb_graph_node); void add_physical_pb_graph_node(t_pb_graph_node* operating_pb_graph_node, t_pb_graph_node* physical_pb_graph_node); diff --git a/openfpga/src/base/openfpga_link_arch_template.h b/openfpga/src/base/openfpga_link_arch_template.h index 52ebb78c4..bc42ee49e 100644 --- a/openfpga/src/base/openfpga_link_arch_template.h +++ b/openfpga/src/base/openfpga_link_arch_template.h @@ -177,7 +177,7 @@ int link_arch_template(T& openfpga_ctx, const Command& cmd, if (CMD_EXEC_FATAL_ERROR == annotate_bitstream_setting( openfpga_ctx.bitstream_setting(), g_vpr_ctx.device(), - openfpga_ctx.vpr_device_annotation(), + openfpga_ctx.mutable_vpr_device_annotation(), openfpga_ctx.mutable_vpr_bitstream_annotation())) { return CMD_EXEC_FATAL_ERROR; }