Add docs and support special __layout__ case

This commit is contained in:
chungshien 2024-02-13 22:30:21 -08:00
parent d909d5ac51
commit 1e5e15e281
5 changed files with 118 additions and 42 deletions

View File

@ -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>"/>
<none_fabric name="<string>" file="<string>">
<pb name="<string>" type="<string>" content="<string>"/>
</none_fabric>
</openfpga_bitstream_setting>
pb_type-related Settings
@ -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>"
@ -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.
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="<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
<none_fabric name="bram" file="bram_bitstream.json">
<pb name=".bram_lr[mem_36K_tdp].mem_36K" content=".param INIT_i"/>
</none_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``.

View File

@ -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));
}
}
/************************************************************************

View File

@ -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(

View File

@ -77,7 +77,8 @@ static void read_xml_bitstream_interconnect_setting(
}
/********************************************************************
* Parse XML description for a none_fabric annotation under a <none_fabric> XML node
* Parse XML description for a none_fabric annotation under a <none_fabric> 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);
}
}

View File

@ -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");