diff --git a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 75a6ae6d8..181ee531c 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -43,10 +43,10 @@ void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type, content_attr); /* Parse if the bitstream overwritting is applied to mode bits of a pb_type */ - const bool& is_mode_select_bitstream = get_attribute(xml_pb_type, "is_mode_select_bitstream", loc_data).as_bool(false); + const bool& is_mode_select_bitstream = get_attribute(xml_pb_type, "is_mode_select_bitstream", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false); bitstream_setting.set_mode_select_bitstream(bitstream_pb_type_id, is_mode_select_bitstream); - const int& offset = get_attribute(xml_pb_type, "bitstream_offset", loc_data).as_int(0); + const int& offset = get_attribute(xml_pb_type, "bitstream_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0); bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset); } diff --git a/openfpga/src/annotation/annotate_bitstream_setting.cpp b/openfpga/src/annotation/annotate_bitstream_setting.cpp index fbcb92cf0..48002a08b 100644 --- a/openfpga/src/annotation/annotate_bitstream_setting.cpp +++ b/openfpga/src/annotation/annotate_bitstream_setting.cpp @@ -56,17 +56,30 @@ int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting, if (nullptr == target_pb_type) { continue; } + /* Found one, build annotation */ - if (std::string("eblif") == bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id)) { - vpr_bitstream_annotation.set_pb_type_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); - } else { + if (std::string("eblif") != bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id)) { /* Invalid source, error out! */ VTR_LOG_ERROR("Invalid bitstream source '%s' for pb_type '%s' which is defined in bitstream setting\n", bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id).c_str(), target_pb_type_names[0].c_str()); return CMD_EXEC_FATAL_ERROR; } - vpr_bitstream_annotation.set_pb_type_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + + /* Depending on the bitstream type, annotate through different entrances + * - For regular bitstream, set bitstream content, flags etc. + * - For mode-select bitstream, set mode-select bitstream content, flags etc. + */ + if (false == bitstream_setting.is_mode_select_bitstream(bitstream_pb_type_setting_id)) { + vpr_bitstream_annotation.set_pb_type_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); + vpr_bitstream_annotation.set_pb_type_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_bitstream_offset(target_pb_type, bitstream_setting.bitstream_offset(bitstream_pb_type_setting_id)); + } else { + VTR_ASSERT_SAFE(false == bitstream_setting.is_mode_select_bitstream(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_offset(target_pb_type, bitstream_setting.bitstream_offset(bitstream_pb_type_setting_id)); + } link_success = true; } diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.cpp b/openfpga/src/annotation/vpr_bitstream_annotation.cpp index 5a221c7d4..3361d598c 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.cpp +++ b/openfpga/src/annotation/vpr_bitstream_annotation.cpp @@ -38,16 +38,6 @@ std::string VprBitstreamAnnotation::pb_type_bitstream_content(t_pb_type* pb_type return std::string(); } -bool VprBitstreamAnnotation::pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const { - auto result = contain_mode_select_bitstreams_.find(pb_type); - if (result != contain_mode_select_bitstreams_.end()) { - return result->second; - } - - /* Not found, return false as default */ - return false; -} - size_t VprBitstreamAnnotation::pb_type_bitstream_offset(t_pb_type* pb_type) const { auto result = bitstream_offsets_.find(pb_type); if (result != bitstream_offsets_.end()) { @@ -58,6 +48,26 @@ size_t VprBitstreamAnnotation::pb_type_bitstream_offset(t_pb_type* pb_type) cons return 0; } +VprBitstreamAnnotation::e_bitstream_source_type VprBitstreamAnnotation::pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const { + auto result = mode_select_bitstream_sources_.find(pb_type); + if (result != mode_select_bitstream_sources_.end()) { + return result->second; + } + + /* Not found, return an invalid type*/ + return NUM_BITSTREAM_SOURCE_TYPES; +} + +std::string VprBitstreamAnnotation::pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const { + auto result = mode_select_bitstream_contents_.find(pb_type); + if (result != mode_select_bitstream_contents_.end()) { + return result->second; + } + + /* Not found, return an invalid type */ + return std::string(); +} + size_t VprBitstreamAnnotation::pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const { auto result = mode_select_bitstream_offsets_.find(pb_type); if (result != mode_select_bitstream_offsets_.end()) { @@ -81,16 +91,21 @@ void VprBitstreamAnnotation::set_pb_type_bitstream_content(t_pb_type* pb_type, bitstream_contents_[pb_type] = bitstream_content; } -void VprBitstreamAnnotation::set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, - const bool& contain_mode_select_bitstream) { - contain_mode_select_bitstreams_[pb_type] = contain_mode_select_bitstream; -} - void VprBitstreamAnnotation::set_pb_type_bitstream_offset(t_pb_type* pb_type, const size_t& offset) { bitstream_offsets_[pb_type] = offset; } +void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_source(t_pb_type* pb_type, + const e_bitstream_source_type& bitstream_source) { + mode_select_bitstream_sources_[pb_type] = bitstream_source; +} + +void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_content(t_pb_type* pb_type, + const std::string& bitstream_content) { + mode_select_bitstream_contents_[pb_type] = bitstream_content; +} + void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, const size_t& offset) { mode_select_bitstream_offsets_[pb_type] = offset; diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.h b/openfpga/src/annotation/vpr_bitstream_annotation.h index f12dbc44d..c562e4aa2 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.h +++ b/openfpga/src/annotation/vpr_bitstream_annotation.h @@ -33,29 +33,39 @@ class VprBitstreamAnnotation { public: /* Public accessors */ 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; - bool pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const; size_t pb_type_bitstream_offset(t_pb_type* pb_type) const; + + e_bitstream_source_type pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const; + std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const; size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const; public: /* Public mutators */ void set_pb_type_bitstream_source(t_pb_type* pb_type, const e_bitstream_source_type& bitstream_source); void set_pb_type_bitstream_content(t_pb_type* pb_type, const std::string& bitstream_content); - void set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, - const bool& contain_mode_select_bitstream); void set_pb_type_bitstream_offset(t_pb_type* pb_type, const size_t& offset); + + 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(t_pb_type* pb_type, + const std::string& bitstream_content); void set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, const size_t& offset); private: /* Internal data */ + /* For regular bitstreams */ /* A look up for pb type to find bitstream source type */ std::map bitstream_sources_; /* Binding from pb type to bitstream content */ std::map bitstream_contents_; - /* A flag to identify if the pb_type has an external mode-select bitstream */ - std::map contain_mode_select_bitstreams_; /* Offset to be applied to bitstream */ std::map bitstream_offsets_; + + /* For mode-select bitstreams */ + /* A look up for pb type to find bitstream source type */ + std::map mode_select_bitstream_sources_; + /* Binding from pb type to bitstream content */ + std::map mode_select_bitstream_contents_; /* Offset to be applied to mode-select bitstream */ std::map mode_select_bitstream_offsets_; }; diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 668ed8e08..f0cfab7dd 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -450,20 +450,16 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, std::string fixed_bitstream = physical_pb.fixed_bitstream(lut_pb_id); size_t start_index = physical_pb.fixed_bitstream_offset(lut_pb_id); /* Ensure the length matches!!! */ - if (lut_bitstream.size() - start_index != fixed_bitstream.size()) { - VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be %ld bits\n", + if (lut_bitstream.size() - start_index < fixed_bitstream.size()) { + VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be less than %ld bits\n", fixed_bitstream.c_str(), - lut_bitstream.size()); + lut_bitstream.size() - start_index); exit(1); } - /* Overload here - * - if there is a non-zero offset, we just erase part of the bitstream - * - otherwise, overwrite the whole bitstream - */ - lut_bitstream.erase(lut_bitstream.begin() + start_index, lut_bitstream.end()); - for (const char& fixed_bit : fixed_bitstream) { - VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); - lut_bitstream.push_back('1' == fixed_bit); + /* Overload the bitstream here */ + for (size_t bit_index = 0; bit_index < lut_bitstream.size(); ++bit_index) { + VTR_ASSERT('0' == fixed_bitstream[bit_index] || '1' == fixed_bitstream[bit_index]); + lut_bitstream[bit_index + start_index] = ('1' == fixed_bitstream[bit_index]); } } } @@ -473,32 +469,29 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, std::vector mode_select_bitstream; if (true == physical_pb.valid_pb_id(lut_pb_id)) { mode_select_bitstream = generate_mode_select_bitstream(physical_pb.mode_bits(lut_pb_id)); + + /* If the physical pb contains fixed mode-select bitstream, overload here */ + if (false == physical_pb.fixed_mode_select_bitstream(lut_pb_id).empty()) { + std::string fixed_mode_select_bitstream = physical_pb.fixed_mode_select_bitstream(lut_pb_id); + size_t mode_bits_start_index = physical_pb.fixed_mode_select_bitstream_offset(lut_pb_id); + /* Ensure the length matches!!! */ + if (mode_select_bitstream.size() - mode_bits_start_index < fixed_mode_select_bitstream.size()) { + VTR_LOG_ERROR("Unmatched length of fixed mode_select_bitstream %s!Expected to be less than %ld bits\n", + fixed_mode_select_bitstream.c_str(), + mode_select_bitstream.size() - mode_bits_start_index); + exit(1); + } + /* Overload the bitstream here */ + for (size_t bit_index = 0; bit_index < fixed_mode_select_bitstream.size(); ++bit_index) { + VTR_ASSERT('0' == fixed_mode_select_bitstream[bit_index] || '1' == fixed_mode_select_bitstream[bit_index]); + mode_select_bitstream[bit_index + mode_bits_start_index] = ('1' == fixed_mode_select_bitstream[bit_index]); + } + + } } else { /* get default mode_bits */ mode_select_bitstream = generate_mode_select_bitstream(device_annotation.pb_type_mode_bits(lut_pb_type)); } - /* If the physical pb contains fixed mode-select bitstream, overload here */ - if (false == physical_pb.fixed_mode_select_bitstream(lut_pb_id).empty()) { - std::string fixed_mode_select_bitstream = physical_pb.fixed_mode_select_bitstream(lut_pb_id); - size_t mode_bits_start_index = physical_pb.fixed_mode_select_bitstream_offset(lut_pb_id); - /* Ensure the length matches!!! */ - if (mode_select_bitstream.size() - mode_bits_start_index != fixed_mode_select_bitstream.size()) { - VTR_LOG_ERROR("Unmatched length of fixed mode_select_bitstream %s!Expected to be %ld bits\n", - fixed_mode_select_bitstream.c_str(), - mode_select_bitstream.size()); - exit(1); - } - /* Overload here - * - if there is a non-zero offset, we just erase part of the bitstream - * - otherwise, overwrite the whole bitstream - */ - mode_select_bitstream.erase(mode_select_bitstream.begin() + mode_bits_start_index, mode_select_bitstream.end()); - for (const char& fixed_bit : fixed_mode_select_bitstream) { - VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); - mode_select_bitstream.push_back('1' == fixed_bit); - } - } - /* Conjunct the mode-select bitstream to the lut bitstream */ for (const bool& bit : mode_select_bitstream) { lut_bitstream.push_back(bit); diff --git a/openfpga/src/utils/physical_pb_utils.cpp b/openfpga/src/utils/physical_pb_utils.cpp index 9b2668d13..2b366c305 100644 --- a/openfpga/src/utils/physical_pb_utils.cpp +++ b/openfpga/src/utils/physical_pb_utils.cpp @@ -304,7 +304,7 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, VTR_ASSERT(atom_blk); phy_pb.add_atom_block(physical_pb, atom_blk); - + /* if the operating pb type has bitstream annotation, * bind the bitstream value from atom block to the physical pb */ @@ -320,14 +320,8 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, if (param_search.first != tokens[1]) { continue; } - if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { - phy_pb.set_fixed_bitstream(physical_pb, param_search.second); - phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); - } else { - VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); - phy_pb.set_fixed_mode_select_bitstream(physical_pb, param_search.second); - phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); - } + phy_pb.set_fixed_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); } } else if (std::string(".attr") == tokens[0]) { for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { @@ -335,14 +329,39 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, if (attr_search.first == tokens[1]) { continue; } - if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { - phy_pb.set_fixed_bitstream(physical_pb, attr_search.second); - phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); - } else { - VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); - phy_pb.set_fixed_mode_select_bitstream(physical_pb, attr_search.second); - phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); - } + phy_pb.set_fixed_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); + } + } + } + + + /* if the operating pb type has mode-select bitstream annotation, + * bind the bitstream value from atom block to the physical pb + */ + if (VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF == bitstream_annotation.pb_type_mode_select_bitstream_source(pb_type)) { + StringToken tokenizer = bitstream_annotation.pb_type_mode_select_bitstream_content(pb_type); + std::vector tokens = tokenizer.split(" "); + /* FIXME: The token-level check should be done much earlier!!! */ + VTR_ASSERT(2 == tokens.size()); + /* The token is typically organized as <.param|.attr> */ + if (std::string(".param") == tokens[0]) { + for (const auto& param_search : atom_ctx.nlist.block_params(atom_blk)) { + /* Bypass unmatched parameter identifier */ + if (param_search.first != tokens[1]) { + continue; + } + phy_pb.set_fixed_mode_select_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); + } + } else if (std::string(".attr") == tokens[0]) { + for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { + /* Bypass unmatched parameter identifier */ + if (attr_search.first == tokens[1]) { + continue; + } + phy_pb.set_fixed_mode_select_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); } } }