[core] add missing file
This commit is contained in:
parent
279e790fd8
commit
52e803804d
|
@ -0,0 +1,236 @@
|
|||
#ifndef OPENFPGA_BUILD_FABRIC_TEMPLATE_H
|
||||
#define OPENFPGA_BUILD_FABRIC_TEMPLATE_H
|
||||
/********************************************************************
|
||||
* This file includes functions to compress the hierachy of routing architecture
|
||||
*******************************************************************/
|
||||
#include "build_device_module.h"
|
||||
#include "build_fabric_global_port_info.h"
|
||||
#include "build_fabric_io_location_map.h"
|
||||
#include "command.h"
|
||||
#include "command_context.h"
|
||||
#include "command_exit_codes.h"
|
||||
#include "device_rr_gsb.h"
|
||||
#include "device_rr_gsb_utils.h"
|
||||
#include "fabric_hierarchy_writer.h"
|
||||
#include "fabric_key_writer.h"
|
||||
#include "globals.h"
|
||||
#include "read_xml_fabric_key.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Identify the unique GSBs from the Device RR GSB arrays
|
||||
* This function should only be called after the GSB builder is done
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
void compress_routing_hierarchy_template(T& openfpga_ctx,
|
||||
const bool& verbose_output) {
|
||||
vtr::ScopedStartFinishTimer timer(
|
||||
"Identify unique General Switch Blocks (GSBs)");
|
||||
|
||||
/* Build unique module lists */
|
||||
openfpga_ctx.mutable_device_rr_gsb().build_unique_module(
|
||||
g_vpr_ctx.device().rr_graph);
|
||||
|
||||
/* Report the stats */
|
||||
VTR_LOGV(
|
||||
verbose_output,
|
||||
"Detected %lu unique X-direction connection blocks from a total of %d "
|
||||
"(compression rate=%.2f%)\n",
|
||||
openfpga_ctx.device_rr_gsb().get_num_cb_unique_module(CHANX),
|
||||
find_device_rr_gsb_num_cb_modules(openfpga_ctx.device_rr_gsb(), CHANX),
|
||||
100. *
|
||||
((float)find_device_rr_gsb_num_cb_modules(openfpga_ctx.device_rr_gsb(),
|
||||
CHANX) /
|
||||
(float)openfpga_ctx.device_rr_gsb().get_num_cb_unique_module(CHANX) -
|
||||
1.));
|
||||
|
||||
VTR_LOGV(
|
||||
verbose_output,
|
||||
"Detected %lu unique Y-direction connection blocks from a total of %d "
|
||||
"(compression rate=%.2f%)\n",
|
||||
openfpga_ctx.device_rr_gsb().get_num_cb_unique_module(CHANY),
|
||||
find_device_rr_gsb_num_cb_modules(openfpga_ctx.device_rr_gsb(), CHANY),
|
||||
100. *
|
||||
((float)find_device_rr_gsb_num_cb_modules(openfpga_ctx.device_rr_gsb(),
|
||||
CHANY) /
|
||||
(float)openfpga_ctx.device_rr_gsb().get_num_cb_unique_module(CHANY) -
|
||||
1.));
|
||||
|
||||
VTR_LOGV(
|
||||
verbose_output,
|
||||
"Detected %lu unique switch blocks from a total of %d (compression "
|
||||
"rate=%.2f%)\n",
|
||||
openfpga_ctx.device_rr_gsb().get_num_sb_unique_module(),
|
||||
find_device_rr_gsb_num_sb_modules(openfpga_ctx.device_rr_gsb()),
|
||||
100. *
|
||||
((float)find_device_rr_gsb_num_sb_modules(openfpga_ctx.device_rr_gsb()) /
|
||||
(float)openfpga_ctx.device_rr_gsb().get_num_sb_unique_module() -
|
||||
1.));
|
||||
|
||||
VTR_LOG(
|
||||
"Detected %lu unique general switch blocks from a total of %d (compression "
|
||||
"rate=%.2f%)\n",
|
||||
openfpga_ctx.device_rr_gsb().get_num_gsb_unique_module(),
|
||||
find_device_rr_gsb_num_gsb_modules(openfpga_ctx.device_rr_gsb()),
|
||||
100. *
|
||||
((float)find_device_rr_gsb_num_gsb_modules(openfpga_ctx.device_rr_gsb()) /
|
||||
(float)openfpga_ctx.device_rr_gsb().get_num_gsb_unique_module() -
|
||||
1.));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Build the module graph for FPGA device
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
int build_fabric_template(T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_frame_view = cmd.option("frame_view");
|
||||
CommandOptionId opt_compress_routing = cmd.option("compress_routing");
|
||||
CommandOptionId opt_duplicate_grid_pin = cmd.option("duplicate_grid_pin");
|
||||
CommandOptionId opt_gen_random_fabric_key =
|
||||
cmd.option("generate_random_fabric_key");
|
||||
CommandOptionId opt_write_fabric_key = cmd.option("write_fabric_key");
|
||||
CommandOptionId opt_load_fabric_key = cmd.option("load_fabric_key");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
if (true == cmd_context.option_enable(cmd, opt_compress_routing)) {
|
||||
compress_routing_hierarchy_template<T>(
|
||||
openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose));
|
||||
/* Update flow manager to enable compress routing */
|
||||
openfpga_ctx.mutable_flow_manager().set_compress_routing(true);
|
||||
}
|
||||
|
||||
VTR_LOG("\n");
|
||||
|
||||
/* Record the execution status in curr_status for each command
|
||||
* and summarize them in the final status
|
||||
*/
|
||||
int curr_status = CMD_EXEC_SUCCESS;
|
||||
int final_status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Load fabric key from file */
|
||||
FabricKey predefined_fabric_key;
|
||||
if (true == cmd_context.option_enable(cmd, opt_load_fabric_key)) {
|
||||
std::string fkey_fname = cmd_context.option_value(cmd, opt_load_fabric_key);
|
||||
VTR_ASSERT(false == fkey_fname.empty());
|
||||
predefined_fabric_key = read_xml_fabric_key(fkey_fname.c_str());
|
||||
}
|
||||
|
||||
VTR_LOG("\n");
|
||||
|
||||
curr_status = build_device_module_graph(
|
||||
openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_decoder_lib(),
|
||||
openfpga_ctx.mutable_blwl_shift_register_banks(),
|
||||
const_cast<const T&>(openfpga_ctx), g_vpr_ctx.device(),
|
||||
cmd_context.option_enable(cmd, opt_frame_view),
|
||||
cmd_context.option_enable(cmd, opt_compress_routing),
|
||||
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
|
||||
predefined_fabric_key,
|
||||
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* If there is any error, final status cannot be overwritten by a success flag
|
||||
*/
|
||||
if (CMD_EXEC_SUCCESS != curr_status) {
|
||||
final_status = curr_status;
|
||||
}
|
||||
|
||||
/* Build I/O location map */
|
||||
openfpga_ctx.mutable_io_location_map() = build_fabric_io_location_map(
|
||||
openfpga_ctx.module_graph(), g_vpr_ctx.device().grid);
|
||||
|
||||
/* Build fabric global port information */
|
||||
openfpga_ctx.mutable_fabric_global_port_info() =
|
||||
build_fabric_global_port_info(
|
||||
openfpga_ctx.module_graph(), openfpga_ctx.arch().config_protocol,
|
||||
openfpga_ctx.arch().tile_annotations, openfpga_ctx.arch().circuit_lib);
|
||||
|
||||
/* Output fabric key if user requested */
|
||||
if (true == cmd_context.option_enable(cmd, opt_write_fabric_key)) {
|
||||
std::string fkey_fname =
|
||||
cmd_context.option_value(cmd, opt_write_fabric_key);
|
||||
VTR_ASSERT(false == fkey_fname.empty());
|
||||
curr_status =
|
||||
write_fabric_key_to_xml_file(openfpga_ctx.module_graph(), fkey_fname,
|
||||
openfpga_ctx.arch().config_protocol,
|
||||
openfpga_ctx.blwl_shift_register_banks(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
/* If there is any error, final status cannot be overwritten by a success
|
||||
* flag */
|
||||
if (CMD_EXEC_SUCCESS != curr_status) {
|
||||
final_status = curr_status;
|
||||
}
|
||||
}
|
||||
|
||||
return final_status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Write hierarchy of the module graph for FPGA device to a file
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
int write_fabric_hierarchy_template(const T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* 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());
|
||||
|
||||
/* Default depth requirement, will not stop until the leaf */
|
||||
int depth = -1;
|
||||
CommandOptionId opt_depth = cmd.option("depth");
|
||||
if (true == cmd_context.option_enable(cmd, opt_depth)) {
|
||||
depth = std::atoi(cmd_context.option_value(cmd, opt_depth).c_str());
|
||||
/* Error out if we have negative depth */
|
||||
if (0 > depth) {
|
||||
VTR_LOG_ERROR(
|
||||
"Invalid depth '%d' which should be 0 or a positive number!\n", depth);
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
std::string hie_file_name = cmd_context.option_value(cmd, opt_file);
|
||||
|
||||
/* Write hierarchy to a file */
|
||||
return write_fabric_hierarchy_to_text_file(
|
||||
openfpga_ctx.module_graph(), hie_file_name, size_t(depth),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Write the I/O information of module graph to a file
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
int write_fabric_io_info_template(const T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
|
||||
|
||||
/* 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 file_name = cmd_context.option_value(cmd, opt_file);
|
||||
|
||||
/* Write hierarchy to a file */
|
||||
return openfpga_ctx.io_location_map().write_to_xml_file(
|
||||
file_name, !cmd_context.option_enable(cmd, opt_no_time_stamp),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,187 @@
|
|||
#ifndef OPENFPGA_LINK_ARCH_TEMPLATE_H
|
||||
#define OPENFPGA_LINK_ARCH_TEMPLATE_H
|
||||
/********************************************************************
|
||||
* This file includes functions to read an OpenFPGA architecture file
|
||||
* which are built on the libarchopenfpga library
|
||||
*******************************************************************/
|
||||
#include "annotate_bitstream_setting.h"
|
||||
#include "annotate_clustering.h"
|
||||
#include "annotate_pb_graph.h"
|
||||
#include "annotate_pb_types.h"
|
||||
#include "annotate_physical_tiles.h"
|
||||
#include "annotate_placement.h"
|
||||
#include "annotate_rr_graph.h"
|
||||
#include "annotate_simulation_setting.h"
|
||||
#include "build_tile_direct.h"
|
||||
#include "command.h"
|
||||
#include "command_context.h"
|
||||
#include "command_exit_codes.h"
|
||||
#include "globals.h"
|
||||
#include "mux_library_builder.h"
|
||||
#include "openfpga_annotate_routing.h"
|
||||
#include "openfpga_rr_graph_support.h"
|
||||
#include "pb_type_utils.h"
|
||||
#include "read_activity.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Top-level function to link openfpga architecture to VPR, including:
|
||||
* - physical pb_type
|
||||
* - mode selection bits for pb_type and pb interconnect
|
||||
* - circuit models for pb_type and pb interconnect
|
||||
* - physical pb_graph nodes and pb_graph pins
|
||||
* - circuit models for global routing architecture
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
int link_arch_template(T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
vtr::ScopedStartFinishTimer timer(
|
||||
"Link OpenFPGA architecture to VPR architecture");
|
||||
|
||||
CommandOptionId opt_activity_file = cmd.option("activity_file");
|
||||
CommandOptionId opt_sort_edge = cmd.option("sort_gsb_chan_node_in_edges");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* Build fast look-up between physical tile pin index and port information */
|
||||
build_physical_tile_pin2port_info(
|
||||
g_vpr_ctx.device(), openfpga_ctx.mutable_vpr_device_annotation());
|
||||
|
||||
/* Annotate pb_type graphs
|
||||
* - physical pb_type
|
||||
* - mode selection bits for pb_type and pb interconnect
|
||||
* - circuit models for pb_type and pb interconnect
|
||||
*/
|
||||
annotate_pb_types(g_vpr_ctx.device(), openfpga_ctx.arch(),
|
||||
openfpga_ctx.mutable_vpr_device_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Annotate pb_graph_nodes
|
||||
* - Give unique index to each node in the same type
|
||||
* - Bind operating pb_graph_node to their physical pb_graph_node
|
||||
* - Bind pins from operating pb_graph_node to their physical pb_graph_node
|
||||
* pins
|
||||
*/
|
||||
annotate_pb_graph(g_vpr_ctx.device(),
|
||||
openfpga_ctx.mutable_vpr_device_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Annotate routing architecture to circuit library */
|
||||
annotate_rr_graph_circuit_models(g_vpr_ctx.device(), openfpga_ctx.arch(),
|
||||
openfpga_ctx.mutable_vpr_device_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Annotate routing results:
|
||||
* - net mapping to each rr_node
|
||||
* - previous nodes driving each rr_node
|
||||
*/
|
||||
openfpga_ctx.mutable_vpr_routing_annotation().init(
|
||||
g_vpr_ctx.device().rr_graph);
|
||||
|
||||
annotate_vpr_rr_node_nets(g_vpr_ctx.device(), g_vpr_ctx.clustering(),
|
||||
g_vpr_ctx.routing(),
|
||||
openfpga_ctx.mutable_vpr_routing_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
annotate_rr_node_previous_nodes(g_vpr_ctx.device(), g_vpr_ctx.clustering(),
|
||||
g_vpr_ctx.routing(),
|
||||
openfpga_ctx.mutable_vpr_routing_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Build the routing graph annotation
|
||||
* - RRGSB
|
||||
* - DeviceRRGSB
|
||||
*/
|
||||
if (false == is_vpr_rr_graph_supported(g_vpr_ctx.device().rr_graph)) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Build incoming edges as VPR only builds fan-out edges for each node */
|
||||
g_vpr_ctx.mutable_device().rr_graph_builder.build_in_edges();
|
||||
VTR_LOG("Built %ld incoming edges for routing resource graph\n",
|
||||
g_vpr_ctx.device().rr_graph.in_edges_count());
|
||||
VTR_ASSERT(g_vpr_ctx.device().rr_graph.validate_in_edges());
|
||||
annotate_device_rr_gsb(g_vpr_ctx.device(),
|
||||
openfpga_ctx.mutable_device_rr_gsb(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
if (true == cmd_context.option_enable(cmd, opt_sort_edge)) {
|
||||
sort_device_rr_gsb_chan_node_in_edges(
|
||||
g_vpr_ctx.device().rr_graph, openfpga_ctx.mutable_device_rr_gsb(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
sort_device_rr_gsb_ipin_node_in_edges(
|
||||
g_vpr_ctx.device().rr_graph, openfpga_ctx.mutable_device_rr_gsb(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
}
|
||||
|
||||
/* Build multiplexer library */
|
||||
openfpga_ctx.mutable_mux_lib() = build_device_mux_library(
|
||||
g_vpr_ctx.device(), const_cast<const T&>(openfpga_ctx));
|
||||
|
||||
/* Build tile direct annotation */
|
||||
openfpga_ctx.mutable_tile_direct() = build_device_tile_direct(
|
||||
g_vpr_ctx.device(), openfpga_ctx.arch().arch_direct,
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* Annotate clustering results */
|
||||
if (CMD_EXEC_FATAL_ERROR ==
|
||||
annotate_post_routing_cluster_sync_results(
|
||||
g_vpr_ctx.device(), g_vpr_ctx.clustering(),
|
||||
openfpga_ctx.mutable_vpr_clustering_annotation())) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Annotate placement results */
|
||||
annotate_mapped_blocks(g_vpr_ctx.device(), g_vpr_ctx.clustering(),
|
||||
g_vpr_ctx.placement(),
|
||||
openfpga_ctx.mutable_vpr_placement_annotation());
|
||||
|
||||
/* Read activity file is manadatory in the following flow-run settings
|
||||
* - When users specify that number of clock cycles
|
||||
* should be inferred from FPGA implmentation
|
||||
* - When FPGA-SPICE is enabled
|
||||
*/
|
||||
std::unordered_map<AtomNetId, t_net_power> net_activity;
|
||||
if (true == cmd_context.option_enable(cmd, opt_activity_file)) {
|
||||
net_activity =
|
||||
read_activity(g_vpr_ctx.atom().nlist,
|
||||
cmd_context.option_value(cmd, opt_activity_file).c_str());
|
||||
}
|
||||
|
||||
/* TODO: Annotate the number of clock cycles and clock frequency by following
|
||||
* VPR results We SHOULD create a new simulation setting for OpenFPGA use only
|
||||
* Avoid overwrite the raw data achieved when parsing!!!
|
||||
*/
|
||||
/* OVERWRITE the simulation setting in openfpga context from the arch
|
||||
* TODO: This will be removed when openfpga flow is updated
|
||||
*/
|
||||
// openfpga_ctx.mutable_simulation_setting() =
|
||||
// openfpga_ctx.mutable_arch().sim_setting;
|
||||
if (CMD_EXEC_FATAL_ERROR ==
|
||||
annotate_simulation_setting(g_vpr_ctx.atom(), g_vpr_ctx.clustering(),
|
||||
net_activity,
|
||||
openfpga_ctx.mutable_simulation_setting())) {
|
||||
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.vpr_device_annotation(),
|
||||
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;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue