diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst index d46751a146..7cc340da06 100644 --- a/docs/source/manual/file_formats/bitstream_setting.rst +++ b/docs/source/manual/file_formats/bitstream_setting.rst @@ -12,6 +12,7 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab + @@ -54,6 +55,32 @@ The following syntax are applicable to the XML definition tagged by ``pb_type`` Specify the offset to be applied when overloading the bitstream to a target. For example, a LUT may have a 16-bit bitstream. When ``offset=1``, bitstream overloading will skip the first bit and start from the second bit of the 16-bit bitstream. +Default Mode Bits-related Settings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following syntax are applicable to the XML definition tagged by ``default_mode_bits`` in bitstream setting files. + +.. option:: name="" + + The ``pb_type`` name to be constrained, which should be the full path of a ``pb_type`` consistent with VPR's architecture description. For example, + + .. note:: This must be a valid primitive pb_type (one has zero leaf nodes)! + + .. code-block:: xml + + pb_type="clb.fle[arithmetic].soft_adder.adder_lut4" + +.. option:: mode_bits="" + + The default mode bits when the ``pb_type`` is not mapped. Note that the size of mode bits must comply with the definition in the OpenFPGA architecture description (See details in :ref:`annotate_vpr_arch_pb_type_annotation`). For example, + + .. note:: Bitstream setting has a higher priority than the ``mode_bits`` definition in the OpenFPGA architecture description! + + .. code-block:: xml + + mode_bits="0100" + + Interconnection-related Settings ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index 6092bd91e1..3a92a519f3 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -18,6 +18,12 @@ BitstreamSetting::pb_type_settings() const { pb_type_setting_ids_.end()); } +BitstreamSetting::bitstream_default_mode_setting_range +BitstreamSetting::default_mode_settings() const { + return vtr::make_range(default_mode_setting_ids_.begin(), + default_mode_setting_ids_.end()); +} + BitstreamSetting::bitstream_interconnect_setting_range BitstreamSetting::interconnect_settings() const { return vtr::make_range(interconnect_setting_ids_.begin(), @@ -80,6 +86,46 @@ size_t BitstreamSetting::bitstream_offset( return bitstream_offsets_[pb_type_setting_id]; } +std::string BitstreamSetting::default_mode_pb_type_name( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const { + VTR_ASSERT(true == + valid_bitstream_default_mode_setting_id(default_mode_setting_id)); + return default_mode_pb_type_names_[default_mode_setting_id]; +} + +std::vector BitstreamSetting::default_mode_parent_pb_type_names( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const { + VTR_ASSERT(true == + valid_bitstream_default_mode_setting_id(default_mode_setting_id)); + return default_mode_parent_pb_type_names_[default_mode_setting_id]; +} + +std::vector BitstreamSetting::default_mode_parent_mode_names( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const { + VTR_ASSERT(true == + valid_bitstream_default_mode_setting_id(default_mode_setting_id)); + return default_mode_parent_mode_names_[default_mode_setting_id]; +} + +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 == @@ -159,6 +205,23 @@ void BitstreamSetting::set_bitstream_offset( bitstream_offsets_[pb_type_setting_id] = offset; } +BitstreamDefaultModeSettingId +BitstreamSetting::add_bitstream_default_mode_setting( + const std::string& pb_type_name, + const std::vector& parent_pb_type_names, + const std::vector& parent_mode_names, + 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); + default_mode_pb_type_names_.push_back(pb_type_name); + default_mode_parent_pb_type_names_.push_back(parent_pb_type_names); + default_mode_parent_mode_names_.push_back(parent_mode_names); + pb_type_default_mode_bits_.push_back(mode_bits); + + return default_mode_setting_id; +} + BitstreamInterconnectSettingId BitstreamSetting::add_bitstream_interconnect_setting( const std::string& interconnect_name, @@ -220,6 +283,13 @@ bool BitstreamSetting::valid_bitstream_pb_type_setting_id( (pb_type_setting_id == pb_type_setting_ids_[pb_type_setting_id]); } +bool BitstreamSetting::valid_bitstream_default_mode_setting_id( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const { + return (size_t(default_mode_setting_id) < default_mode_setting_ids_.size()) && + (default_mode_setting_id == + default_mode_setting_ids_[default_mode_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()) && diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index 042e850e01..e97b1e912c 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -9,6 +9,7 @@ #include #include "bitstream_setting_fwd.h" +#include "vtr_geometry.h" #include "vtr_vector.h" /* namespace openfpga begins */ @@ -58,6 +59,9 @@ class BitstreamSetting { typedef vtr::vector::const_iterator bitstream_pb_type_setting_iterator; + typedef vtr::vector::const_iterator + bitstream_default_mode_setting_iterator; typedef vtr::vector::const_iterator bitstream_interconnect_setting_iterator; @@ -67,6 +71,8 @@ class BitstreamSetting { /* Create range */ typedef vtr::Range bitstream_pb_type_setting_range; + typedef vtr::Range + bitstream_default_mode_setting_range; typedef vtr::Range bitstream_interconnect_setting_range; typedef vtr::Range overwrite_bitstream_range; @@ -76,6 +82,7 @@ class BitstreamSetting { public: /* Accessors: aggregates */ bitstream_pb_type_setting_range pb_type_settings() const; + bitstream_default_mode_setting_range default_mode_settings() const; bitstream_interconnect_setting_range interconnect_settings() const; overwrite_bitstream_range overwrite_bitstreams() const; @@ -94,6 +101,19 @@ class BitstreamSetting { const BitstreamPbTypeSettingId& pb_type_setting_id) const; size_t bitstream_offset( const BitstreamPbTypeSettingId& pb_type_setting_id) const; + + /* Default Mode Bit settings */ + std::string default_mode_pb_type_name( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const; + std::vector default_mode_parent_pb_type_names( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const; + std::vector default_mode_parent_mode_names( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const; + 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( const BitstreamInterconnectSettingId& interconnect_setting_id) const; std::vector parent_pb_type_names( @@ -118,6 +138,12 @@ class BitstreamSetting { void set_bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id, const size_t& offset); + BitstreamDefaultModeSettingId add_bitstream_default_mode_setting( + const std::string& pb_type_name, + const std::vector& parent_pb_type_names, + const std::vector& parent_mode_names, + const std::vector& mode_bits); + BitstreamInterconnectSettingId add_bitstream_interconnect_setting( const std::string& interconnect_name, const std::vector& parent_pb_type_names, @@ -133,6 +159,8 @@ class BitstreamSetting { public: /* Public Validators */ bool valid_bitstream_pb_type_setting_id( const BitstreamPbTypeSettingId& pb_type_setting_id) const; + bool valid_bitstream_default_mode_setting_id( + const BitstreamDefaultModeSettingId& default_mode_setting_id) const; bool valid_bitstream_interconnect_setting_id( const BitstreamInterconnectSettingId& interconnect_setting_id) const; bool valid_overwrite_bitstream_id(const OverwriteBitstreamId& id) const; @@ -158,6 +186,18 @@ class BitstreamSetting { * pb_type */ vtr::vector bitstream_offsets_; + /* Pb type - default mode bits overwrite */ + vtr::vector + default_mode_setting_ids_; + vtr::vector + default_mode_pb_type_names_; + vtr::vector> + default_mode_parent_pb_type_names_; + vtr::vector> + default_mode_parent_mode_names_; + vtr::vector> + pb_type_default_mode_bits_; + /* Interconnect-related settings: * - Name of interconnect under a given pb_type * - The default path to be considered for a given interconnect during diff --git a/libs/libarchopenfpga/src/bitstream_setting_fwd.h b/libs/libarchopenfpga/src/bitstream_setting_fwd.h index dbcc705531..06d9655c79 100644 --- a/libs/libarchopenfpga/src/bitstream_setting_fwd.h +++ b/libs/libarchopenfpga/src/bitstream_setting_fwd.h @@ -14,11 +14,14 @@ #include "vtr_strong_id.h" struct bitstream_pb_type_setting_id_tag; +struct bitstream_default_mode_setting_id_tag; struct bitstream_interconnect_setting_id_tag; struct overwrite_bitstream_id_tag; typedef vtr::StrongId BitstreamPbTypeSettingId; +typedef vtr::StrongId + BitstreamDefaultModeSettingId; typedef vtr::StrongId BitstreamInterconnectSettingId; typedef vtr::StrongId OverwriteBitstreamId; diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 244703fc14..7d27216ad4 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" /******************************************************************** @@ -56,6 +57,29 @@ static void read_xml_bitstream_pb_type_setting( bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset); } +/******************************************************************** + * Parse XML description for a pb_type annotation under a + *XML node + *******************************************************************/ +static void read_xml_bitstream_default_mode_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(); + /* Parse the attributes for operating pb_type */ + openfpga::PbParser operating_pb_parser(name_attr); + + 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); +} + /******************************************************************** * Parse XML description for a pb_type annotation under a XML node *******************************************************************/ @@ -137,18 +161,25 @@ openfpga::BitstreamSetting read_xml_bitstream_setting( * each child should be named after */ for (pugi::xml_node xml_child : Node.children()) { - /* Error out if the XML child has an invalid name! */ + /* Error out if the XML child has an invalid name! + * TODO: Use std::map or something similar to apply checks! + */ if ((xml_child.name() != std::string("pb_type")) && + (xml_child.name() != std::string("default_mode_bits")) && (xml_child.name() != std::string("interconnect")) && (xml_child.name() != std::string("non_fabric")) && (xml_child.name() != std::string("overwrite_bitstream"))) { bad_tag(xml_child, loc_data, Node, - {"pb_type | interconnect | non_fabric | overwrite_bitstream"}); + {"pb_type | interconnect | default_mode_bits | non_fabric | " + "overwrite_bitstream"}); } if (xml_child.name() == std::string("pb_type")) { read_xml_bitstream_pb_type_setting(xml_child, loc_data, bitstream_setting); + } else if (xml_child.name() == std::string("default_mode_bits")) { + read_xml_bitstream_default_mode_setting(xml_child, loc_data, + bitstream_setting); } else if (xml_child.name() == std::string("interconnect")) { read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting); 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 0000000000..7cdf86e932 --- /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 0000000000..73fadefa5d --- /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 8e2075bb62..ea519ca15f 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/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp index f9268e653a..f0a0427832 100644 --- a/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp @@ -47,6 +47,43 @@ static std::string generate_bitstream_setting_pb_type_hierarchy_name( return hie_name; } +/******************************************************************** + * 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 BitstreamDefaultModeSettingId& bitstream_pb_type_setting_id) { + /* Iterate over the parent_pb_type and modes names, they should well match */ + VTR_ASSERT_SAFE( + bitstream_setting + .default_mode_parent_pb_type_names(bitstream_pb_type_setting_id) + .size() == bitstream_setting + .default_mode_parent_mode_names(bitstream_pb_type_setting_id) + .size()); + + std::string hie_name; + + for (size_t i = 0; + i < bitstream_setting + .default_mode_parent_pb_type_names(bitstream_pb_type_setting_id) + .size(); + ++i) { + hie_name += bitstream_setting.default_mode_parent_pb_type_names( + bitstream_pb_type_setting_id)[i]; + hie_name += std::string("["); + hie_name += bitstream_setting.default_mode_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.default_mode_pb_type_name(bitstream_pb_type_setting_id); + + return hie_name; +} + /******************************************************************** * Generate the full hierarchy name for an interconnect in bitstream setting *******************************************************************/ @@ -118,6 +155,34 @@ static void write_xml_bitstream_pb_type_setting( << "\n"; } +/******************************************************************** + * A writer to output a bitstream pb_type setting to XML format + *******************************************************************/ +static void write_xml_bitstream_default_mode_setting( + std::fstream& fp, const char* fname, + const openfpga::BitstreamSetting& bitstream_setting, + const BitstreamDefaultModeSettingId& bitstream_default_mode_setting_id) { + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + fp << "\t" + << "" + << "\n"; +} + /******************************************************************** * A writer to output a bitstream interconnect setting to XML format *******************************************************************/ @@ -166,6 +231,13 @@ void write_xml_bitstream_setting( bitstream_pb_type_setting_id); } + /* Write default_mode -related settings */ + for (const auto& bitstream_default_mode_setting_id : + bitstream_setting.default_mode_settings()) { + write_xml_bitstream_default_mode_setting(fp, fname, bitstream_setting, + bitstream_default_mode_setting_id); + } + /* Write interconnect -related settings */ for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) { diff --git a/libs/libopenfpgacapnproto/gen/unique_blocks_uxsdcxx.capnp b/libs/libopenfpgacapnproto/gen/unique_blocks_uxsdcxx.capnp index 340fb23349..3de2e7618f 100644 --- a/libs/libopenfpgacapnproto/gen/unique_blocks_uxsdcxx.capnp +++ b/libs/libopenfpgacapnproto/gen/unique_blocks_uxsdcxx.capnp @@ -6,7 +6,7 @@ # Input file: /home/xifan/github/OpenFPGA/libs/libopenfpgacapnproto/gen/unique_blocks.xsd # md5sum of input file: 1db9d740309076fa51f61413bae1e072 -@0xdda3f3f93e497b0c; +@0xe572df7b6c5621b7; using Cxx = import "/capnp/c++.capnp"; $Cxx.namespace("ucap"); diff --git a/openfpga/src/annotation/annotate_bitstream_setting.cpp b/openfpga/src/annotation/annotate_bitstream_setting.cpp index 2662025057..5a8232734b 100644 --- a/openfpga/src/annotation/annotate_bitstream_setting.cpp +++ b/openfpga/src/annotation/annotate_bitstream_setting.cpp @@ -128,6 +128,89 @@ 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) + .c_str()); + 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 +342,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 +352,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 3adc176399..947e17897a 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 69e1ebc96a..3dd7357f84 100644 --- a/openfpga/src/annotation/annotate_pb_types.cpp +++ b/openfpga/src/annotation/annotate_pb_types.cpp @@ -990,8 +990,8 @@ 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()); + vpr_device_annotation.add_pb_type_mode_bits( + primitive_pb_type, 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 1f7c47cff7..000b9c6872 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 6d99d60e98..3ddb330c0f 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 07f686302b..3126c4f110 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,13 +568,14 @@ 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", - pb_type->name); + VTR_LOGV_WARN(verbose, "Override the mode bits mapping for pb_type '%s'!\n", + pb_type->name); } pb_type_mode_bits_[pb_type] = mode_bits; diff --git a/openfpga/src/annotation/vpr_device_annotation.h b/openfpga/src/annotation/vpr_device_annotation.h index d5330d737f..43d386d085 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 52ebb78c43..bc42ee49e2 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; } diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh index 8fc5e022c3..24f82e1f4f 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -37,6 +37,8 @@ echo -e "Testing overloading default paths for programmable interconnect when ge run-task fpga_bitstream/overload_mux_default_path $@ echo -e "Testing overloading mode bits for DSP blocks when generating bitstream"; run-task fpga_bitstream/overload_dsp_mode_bit $@ +echo -e "Testing overloading default mode bits"; +run-task fpga_bitstream/overload_default_mode_bit $@ echo -e "Testing outputting I/O mapping result to file"; run-task fpga_bitstream/write_io_mapping $@ diff --git a/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/bitstream_annotation.xml b/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/bitstream_annotation.xml new file mode 100644 index 0000000000..2885307f5d --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/bitstream_annotation.xml @@ -0,0 +1,3 @@ + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/task.conf new file mode 100644 index 0000000000..7d6e82a088 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/overload_default_mode_bit/config/task.conf @@ -0,0 +1,45 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/bitstream_setting_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_frac_dsp16_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_bitstream_setting_file=${PATH:TASK_DIR}/config/bitstream_annotation.xml +# VPR parameter +openfpga_vpr_circuit_format=eblif + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_frac_dsp16_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mult/mult8/mult8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_N4_tileable_frac_dsp16_40nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_N4_tileable_frac_dsp16_40nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mult8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist=