BRAM preload data - generic way to extract data from design
This commit is contained in:
parent
de146c3f7f
commit
d909d5ac51
|
@ -102,6 +102,10 @@ std::string BitstreamSetting::default_path(
|
||||||
return interconnect_default_paths_[interconnect_setting_id];
|
return interconnect_default_paths_[interconnect_setting_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<NoneFabricBitstreamSetting> BitstreamSetting::none_fabric() const {
|
||||||
|
return none_fabric_;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Public Mutators
|
* Public Mutators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -154,6 +158,22 @@ BitstreamSetting::add_bitstream_interconnect_setting(
|
||||||
return interc_setting_id;
|
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
|
* Public Validators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* which are used by OpenFPGA
|
* which are used by OpenFPGA
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "bitstream_setting_fwd.h"
|
#include "bitstream_setting_fwd.h"
|
||||||
#include "vtr_vector.h"
|
#include "vtr_vector.h"
|
||||||
|
@ -13,6 +14,29 @@
|
||||||
/* namespace openfpga begins */
|
/* namespace openfpga begins */
|
||||||
namespace openfpga {
|
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<NoneFabricBitstreamPBSetting> pbs;
|
||||||
|
};
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* A data structure to describe bitstream settings
|
* A data structure to describe bitstream settings
|
||||||
*
|
*
|
||||||
|
@ -73,6 +97,7 @@ class BitstreamSetting {
|
||||||
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||||
std::string default_path(
|
std::string default_path(
|
||||||
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||||
|
std::vector<NoneFabricBitstreamSetting> none_fabric() const;
|
||||||
|
|
||||||
public: /* Public Mutators */
|
public: /* Public Mutators */
|
||||||
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
|
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
|
||||||
|
@ -92,6 +117,10 @@ class BitstreamSetting {
|
||||||
const std::vector<std::string>& parent_mode_names,
|
const std::vector<std::string>& parent_mode_names,
|
||||||
const std::string& default_path);
|
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 */
|
public: /* Public Validators */
|
||||||
bool valid_bitstream_pb_type_setting_id(
|
bool valid_bitstream_pb_type_setting_id(
|
||||||
const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||||
|
@ -133,6 +162,7 @@ class BitstreamSetting {
|
||||||
interconnect_parent_mode_names_;
|
interconnect_parent_mode_names_;
|
||||||
vtr::vector<BitstreamInterconnectSettingId, std::string>
|
vtr::vector<BitstreamInterconnectSettingId, std::string>
|
||||||
interconnect_default_paths_;
|
interconnect_default_paths_;
|
||||||
|
std::vector<NoneFabricBitstreamSetting> none_fabric_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace openfpga
|
} // namespace openfpga
|
||||||
|
|
|
@ -76,6 +76,33 @@ static void read_xml_bitstream_interconnect_setting(
|
||||||
operating_pb_parser.modes(), default_path_attr);
|
operating_pb_parser.modes(), default_path_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* 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,
|
||||||
|
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 <openfpga_bitstream_setting> to an object
|
* Parse XML codes about <openfpga_bitstream_setting> to an object
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
@ -89,17 +116,22 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(
|
||||||
for (pugi::xml_node xml_child : Node.children()) {
|
for (pugi::xml_node xml_child : Node.children()) {
|
||||||
/* Error out if the XML child has an invalid name! */
|
/* Error out if the XML child has an invalid name! */
|
||||||
if ((xml_child.name() != std::string("pb_type")) &&
|
if ((xml_child.name() != std::string("pb_type")) &&
|
||||||
(xml_child.name() != std::string("interconnect"))) {
|
(xml_child.name() != std::string("interconnect")) &&
|
||||||
bad_tag(xml_child, loc_data, Node, {"pb_type | 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")) {
|
if (xml_child.name() == std::string("pb_type")) {
|
||||||
read_xml_bitstream_pb_type_setting(xml_child, loc_data,
|
read_xml_bitstream_pb_type_setting(xml_child, loc_data,
|
||||||
bitstream_setting);
|
bitstream_setting);
|
||||||
} else {
|
} else if (xml_child.name() == std::string("interconnect")) {
|
||||||
VTR_ASSERT_SAFE(xml_child.name() == std::string("interconnect"));
|
|
||||||
read_xml_bitstream_interconnect_setting(xml_child, loc_data,
|
read_xml_bitstream_interconnect_setting(xml_child, loc_data,
|
||||||
bitstream_setting);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "command_context.h"
|
#include "command_context.h"
|
||||||
#include "command_exit_codes.h"
|
#include "command_exit_codes.h"
|
||||||
|
#include "extract_device_none_fabric_bitstream.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "openfpga_digest.h"
|
#include "openfpga_digest.h"
|
||||||
#include "openfpga_naming.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));
|
!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 */
|
/* TODO: should identify the error code from internal function execution */
|
||||||
return CMD_EXEC_SUCCESS;
|
return CMD_EXEC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/* 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<std::string> 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<NoneFabricBitstreamSetting> 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 */
|
|
@ -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 <vector>
|
||||||
|
|
||||||
|
#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
|
Loading…
Reference in New Issue