From d909d5ac51fec1856a4d87e18f292af3d84a7b13 Mon Sep 17 00:00:00 2001 From: chungshien Date: Tue, 13 Feb 2024 10:36:17 -0800 Subject: [PATCH 1/6] BRAM preload data - generic way to extract data from design --- .../libarchopenfpga/src/bitstream_setting.cpp | 20 ++ libs/libarchopenfpga/src/bitstream_setting.h | 30 +++ .../src/read_xml_bitstream_setting.cpp | 40 ++- .../src/base/openfpga_bitstream_template.h | 4 + .../extract_device_none_fabric_bitstream.cpp | 255 ++++++++++++++++++ .../extract_device_none_fabric_bitstream.h | 25 ++ 6 files changed, 370 insertions(+), 4 deletions(-) create mode 100644 openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp create mode 100644 openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index c04eeba879..7186864b2b 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -102,6 +102,10 @@ std::string BitstreamSetting::default_path( return interconnect_default_paths_[interconnect_setting_id]; } +std::vector BitstreamSetting::none_fabric() const { + return none_fabric_; +} + /************************************************************************ * Public Mutators ***********************************************************************/ @@ -154,6 +158,22 @@ BitstreamSetting::add_bitstream_interconnect_setting( return interc_setting_id; } +void BitstreamSetting::add_none_fabric(const std::string& name, + const std::string& file) { + VTR_ASSERT(name.size()); + VTR_ASSERT(file.size()); + none_fabric_.push_back(NoneFabricBitstreamSetting(name, file)); +} + +void BitstreamSetting::add_none_fabric_pb(const std::string& pb, + const std::string& type, + const std::string& content) { + VTR_ASSERT(none_fabric_.size()); + VTR_ASSERT(type == "param" || type == "attr"); + VTR_ASSERT(content.size()); + none_fabric_.back().add_pb(pb, type, content); +} + /************************************************************************ * Public Validators ***********************************************************************/ diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index 7963942a08..1bd6ec525e 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -6,6 +6,7 @@ * which are used by OpenFPGA *******************************************************************/ #include +#include #include "bitstream_setting_fwd.h" #include "vtr_vector.h" @@ -13,6 +14,29 @@ /* namespace openfpga begins */ namespace openfpga { +struct NoneFabricBitstreamPBSetting { + NoneFabricBitstreamPBSetting(const std::string& p = "", + const std::string& t = "", + const std::string& c = "") + : pb(p), type(t), content(c) {} + const std::string pb = ""; + const std::string type = ""; + const std::string content = ""; +}; + +struct NoneFabricBitstreamSetting { + NoneFabricBitstreamSetting(const std::string& n = "", + const std::string& f = "") + : name(n), file(f) {} + void add_pb(const std::string& p, const std::string& t, + const std::string& c) { + pbs.push_back(NoneFabricBitstreamPBSetting(p, t, c)); + } + const std::string name = ""; + const std::string file = ""; + std::vector pbs; +}; + /******************************************************************** * A data structure to describe bitstream settings * @@ -73,6 +97,7 @@ class BitstreamSetting { const BitstreamInterconnectSettingId& interconnect_setting_id) const; std::string default_path( const BitstreamInterconnectSettingId& interconnect_setting_id) const; + std::vector none_fabric() const; public: /* Public Mutators */ BitstreamPbTypeSettingId add_bitstream_pb_type_setting( @@ -92,6 +117,10 @@ class BitstreamSetting { const std::vector& parent_mode_names, const std::string& default_path); + void add_none_fabric(const std::string& name, const std::string& file); + void add_none_fabric_pb(const std::string& pb, const std::string& type, + const std::string& content); + public: /* Public Validators */ bool valid_bitstream_pb_type_setting_id( const BitstreamPbTypeSettingId& pb_type_setting_id) const; @@ -133,6 +162,7 @@ class BitstreamSetting { interconnect_parent_mode_names_; vtr::vector interconnect_default_paths_; + std::vector none_fabric_; }; } // namespace openfpga diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 7447bec2a7..876ae05629 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -76,6 +76,33 @@ static void read_xml_bitstream_interconnect_setting( operating_pb_parser.modes(), default_path_attr); } +/******************************************************************** + * Parse XML description for a none_fabric annotation under a XML node + *******************************************************************/ +static void read_xml_none_fabric_bitstream_setting( + pugi::xml_node& xml_none_fabric, const pugiutil::loc_data& loc_data, + openfpga::BitstreamSetting& bitstream_setting) { + const std::string& name_attr = + get_attribute(xml_none_fabric, "name", loc_data).as_string(); + const std::string& file_attr = + get_attribute(xml_none_fabric, "file", loc_data).as_string(); + /* Add to none fabric */ + bitstream_setting.add_none_fabric(name_attr, file_attr); + for (pugi::xml_node xml_child : xml_none_fabric.children()) { + if (xml_child.name() != std::string("pb")) { + bad_tag(xml_child, loc_data, xml_none_fabric, {"pb"}); + } + const std::string& pb_name_attr = + get_attribute(xml_child, "name", loc_data).as_string(); + const std::string& type_attr = + get_attribute(xml_child, "type", loc_data).as_string(); + const std::string& content_attr = + get_attribute(xml_child, "content", loc_data).as_string(); + /* Add PB to none fabric */ + bitstream_setting.add_none_fabric_pb(pb_name_attr, type_attr, content_attr); + } +} + /******************************************************************** * Parse XML codes about to an object *******************************************************************/ @@ -89,17 +116,22 @@ openfpga::BitstreamSetting read_xml_bitstream_setting( for (pugi::xml_node xml_child : Node.children()) { /* Error out if the XML child has an invalid name! */ if ((xml_child.name() != std::string("pb_type")) && - (xml_child.name() != std::string("interconnect"))) { - bad_tag(xml_child, loc_data, Node, {"pb_type | interconnect"}); + (xml_child.name() != std::string("interconnect")) && + (xml_child.name() != std::string("none_fabric"))) { + bad_tag(xml_child, loc_data, Node, + {"pb_type | interconnect | none_fabric"}); } if (xml_child.name() == std::string("pb_type")) { read_xml_bitstream_pb_type_setting(xml_child, loc_data, bitstream_setting); - } else { - VTR_ASSERT_SAFE(xml_child.name() == std::string("interconnect")); + } else if (xml_child.name() == std::string("interconnect")) { read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting); + } else { + VTR_ASSERT_SAFE(xml_child.name() == std::string("none_fabric")); + read_xml_none_fabric_bitstream_setting(xml_child, loc_data, + bitstream_setting); } } diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index 8821c8392b..c3d0ea3d64 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -11,6 +11,7 @@ #include "command.h" #include "command_context.h" #include "command_exit_codes.h" +#include "extract_device_none_fabric_bitstream.h" #include "globals.h" #include "openfpga_digest.h" #include "openfpga_naming.h" @@ -59,6 +60,9 @@ int fpga_bitstream_template(T& openfpga_ctx, const Command& cmd, !cmd_context.option_enable(cmd, opt_no_time_stamp)); } + extract_device_none_fabric_bitstream( + g_vpr_ctx, openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose)); + /* TODO: should identify the error code from internal function execution */ return CMD_EXEC_SUCCESS; } diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp new file mode 100644 index 0000000000..385f58b337 --- /dev/null +++ b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp @@ -0,0 +1,255 @@ +/******************************************************************** + * This file includes functions to build bitstream from a mapped + * FPGA fabric. + * We decode the bitstream from configuration of routing multiplexers + * and Look-Up Tables (LUTs) which locate in CLBs and global routing + *architecture + *******************************************************************/ +#include +#include + +/* Headers from vtrutil library */ +#include "extract_device_none_fabric_bitstream.h" +#include "openfpga_pb_parser.h" +#include "pb_type_utils.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Extract data from the targetted PB + * 1. If it is primitive + * a. If it match the targetted PB, try to get data from + * param of attr depends on what being defined in XML + * b. If it is does not match, do nothing + * 2. If it is not primitive, then we loop for the child + *******************************************************************/ +static bool extract_pb_data(std::fstream& fp, const AtomContext& atom_ctx, + const t_pb* op_pb, const t_pb_type* target_pb_type, + const NoneFabricBitstreamPBSetting& setting) { + t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node; + t_pb_type* pb_type = pb_graph_node->pb_type; + bool found_pb = false; + if (true == is_primitive_pb_type(pb_type)) { + if (target_pb_type == pb_type) { + AtomBlockId atom_blk = atom_ctx.nlist.find_block(op_pb->name); + VTR_ASSERT(atom_blk); + if (setting.type == "param") { + for (const auto& param_search : atom_ctx.nlist.block_params(atom_blk)) { + std::string param = param_search.first; + std::string content = param_search.second; + if (setting.content == param) { + fp << ",\n \"data\" : \"" << content.c_str() << "\""; + break; + } + } + } else { + VTR_ASSERT(setting.type == "attr"); + for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { + std::string attr = attr_search.first; + std::string content = attr_search.second; + if (setting.content == attr) { + fp << ",\n \"data\" : \"" << content.c_str() << "\""; + break; + } + } + } + found_pb = true; + } + } else { + t_mode* mapped_mode = &(pb_graph_node->pb_type->modes[op_pb->mode]); + for (int ipb = 0; ipb < mapped_mode->num_pb_type_children && !found_pb; + ++ipb) { + /* Each child may exist multiple times in the hierarchy*/ + for (int jpb = 0; + jpb < mapped_mode->pb_type_children[ipb].num_pb && !found_pb; + ++jpb) { + if ((nullptr != op_pb->child_pbs[ipb]) && + (nullptr != op_pb->child_pbs[ipb][jpb].name)) { + found_pb = + extract_pb_data(fp, atom_ctx, &(op_pb->child_pbs[ipb][jpb]), + target_pb_type, setting); + } + } + } + } + return found_pb; +} + +/******************************************************************** + * Extract data from the targetted PB (from that particular grid) + *******************************************************************/ +static void extract_grid_none_fabric_bitstream( + std::fstream& fp, const VprContext& vpr_ctx, + const OpenfpgaContext& openfpga_ctx, const ClusterBlockId& cluster_block_id, + const t_pb_type* target_pb_type, const NoneFabricBitstreamPBSetting setting) { + const ClusteringContext& clustering_ctx = vpr_ctx.clustering(); + const AtomContext& atom_ctx = vpr_ctx.atom(); + + if (ClusterBlockId::INVALID() != cluster_block_id) { + const t_pb* op_pb = clustering_ctx.clb_nlist.block_pb(cluster_block_id); + extract_pb_data(fp, atom_ctx, op_pb, target_pb_type, setting); + } else { + // Grid is valid, but this resource is not being used + } +} + +/******************************************************************** + * Extract data from the targetted PB (from the device) + *******************************************************************/ +static void extract_device_none_fabric_pb_bitstream( + std::fstream& fp, const NoneFabricBitstreamPBSetting setting, + const std::string& target_parent_pb_name, const t_pb_type* target_pb_type, + const VprContext& vpr_ctx, const OpenfpgaContext& openfpga_ctx) { + const DeviceContext& device_ctx = vpr_ctx.device(); + const PlacementContext& placement_ctx = vpr_ctx.placement(); + const DeviceGrid& grids = device_ctx.grid; + const size_t& layer = 0; + + // Loop logic block one by one + fp << ",\n \"grid\" : ["; + size_t grid_count = 0; + for (size_t ix = 1; ix < grids.width() - 1; ++ix) { + for (size_t iy = 1; iy < grids.height() - 1; ++iy) { + t_physical_tile_loc phy_tile_loc(ix, iy, layer); + t_physical_tile_type_ptr grid_type = + grids.get_physical_type(phy_tile_loc); + // Bypass EMPTY grid + if (true == is_empty_type(grid_type)) { + continue; + } + + // Skip width > 1 or height > 1 tiles (mostly heterogeneous blocks) + if ((0 < grids.get_width_offset(phy_tile_loc)) || + (0 < grids.get_height_offset(phy_tile_loc))) { + continue; + } + + // Skip if this grid is not what we are looking for + if (target_parent_pb_name != std::string(grid_type->name)) { + continue; + } + + // Get the mapped blocks to this grid + for (int isubtile = 0; isubtile < grid_type->capacity; ++isubtile) { + ClusterBlockId cluster_blk_id = + placement_ctx.grid_blocks.block_at_location( + {(int)ix, (int)iy, (int)isubtile, (int)layer}); + if (grid_count) { + fp << ","; + } + fp << "\n"; + fp << " {\n"; + fp << " \"x\" : " << (uint32_t)(ix) << ",\n"; + fp << " \"y\" : " << (uint32_t)(iy); + extract_grid_none_fabric_bitstream( + fp, vpr_ctx, openfpga_ctx, cluster_blk_id, target_pb_type, setting); + fp << "\n }"; + grid_count++; + } + } + } + fp << "\n ]"; +} + +/******************************************************************** + * Search the PB type based on the given name defined in XML + *******************************************************************/ +static t_pb_type* find_pb_type(const DeviceContext& device_ctx, + const std::string& parent_pb, + const std::string& pb) { + t_pb_type* pb_type = nullptr; + openfpga::PbParser pb_parser(pb); + std::vector names = pb_parser.parents(); + names.push_back(pb_parser.leaf()); + for (const t_logical_block_type& lb_type : device_ctx.logical_block_types) { + /* Bypass 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 (parent_pb != 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 */ + pb_type = try_find_pb_type_with_given_path(lb_type.pb_type, names, + pb_parser.modes()); + if (nullptr == pb_type) { + continue; + } + break; + } + return pb_type; +} + +/******************************************************************** + * A top-level function to extract data based on none-fabric bitstream setting + *******************************************************************/ +void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, + const OpenfpgaContext& openfpga_ctx, + const bool& verbose) { + std::string timer_message = + std::string("\nBuild none-fabric bitstream for implementation '") + + vpr_ctx.atom().nlist.netlist_name() + std::string("'\n"); + vtr::ScopedStartFinishTimer timer(timer_message); + const openfpga::BitstreamSetting& bitstream_setting = + openfpga_ctx.bitstream_setting(); + std::vector none_fabric_setting = + bitstream_setting.none_fabric(); + + // Only proceed if it is defined in bitstream_setting.xml + if (none_fabric_setting.size()) { + // Go through each none_fabric settting + for (auto setting : none_fabric_setting) { + std::fstream fp; + fp.open(setting.file.c_str(), std::fstream::out); + fp << "{\n"; + fp << " \"" << setting.name.c_str() << "\" : [\n"; + int pb_count = 0; + // Extract each needed PB data + for (auto pb_setting : setting.pbs) { + std::string pb_type = setting.name + pb_setting.pb; + t_pb_type* target_pb_type = + find_pb_type(vpr_ctx.device(), setting.name, pb_type); + if (pb_count) { + fp << ",\n"; + } + fp << " {\n"; + fp << " \"pb\" : \"" << pb_type.c_str() << "\",\n"; + if (target_pb_type == nullptr) { + fp << " \"is_primitive_pb_type\" : \"invalid\"\n"; + } else { + if (is_primitive_pb_type(target_pb_type)) { + fp << " \"is_primitive_pb_type\" : \"true\",\n"; + } else { + fp << " \"is_primitive_pb_type\" : \"false\",\n"; + } + } + fp << " \"type\" : \"" << pb_setting.type.c_str() << "\",\n"; + fp << " \"content\" : \"" << pb_setting.content.c_str() << "\""; + if (target_pb_type != nullptr && is_primitive_pb_type(target_pb_type)) { + extract_device_none_fabric_pb_bitstream(fp, pb_setting, setting.name, + target_pb_type, vpr_ctx, + openfpga_ctx); + } + fp << "\n }"; + pb_count++; + } + if (pb_count) { + fp << "\n"; + } + fp << " ]\n"; + fp << "}\n"; + } + } + VTR_LOGV(verbose, "Done\n"); +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h new file mode 100644 index 0000000000..2a83bc63ff --- /dev/null +++ b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h @@ -0,0 +1,25 @@ +#ifndef EXTRACT_DEVICE_NONE_FABRIC_BITSTREAM_H +#define EXTRACT_DEVICE_NONE_FABRIC_BITSTREAM_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +#include "openfpga_context.h" +#include "vpr_context.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, + const OpenfpgaContext& openfpga_ctx, + const bool& verbose); + +} /* end namespace openfpga */ + +#endif From 1e5e15e2813fa07ae358b5a712a269b8d7be912e Mon Sep 17 00:00:00 2001 From: chungshien Date: Tue, 13 Feb 2024 22:30:21 -0800 Subject: [PATCH 2/6] Add docs and support special __layout__ case --- .../manual/file_formats/bitstream_setting.rst | 46 +++++++++- .../libarchopenfpga/src/bitstream_setting.cpp | 12 ++- libs/libarchopenfpga/src/bitstream_setting.h | 3 +- .../src/read_xml_bitstream_setting.cpp | 7 +- .../extract_device_none_fabric_bitstream.cpp | 90 ++++++++++++------- 5 files changed, 117 insertions(+), 41 deletions(-) diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst index 764bf0c87d..894f5b93db 100644 --- a/docs/source/manual/file_formats/bitstream_setting.rst +++ b/docs/source/manual/file_formats/bitstream_setting.rst @@ -13,6 +13,9 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab + + + pb_type-related Settings @@ -39,7 +42,6 @@ The following syntax are applicable to the XML definition tagged by ``pb_type`` .. option:: content="" The content of the ``pb_type`` bitstream, which could be a keyword in a ``.eblif`` file. For example, ``content=".attr LUT"`` means that the bitstream will be extracted from the ``.attr LUT`` line which is defined under the ``.blif model`` (that is defined under the ``pb_type`` in VPR architecture file). - .. option:: is_mode_select_bitstream="" @@ -71,3 +73,45 @@ The following syntax are applicable to the XML definition tagged by ``interconne The default path can be either ``iopad.inpad`` or ``ff.Q`` which corresponds to the first input and the second input respectively. + +none_fabric-related Settings +^^^^^^^^^^^^^^^^^^^^^^^^ + +This is special syntax to extract PB defined parameter or attribute and save the data into dedicated JSON file outside of fabric bitstream + +The following syntax are applicable to the XML definition tagged by ``none-fabric`` in bitstream setting files. + +.. option:: name="" + + The ``pb_type`` top level name that the data to be extracted. For example, + + .. code-block:: xml + + name="bram" + +.. option:: file="" + + The filepath the data is saved to. For example, + + .. code-block:: xml + + file="bram.json" + +.. option:: ``pb`` child element name="" + + Together with ``pb_type`` top level name, that is the source of the ``pb_type`` bitstream + + The final ``pb_type`` name is "" + "" + + For example, + + .. code-block:: xml + + + + + The final ``pb_type`` name is "bram.bram_lr[mem_36K_tdp].mem_36K" + +.. option:: ``pb`` child element content="" + + The content of the ``pb_type`` data to be extracted. For example, ``content=".param INIT_i"`` means that the data will be extracted from the ``.param INIT_i`` line defined under the ``.blif model``. diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index 7186864b2b..29dd029fac 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -166,12 +166,16 @@ void BitstreamSetting::add_none_fabric(const std::string& name, } void BitstreamSetting::add_none_fabric_pb(const std::string& pb, - const std::string& type, const std::string& content) { VTR_ASSERT(none_fabric_.size()); - VTR_ASSERT(type == "param" || type == "attr"); - VTR_ASSERT(content.size()); - none_fabric_.back().add_pb(pb, type, content); + VTR_ASSERT(content.find(".param ") == 0 || content.find(".attr ") == 0); + if (content.find(".param ") == 0) { + VTR_ASSERT(content.size() > 7); + none_fabric_.back().add_pb(pb, "param", content.substr(7)); + } else { + VTR_ASSERT(content.size() > 6); + none_fabric_.back().add_pb(pb, "attr", content.substr(6)); + } } /************************************************************************ diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index 1bd6ec525e..cc6969aad2 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -118,8 +118,7 @@ class BitstreamSetting { const std::string& default_path); void add_none_fabric(const std::string& name, const std::string& file); - void add_none_fabric_pb(const std::string& pb, const std::string& type, - const std::string& content); + void add_none_fabric_pb(const std::string& pb, const std::string& content); public: /* Public Validators */ bool valid_bitstream_pb_type_setting_id( diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 876ae05629..a18baee12c 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -77,7 +77,8 @@ static void read_xml_bitstream_interconnect_setting( } /******************************************************************** - * Parse XML description for a none_fabric annotation under a XML node + * Parse XML description for a none_fabric annotation under a XML + *node *******************************************************************/ static void read_xml_none_fabric_bitstream_setting( pugi::xml_node& xml_none_fabric, const pugiutil::loc_data& loc_data, @@ -94,12 +95,10 @@ static void read_xml_none_fabric_bitstream_setting( } const std::string& pb_name_attr = get_attribute(xml_child, "name", loc_data).as_string(); - const std::string& type_attr = - get_attribute(xml_child, "type", loc_data).as_string(); const std::string& content_attr = get_attribute(xml_child, "content", loc_data).as_string(); /* Add PB to none fabric */ - bitstream_setting.add_none_fabric_pb(pb_name_attr, type_attr, content_attr); + bitstream_setting.add_none_fabric_pb(pb_name_attr, content_attr); } } diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp index 385f58b337..73e1910ba8 100644 --- a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp @@ -19,6 +19,8 @@ /* begin namespace openfpga */ namespace openfpga { +#define PRINT_LAYOUT_NAME "__layout__" + /******************************************************************** * Extract data from the targetted PB * 1. If it is primitive @@ -110,7 +112,9 @@ static void extract_device_none_fabric_pb_bitstream( const size_t& layer = 0; // Loop logic block one by one - fp << ",\n \"grid\" : ["; + if (target_parent_pb_name != PRINT_LAYOUT_NAME) { + fp << ",\n \"grid\" : ["; + } size_t grid_count = 0; for (size_t ix = 1; ix < grids.width() - 1; ++ix) { for (size_t iy = 1; iy < grids.height() - 1; ++iy) { @@ -128,6 +132,20 @@ static void extract_device_none_fabric_pb_bitstream( continue; } + // Skip if this grid is not what we are looking for + if (target_parent_pb_name == PRINT_LAYOUT_NAME) { + if (grid_count) { + fp << ",\n"; + } + fp << " {\n"; + fp << " \"x\" : " << (uint32_t)(ix) << ",\n"; + fp << " \"y\" : " << (uint32_t)(iy) << ",\n"; + fp << " \"name\" : \"" << grid_type->name << "\"\n"; + fp << " }"; + grid_count++; + continue; + } + // Skip if this grid is not what we are looking for if (target_parent_pb_name != std::string(grid_type->name)) { continue; @@ -152,7 +170,11 @@ static void extract_device_none_fabric_pb_bitstream( } } } - fp << "\n ]"; + if (target_parent_pb_name == PRINT_LAYOUT_NAME) { + fp << "\n"; + } else { + fp << "\n ]"; + } } /******************************************************************** @@ -212,41 +234,49 @@ void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, fp.open(setting.file.c_str(), std::fstream::out); fp << "{\n"; fp << " \"" << setting.name.c_str() << "\" : [\n"; - int pb_count = 0; - // Extract each needed PB data - for (auto pb_setting : setting.pbs) { - std::string pb_type = setting.name + pb_setting.pb; - t_pb_type* target_pb_type = - find_pb_type(vpr_ctx.device(), setting.name, pb_type); - if (pb_count) { - fp << ",\n"; - } - fp << " {\n"; - fp << " \"pb\" : \"" << pb_type.c_str() << "\",\n"; - if (target_pb_type == nullptr) { - fp << " \"is_primitive_pb_type\" : \"invalid\"\n"; - } else { - if (is_primitive_pb_type(target_pb_type)) { - fp << " \"is_primitive_pb_type\" : \"true\",\n"; + if (setting.name == PRINT_LAYOUT_NAME) { + extract_device_none_fabric_pb_bitstream( + fp, NoneFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_ctx, + openfpga_ctx); + } else { + int pb_count = 0; + // Extract each needed PB data + for (auto pb_setting : setting.pbs) { + std::string pb_type = setting.name + pb_setting.pb; + t_pb_type* target_pb_type = + find_pb_type(vpr_ctx.device(), setting.name, pb_type); + if (pb_count) { + fp << ",\n"; + } + fp << " {\n"; + fp << " \"pb\" : \"" << pb_type.c_str() << "\",\n"; + if (target_pb_type == nullptr) { + fp << " \"is_primitive_pb_type\" : \"invalid\",\n"; } else { - fp << " \"is_primitive_pb_type\" : \"false\",\n"; + if (is_primitive_pb_type(target_pb_type)) { + fp << " \"is_primitive_pb_type\" : \"true\",\n"; + } else { + fp << " \"is_primitive_pb_type\" : \"false\",\n"; + } + } + fp << " \"type\" : \"" << pb_setting.type.c_str() << "\",\n"; + fp << " \"content\" : \"" << pb_setting.content.c_str() << "\""; + if (target_pb_type != nullptr && + is_primitive_pb_type(target_pb_type)) { + extract_device_none_fabric_pb_bitstream( + fp, pb_setting, setting.name, target_pb_type, vpr_ctx, + openfpga_ctx); } + fp << "\n }"; + pb_count++; } - fp << " \"type\" : \"" << pb_setting.type.c_str() << "\",\n"; - fp << " \"content\" : \"" << pb_setting.content.c_str() << "\""; - if (target_pb_type != nullptr && is_primitive_pb_type(target_pb_type)) { - extract_device_none_fabric_pb_bitstream(fp, pb_setting, setting.name, - target_pb_type, vpr_ctx, - openfpga_ctx); + if (pb_count) { + fp << "\n"; } - fp << "\n }"; - pb_count++; - } - if (pb_count) { - fp << "\n"; } fp << " ]\n"; fp << "}\n"; + fp.close(); } } VTR_LOGV(verbose, "Done\n"); From efe75c21d674c42f9072c7ad96d6451f4859593d Mon Sep 17 00:00:00 2001 From: chungshien Date: Wed, 14 Feb 2024 00:56:50 -0800 Subject: [PATCH 3/6] Add test --- .../fpga_bitstream_reg_test.sh | 3 ++ .../config/bitstream_annotation.xml | 7 +++ .../extract_dsp_mode_bit/config/task.conf | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml create mode 100644 openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/task.conf 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 184eceee92..8d46be27f1 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -52,3 +52,6 @@ run-task fpga_bitstream/filter_value0 $@ run-task fpga_bitstream/filter_value1 $@ run-task fpga_bitstream/path_only $@ run-task fpga_bitstream/value_only $@ + +echo -e "Testing extracting mode bits for DSP blocks when generating bitstream"; +run-task fpga_bitstream/extract_dsp_mode_bit $@ diff --git a/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml new file mode 100644 index 0000000000..33807b0433 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/task.conf new file mode 100644 index 0000000000..9086785718 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/task.conf @@ -0,0 +1,44 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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= From 4f6cde54e5b40efa9126128d935ce2745d4dfc92 Mon Sep 17 00:00:00 2001 From: chungshien Date: Wed, 14 Feb 2024 01:46:04 -0800 Subject: [PATCH 4/6] Fix warning --- .../extract_device_none_fabric_bitstream.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp index 73e1910ba8..d208a0b2b9 100644 --- a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp @@ -86,8 +86,8 @@ static bool extract_pb_data(std::fstream& fp, const AtomContext& atom_ctx, *******************************************************************/ static void extract_grid_none_fabric_bitstream( std::fstream& fp, const VprContext& vpr_ctx, - const OpenfpgaContext& openfpga_ctx, const ClusterBlockId& cluster_block_id, - const t_pb_type* target_pb_type, const NoneFabricBitstreamPBSetting setting) { + const ClusterBlockId& cluster_block_id, const t_pb_type* target_pb_type, + const NoneFabricBitstreamPBSetting setting) { const ClusteringContext& clustering_ctx = vpr_ctx.clustering(); const AtomContext& atom_ctx = vpr_ctx.atom(); @@ -105,7 +105,7 @@ static void extract_grid_none_fabric_bitstream( static void extract_device_none_fabric_pb_bitstream( std::fstream& fp, const NoneFabricBitstreamPBSetting setting, const std::string& target_parent_pb_name, const t_pb_type* target_pb_type, - const VprContext& vpr_ctx, const OpenfpgaContext& openfpga_ctx) { + const VprContext& vpr_ctx) { const DeviceContext& device_ctx = vpr_ctx.device(); const PlacementContext& placement_ctx = vpr_ctx.placement(); const DeviceGrid& grids = device_ctx.grid; @@ -163,8 +163,8 @@ static void extract_device_none_fabric_pb_bitstream( fp << " {\n"; fp << " \"x\" : " << (uint32_t)(ix) << ",\n"; fp << " \"y\" : " << (uint32_t)(iy); - extract_grid_none_fabric_bitstream( - fp, vpr_ctx, openfpga_ctx, cluster_blk_id, target_pb_type, setting); + extract_grid_none_fabric_bitstream(fp, vpr_ctx, cluster_blk_id, + target_pb_type, setting); fp << "\n }"; grid_count++; } @@ -236,8 +236,7 @@ void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, fp << " \"" << setting.name.c_str() << "\" : [\n"; if (setting.name == PRINT_LAYOUT_NAME) { extract_device_none_fabric_pb_bitstream( - fp, NoneFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_ctx, - openfpga_ctx); + fp, NoneFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_ctx); } else { int pb_count = 0; // Extract each needed PB data @@ -264,8 +263,7 @@ void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, if (target_pb_type != nullptr && is_primitive_pb_type(target_pb_type)) { extract_device_none_fabric_pb_bitstream( - fp, pb_setting, setting.name, target_pb_type, vpr_ctx, - openfpga_ctx); + fp, pb_setting, setting.name, target_pb_type, vpr_ctx); } fp << "\n }"; pb_count++; From 49cdb4e9c80d08de144269ad9aaae0d9c5660aea Mon Sep 17 00:00:00 2001 From: chungshien Date: Tue, 20 Feb 2024 21:05:13 -0800 Subject: [PATCH 5/6] Change none-fabric to non-fabric --- .../manual/file_formats/bitstream_setting.rst | 12 ++--- .../libarchopenfpga/src/bitstream_setting.cpp | 20 ++++----- libs/libarchopenfpga/src/bitstream_setting.h | 26 +++++------ .../src/read_xml_bitstream_setting.cpp | 32 +++++++------- .../src/base/openfpga_bitstream_template.h | 4 +- ...> extract_device_non_fabric_bitstream.cpp} | 44 +++++++++---------- ... => extract_device_non_fabric_bitstream.h} | 10 ++--- .../config/bitstream_annotation.xml | 4 +- 8 files changed, 76 insertions(+), 76 deletions(-) rename openfpga/src/fpga_bitstream/{extract_device_none_fabric_bitstream.cpp => extract_device_non_fabric_bitstream.cpp} (87%) rename openfpga/src/fpga_bitstream/{extract_device_none_fabric_bitstream.h => extract_device_non_fabric_bitstream.h} (63%) diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst index 894f5b93db..eb2af5ddfa 100644 --- a/docs/source/manual/file_formats/bitstream_setting.rst +++ b/docs/source/manual/file_formats/bitstream_setting.rst @@ -13,9 +13,9 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab - + - + pb_type-related Settings @@ -74,12 +74,12 @@ The following syntax are applicable to the XML definition tagged by ``interconne The default path can be either ``iopad.inpad`` or ``ff.Q`` which corresponds to the first input and the second input respectively. -none_fabric-related Settings +non_fabric-related Settings ^^^^^^^^^^^^^^^^^^^^^^^^ This is special syntax to extract PB defined parameter or attribute and save the data into dedicated JSON file outside of fabric bitstream -The following syntax are applicable to the XML definition tagged by ``none-fabric`` in bitstream setting files. +The following syntax are applicable to the XML definition tagged by ``non_fabric`` in bitstream setting files. .. option:: name="" @@ -106,9 +106,9 @@ The following syntax are applicable to the XML definition tagged by ``none-fabri For example, .. code-block:: xml - + - + The final ``pb_type`` name is "bram.bram_lr[mem_36K_tdp].mem_36K" diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index 29dd029fac..7d763f9d2b 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -102,8 +102,8 @@ std::string BitstreamSetting::default_path( return interconnect_default_paths_[interconnect_setting_id]; } -std::vector BitstreamSetting::none_fabric() const { - return none_fabric_; +std::vector BitstreamSetting::non_fabric() const { + return non_fabric_; } /************************************************************************ @@ -158,23 +158,23 @@ BitstreamSetting::add_bitstream_interconnect_setting( return interc_setting_id; } -void BitstreamSetting::add_none_fabric(const std::string& name, - const std::string& file) { +void BitstreamSetting::add_non_fabric(const std::string& name, + const std::string& file) { VTR_ASSERT(name.size()); VTR_ASSERT(file.size()); - none_fabric_.push_back(NoneFabricBitstreamSetting(name, file)); + non_fabric_.push_back(NonFabricBitstreamSetting(name, file)); } -void BitstreamSetting::add_none_fabric_pb(const std::string& pb, - const std::string& content) { - VTR_ASSERT(none_fabric_.size()); +void BitstreamSetting::add_non_fabric_pb(const std::string& pb, + const std::string& content) { + VTR_ASSERT(non_fabric_.size()); VTR_ASSERT(content.find(".param ") == 0 || content.find(".attr ") == 0); if (content.find(".param ") == 0) { VTR_ASSERT(content.size() > 7); - none_fabric_.back().add_pb(pb, "param", content.substr(7)); + non_fabric_.back().add_pb(pb, "param", content.substr(7)); } else { VTR_ASSERT(content.size() > 6); - none_fabric_.back().add_pb(pb, "attr", content.substr(6)); + non_fabric_.back().add_pb(pb, "attr", content.substr(6)); } } diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index cc6969aad2..1b12c8de32 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -14,27 +14,27 @@ /* namespace openfpga begins */ namespace openfpga { -struct NoneFabricBitstreamPBSetting { - NoneFabricBitstreamPBSetting(const std::string& p = "", - const std::string& t = "", - const std::string& c = "") +struct NonFabricBitstreamPBSetting { + NonFabricBitstreamPBSetting(const std::string& p = "", + const std::string& t = "", + const std::string& c = "") : pb(p), type(t), content(c) {} const std::string pb = ""; const std::string type = ""; const std::string content = ""; }; -struct NoneFabricBitstreamSetting { - NoneFabricBitstreamSetting(const std::string& n = "", - const std::string& f = "") +struct NonFabricBitstreamSetting { + NonFabricBitstreamSetting(const std::string& n = "", + const std::string& f = "") : name(n), file(f) {} void add_pb(const std::string& p, const std::string& t, const std::string& c) { - pbs.push_back(NoneFabricBitstreamPBSetting(p, t, c)); + pbs.push_back(NonFabricBitstreamPBSetting(p, t, c)); } const std::string name = ""; const std::string file = ""; - std::vector pbs; + std::vector pbs; }; /******************************************************************** @@ -97,7 +97,7 @@ class BitstreamSetting { const BitstreamInterconnectSettingId& interconnect_setting_id) const; std::string default_path( const BitstreamInterconnectSettingId& interconnect_setting_id) const; - std::vector none_fabric() const; + std::vector non_fabric() const; public: /* Public Mutators */ BitstreamPbTypeSettingId add_bitstream_pb_type_setting( @@ -117,8 +117,8 @@ class BitstreamSetting { const std::vector& parent_mode_names, const std::string& default_path); - void add_none_fabric(const std::string& name, const std::string& file); - void add_none_fabric_pb(const std::string& pb, const std::string& content); + void add_non_fabric(const std::string& name, const std::string& file); + void add_non_fabric_pb(const std::string& pb, const std::string& content); public: /* Public Validators */ bool valid_bitstream_pb_type_setting_id( @@ -161,7 +161,7 @@ class BitstreamSetting { interconnect_parent_mode_names_; vtr::vector interconnect_default_paths_; - std::vector none_fabric_; + std::vector non_fabric_; }; } // namespace openfpga diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index a18baee12c..7f6bd12372 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -77,28 +77,28 @@ static void read_xml_bitstream_interconnect_setting( } /******************************************************************** - * Parse XML description for a none_fabric annotation under a XML + * Parse XML description for a non_fabric annotation under a XML *node *******************************************************************/ -static void read_xml_none_fabric_bitstream_setting( - pugi::xml_node& xml_none_fabric, const pugiutil::loc_data& loc_data, +static void read_xml_non_fabric_bitstream_setting( + pugi::xml_node& xml_non_fabric, const pugiutil::loc_data& loc_data, openfpga::BitstreamSetting& bitstream_setting) { const std::string& name_attr = - get_attribute(xml_none_fabric, "name", loc_data).as_string(); + get_attribute(xml_non_fabric, "name", loc_data).as_string(); const std::string& file_attr = - get_attribute(xml_none_fabric, "file", loc_data).as_string(); - /* Add to none fabric */ - bitstream_setting.add_none_fabric(name_attr, file_attr); - for (pugi::xml_node xml_child : xml_none_fabric.children()) { + get_attribute(xml_non_fabric, "file", loc_data).as_string(); + /* Add to non-fabric */ + bitstream_setting.add_non_fabric(name_attr, file_attr); + for (pugi::xml_node xml_child : xml_non_fabric.children()) { if (xml_child.name() != std::string("pb")) { - bad_tag(xml_child, loc_data, xml_none_fabric, {"pb"}); + bad_tag(xml_child, loc_data, xml_non_fabric, {"pb"}); } const std::string& pb_name_attr = get_attribute(xml_child, "name", loc_data).as_string(); const std::string& content_attr = get_attribute(xml_child, "content", loc_data).as_string(); - /* Add PB to none fabric */ - bitstream_setting.add_none_fabric_pb(pb_name_attr, content_attr); + /* Add PB to non-fabric */ + bitstream_setting.add_non_fabric_pb(pb_name_attr, content_attr); } } @@ -116,9 +116,9 @@ openfpga::BitstreamSetting read_xml_bitstream_setting( /* Error out if the XML child has an invalid name! */ if ((xml_child.name() != std::string("pb_type")) && (xml_child.name() != std::string("interconnect")) && - (xml_child.name() != std::string("none_fabric"))) { + (xml_child.name() != std::string("non_fabric"))) { bad_tag(xml_child, loc_data, Node, - {"pb_type | interconnect | none_fabric"}); + {"pb_type | interconnect | non_fabric"}); } if (xml_child.name() == std::string("pb_type")) { @@ -128,9 +128,9 @@ openfpga::BitstreamSetting read_xml_bitstream_setting( read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting); } else { - VTR_ASSERT_SAFE(xml_child.name() == std::string("none_fabric")); - read_xml_none_fabric_bitstream_setting(xml_child, loc_data, - bitstream_setting); + VTR_ASSERT_SAFE(xml_child.name() == std::string("non_fabric")); + read_xml_non_fabric_bitstream_setting(xml_child, loc_data, + bitstream_setting); } } diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index c3d0ea3d64..c132e907f7 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -11,7 +11,7 @@ #include "command.h" #include "command_context.h" #include "command_exit_codes.h" -#include "extract_device_none_fabric_bitstream.h" +#include "extract_device_non_fabric_bitstream.h" #include "globals.h" #include "openfpga_digest.h" #include "openfpga_naming.h" @@ -60,7 +60,7 @@ int fpga_bitstream_template(T& openfpga_ctx, const Command& cmd, !cmd_context.option_enable(cmd, opt_no_time_stamp)); } - extract_device_none_fabric_bitstream( + extract_device_non_fabric_bitstream( g_vpr_ctx, openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose)); /* TODO: should identify the error code from internal function execution */ diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp similarity index 87% rename from openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp rename to openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp index d208a0b2b9..3793c1b3d8 100644 --- a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp @@ -9,7 +9,7 @@ #include /* Headers from vtrutil library */ -#include "extract_device_none_fabric_bitstream.h" +#include "extract_device_non_fabric_bitstream.h" #include "openfpga_pb_parser.h" #include "pb_type_utils.h" #include "vtr_assert.h" @@ -31,7 +31,7 @@ namespace openfpga { *******************************************************************/ static bool extract_pb_data(std::fstream& fp, const AtomContext& atom_ctx, const t_pb* op_pb, const t_pb_type* target_pb_type, - const NoneFabricBitstreamPBSetting& setting) { + const NonFabricBitstreamPBSetting& setting) { t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node; t_pb_type* pb_type = pb_graph_node->pb_type; bool found_pb = false; @@ -84,10 +84,10 @@ static bool extract_pb_data(std::fstream& fp, const AtomContext& atom_ctx, /******************************************************************** * Extract data from the targetted PB (from that particular grid) *******************************************************************/ -static void extract_grid_none_fabric_bitstream( +static void extract_grid_non_fabric_bitstream( std::fstream& fp, const VprContext& vpr_ctx, const ClusterBlockId& cluster_block_id, const t_pb_type* target_pb_type, - const NoneFabricBitstreamPBSetting setting) { + const NonFabricBitstreamPBSetting setting) { const ClusteringContext& clustering_ctx = vpr_ctx.clustering(); const AtomContext& atom_ctx = vpr_ctx.atom(); @@ -102,8 +102,8 @@ static void extract_grid_none_fabric_bitstream( /******************************************************************** * Extract data from the targetted PB (from the device) *******************************************************************/ -static void extract_device_none_fabric_pb_bitstream( - std::fstream& fp, const NoneFabricBitstreamPBSetting setting, +static void extract_device_non_fabric_pb_bitstream( + std::fstream& fp, const NonFabricBitstreamPBSetting setting, const std::string& target_parent_pb_name, const t_pb_type* target_pb_type, const VprContext& vpr_ctx) { const DeviceContext& device_ctx = vpr_ctx.device(); @@ -163,8 +163,8 @@ static void extract_device_none_fabric_pb_bitstream( fp << " {\n"; fp << " \"x\" : " << (uint32_t)(ix) << ",\n"; fp << " \"y\" : " << (uint32_t)(iy); - extract_grid_none_fabric_bitstream(fp, vpr_ctx, cluster_blk_id, - target_pb_type, setting); + extract_grid_non_fabric_bitstream(fp, vpr_ctx, cluster_blk_id, + target_pb_type, setting); fp << "\n }"; grid_count++; } @@ -212,31 +212,31 @@ static t_pb_type* find_pb_type(const DeviceContext& device_ctx, } /******************************************************************** - * A top-level function to extract data based on none-fabric bitstream setting + * A top-level function to extract data based on non-fabric bitstream setting *******************************************************************/ -void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, - const OpenfpgaContext& openfpga_ctx, - const bool& verbose) { +void extract_device_non_fabric_bitstream(const VprContext& vpr_ctx, + const OpenfpgaContext& openfpga_ctx, + const bool& verbose) { std::string timer_message = - std::string("\nBuild none-fabric bitstream for implementation '") + + std::string("\nBuild non-fabric bitstream for implementation '") + vpr_ctx.atom().nlist.netlist_name() + std::string("'\n"); vtr::ScopedStartFinishTimer timer(timer_message); const openfpga::BitstreamSetting& bitstream_setting = openfpga_ctx.bitstream_setting(); - std::vector none_fabric_setting = - bitstream_setting.none_fabric(); + std::vector non_fabric_setting = + bitstream_setting.non_fabric(); // Only proceed if it is defined in bitstream_setting.xml - if (none_fabric_setting.size()) { - // Go through each none_fabric settting - for (auto setting : none_fabric_setting) { + if (non_fabric_setting.size()) { + // Go through each non_fabric settting + for (auto setting : non_fabric_setting) { std::fstream fp; fp.open(setting.file.c_str(), std::fstream::out); fp << "{\n"; fp << " \"" << setting.name.c_str() << "\" : [\n"; if (setting.name == PRINT_LAYOUT_NAME) { - extract_device_none_fabric_pb_bitstream( - fp, NoneFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_ctx); + extract_device_non_fabric_pb_bitstream( + fp, NonFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_ctx); } else { int pb_count = 0; // Extract each needed PB data @@ -262,8 +262,8 @@ void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, fp << " \"content\" : \"" << pb_setting.content.c_str() << "\""; if (target_pb_type != nullptr && is_primitive_pb_type(target_pb_type)) { - extract_device_none_fabric_pb_bitstream( - fp, pb_setting, setting.name, target_pb_type, vpr_ctx); + extract_device_non_fabric_pb_bitstream(fp, pb_setting, setting.name, + target_pb_type, vpr_ctx); } fp << "\n }"; pb_count++; diff --git a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h similarity index 63% rename from openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h rename to openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h index 2a83bc63ff..658c40b96a 100644 --- a/openfpga/src/fpga_bitstream/extract_device_none_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h @@ -1,5 +1,5 @@ -#ifndef EXTRACT_DEVICE_NONE_FABRIC_BITSTREAM_H -#define EXTRACT_DEVICE_NONE_FABRIC_BITSTREAM_H +#ifndef EXTRACT_DEVICE_NON_FABRIC_BITSTREAM_H +#define EXTRACT_DEVICE_NON_FABRIC_BITSTREAM_H /******************************************************************** * Include header files that are required by function declaration @@ -16,9 +16,9 @@ /* begin namespace openfpga */ namespace openfpga { -void extract_device_none_fabric_bitstream(const VprContext& vpr_ctx, - const OpenfpgaContext& openfpga_ctx, - const bool& verbose); +void extract_device_non_fabric_bitstream(const VprContext& vpr_ctx, + const OpenfpgaContext& openfpga_ctx, + const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml index 33807b0433..7c835ad7e3 100644 --- a/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml +++ b/openfpga_flow/tasks/fpga_bitstream/extract_dsp_mode_bit/config/bitstream_annotation.xml @@ -1,7 +1,7 @@ - + - + From b4f7fd5f0294d7a06c3d8786b75e3dfe816b3eb7 Mon Sep 17 00:00:00 2001 From: chungshien-chai Date: Tue, 18 Jun 2024 01:18:57 -0700 Subject: [PATCH 6/6] Make sure net is valid before setting it as wire LUT output --- openfpga/src/utils/physical_pb_utils.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openfpga/src/utils/physical_pb_utils.cpp b/openfpga/src/utils/physical_pb_utils.cpp index ddb8c954f6..7efc3465ca 100644 --- a/openfpga/src/utils/physical_pb_utils.cpp +++ b/openfpga/src/utils/physical_pb_utils.cpp @@ -316,6 +316,13 @@ static void mark_physical_pb_wired_lut_outputs( device_annotation.physical_pb_graph_pin(pb_graph_pin); VTR_ASSERT(nullptr != physical_pb_graph_pin); + // Skip if the output net is invalid + AtomNetId output_net = + phy_pb.pb_graph_pin_atom_net(primitive_pb, pb_graph_pin); + if (AtomNetId::INVALID() == output_net) { + continue; + } + /* Print debug info */ VTR_LOGV(verbose, "Mark physical pb_graph pin '%s' as wire LUT output\n", physical_pb_graph_pin->to_string().c_str());