[Tool] Add bitstream annotation support
This commit is contained in:
parent
faabdab815
commit
0c409b5bcc
|
@ -0,0 +1,85 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that are used to annotate pb_type
|
||||
* from VPR to OpenFPGA
|
||||
*******************************************************************/
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
#include "pb_type_utils.h"
|
||||
#include "annotate_bitstream_setting.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Annotate bitstream setting based on VPR device information
|
||||
* - 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) {
|
||||
|
||||
for (const auto& bitstream_pb_type_setting_id : bitstream_setting.pb_type_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_pb_type_setting_id);
|
||||
target_pb_type_names.push_back(bitstream_setting.pb_type_name(bitstream_pb_type_setting_id));
|
||||
target_pb_mode_names = bitstream_setting.parent_mode_names(bitstream_pb_type_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 */
|
||||
if (std::string("eblif") == bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id)) {
|
||||
vpr_bitstream_annotation.set_pb_type_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF);
|
||||
} else {
|
||||
/* Invalid source, error out! */
|
||||
VTR_LOG_ERROR("Invalid bitstream source '%s' for pb_type '%s' which is defined in bitstream setting\n",
|
||||
bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id).c_str(),
|
||||
target_pb_type_names[0].c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
vpr_bitstream_annotation.set_pb_type_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_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 a pb_type '%s' which is defined in bitstream setting from VPR architecture description\n",
|
||||
target_pb_type_names[0].c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef ANNOTATE_BITSTREAM_SETTING_H
|
||||
#define ANNOTATE_BITSTREAM_SETTING_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "vpr_context.h"
|
||||
#include "openfpga_context.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
/************************************************************************
|
||||
* Member functions for class VprBitstreamAnnotation
|
||||
***********************************************************************/
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
|
||||
/* namespace openfpga begins */
|
||||
namespace openfpga {
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
VprBitstreamAnnotation::VprBitstreamAnnotation() {
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public accessors
|
||||
***********************************************************************/
|
||||
VprBitstreamAnnotation::e_bitstream_source_type VprBitstreamAnnotation::pb_type_bitstream_source(t_pb_type* pb_type) const {
|
||||
auto result = bitstream_sources_.find(pb_type);
|
||||
if (result != bitstream_sources_.end()) {
|
||||
return result->second;
|
||||
}
|
||||
|
||||
/* Not found, return an invalid type*/
|
||||
return NUM_BITSTREAM_SOURCE_TYPES;
|
||||
}
|
||||
|
||||
std::string VprBitstreamAnnotation::pb_type_bitstream_content(t_pb_type* pb_type) const {
|
||||
auto result = bitstream_contents_.find(pb_type);
|
||||
if (result != bitstream_contents_.end()) {
|
||||
return result->second;
|
||||
}
|
||||
|
||||
/* Not found, return an invalid type */
|
||||
return std::string();
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public mutators
|
||||
***********************************************************************/
|
||||
void VprBitstreamAnnotation::set_pb_type_bitstream_source(t_pb_type* pb_type,
|
||||
const e_bitstream_source_type& bitstream_source) {
|
||||
bitstream_sources_[pb_type] = bitstream_source;
|
||||
}
|
||||
void VprBitstreamAnnotation::set_pb_type_bitstream_content(t_pb_type* pb_type,
|
||||
const std::string& bitstream_content) {
|
||||
bitstream_contents_[pb_type] = bitstream_content;
|
||||
}
|
||||
|
||||
|
||||
} /* End namespace openfpga*/
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef VPR_BITSTREAM_ANNOTATION_H
|
||||
#define VPR_BITSTREAM_ANNOTATION_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
/* Header from vpr library */
|
||||
#include "vpr_context.h"
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* This is the critical data structure to link the pb_type in VPR
|
||||
* to openfpga annotations
|
||||
* With a given pb_type pointer, it aims to identify:
|
||||
* 1. if the pb_type requires another bitstream source than .blif file
|
||||
* which may be .eblif file
|
||||
* 2. if the pb_type requires a fixed bitstream value
|
||||
* or an attribute line in the .eblif file
|
||||
*******************************************************************/
|
||||
class VprBitstreamAnnotation {
|
||||
public: /* Type */
|
||||
enum e_bitstream_source_type {
|
||||
BITSTREAM_SOURCE_EBLIF,
|
||||
NUM_BITSTREAM_SOURCE_TYPES
|
||||
};
|
||||
public: /* Constructor */
|
||||
VprBitstreamAnnotation();
|
||||
public: /* Public accessors */
|
||||
e_bitstream_source_type pb_type_bitstream_source(t_pb_type* pb_type) const;
|
||||
std::string pb_type_bitstream_content(t_pb_type* pb_type) const;
|
||||
public: /* Public mutators */
|
||||
void set_pb_type_bitstream_source(t_pb_type* pb_type,
|
||||
const e_bitstream_source_type& bitstream_source);
|
||||
void set_pb_type_bitstream_content(t_pb_type* pb_type,
|
||||
const std::string& bitstream_content);
|
||||
private: /* Internal data */
|
||||
/* A look up for pb type to find bitstream source type */
|
||||
std::map<t_pb_type*, e_bitstream_source_type> bitstream_sources_;
|
||||
/* Binding from pb type to bitstream content */
|
||||
std::map<t_pb_type*, std::string> bitstream_contents_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
||||
#endif
|
|
@ -5,11 +5,13 @@
|
|||
#include "vpr_context.h"
|
||||
#include "openfpga_arch.h"
|
||||
#include "simulation_setting.h"
|
||||
#include "bitstream_setting.h"
|
||||
#include "vpr_netlist_annotation.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_clustering_annotation.h"
|
||||
#include "vpr_placement_annotation.h"
|
||||
#include "vpr_routing_annotation.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
#include "mux_library.h"
|
||||
#include "decoder_library.h"
|
||||
#include "tile_direct.h"
|
||||
|
@ -53,11 +55,13 @@ class OpenfpgaContext : public Context {
|
|||
public: /* Public accessors */
|
||||
const openfpga::Arch& arch() const { return arch_; }
|
||||
const openfpga::SimulationSetting& simulation_setting() const { return sim_setting_; }
|
||||
const openfpga::BitstreamSetting& bitstream_setting() const { return bitstream_setting_; }
|
||||
const openfpga::VprDeviceAnnotation& vpr_device_annotation() const { return vpr_device_annotation_; }
|
||||
const openfpga::VprNetlistAnnotation& vpr_netlist_annotation() const { return vpr_netlist_annotation_; }
|
||||
const openfpga::VprClusteringAnnotation& vpr_clustering_annotation() const { return vpr_clustering_annotation_; }
|
||||
const openfpga::VprPlacementAnnotation& vpr_placement_annotation() const { return vpr_placement_annotation_; }
|
||||
const openfpga::VprRoutingAnnotation& vpr_routing_annotation() const { return vpr_routing_annotation_; }
|
||||
const openfpga::VprBitstreamAnnotation& vpr_bitstream_annotation() const { return vpr_bitstream_annotation_; }
|
||||
const openfpga::DeviceRRGSB& device_rr_gsb() const { return device_rr_gsb_; }
|
||||
const openfpga::MuxLibrary& mux_lib() const { return mux_lib_; }
|
||||
const openfpga::DecoderLibrary& decoder_lib() const { return decoder_lib_; }
|
||||
|
@ -73,11 +77,13 @@ class OpenfpgaContext : public Context {
|
|||
public: /* Public mutators */
|
||||
openfpga::Arch& mutable_arch() { return arch_; }
|
||||
openfpga::SimulationSetting& mutable_simulation_setting() { return sim_setting_; }
|
||||
openfpga::BitstreamSetting& mutable_bitstream_setting() { return bitstream_setting_; }
|
||||
openfpga::VprDeviceAnnotation& mutable_vpr_device_annotation() { return vpr_device_annotation_; }
|
||||
openfpga::VprNetlistAnnotation& mutable_vpr_netlist_annotation() { return vpr_netlist_annotation_; }
|
||||
openfpga::VprClusteringAnnotation& mutable_vpr_clustering_annotation() { return vpr_clustering_annotation_; }
|
||||
openfpga::VprPlacementAnnotation& mutable_vpr_placement_annotation() { return vpr_placement_annotation_; }
|
||||
openfpga::VprRoutingAnnotation& mutable_vpr_routing_annotation() { return vpr_routing_annotation_; }
|
||||
openfpga::VprBitstreamAnnotation& mutable_vpr_bitstream_annotation() { return vpr_bitstream_annotation_; }
|
||||
openfpga::DeviceRRGSB& mutable_device_rr_gsb() { return device_rr_gsb_; }
|
||||
openfpga::MuxLibrary& mutable_mux_lib() { return mux_lib_; }
|
||||
openfpga::DecoderLibrary& mutable_decoder_lib() { return decoder_lib_; }
|
||||
|
@ -94,6 +100,7 @@ class OpenfpgaContext : public Context {
|
|||
/* Data structure to store information from read_openfpga_arch library */
|
||||
openfpga::Arch arch_;
|
||||
openfpga::SimulationSetting sim_setting_;
|
||||
openfpga::BitstreamSetting bitstream_setting_;
|
||||
|
||||
/* Annotation to pb_type of VPR */
|
||||
openfpga::VprDeviceAnnotation vpr_device_annotation_;
|
||||
|
@ -110,6 +117,9 @@ class OpenfpgaContext : public Context {
|
|||
/* Routing results annotation */
|
||||
openfpga::VprRoutingAnnotation vpr_routing_annotation_;
|
||||
|
||||
/* Annotation to pb_type of VPR */
|
||||
openfpga::VprBitstreamAnnotation vpr_bitstream_annotation_;
|
||||
|
||||
/* Device-level annotation */
|
||||
openfpga::DeviceRRGSB device_rr_gsb_;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "annotate_routing.h"
|
||||
#include "annotate_rr_graph.h"
|
||||
#include "annotate_simulation_setting.h"
|
||||
#include "annotate_bitstream_setting.h"
|
||||
#include "mux_library_builder.h"
|
||||
#include "build_tile_direct.h"
|
||||
#include "annotate_placement.h"
|
||||
|
@ -168,6 +169,14 @@ int link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* 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.mutable_vpr_bitstream_annotation())) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -152,5 +152,59 @@ int write_simulation_setting(const OpenfpgaContext& openfpga_context,
|
|||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Top-level function to read an OpenFPGA bitstream setting file
|
||||
* we use the APIs from the libarchopenfpga library
|
||||
*
|
||||
* The command will accept an option '--file' which is the bitstream setting
|
||||
* file provided by users
|
||||
*******************************************************************/
|
||||
int read_bitstream_setting(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
/* Check the option '--file' is enabled or not
|
||||
* Actually, it must be enabled as the shell interface will check
|
||||
* before reaching this fuction
|
||||
*/
|
||||
CommandOptionId opt_file = cmd.option("file");
|
||||
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file));
|
||||
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty());
|
||||
|
||||
std::string arch_file_name = cmd_context.option_value(cmd, opt_file);
|
||||
|
||||
VTR_LOG("Reading XML bitstream setting '%s'...\n",
|
||||
arch_file_name.c_str());
|
||||
openfpga_context.mutable_bitstream_setting() = read_xml_openfpga_bitstream_settings(arch_file_name.c_str());
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A function to write an OpenFPGA bitstream setting file
|
||||
* we use the APIs from the libarchopenfpga library
|
||||
*
|
||||
* The command will accept an option '--file' which is the simulation setting
|
||||
* file provided by users
|
||||
*******************************************************************/
|
||||
int write_bitstream_setting(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
/* Check the option '--file' is enabled or not
|
||||
* Actually, it must be enabled as the shell interface will check
|
||||
* before reaching this fuction
|
||||
*/
|
||||
CommandOptionId opt_file = cmd.option("file");
|
||||
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file));
|
||||
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty());
|
||||
|
||||
std::string arch_file_name = cmd_context.option_value(cmd, opt_file);
|
||||
|
||||
VTR_LOG("Writing XML bitstream setting to '%s'...\n",
|
||||
arch_file_name.c_str());
|
||||
write_xml_openfpga_bitstream_settings(arch_file_name.c_str(), openfpga_context.bitstream_setting());
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -27,6 +27,13 @@ int read_simulation_setting(OpenfpgaContext& openfpga_context,
|
|||
int write_simulation_setting(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
int read_bitstream_setting(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
int write_bitstream_setting(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,7 @@ int repack(OpenfpgaContext& openfpga_ctx,
|
|||
g_vpr_ctx.clustering(),
|
||||
openfpga_ctx.mutable_vpr_device_annotation(),
|
||||
openfpga_ctx.mutable_vpr_clustering_annotation(),
|
||||
openfpga_ctx.vpr_bitstream_annotation(),
|
||||
repack_design_constraints,
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
|
|
|
@ -113,6 +113,55 @@ ShellCommandId add_openfpga_write_simulation_setting_command(openfpga::Shell<Ope
|
|||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: read_openfpga_bitstream_setting
|
||||
* - Add associated options
|
||||
* - Add command dependency
|
||||
*******************************************************************/
|
||||
static
|
||||
ShellCommandId add_openfpga_read_bitstream_setting_command(openfpga::Shell<OpenfpgaContext>& shell,
|
||||
const ShellCommandClassId& cmd_class_id) {
|
||||
Command shell_cmd("read_openfpga_bitstream_setting");
|
||||
|
||||
/* Add an option '--file' in short '-f'*/
|
||||
CommandOptionId opt_file = shell_cmd.add_option("file", true, "file path to the bitstream setting XML");
|
||||
shell_cmd.set_option_short_name(opt_file, "f");
|
||||
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
|
||||
|
||||
/* Add command 'read_openfpga_bitstream_setting' to the Shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "read OpenFPGA bitstream setting file");
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_execute_function(shell_cmd_id, read_bitstream_setting);
|
||||
|
||||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: write_openfpga_bitstream_setting
|
||||
* - Add associated options
|
||||
* - Add command dependency
|
||||
*******************************************************************/
|
||||
static
|
||||
ShellCommandId add_openfpga_write_bitstream_setting_command(openfpga::Shell<OpenfpgaContext>& shell,
|
||||
const ShellCommandClassId& cmd_class_id,
|
||||
const std::vector<ShellCommandId>& dependent_cmds) {
|
||||
Command shell_cmd("write_openfpga_bitstream_setting");
|
||||
/* Add an option '--file' in short '-f'*/
|
||||
CommandOptionId opt_file = shell_cmd.add_option("file", true, "file path to the bitstream setting XML");
|
||||
shell_cmd.set_option_short_name(opt_file, "f");
|
||||
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
|
||||
|
||||
/* Add command 'write_openfpga_bitstream_setting' to the Shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "write OpenFPGA bitstream setting file");
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_const_execute_function(shell_cmd_id, write_bitstream_setting);
|
||||
|
||||
/* Add command dependency to the Shell */
|
||||
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
|
||||
|
||||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: link_openfpga_arch
|
||||
* - Add associated options
|
||||
|
@ -373,6 +422,22 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
|||
openfpga_setup_cmd_class,
|
||||
write_sim_setting_dependent_cmds);
|
||||
|
||||
/********************************
|
||||
* Command 'read_openfpga_bitstream_setting'
|
||||
*/
|
||||
ShellCommandId read_bitstream_setting_cmd_id = add_openfpga_read_bitstream_setting_command(shell,
|
||||
openfpga_setup_cmd_class);
|
||||
|
||||
/********************************
|
||||
* Command 'write_openfpga_bitstream_setting'
|
||||
*/
|
||||
/* The 'write_openfpga_bitstream_setting' command should NOT be executed before 'read_openfpga_bitstream_setting' */
|
||||
std::vector<ShellCommandId> write_bitstream_setting_dependent_cmds(1, read_bitstream_setting_cmd_id);
|
||||
add_openfpga_write_bitstream_setting_command(shell,
|
||||
openfpga_setup_cmd_class,
|
||||
write_bitstream_setting_dependent_cmds);
|
||||
|
||||
|
||||
/********************************
|
||||
* Command 'link_openfpga_arch'
|
||||
*/
|
||||
|
|
|
@ -445,6 +445,23 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager,
|
|||
device_annotation,
|
||||
physical_pb.truth_tables(lut_pb_id),
|
||||
circuit_lib.port_default_value(lut_regular_sram_ports[0]));
|
||||
/* If the physical pb contains fixed bitstream, overload here */
|
||||
if (false == physical_pb.fixed_bitstream(lut_pb_id).empty()) {
|
||||
std::string fixed_bitstream = physical_pb.fixed_bitstream(lut_pb_id);
|
||||
/* Ensure the length matches!!! */
|
||||
if (lut_bitstream.size() != fixed_bitstream.size()) {
|
||||
VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be %ld bits\n",
|
||||
fixed_bitstream.c_str(),
|
||||
lut_bitstream.size());
|
||||
exit(1);
|
||||
}
|
||||
/* Overload here */
|
||||
lut_bitstream.clear();
|
||||
for (const char& fixed_bit : fixed_bitstream) {
|
||||
VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit);
|
||||
lut_bitstream.push_back('1' == fixed_bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate bitstream for mode-select ports */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "vpr_context.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_clustering_annotation.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
#include "circuit_library.h"
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -102,6 +102,11 @@ std::vector<size_t> PhysicalPb::mode_bits(const PhysicalPbId& pb) const {
|
|||
return mode_bits_[pb];
|
||||
}
|
||||
|
||||
std::string PhysicalPb::fixed_bitstream(const PhysicalPbId& pb) const {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
return fixed_bitstreams_[pb];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
|
@ -128,6 +133,7 @@ PhysicalPbId PhysicalPb::create_pb(const t_pb_graph_node* pb_graph_node) {
|
|||
|
||||
truth_tables_.emplace_back();
|
||||
mode_bits_.emplace_back();
|
||||
fixed_bitstreams_.emplace_back();
|
||||
|
||||
/* Register in the name2id map */
|
||||
type2id_map_[pb_graph_node] = pb;
|
||||
|
@ -206,6 +212,12 @@ void PhysicalPb::set_wire_lut_output(const PhysicalPbId& pb,
|
|||
wire_lut_outputs_[pb][pb_graph_pin] = wire_lut_output;
|
||||
}
|
||||
|
||||
void PhysicalPb::set_fixed_bitstream(const PhysicalPbId& pb,
|
||||
const std::string& fixed_bitstream) {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
fixed_bitstreams_[pb] = fixed_bitstream;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private validators/invalidators
|
||||
******************************************************************************/
|
||||
|
|
|
@ -54,6 +54,7 @@ class PhysicalPb {
|
|||
const t_pb_graph_pin* pb_graph_pin) const;
|
||||
std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> truth_tables(const PhysicalPbId& pb) const;
|
||||
std::vector<size_t> mode_bits(const PhysicalPbId& pb) const;
|
||||
std::string fixed_bitstream(const PhysicalPbId& pb) const;
|
||||
public: /* Public mutators */
|
||||
PhysicalPbId create_pb(const t_pb_graph_node* pb_graph_node);
|
||||
void add_child(const PhysicalPbId& parent,
|
||||
|
@ -72,6 +73,8 @@ class PhysicalPb {
|
|||
void set_wire_lut_output(const PhysicalPbId& pb,
|
||||
const t_pb_graph_pin* pb_graph_pin,
|
||||
const bool& wire_lut_output);
|
||||
void set_fixed_bitstream(const PhysicalPbId& pb,
|
||||
const std::string& fixed_bitstream);
|
||||
public: /* Public validators/invalidators */
|
||||
bool valid_pb_id(const PhysicalPbId& pb_id) const;
|
||||
bool empty() const;
|
||||
|
@ -94,6 +97,8 @@ class PhysicalPb {
|
|||
|
||||
vtr::vector<PhysicalPbId, std::vector<size_t>> mode_bits_;
|
||||
|
||||
vtr::vector<PhysicalPbId, std::string> fixed_bitstreams_;
|
||||
|
||||
/* Fast lookup */
|
||||
std::map<const t_pb_graph_node*, PhysicalPbId> type2id_map_;
|
||||
};
|
||||
|
|
|
@ -611,6 +611,7 @@ void repack_cluster(const AtomContext& atom_ctx,
|
|||
const ClusteringContext& clustering_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const RepackDesignConstraints& design_constraints,
|
||||
const ClusterBlockId& block_id,
|
||||
const bool& verbose) {
|
||||
|
@ -659,6 +660,7 @@ void repack_cluster(const AtomContext& atom_ctx,
|
|||
clustering_ctx.clb_nlist.block_pb(block_id)->pb_route,
|
||||
atom_ctx,
|
||||
device_annotation,
|
||||
bitstream_annotation,
|
||||
verbose);
|
||||
/* Save routing results */
|
||||
save_lb_router_results_to_physical_pb(phy_pb, lb_router, lb_rr_graph);
|
||||
|
@ -678,6 +680,7 @@ void repack_clusters(const AtomContext& atom_ctx,
|
|||
const ClusteringContext& clustering_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const RepackDesignConstraints& design_constraints,
|
||||
const bool& verbose) {
|
||||
vtr::ScopedStartFinishTimer timer("Repack clustered blocks to physical implementation of logical tile");
|
||||
|
@ -686,6 +689,7 @@ void repack_clusters(const AtomContext& atom_ctx,
|
|||
repack_cluster(atom_ctx, clustering_ctx,
|
||||
device_annotation,
|
||||
clustering_annotation,
|
||||
bitstream_annotation,
|
||||
design_constraints,
|
||||
blk_id, verbose);
|
||||
}
|
||||
|
@ -706,6 +710,7 @@ void pack_physical_pbs(const DeviceContext& device_ctx,
|
|||
const ClusteringContext& clustering_ctx,
|
||||
VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const RepackDesignConstraints& design_constraints,
|
||||
const bool& verbose) {
|
||||
|
||||
|
@ -716,7 +721,9 @@ void pack_physical_pbs(const DeviceContext& device_ctx,
|
|||
|
||||
/* Call the LbRouter to re-pack each clustered block to physical implementation */
|
||||
repack_clusters(atom_ctx, clustering_ctx,
|
||||
const_cast<const VprDeviceAnnotation&>(device_annotation), clustering_annotation,
|
||||
const_cast<const VprDeviceAnnotation&>(device_annotation),
|
||||
clustering_annotation,
|
||||
bitstream_annotation,
|
||||
design_constraints,
|
||||
verbose);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_clustering_annotation.h"
|
||||
#include "vpr_routing_annotation.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
#include "repack_design_constraints.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -22,6 +23,7 @@ void pack_physical_pbs(const DeviceContext& device_ctx,
|
|||
const ClusteringContext& clustering_ctx,
|
||||
VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const RepackDesignConstraints& design_constraints,
|
||||
const bool& verbose);
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_tokenizer.h"
|
||||
|
||||
#include "openfpga_naming.h"
|
||||
#include "pb_type_utils.h"
|
||||
#include "physical_pb_utils.h"
|
||||
|
@ -278,6 +281,7 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
|||
const t_pb_routes& pb_route,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const bool& verbose) {
|
||||
t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node;
|
||||
t_pb_type* pb_type = pb_graph_node->pb_type;
|
||||
|
@ -297,6 +301,29 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
|||
VTR_ASSERT(atom_blk);
|
||||
|
||||
phy_pb.add_atom_block(physical_pb, atom_blk);
|
||||
|
||||
/* if the operating pb type has bitstream annotation,
|
||||
* bind the bitstream value from atom block to the physical pb
|
||||
*/
|
||||
if (VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF == bitstream_annotation.pb_type_bitstream_source(pb_type)) {
|
||||
StringToken tokenizer = bitstream_annotation.pb_type_bitstream_content(pb_type);
|
||||
std::vector<std::string> tokens = tokenizer.split(" ");
|
||||
/* FIXME: The token-level check should be done much earlier!!! */
|
||||
VTR_ASSERT(2 == tokens.size());
|
||||
if (std::string(".param") == tokens[0]) {
|
||||
for (const auto& param_search : atom_ctx.nlist.block_params(atom_blk)) {
|
||||
if (param_search.first == tokens[1]) {
|
||||
phy_pb.set_fixed_bitstream(physical_pb, param_search.second);
|
||||
}
|
||||
}
|
||||
} else if (std::string(".attr") == tokens[0]) {
|
||||
for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) {
|
||||
if (attr_search.first == tokens[1]) {
|
||||
phy_pb.set_fixed_bitstream(physical_pb, attr_search.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate over ports and annotate the atom pins */
|
||||
synchronize_primitive_physical_pb_atom_nets(phy_pb, physical_pb,
|
||||
|
@ -318,6 +345,7 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
|||
pb_route,
|
||||
atom_ctx,
|
||||
device_annotation,
|
||||
bitstream_annotation,
|
||||
verbose);
|
||||
} else {
|
||||
/* Some pb may be used just in routing purpose, find out the output nets */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
#include "physical_types.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
#include "vpr_context.h"
|
||||
#include "physical_pb.h"
|
||||
|
||||
|
@ -29,6 +30,7 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
|||
const t_pb_routes& pb_route,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
Loading…
Reference in New Issue