Use Bitstream Setting XML

This commit is contained in:
chungshien-chai 2024-07-26 01:36:49 -07:00
parent 2ef362d53d
commit e60777d23e
13 changed files with 143 additions and 311 deletions

View File

@ -106,6 +106,10 @@ std::vector<NonFabricBitstreamSetting> BitstreamSetting::non_fabric() const {
return non_fabric_; return non_fabric_;
} }
std::vector<PathBitSetting> BitstreamSetting::path_bit_settings() const {
return path_bit_settings_;
}
/************************************************************************ /************************************************************************
* Public Mutators * Public Mutators
***********************************************************************/ ***********************************************************************/
@ -178,6 +182,12 @@ void BitstreamSetting::add_non_fabric_pb(const std::string& pb,
} }
} }
void BitstreamSetting::add_path_bit_setting(const std::string& path,
const bool value) {
VTR_ASSERT(path.size());
path_bit_settings_.push_back(PathBitSetting(path, value));
}
/************************************************************************ /************************************************************************
* Public Validators * Public Validators
***********************************************************************/ ***********************************************************************/

View File

@ -37,6 +37,12 @@ struct NonFabricBitstreamSetting {
std::vector<NonFabricBitstreamPBSetting> pbs; std::vector<NonFabricBitstreamPBSetting> pbs;
}; };
struct PathBitSetting {
PathBitSetting(const std::string& p, bool v) : path(p), value(v) {}
const std::string path = "";
const bool value = false;
};
/******************************************************************** /********************************************************************
* A data structure to describe bitstream settings * A data structure to describe bitstream settings
* *
@ -98,6 +104,7 @@ class BitstreamSetting {
std::string default_path( std::string default_path(
const BitstreamInterconnectSettingId& interconnect_setting_id) const; const BitstreamInterconnectSettingId& interconnect_setting_id) const;
std::vector<NonFabricBitstreamSetting> non_fabric() const; std::vector<NonFabricBitstreamSetting> non_fabric() const;
std::vector<PathBitSetting> path_bit_settings() const;
public: /* Public Mutators */ public: /* Public Mutators */
BitstreamPbTypeSettingId add_bitstream_pb_type_setting( BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
@ -120,6 +127,8 @@ class BitstreamSetting {
void add_non_fabric(const std::string& name, const std::string& file); 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); void add_non_fabric_pb(const std::string& pb, const std::string& content);
void add_path_bit_setting(const std::string& path, const bool value);
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;
@ -162,6 +171,7 @@ class BitstreamSetting {
vtr::vector<BitstreamInterconnectSettingId, std::string> vtr::vector<BitstreamInterconnectSettingId, std::string>
interconnect_default_paths_; interconnect_default_paths_;
std::vector<NonFabricBitstreamSetting> non_fabric_; std::vector<NonFabricBitstreamSetting> non_fabric_;
std::vector<PathBitSetting> path_bit_settings_;
}; };
} // namespace openfpga } // namespace openfpga

View File

