diff --git a/openfpga/src/annotation/annotate_bitstream_setting.cpp b/openfpga/src/annotation/annotate_bitstream_setting.cpp new file mode 100644 index 000000000..fbcb92cf0 --- /dev/null +++ b/openfpga/src/annotation/annotate_bitstream_setting.cpp @@ -0,0 +1,85 @@ +/******************************************************************** + * This file includes functions that are used to annotate pb_type + * from VPR to OpenFPGA + *******************************************************************/ +#include +#include + +/* 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 target_pb_type_names; + std::vector 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 */ diff --git a/openfpga/src/annotation/annotate_bitstream_setting.h b/openfpga/src/annotation/annotate_bitstream_setting.h new file mode 100644 index 000000000..053ca2fbe --- /dev/null +++ b/openfpga/src/annotation/annotate_bitstream_setting.h @@ -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 diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.cpp b/openfpga/src/annotation/vpr_bitstream_annotation.cpp new file mode 100644 index 000000000..fdb66048c --- /dev/null +++ b/openfpga/src/annotation/vpr_bitstream_annotation.cpp @@ -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*/ diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.h b/openfpga/src/annotation/vpr_bitstream_annotation.h new file mode 100644 index 000000000..c8d4102a0 --- /dev/null +++ b/openfpga/src/annotation/vpr_bitstream_annotation.h @@ -0,0 +1,50 @@ +#ifndef VPR_BITSTREAM_ANNOTATION_H +#define VPR_BITSTREAM_ANNOTATION_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include + +/* 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 bitstream_sources_; + /* Binding from pb type to bitstream content */ + std::map bitstream_contents_; +}; + +} /* End namespace openfpga*/ + +#endif diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index 0bff4448e..c85bf8607 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -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_; diff --git a/openfpga/src/base/openfpga_link_arch.cpp b/openfpga/src/base/openfpga_link_arch.cpp index efedf9584..f33a292c6 100644 --- a/openfpga/src/base/openfpga_link_arch.cpp +++ b/openfpga/src/base/openfpga_link_arch.cpp @@ -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; } diff --git a/openfpga/src/base/openfpga_read_arch.cpp b/openfpga/src/base/openfpga_read_arch.cpp index 1e58ec373..25bfc3831 100644 --- a/openfpga/src/base/openfpga_read_arch.cpp +++ b/openfpga/src/base/openfpga_read_arch.cpp @@ -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 */ diff --git a/openfpga/src/base/openfpga_read_arch.h b/openfpga/src/base/openfpga_read_arch.h index d5502db56..9ffc0d3cb 100644 --- a/openfpga/src/base/openfpga_read_arch.h +++ b/openfpga/src/base/openfpga_read_arch.h @@ -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 diff --git a/openfpga/src/base/openfpga_repack.cpp b/openfpga/src/base/openfpga_repack.cpp index 872de054c..8e8a79141 100644 --- a/openfpga/src/base/openfpga_repack.cpp +++ b/openfpga/src/base/openfpga_repack.cpp @@ -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)); diff --git a/openfpga/src/base/openfpga_setup_command.cpp b/openfpga/src/base/openfpga_setup_command.cpp index 7e484731d..517ed364a 100644 --- a/openfpga/src/base/openfpga_setup_command.cpp +++ b/openfpga/src/base/openfpga_setup_command.cpp @@ -113,6 +113,55 @@ ShellCommandId add_openfpga_write_simulation_setting_command(openfpga::Shell& 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& shell, + const ShellCommandClassId& cmd_class_id, + const std::vector& 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& 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 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' */ diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 3397be4b8..3062c126f 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -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 */ diff --git a/openfpga/src/repack/build_physical_truth_table.h b/openfpga/src/repack/build_physical_truth_table.h index 3c0c8ebf3..ecd4daad5 100644 --- a/openfpga/src/repack/build_physical_truth_table.h +++ b/openfpga/src/repack/build_physical_truth_table.h @@ -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" /******************************************************************** diff --git a/openfpga/src/repack/physical_pb.cpp b/openfpga/src/repack/physical_pb.cpp index 4650d7d0d..c64f05f07 100644 --- a/openfpga/src/repack/physical_pb.cpp +++ b/openfpga/src/repack/physical_pb.cpp @@ -102,6 +102,11 @@ std::vector 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 ******************************************************************************/ diff --git a/openfpga/src/repack/physical_pb.h b/openfpga/src/repack/physical_pb.h index 6d8d2ba3b..078cc6bc9 100644 --- a/openfpga/src/repack/physical_pb.h +++ b/openfpga/src/repack/physical_pb.h @@ -54,6 +54,7 @@ class PhysicalPb { const t_pb_graph_pin* pb_graph_pin) const; std::map truth_tables(const PhysicalPbId& pb) const; std::vector 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> mode_bits_; + vtr::vector fixed_bitstreams_; + /* Fast lookup */ std::map type2id_map_; }; diff --git a/openfpga/src/repack/repack.cpp b/openfpga/src/repack/repack.cpp index 7869448be..e737991b8 100644 --- a/openfpga/src/repack/repack.cpp +++ b/openfpga/src/repack/repack.cpp @@ -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(device_annotation), clustering_annotation, + const_cast(device_annotation), + clustering_annotation, + bitstream_annotation, design_constraints, verbose); } diff --git a/openfpga/src/repack/repack.h b/openfpga/src/repack/repack.h index 3ca3a613f..feb48a578 100644 --- a/openfpga/src/repack/repack.h +++ b/openfpga/src/repack/repack.h @@ -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); diff --git a/openfpga/src/utils/physical_pb_utils.cpp b/openfpga/src/utils/physical_pb_utils.cpp index 129784575..9f3cbf087 100644 --- a/openfpga/src/utils/physical_pb_utils.cpp +++ b/openfpga/src/utils/physical_pb_utils.cpp @@ -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 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 */ diff --git a/openfpga/src/utils/physical_pb_utils.h b/openfpga/src/utils/physical_pb_utils.h index 227feec6c..faa18bc91 100644 --- a/openfpga/src/utils/physical_pb_utils.h +++ b/openfpga/src/utils/physical_pb_utils.h @@ -10,6 +10,7 @@ #include #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 */