diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst index 764bf0c87..894f5b93d 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 7186864b2..29dd029fa 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 1bd6ec525..cc6969aad 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 876ae0562..a18baee12 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 385f58b33..73e1910ba 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"; - } else { - fp << " \"is_primitive_pb_type\" : \"false\",\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 { + 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");