[Tool] Update FPGA core engine to support mux default path overloading through bitstream setting file

This commit is contained in:
tangxifan 2021-04-19 15:53:33 -06:00
parent 5364b94cf8
commit 0aec30bac6
8 changed files with 195 additions and 15 deletions

View File

@ -12,6 +12,9 @@
#include "vtr_assert.h"
#include "vtr_log.h"
/* Headers from openfpgautil library */
#include "openfpga_tokenizer.h"
#include "pb_type_utils.h"
#include "annotate_bitstream_setting.h"
@ -23,9 +26,10 @@ namespace openfpga {
* - Find the pb_type and link to the bitstream source
* - Find the pb_type and link to the bitstream content
*******************************************************************/
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
const DeviceContext& vpr_device_ctx,
VprBitstreamAnnotation& vpr_bitstream_annotation) {
static
int annotate_bitstream_pb_type_setting(const BitstreamSetting& bitstream_setting,
const DeviceContext& vpr_device_ctx,
VprBitstreamAnnotation& vpr_bitstream_annotation) {
for (const auto& bitstream_pb_type_setting_id : bitstream_setting.pb_type_settings()) {
/* Get the full name of pb_type */
@ -95,4 +99,135 @@ int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Annotate bitstream setting based on VPR device information
* - Find the interconnect and link to the default path id
*******************************************************************/
static
int annotate_bitstream_interconnect_setting(const BitstreamSetting& bitstream_setting,
const DeviceContext& vpr_device_ctx,
const VprDeviceAnnotation& vpr_device_annotation,
VprBitstreamAnnotation& vpr_bitstream_annotation) {
for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) {
/* Get the full name of pb_type */
std::vector<std::string> target_pb_type_names;
std::vector<std::string> target_pb_mode_names;
target_pb_type_names = bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id);
target_pb_mode_names = bitstream_setting.parent_mode_names(bitstream_interc_setting_id);
/* Kick out the last mode so that we can use an existing function search the pb_type in graph */
std::string expected_physical_mode_name = target_pb_mode_names.back();
target_pb_mode_names.pop_back();
std::string interconnect_name = bitstream_setting.interconnect_name(bitstream_interc_setting_id);
std::string expected_input_path = bitstream_setting.default_path(bitstream_interc_setting_id);
/* Pb type information are located at the logic_block_types in the device context of VPR
* We iterate over the vectors and find the pb_type matches the parent_pb_type_name
*/
bool link_success = false;
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
/* By pass 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 (target_pb_type_names[0] != 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 */
t_pb_type* target_pb_type = try_find_pb_type_with_given_path(lb_type.pb_type, target_pb_type_names,
target_pb_mode_names);
if (nullptr == target_pb_type) {
continue;
}
/* Found one, build annotation */
t_mode* physical_mode = vpr_device_annotation.physical_mode(target_pb_type);
VTR_ASSERT(nullptr != physical_mode);
/* Ensure that the annotation is only applicable to physical mode */
if (std::string(physical_mode->name) != expected_physical_mode_name) {
VTR_LOG_ERROR("The physical mode '%s' under pb_type '%s' does not match in the bitstream setting '%s'!\n",
physical_mode->name,
target_pb_type->name,
expected_physical_mode_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Find the interconnect name under the physical mode of a physical pb_type */
t_interconnect* pb_interc = find_pb_mode_interconnect(physical_mode, interconnect_name.c_str());
if (nullptr == pb_interc) {
VTR_LOG_ERROR("Unable to find interconnect '%s' under physical mode '%s' of pb_type '%s'!\n",
interconnect_name.c_str(),
physical_mode->name,
target_pb_type->name);
return CMD_EXEC_FATAL_ERROR;
}
/* Find the default path and spot the path id from the input string recorded */
StringToken input_string_tokenizer(std::string(pb_interc->input_string));
std::vector<std::string> input_paths = input_string_tokenizer.split(' ');
size_t input_path_id = input_paths.size();
for (size_t ipath = 0; ipath < input_paths.size(); ++ipath) {
if (expected_input_path == input_paths[ipath]) {
input_path_id = ipath;
break;
}
}
/* If the input_path id is invalid, error out! */
if (input_path_id == input_paths.size()) {
VTR_LOG_ERROR("Invalid default path '%s' for interconnect '%s' which inputs are '%s'\n",
expected_input_path.c_str(),
interconnect_name.c_str(),
pb_interc->input_string);
return CMD_EXEC_FATAL_ERROR;
}
vpr_bitstream_annotation.set_interconnect_default_path_id(pb_interc, input_path_id);
link_success = true;
}
/* If fail to link bitstream setting to architecture, error out immediately */
if (false == link_success) {
VTR_LOG_ERROR("Fail to find an interconnect '%s' with default path '%s', which is defined in bitstream setting from VPR architecture description\n",
interconnect_name.c_str(),
expected_input_path.c_str());
return CMD_EXEC_FATAL_ERROR;
}
}
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Annotate bitstream setting based on VPR device information
* - Fill pb_type -related mapping
* - Fill interconnect -related mapping
*******************************************************************/
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
const DeviceContext& vpr_device_ctx,
const VprDeviceAnnotation& vpr_device_annotation,
VprBitstreamAnnotation& vpr_bitstream_annotation) {
int status = CMD_EXEC_SUCCESS;
status = annotate_bitstream_pb_type_setting(bitstream_setting,
vpr_device_ctx,
vpr_bitstream_annotation);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}
status = annotate_bitstream_interconnect_setting(bitstream_setting,
vpr_device_ctx, vpr_device_annotation,
vpr_bitstream_annotation);
return status;
}
} /* end namespace openfpga */