@ -102,6 +102,21 @@ static void read_xml_non_fabric_bitstream_setting(
} }
} }
/********************************************************************
* Parse XML description for a bit setting under a <bit> XML node
*******************************************************************/
static void read_xml_bit_setting(
pugi::xml_node& xml_bit, const pugiutil::loc_data& loc_data,
openfpga::BitstreamSetting& bitstream_setting) {
const std::string& path_attr =
get_attribute(xml_bit, "path", loc_data).as_string();
const std::string& value_attr =
get_attribute(xml_bit, "value", loc_data).as_string();
VTR_ASSERT_SAFE(value_attr == "0" || value_attr == "1");
/* Add to bit */
bitstream_setting.add_path_bit_setting(path_attr, value_attr == "1");
}
/******************************************************************** /********************************************************************
* Parse XML codes about <openfpga_bitstream_setting> to an object * Parse XML codes about <openfpga_bitstream_setting> to an object
*******************************************************************/ *******************************************************************/
@ -116,9 +131,10 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(
/* 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")) &&
(xml_child.name() != std::string("non_fabric"))) { (xml_child.name() != std::string("non_fabric")) &&
(xml_child.name() != std::string("bit"))) {
bad_tag(xml_child, loc_data, Node, bad_tag(xml_child, loc_data, Node,
{"pb_type | interconnect | non_fabric"}); {"pb_type | interconnect | non_fabric | bit"});
} }
if (xml_child.name() == std::string("pb_type")) { if (xml_child.name() == std::string("pb_type")) {
@ -127,10 +143,12 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(
} else if (xml_child.name() == std::string("interconnect")) { } else if (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 { } else if (xml_child.name() == std::string("non_fabric")) {
VTR_ASSERT_SAFE(xml_child.name() == std::string("non_fabric"));
read_xml_non_fabric_bitstream_setting(xml_child, loc_data, read_xml_non_fabric_bitstream_setting(xml_child, loc_data,
bitstream_setting); bitstream_setting);
} else {
VTR_ASSERT_SAFE(xml_child.name() == std::string("bit"));
read_xml_bit_setting(xml_child, loc_data, bitstream_setting);
} }
} }

View File

@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include "bitstream_manager_utils.h"
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
@ -296,6 +297,44 @@ void BitstreamManager::add_output_net_id_to_block(
block_output_net_ids_[block] = output_net_id; block_output_net_ids_[block] = output_net_id;
} }
void BitstreamManager::set_path_bit(const std::string& path, const bool value) {
ConfigBlockId block;
std::vector<std::string> blocks =
reverse_split_bit_path_to_blocks((std::string)(path));
std::string block_name = "";
bool match = false;
for (size_t i = 0; i < bit_values_.size() && !match; i++) {
block = bit_parent_blocks_[ConfigBitId(i)];
if (size_t(block) < num_blocks_) {
size_t index = find_bitstream_manager_config_bit_index_in_parent_block(
*this, ConfigBitId(i));
block_name = block_names_[block] + ("[" + std::to_string(index) + "]");
if (block_name == blocks[0]) {
match = true;
for (size_t b = 1; b < blocks.size() && match; b++) {
valid_block_id(block);
block = parent_block_ids_[block];
if (size_t(block) < num_blocks_) {
if (block_names_[block] != blocks[b]) {
match = false;
}
} else {
match = false;
}
}
if (match) {
valid_block_id(block);
if (parent_block_ids_[block] == ConfigBlockId::INVALID()) {
bit_values_[ConfigBitId(i)] = value ? '1' : '0';
} else {
match = false;
}
}
}
}
}
}
/****************************************************************************** /******************************************************************************
* Public Validators * Public Validators
******************************************************************************/ ******************************************************************************/

View File

@ -213,6 +213,9 @@ class BitstreamManager {
void add_output_net_id_to_block(const ConfigBlockId& block, void add_output_net_id_to_block(const ConfigBlockId& block,
const std::string& output_net_id); const std::string& output_net_id);
/* Set bit to the bitstream at the given path */
void set_path_bit(const std::string& path, const bool value);
public: /* Public Validators */ public: /* Public Validators */
bool valid_bit_id(const ConfigBitId& bit_id) const; bool valid_bit_id(const ConfigBitId& bit_id) const;

View File

@ -130,4 +130,21 @@ size_t rec_find_bitstream_manager_block_sum_of_bits(
return sum_of_bits; return sum_of_bits;
} }
/********************************************************************
* Split the bit path with delimiter ".". The blocks is reversed
*******************************************************************/
std::vector<std::string> reverse_split_bit_path_to_blocks(std::string path) {
std::vector<std::string> blocks;
size_t index = path.find_first_of(".");
while (index != std::string::npos) {
blocks.insert(blocks.begin(), path.substr(0, index));
path = path.substr(index + 1);
index = path.find_first_of(".");
}
if (path.size()) {
blocks.insert(blocks.begin(), path);
}
return blocks;
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -31,6 +31,8 @@ size_t find_bitstream_manager_config_bit_index_in_grandparent_block(
size_t rec_find_bitstream_manager_block_sum_of_bits( size_t rec_find_bitstream_manager_block_sum_of_bits(
const BitstreamManager& bitstream_manager, const ConfigBlockId& block); const BitstreamManager& bitstream_manager, const ConfigBlockId& block);
std::vector<std::string> reverse_split_bit_path_to_blocks(std::string path);
} /* end namespace openfpga */ } /* end namespace openfpga */
#endif #endif

View File

@ -78,12 +78,6 @@ ShellCommandId add_build_arch_bitstream_command_template(
shell_cmd.add_option("no_time_stamp", false, shell_cmd.add_option("no_time_stamp", false,
"Do not print time stamp in output files"); "Do not print time stamp in output files");
/* Add an option '--overwrite_bitstream_file' */
CommandOptionId opt_overwrite_file =
shell_cmd.add_option("overwrite_bitstream_file", false,
"file path to read to overwrite bitstream bits");
shell_cmd.set_option_require_value(opt_overwrite_file, openfpga::OPT_STRING);
/* Add an option '--verbose' */ /* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output"); shell_cmd.add_option("verbose", false, "Enable verbose output");

View File

@ -38,17 +38,13 @@ int fpga_bitstream_template(T& openfpga_ctx, const Command& cmd,
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
CommandOptionId opt_write_file = cmd.option("write_file"); CommandOptionId opt_write_file = cmd.option("write_file");
CommandOptionId opt_read_file = cmd.option("read_file"); CommandOptionId opt_read_file = cmd.option("read_file");
CommandOptionId opt_overwrite_bitstream_file =
cmd.option("overwrite_bitstream_file");
if (true == cmd_context.option_enable(cmd, opt_read_file)) { if (true == cmd_context.option_enable(cmd, opt_read_file)) {
openfpga_ctx.mutable_bitstream_manager() = read_xml_architecture_bitstream( openfpga_ctx.mutable_bitstream_manager() = read_xml_architecture_bitstream(
cmd_context.option_value(cmd, opt_read_file).c_str()); cmd_context.option_value(cmd, opt_read_file).c_str());
} else { } else {
openfpga_ctx.mutable_bitstream_manager() = build_device_bitstream( openfpga_ctx.mutable_bitstream_manager() = build_device_bitstream(
g_vpr_ctx, openfpga_ctx, g_vpr_ctx, openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose));
cmd_context.option_value(cmd, opt_overwrite_bitstream_file),
cmd_context.option_enable(cmd, opt_verbose));
} }
if (true == cmd_context.option_enable(cmd, opt_write_file)) { if (true == cmd_context.option_enable(cmd, opt_write_file)) {

View File

@ -147,9 +147,9 @@ static size_t rec_estimate_device_bitstream_num_bits(
* of the FPGA fabric that FPGA-X2P generates! * of the FPGA fabric that FPGA-X2P generates!
* But it can be used to output a generic bitstream for VPR mapping FPGA * But it can be used to output a generic bitstream for VPR mapping FPGA
*******************************************************************/ *******************************************************************/
BitstreamManager build_device_bitstream( BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
const VprContext& vpr_ctx, const OpenfpgaContext& openfpga_ctx, const OpenfpgaContext& openfpga_ctx,
const std::string& overwrite_bitstream_file, const bool& verbose) { const bool& verbose) {
std::string timer_message = std::string timer_message =
std::string("\nBuild fabric-independent bitstream for implementation '") + std::string("\nBuild fabric-independent bitstream for implementation '") +
vpr_ctx.atom().nlist.netlist_name() + std::string("'\n"); vpr_ctx.atom().nlist.netlist_name() + std::string("'\n");
@ -218,7 +218,7 @@ BitstreamManager build_device_bitstream(
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.vpr_clustering_annotation(), openfpga_ctx.vpr_clustering_annotation(),
openfpga_ctx.vpr_placement_annotation(), openfpga_ctx.vpr_placement_annotation(),
openfpga_ctx.vpr_bitstream_annotation(), overwrite_bitstream_file, verbose); openfpga_ctx.vpr_bitstream_annotation(), verbose);
VTR_LOGV(verbose, "Done\n"); VTR_LOGV(verbose, "Done\n");
/* Create bitstream from routing architectures */ /* Create bitstream from routing architectures */
@ -230,6 +230,12 @@ BitstreamManager build_device_bitstream(
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(),
vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(), vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(),
openfpga_ctx.flow_manager().compress_routing(), verbose); openfpga_ctx.flow_manager().compress_routing(), verbose);
/* Apply path bit value */
for (auto bit : openfpga_ctx.bitstream_setting().path_bit_settings()) {
bitstream_manager.set_path_bit(bit.path, bit.value);
}
VTR_LOGV(verbose, "Done\n"); VTR_LOGV(verbose, "Done\n");
VTR_LOGV(verbose, "Decoded %lu configuration bits into %lu blocks\n", VTR_LOGV(verbose, "Decoded %lu configuration bits into %lu blocks\n",

View File

@ -16,9 +16,9 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
BitstreamManager build_device_bitstream( BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
const VprContext& vpr_ctx, const OpenfpgaContext& openfpga_ctx, const OpenfpgaContext& openfpga_ctx,
const std::string& overwrite_bitstream_file, const bool& verbose); const bool& verbose);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -3,7 +3,6 @@
* for grids (CLBs, heterogenerous blocks, I/Os, etc.) * for grids (CLBs, heterogenerous blocks, I/Os, etc.)
*******************************************************************/ *******************************************************************/
#include <cmath> #include <cmath>
#include <fstream>
#include <string> #include <string>
/* Headers from vtrutil library */ /* Headers from vtrutil library */
@ -30,242 +29,6 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
struct OVERWRITE_BITS {
OVERWRITE_BITS(bool i, int s, int e, uint64_t b)
: incr(i), start(s), end(e), bits(b) {}
bool incr = true;
int start = -1;
int end = -1;
uint64_t bits = 0;
};
std::string M_TOP_NAME = "";
std::string M_BLOCK_GRID_NAME = "";
std::map<std::string, std::map<std::string, std::vector<OVERWRITE_BITS>>*>
M_OVERWRITE_GRID_BITS;
std::map<std::string, std::vector<OVERWRITE_BITS>>* M_OVERWRITE_BITS = nullptr;
/********************************************************************
* Track the fabric top name
*******************************************************************/
static void track_fabric_top_name(const std::string& top) {
VTR_ASSERT(top.size());
M_TOP_NAME = top;
}
/********************************************************************
* Track the fabric grid name
*******************************************************************/
static void track_physical_block_grid(const std::string& block) {
VTR_ASSERT(M_TOP_NAME.size());
VTR_ASSERT(block.size());
M_BLOCK_GRID_NAME = M_TOP_NAME + std::string(".") + block;
if (M_OVERWRITE_GRID_BITS.find(M_BLOCK_GRID_NAME) !=
M_OVERWRITE_GRID_BITS.end()) {
M_OVERWRITE_BITS = M_OVERWRITE_GRID_BITS[M_BLOCK_GRID_NAME];
} else {
M_OVERWRITE_BITS = nullptr;
}
}
/********************************************************************
* Trim whitespace
*******************************************************************/
static void trim_white_space(std::string& line) {
const auto begin = line.find_first_not_of(" \t\r\n");
if (begin != std::string::npos) {
const auto end = line.find_last_not_of(" \t\r\n");
const auto count = end - begin + 1;
line = line.substr(begin, count);
}
}
/********************************************************************
* Split the line by delimiter
*******************************************************************/
static std::vector<std::string> split_line_by(
std::string line, const std::string& delimiter = " \t") {
std::vector<std::string> results;
size_t index = line.find_first_of(delimiter);
trim_white_space(line);
while (index != std::string::npos) {
std::string result = line.substr(0, index);
trim_white_space(result);
results.push_back(result);
line = line.substr(index + 1);
trim_white_space(line);
index = line.find_first_of(delimiter);
}
if (line.size()) {
results.push_back(line);
}
return results;
}
/********************************************************************
* Check if the string is all number
*******************************************************************/
static bool is_number(const std::string& s) {
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
/********************************************************************
* Convert string to uint64_t
*******************************************************************/
static uint64_t get_number(const std::string& s) {
uint64_t value = 0;
std::istringstream iss(s);
iss >> value;
return value;
}
/********************************************************************
* Cleanup
*******************************************************************/
static void cleanup_overwrite() {
for (auto& iter : M_OVERWRITE_GRID_BITS) {
delete iter.second;
}
M_OVERWRITE_GRID_BITS.clear();
M_OVERWRITE_BITS = nullptr;
}
/********************************************************************
* Read the overwrite file
*******************************************************************/
static void read_overwrite_file(const std::string& filepath) {
cleanup_overwrite();
if (filepath.size()) {
std::ifstream file(filepath.c_str());
if (file.is_open()) {
if (file.good()) {
std::string line = "";
while (std::getline(file, line)) {
trim_white_space(line);
if (line.size() && line[0] != '#') {
std::vector<std::string> words = split_line_by(line);
if (words.size() >= 3 && words[0].size() > 0 &&
words[1].size() > 0) {
// Prepare the pointer to fillup path and bits (speedup stuff)
M_OVERWRITE_BITS = nullptr;
if (M_OVERWRITE_GRID_BITS.find(words[0]) !=
M_OVERWRITE_GRID_BITS.end()) {
M_OVERWRITE_BITS = M_OVERWRITE_GRID_BITS.at(words[0]);
}
std::string path = std::string(".") + words[1];
for (size_t i = 2; i < words.size(); i++) {
std::vector<std::string> values = split_line_by(words[i], "=");
bool incr = true;
int start = -1;
int end = -1;
uint64_t value = 0;
if (values.size() == 1) {
if (is_number(values[0])) {
value = get_number(values[0]);
} else {
// Bad
continue;
}
} else if (values.size() == 2) {
if (values[0].size() >= 3 && values[0][0] == '[' &&
values[0][values[0].size() - 1] == ']') {
line = values[0].substr(1, values[0].size() - 2);
trim_white_space(line);
std::vector<std::string> range = split_line_by(line, ":");
if (range.size() == 1 && is_number(range[0])) {
start = get_number(range[0]);
end = start;
} else if (range.size() == 2 && is_number(range[0]) &&
is_number(range[1])) {
end = (int)(get_number(range[0]));
start = (int)(get_number(range[1]));
incr = end >= start;
} else {
// Bad
continue;
}
if (is_number(values[1])) {
value = get_number(values[1]);
} else {
// Bad
continue;
}
} else {
// Bad
continue;
}
} else {
// Bad
continue;
}
if ((start == -1 && end == -1) || (start >= 0 && end >= 0)) {
if (M_OVERWRITE_BITS == nullptr) {
M_OVERWRITE_BITS =
new std::map<std::string, std::vector<OVERWRITE_BITS>>;
M_OVERWRITE_GRID_BITS[words[0]] = M_OVERWRITE_BITS;
}
if (M_OVERWRITE_BITS->find(path) == M_OVERWRITE_BITS->end()) {
(*M_OVERWRITE_BITS)[path] = {};
}
M_OVERWRITE_BITS->at(path).push_back(
OVERWRITE_BITS(incr, start, end, value));
}
}
}
}
}
}
file.close();
}
}
M_OVERWRITE_BITS = nullptr;
}
/********************************************************************
* Overwrite the bits
*******************************************************************/
static void overwrite_bits(const std::string& path, std::vector<bool>& bits) {
VTR_ASSERT(M_OVERWRITE_BITS != nullptr);
if (M_OVERWRITE_BITS->find(path) != M_OVERWRITE_BITS->end()) {
for (OVERWRITE_BITS& obits : M_OVERWRITE_BITS->at(path)) {
if (obits.start == -1 && obits.end == -1) {
for (int i = 0; i < int(bits.size()); i++) {
if (obits.bits & (1 << i)) {
bits[i] = true;
} else {
bits[i] = false;
}
}
} else {
int i = 0;
int start = obits.start;
while (true) {
if (start >= 0 && start < int(bits.size())) {
if (obits.bits & (1 << i)) {
bits[start] = true;
} else {
bits[start] = false;
}
} else {
break;
}
if (start == obits.end) {
break;
}
i++;
if (obits.incr) {
start++;
} else {
start--;
}
}
}
}
}
}
/******************************************************************** /********************************************************************
* Decode mode bits "01..." to a bitstream vector * Decode mode bits "01..." to a bitstream vector
*******************************************************************/ *******************************************************************/
@ -292,7 +55,7 @@ static void build_primitive_bitstream(
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const VprDeviceAnnotation& device_annotation, const PhysicalPb& physical_pb, const VprDeviceAnnotation& device_annotation, const PhysicalPb& physical_pb,
const PhysicalPbId& primitive_pb_id, t_pb_type* primitive_pb_type, const PhysicalPbId& primitive_pb_id, t_pb_type* primitive_pb_type,
std::string config_instance_path, const bool& verbose) { const bool& verbose) {
/* Ensure a valid physical pritimive pb */ /* Ensure a valid physical pritimive pb */
if (nullptr == primitive_pb_type) { if (nullptr == primitive_pb_type) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid primitive_pb_type!\n"); VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid primitive_pb_type!\n");
@ -399,11 +162,6 @@ static void build_primitive_bitstream(
bitstream_manager.block_name(parent_configurable_block).c_str()); bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bitstream to the bitstream manager */ /* Add the bitstream to the bitstream manager */
if (M_OVERWRITE_BITS != nullptr) {
std::string path = config_instance_path + std::string(".") +
bitstream_manager.block_name(mem_block);
overwrite_bits(path, mode_select_bitstream);
}
bitstream_manager.add_block_bits(mem_block, mode_select_bitstream); bitstream_manager.add_block_bits(mem_block, mode_select_bitstream);
} }
@ -427,8 +185,7 @@ static void build_physical_block_pin_interc_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const VprBitstreamAnnotation& bitstream_annotation,
const PhysicalPb& physical_pb, t_pb_graph_pin* des_pb_graph_pin, const PhysicalPb& physical_pb, t_pb_graph_pin* des_pb_graph_pin,
t_mode* physical_mode, std::string config_instance_path, t_mode* physical_mode, const bool& verbose) {
const bool& verbose) {
/* Identify the number of fan-in (Consider interconnection edges of only /* Identify the number of fan-in (Consider interconnection edges of only
* selected mode) */ * selected mode) */
t_interconnect* cur_interc = t_interconnect* cur_interc =
@ -572,11 +329,6 @@ static void build_physical_block_pin_interc_bitstream(
bitstream_manager.block_name(parent_configurable_block).c_str()); bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bistream to the bitstream manager */ /* Add the bistream to the bitstream manager */
if (M_OVERWRITE_BITS != nullptr) {
std::string path = config_instance_path + std::string(".") +
bitstream_manager.block_name(mux_mem_block);
overwrite_bits(path, mux_bitstream);
}
bitstream_manager.add_block_bits(mux_mem_block, mux_bitstream); bitstream_manager.add_block_bits(mux_mem_block, mux_bitstream);
/* Record path ids, input and output nets */ /* Record path ids, input and output nets */
bitstream_manager.add_path_id_to_block(mux_mem_block, mux_input_pin_id); bitstream_manager.add_path_id_to_block(mux_mem_block, mux_input_pin_id);
@ -633,7 +385,7 @@ static void build_physical_block_interc_port_bitstream(
const VprBitstreamAnnotation& bitstream_annotation, const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb, t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode, const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode,
std::string config_instance_path, const bool& verbose) { const bool& verbose) {
switch (pb_port_type) { switch (pb_port_type) {
case CIRCUIT_PB_PORT_INPUT: case CIRCUIT_PB_PORT_INPUT:
for (int iport = 0; iport < physical_pb_graph_node->num_input_ports; for (int iport = 0; iport < physical_pb_graph_node->num_input_ports;
@ -646,7 +398,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode, &(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode,
config_instance_path, verbose); verbose);
} }
} }
break; break;
@ -661,7 +413,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode, &(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode,
config_instance_path, verbose); verbose);
} }
} }
break; break;
@ -676,7 +428,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode, &(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode,
config_instance_path, verbose); verbose);
} }
} }
break; break;
@ -699,8 +451,7 @@ static void build_physical_block_interc_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb, t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
t_mode* physical_mode, std::string config_instance_path, t_mode* physical_mode, const bool& verbose) {
const bool& verbose) {
/* Check if the pb_graph node is valid or not */ /* Check if the pb_graph node is valid or not */
if (nullptr == physical_pb_graph_node) { if (nullptr == physical_pb_graph_node) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid physical_pb_graph_node.\n"); VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid physical_pb_graph_node.\n");
@ -721,8 +472,7 @@ static void build_physical_block_interc_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, parent_configurable_block, bitstream_manager, grouped_mem_inst_scoreboard, parent_configurable_block,
module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx, module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx,
device_annotation, bitstream_annotation, physical_pb_graph_node, device_annotation, bitstream_annotation, physical_pb_graph_node,
physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode, config_instance_path, physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode, verbose);
verbose);
/* We check input_pins of child_pb_graph_node and its the input_edges /* We check input_pins of child_pb_graph_node and its the input_edges
* Iterate over the interconnections between inputs of physical_pb_graph_node * Iterate over the interconnections between inputs of physical_pb_graph_node
@ -746,14 +496,14 @@ static void build_physical_block_interc_bitstream(
parent_configurable_block, module_manager, module_name_map, circuit_lib, parent_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode, child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode,
config_instance_path, verbose); verbose);
/* For clock pins, we should do the same work */ /* For clock pins, we should do the same work */
build_physical_block_interc_port_bitstream( build_physical_block_interc_port_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, module_name_map, circuit_lib, parent_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode, child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode,
config_instance_path, verbose); verbose);
} }
} }
} }
@ -769,8 +519,7 @@ static void build_lut_bitstream(
const VprDeviceAnnotation& device_annotation, const VprDeviceAnnotation& device_annotation,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const PhysicalPb& physical_pb, const MuxLibrary& mux_lib, const PhysicalPb& physical_pb,
const PhysicalPbId& lut_pb_id, t_pb_type* lut_pb_type, const PhysicalPbId& lut_pb_id, t_pb_type* lut_pb_type, const bool& verbose) {
std::string config_instance_path, const bool& verbose) {
/* Ensure a valid physical pritimive pb */ /* Ensure a valid physical pritimive pb */
if (nullptr == lut_pb_type) { if (nullptr == lut_pb_type) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid lut_pb_type!\n"); VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid lut_pb_type!\n");
@ -939,11 +688,6 @@ static void build_lut_bitstream(
bitstream_manager.block_name(parent_configurable_block).c_str()); bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bitstream to the bitstream manager */ /* Add the bitstream to the bitstream manager */
if (M_OVERWRITE_BITS != nullptr) {
std::string path = config_instance_path + std::string(".") +
bitstream_manager.block_name(mem_block);
overwrite_bits(path, lut_bitstream);
}
bitstream_manager.add_block_bits(mem_block, lut_bitstream); bitstream_manager.add_block_bits(mem_block, lut_bitstream);
} }
@ -968,7 +712,7 @@ static void rec_build_physical_block_bitstream(
const VprBitstreamAnnotation& bitstream_annotation, const e_side& border_side, const VprBitstreamAnnotation& bitstream_annotation, const e_side& border_side,
const PhysicalPb& physical_pb, const PhysicalPbId& pb_id, const PhysicalPb& physical_pb, const PhysicalPbId& pb_id,
t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index, t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index,
std::string config_instance_path, const bool& verbose) { const bool& verbose) {
/* Get the physical pb_type that is linked to the pb_graph node */ /* Get the physical pb_type that is linked to the pb_graph node */
t_pb_type* physical_pb_type = physical_pb_graph_node->pb_type; t_pb_type* physical_pb_type = physical_pb_graph_node->pb_type;
@ -992,7 +736,6 @@ static void rec_build_physical_block_bitstream(
* manager */ * manager */
std::string pb_block_name = generate_physical_block_instance_name( std::string pb_block_name = generate_physical_block_instance_name(
physical_pb_type, pb_graph_node_index); physical_pb_type, pb_graph_node_index);
config_instance_path += (std::string(".") + pb_block_name);
/* If there are no physical memory blocks under the current module, use the /* If there are no physical memory blocks under the current module, use the
* previous module, which is the physical memory block */ * previous module, which is the physical memory block */
ConfigBlockId pb_configurable_block = parent_configurable_block; ConfigBlockId pb_configurable_block = parent_configurable_block;
@ -1030,7 +773,7 @@ static void rec_build_physical_block_bitstream(
child_pb, child_pb,
&(physical_pb_graph_node &(physical_pb_graph_node
->child_pb_graph_nodes[physical_mode->index][ipb][jpb]), ->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
jpb, config_instance_path, verbose); jpb, verbose);
} }
} }
} }
@ -1045,10 +788,10 @@ static void rec_build_physical_block_bitstream(
/* Special case for LUT !!! /* Special case for LUT !!!
* Mapped logical block information is stored in child_pbs of this pb!!! * Mapped logical block information is stored in child_pbs of this pb!!!
*/ */
build_lut_bitstream( build_lut_bitstream(bitstream_manager, grouped_mem_inst_scoreboard,
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block, pb_configurable_block, device_annotation,
device_annotation, module_manager, circuit_lib, mux_lib, physical_pb, module_manager, circuit_lib, mux_lib, physical_pb,
pb_id, physical_pb_type, config_instance_path, verbose); pb_id, physical_pb_type, verbose);
break; break;
case CIRCUIT_MODEL_FF: case CIRCUIT_MODEL_FF:
case CIRCUIT_MODEL_HARDLOGIC: case CIRCUIT_MODEL_HARDLOGIC:
@ -1057,7 +800,7 @@ static void rec_build_physical_block_bitstream(
build_primitive_bitstream( build_primitive_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block, bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, circuit_lib, device_annotation, physical_pb, pb_id, module_manager, circuit_lib, device_annotation, physical_pb, pb_id,
physical_pb_type, config_instance_path, verbose); physical_pb_type, verbose);
break; break;
default: default:
VTR_LOGF_ERROR(__FILE__, __LINE__, VTR_LOGF_ERROR(__FILE__, __LINE__,
@ -1074,7 +817,7 @@ static void rec_build_physical_block_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block, bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx, module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx,
device_annotation, bitstream_annotation, physical_pb_graph_node, device_annotation, bitstream_annotation, physical_pb_graph_node,
physical_pb, physical_mode, config_instance_path, verbose); physical_pb, physical_mode, verbose);
} }
/******************************************************************** /********************************************************************
@ -1123,7 +866,7 @@ static void build_physical_block_bitstream(
std::string grid_block_name = generate_grid_block_instance_name( std::string grid_block_name = generate_grid_block_instance_name(
grid_module_name_prefix, std::string(grid_type->name), grid_module_name_prefix, std::string(grid_type->name),
is_io_type(grid_type), border_side, grid_coord_in_unique_tile); is_io_type(grid_type), border_side, grid_coord_in_unique_tile);
track_physical_block_grid(grid_block_name);
ConfigBlockId grid_configurable_block = ConfigBlockId grid_configurable_block =
bitstream_manager.add_block(grid_block_name); bitstream_manager.add_block(grid_block_name);
bitstream_manager.add_child_block(top_block, grid_configurable_block); bitstream_manager.add_child_block(top_block, grid_configurable_block);
@ -1188,7 +931,7 @@ static void build_physical_block_bitstream(
grid_configurable_block, module_manager, module_name_map, circuit_lib, grid_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
border_side, PhysicalPb(), PhysicalPbId::INVALID(), border_side, PhysicalPb(), PhysicalPbId::INVALID(),
lb_type->pb_graph_head, z, "", verbose); lb_type->pb_graph_head, z, verbose);
} else { } else {
const PhysicalPb& phy_pb = cluster_annotation.physical_pb( const PhysicalPb& phy_pb = cluster_annotation.physical_pb(
place_annotation.grid_blocks(grid_coord)[z]); place_annotation.grid_blocks(grid_coord)[z]);
@ -1203,7 +946,7 @@ static void build_physical_block_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, bitstream_manager, grouped_mem_inst_scoreboard,
grid_configurable_block, module_manager, module_name_map, circuit_lib, grid_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
border_side, phy_pb, top_pb_id, pb_graph_head, z, "", verbose); border_side, phy_pb, top_pb_id, pb_graph_head, z, verbose);
} }
} }
} }
@ -1223,13 +966,9 @@ void build_grid_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation, const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation, const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose) {
const std::string& overwrite_bitstream_file, const bool& verbose) {
VTR_LOGV(verbose, "Generating bitstream for core grids..."); VTR_LOGV(verbose, "Generating bitstream for core grids...");
/* Read file that might want to overwrite the bitstream */
read_overwrite_file(overwrite_bitstream_file);
/* Generate bitstream for the core logic block one by one */ /* Generate bitstream for the core logic block one by one */
for (size_t ix = 1; ix < grids.width() - 1; ++ix) { for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
for (size_t iy = 1; iy < grids.height() - 1; ++iy) { for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
@ -1263,7 +1002,7 @@ void build_grid_bitstream(
tile_inst_name.c_str(), tile_inst_name.c_str(),
bitstream_manager.block_name(top_block).c_str()); bitstream_manager.block_name(top_block).c_str());
} }
track_fabric_top_name(bitstream_manager.block_name(top_block));
build_physical_block_bitstream( build_physical_block_bitstream(
bitstream_manager, parent_block, module_manager, module_name_map, bitstream_manager, parent_block, module_manager, module_name_map,
fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx, fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx,
@ -1311,7 +1050,7 @@ void build_grid_bitstream(
tile_inst_name.c_str(), tile_inst_name.c_str(),
bitstream_manager.block_name(parent_block).c_str()); bitstream_manager.block_name(parent_block).c_str());
} }
track_fabric_top_name(bitstream_manager.block_name(top_block));
build_physical_block_bitstream( build_physical_block_bitstream(
bitstream_manager, parent_block, module_manager, module_name_map, bitstream_manager, parent_block, module_manager, module_name_map,
fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx, fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx,
@ -1319,7 +1058,6 @@ void build_grid_bitstream(
bitstream_annotation, grids, layer, io_coordinate, io_side, verbose); bitstream_annotation, grids, layer, io_coordinate, io_side, verbose);
} }
} }
cleanup_overwrite();
VTR_LOGV(verbose, "Done\n"); VTR_LOGV(verbose, "Done\n");
} }

View File

@ -34,8 +34,7 @@ void build_grid_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation, const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation, const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose);
const std::string& overwrite_bitstream_file, const bool& verbose);
} /* end namespace openfpga */ } /* end namespace openfpga */