diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst
index 764bf0c87..eb2af5ddf 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.
+
+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=""
+
+ 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 c04eeba87..7d763f9d2 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::non_fabric() const {
+ return non_fabric_;
+}
+
/************************************************************************
* Public Mutators
***********************************************************************/
@@ -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
***********************************************************************/
diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h
index 7963942a0..1b12c8de3 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 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 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 non_fabric() const;
public: /* Public Mutators */
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
@@ -92,6 +117,9 @@ class BitstreamSetting {
const std::vector& 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;
@@ -133,6 +161,7 @@ class BitstreamSetting {
interconnect_parent_mode_names_;
vtr::vector
interconnect_default_paths_;
+ 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 7447bec2a..7f6bd1237 100644
--- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
+++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
@@ -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 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 to an object
*******************************************************************/
@@ -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);
}
}
diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h
index 8821c8392..c132e907f 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_non_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_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;
}
diff --git a/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp
new file mode 100644
index 000000000..3793c1b3d
--- /dev/null
+++ b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.cpp
@@ -0,0 +1,283 @@
+/********************************************************************
+ * 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_non_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 {
+
+#define PRINT_LAYOUT_NAME "__layout__"
+
+/********************************************************************
+ * 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 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;
+ 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_non_fabric_bitstream(
+ std::fstream& fp, const VprContext& vpr_ctx,
+ const ClusterBlockId& cluster_block_id, const t_pb_type* target_pb_type,
+ const NonFabricBitstreamPBSetting 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_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();
+ const PlacementContext& placement_ctx = vpr_ctx.placement();
+ const DeviceGrid& grids = device_ctx.grid;
+ const size_t& layer = 0;
+
+ // Loop logic block one by one
+ 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) {
+ 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 == 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;
+ }
+
+ // 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_non_fabric_bitstream(fp, vpr_ctx, cluster_blk_id,
+ target_pb_type, setting);
+ fp << "\n }";
+ grid_count++;
+ }
+ }
+ }
+ if (target_parent_pb_name == PRINT_LAYOUT_NAME) {
+ fp << "\n";
+ } else {
+ 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 non-fabric bitstream setting
+ *******************************************************************/
+void extract_device_non_fabric_bitstream(const VprContext& vpr_ctx,
+ const OpenfpgaContext& openfpga_ctx,
+ const bool& verbose) {
+ std::string timer_message =
+ 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 non_fabric_setting =
+ bitstream_setting.non_fabric();
+
+ // Only proceed if it is defined in bitstream_setting.xml
+ 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_non_fabric_pb_bitstream(
+ fp, NonFabricBitstreamPBSetting{}, setting.name, nullptr, vpr_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_non_fabric_pb_bitstream(fp, pb_setting, setting.name,
+ target_pb_type, vpr_ctx);
+ }
+ fp << "\n }";
+ pb_count++;
+ }
+ if (pb_count) {
+ fp << "\n";
+ }
+ }
+ fp << " ]\n";
+ fp << "}\n";
+ fp.close();
+ }
+ }
+ VTR_LOGV(verbose, "Done\n");
+}
+
+} /* end namespace openfpga */
diff --git a/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h
new file mode 100644
index 000000000..658c40b96
--- /dev/null
+++ b/openfpga/src/fpga_bitstream/extract_device_non_fabric_bitstream.h
@@ -0,0 +1,25 @@
+#ifndef EXTRACT_DEVICE_NON_FABRIC_BITSTREAM_H
+#define EXTRACT_DEVICE_NON_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_non_fabric_bitstream(const VprContext& vpr_ctx,
+ const OpenfpgaContext& openfpga_ctx,
+ const bool& verbose);
+
+} /* end namespace openfpga */
+
+#endif
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 184eceee9..8d46be27f 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 000000000..7c835ad7e
--- /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 000000000..908678571
--- /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=