View File

@ -16,6 +16,7 @@ namespace openfpga {
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
const DeviceContext& vpr_device_ctx,
const VprDeviceAnnotation& vpr_device_annotation,
VprBitstreamAnnotation& vpr_bitstream_annotation);
} /* end namespace openfpga */

View File

@ -4,6 +4,7 @@
#include "vtr_log.h"
#include "vtr_assert.h"
#include "vpr_bitstream_annotation.h"
#include "mux_bitstream_constants.h"
/* namespace openfpga begins */
namespace openfpga {
@ -78,6 +79,16 @@ size_t VprBitstreamAnnotation::pb_type_mode_select_bitstream_offset(t_pb_type* p
return 0;
}
size_t VprBitstreamAnnotation::interconnect_default_path_id(t_interconnect* interconnect) const {
auto result = interconnect_default_path_ids_.find(interconnect);
if (result != interconnect_default_path_ids_.end()) {
return result->second;
}
/* Not found, return an invalid input id */
return DEFAULT_PATH_ID;
}
/************************************************************************
* Public mutators
***********************************************************************/
@ -111,4 +122,9 @@ void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset(t_pb_type*
mode_select_bitstream_offsets_[pb_type] = offset;
}
void VprBitstreamAnnotation::set_interconnect_default_path_id(t_interconnect* interconnect,
const size_t& default_path_id) {
interconnect_default_path_ids_[interconnect] = default_path_id;
}
} /* End namespace openfpga*/

View File

@ -38,6 +38,7 @@ class VprBitstreamAnnotation {
e_bitstream_source_type pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const;
std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const;
size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const;
size_t interconnect_default_path_id(t_interconnect* interconnect) const;
public: /* Public mutators */
void set_pb_type_bitstream_source(t_pb_type* pb_type,
const e_bitstream_source_type& bitstream_source);
@ -52,6 +53,8 @@ class VprBitstreamAnnotation {
const std::string& bitstream_content);
void set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type,
const size_t& offset);
void set_interconnect_default_path_id(t_interconnect* interconnect,
const size_t& default_path_id);
private: /* Internal data */
/* For regular bitstreams */
/* A look up for pb type to find bitstream source type */
@ -68,6 +71,12 @@ class VprBitstreamAnnotation {
std::map<t_pb_type*, std::string> mode_select_bitstream_contents_;
/* Offset to be applied to mode-select bitstream */
std::map<t_pb_type*, size_t> mode_select_bitstream_offsets_;
/* A look up for interconnect to find default path indices
* Note: this is different from the default path in bitstream setting which is the index
* of inputs in the context of the interconnect input string
*/
std::map<t_interconnect*, size_t> interconnect_default_path_ids_;
};
} /* End namespace openfpga*/

View File

@ -177,7 +177,9 @@ int link_arch(OpenfpgaContext& openfpga_ctx,
/* Build bitstream annotation based on bitstream settings */
if (CMD_EXEC_FATAL_ERROR == annotate_bitstream_setting(openfpga_ctx.bitstream_setting(),
g_vpr_ctx.device(),
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.mutable_vpr_bitstream_annotation())) {
return CMD_EXEC_FATAL_ERROR;
}

View File

@ -189,6 +189,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.vpr_clustering_annotation(),
openfpga_ctx.vpr_placement_annotation(),
openfpga_ctx.vpr_bitstream_annotation(),
verbose);
VTR_LOGV(verbose, "Done\n");

View File

