Skip to content

Commit

Permalink
Support extracting data that is not affecting fabric bitstream (#1566)
Browse files Browse the repository at this point in the history
* BRAM preload data - generic way to extract data from design

* Add docs and support special __layout__ case

* Add test

* Fix warning

* Change none-fabric to non-fabric
  • Loading branch information
chungshien authored Mar 10, 2024
1 parent 2a46a99 commit 4365d16
Show file tree
Hide file tree
Showing 10 changed files with 499 additions and 5 deletions.
46 changes: 45 additions & 1 deletion docs/source/manual/file_formats/bitstream_setting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab
<openfpga_bitstream_setting>
<pb_type name="<string>" source="eblif" content=".param LUT" is_mode_select_bistream="true" bitstream_offset="1"/>
<interconnect name="<string>" default_path="<string>"/>
<non_fabric name="<string>" file="<string>">
<pb name="<string>" type="<string>" content="<string>"/>
</non_fabric>
</openfpga_bitstream_setting>
pb_type-related Settings
Expand All @@ -39,7 +42,6 @@ The following syntax are applicable to the XML definition tagged by ``pb_type``
.. option:: content="<string>"

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="<bool>"

Expand Down Expand Up @@ -71,3 +73,45 @@ The following syntax are applicable to the XML definition tagged by ``interconne
<mux name="mux1" input="iopad.inpad ff.Q" output="io.inpad"/>
The default path can be either ``iopad.inpad`` or ``ff.Q`` which corresponds to the first input and the second input respectively.

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 ``non_fabric`` in bitstream setting files.

.. option:: name="<string: pb_type top level name>"

The ``pb_type`` top level name that the data to be extracted. For example,

.. code-block:: xml
name="bram"
.. option:: file="<string: JSON filepath>"

The filepath the data is saved to. For example,

.. code-block:: xml
file="bram.json"
.. option:: ``pb`` child element name="<string: pb_type child name>"

Together with ``pb_type`` top level name, that is the source of the ``pb_type`` bitstream

The final ``pb_type`` name is "<pb_type top level name>" + "<pb_type child name>"

For example,

.. code-block:: xml
<non_fabric name="bram" file="bram_bitstream.json">
<pb name=".bram_lr[mem_36K_tdp].mem_36K" content=".param INIT_i"/>
</non_fabric>
The final ``pb_type`` name is "bram.bram_lr[mem_36K_tdp].mem_36K"

.. option:: ``pb`` child element content="<string>"

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``.
24 changes: 24 additions & 0 deletions libs/libarchopenfpga/src/bitstream_setting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ std::string BitstreamSetting::default_path(
return interconnect_default_paths_[interconnect_setting_id];
}

std::vector<NonFabricBitstreamSetting> BitstreamSetting::non_fabric() const {
return non_fabric_;
}

/************************************************************************
* Public Mutators
***********************************************************************/
Expand Down Expand Up @@ -154,6 +158,26 @@ BitstreamSetting::add_bitstream_interconnect_setting(
return interc_setting_id;
}

void BitstreamSetting::add_non_fabric(const std::string& name,
const std::string& file) {
VTR_ASSERT(name.size());
VTR_ASSERT(file.size());
non_fabric_.push_back(NonFabricBitstreamSetting(name, file));
}

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);
non_fabric_.back().add_pb(pb, "param", content.substr(7));
} else {
VTR_ASSERT(content.size() > 6);
non_fabric_.back().add_pb(pb, "attr", content.substr(6));
}
}

/************************************************************************
* Public Validators
***********************************************************************/
Expand Down
29 changes: 29 additions & 0 deletions libs/libarchopenfpga/src/bitstream_setting.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,37 @@
* which are used by OpenFPGA
*******************************************************************/
#include <string>
#include <vector>

#include "bitstream_setting_fwd.h"
#include "vtr_vector.h"

/* namespace openfpga begins */
namespace openfpga {

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 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(NonFabricBitstreamPBSetting(p, t, c));
}
const std::string name = "";
const std::string file = "";
std::vector<NonFabricBitstreamPBSetting> pbs;
};

/********************************************************************
* A data structure to describe bitstream settings
*
Expand Down Expand Up @@ -73,6 +97,7 @@ class BitstreamSetting {
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::string default_path(
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::vector<NonFabricBitstreamSetting> non_fabric() const;

public: /* Public Mutators */
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
Expand All @@ -92,6 +117,9 @@ class BitstreamSetting {
const std::vector<std::string>& parent_mode_names,
const std::string& default_path);

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(
const BitstreamPbTypeSettingId& pb_type_setting_id) const;
Expand Down Expand Up @@ -133,6 +161,7 @@ class BitstreamSetting {
interconnect_parent_mode_names_;
vtr::vector<BitstreamInterconnectSettingId, std::string>
interconnect_default_paths_;
std::vector<NonFabricBitstreamSetting> non_fabric_;
};

} // namespace openfpga
Expand Down
39 changes: 35 additions & 4 deletions libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,32 @@ static void read_xml_bitstream_interconnect_setting(
operating_pb_parser.modes(), default_path_attr);
}

/********************************************************************
* Parse XML description for a non_fabric annotation under a <non_fabric> XML
*node
*******************************************************************/
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_non_fabric, "name", loc_data).as_string();
const std::string& file_attr =
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_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 non-fabric */
bitstream_setting.add_non_fabric_pb(pb_name_attr, content_attr);
}
}

/********************************************************************
* Parse XML codes about <openfpga_bitstream_setting> to an object
*******************************************************************/
Expand All @@ -89,17 +115,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("non_fabric"))) {
bad_tag(xml_child, loc_data, Node,
{"pb_type | interconnect | non_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("non_fabric"));
read_xml_non_fabric_bitstream_setting(xml_child, loc_data,
bitstream_setting);
}
}

Expand Down
4 changes: 4 additions & 0 deletions openfpga/src/base/openfpga_bitstream_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "command.h"
#include "command_context.h"
#include "command_exit_codes.h"
#include "extract_device_non_fabric_bitstream.h"
#include "globals.h"
#include "openfpga_digest.h"
#include "openfpga_naming.h"
Expand Down Expand Up @@ -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_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 */
return CMD_EXEC_SUCCESS;
}
Expand Down
Loading

0 comments on commit 4365d16

Please sign in to comment.