@ -129,6 +129,7 @@ void build_physical_block_pin_interc_bitstream(BitstreamManager& bitstream_manag
const MuxLibrary& mux_lib,
const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const PhysicalPb& physical_pb,
t_pb_graph_pin* des_pb_graph_pin,
t_mode* physical_mode) {
@ -197,6 +198,12 @@ void build_physical_block_pin_interc_bitstream(BitstreamManager& bitstream_manag
}
}
/* Overwrite the default path if defined in bitstream annotation */
if ( (size_t(DEFAULT_PATH_ID) == mux_input_pin_id)
&& (mux_input_pin_id != bitstream_annotation.interconnect_default_path_id(cur_interc)) ) {
mux_input_pin_id = bitstream_annotation.interconnect_default_path_id(cur_interc);
}
/* Generate bitstream depend on both technology and structure of this MUX */
std::vector<bool> mux_bitstream = build_mux_bitstream(circuit_lib, mux_model, mux_lib, datapath_mux_size, mux_input_pin_id);
@ -266,6 +273,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
const MuxLibrary& mux_lib,
const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node,
const PhysicalPb& physical_pb,
const e_circuit_pb_port_type& pb_port_type,
@ -276,7 +284,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
for (int ipin = 0; ipin < physical_pb_graph_node->num_input_pins[iport]; ++ipin) {
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
physical_pb,
&(physical_pb_graph_node->input_pins[iport][ipin]),
physical_mode);
@ -288,7 +296,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
for (int ipin = 0; ipin < physical_pb_graph_node->num_output_pins[iport]; ++ipin) {
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
physical_pb,
&(physical_pb_graph_node->output_pins[iport][ipin]),
physical_mode);
@ -300,7 +308,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
for (int ipin = 0; ipin < physical_pb_graph_node->num_clock_pins[iport]; ++ipin) {
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
physical_pb,
&(physical_pb_graph_node->clock_pins[iport][ipin]),
physical_mode);
@ -327,6 +335,7 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
const MuxLibrary& mux_lib,
const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node,
const PhysicalPb& physical_pb,
t_mode* physical_mode) {
@ -348,7 +357,7 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
*/
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
physical_pb_graph_node, physical_pb,
CIRCUIT_PB_PORT_OUTPUT, physical_mode);
@ -367,13 +376,13 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
/* For each child_pb_graph_node input pins*/
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb,
CIRCUIT_PB_PORT_INPUT, physical_mode);
/* For clock pins, we should do the same work */
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb,
CIRCUIT_PB_PORT_CLOCK, physical_mode);
}
@ -534,6 +543,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
const MuxLibrary& mux_lib,
const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const e_side& border_side,
const PhysicalPb& physical_pb,
const PhysicalPbId& pb_id,
@ -578,7 +588,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
rec_build_physical_block_bitstream(bitstream_manager, pb_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx,
device_annotation,
device_annotation, bitstream_annotation,
border_side,
physical_pb, child_pb,
&(physical_pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
@ -623,7 +633,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
build_physical_block_interc_bitstream(bitstream_manager, pb_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx,
device_annotation,
device_annotation, bitstream_annotation,
physical_pb_graph_node, physical_pb,
physical_mode);
}
@ -644,6 +654,7 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const DeviceGrid& grids,
const vtr::Point<size_t>& grid_coord,
const e_side& border_side) {
@ -692,7 +703,8 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
rec_build_physical_block_bitstream(bitstream_manager, grid_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx,
device_annotation, border_side,
device_annotation, bitstream_annotation,
border_side,
PhysicalPb(), PhysicalPbId::INVALID(),
lb_type->pb_graph_head, z);
} else {
@ -707,7 +719,8 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
rec_build_physical_block_bitstream(bitstream_manager, grid_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx,
device_annotation, border_side,
device_annotation, bitstream_annotation,
border_side,
phy_pb, top_pb_id, pb_graph_head, z);
}
}
@ -731,6 +744,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const bool& verbose) {
VTR_LOGV(verbose, "Generating bitstream for core grids...");
@ -753,7 +767,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
circuit_lib, mux_lib,
atom_ctx,
device_annotation, cluster_annotation,
place_annotation,
place_annotation, bitstream_annotation,
grids, grid_coord, NUM_SIDES);
}
}
@ -780,7 +794,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
circuit_lib, mux_lib,
atom_ctx,
device_annotation, cluster_annotation,
place_annotation,
place_annotation, bitstream_annotation,
grids, io_coordinate, io_side);
}
}

View File

@ -14,6 +14,7 @@
#include "vpr_device_annotation.h"
#include "vpr_clustering_annotation.h"
#include "vpr_placement_annotation.h"
#include "vpr_bitstream_annotation.h"
/********************************************************************
* Function declaration
@ -32,6 +33,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const bool& verbose);
} /* end namespace openfpga */