put analysis sdc writer online. Minor bug in redudant '/' to be fixed
This commit is contained in:
parent
037c7e5c43
commit
3241d8bd37
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "circuit_library_utils.h"
|
||||
#include "pnr_sdc_writer.h"
|
||||
#include "analysis_sdc_writer.h"
|
||||
#include "openfpga_sdc.h"
|
||||
|
||||
/* Include global variables of VPR */
|
||||
|
@ -77,4 +78,38 @@ void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the analysis SDC generator of FPGA-SDC
|
||||
*******************************************************************/
|
||||
void write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
|
||||
/* This is an intermediate data structure which is designed to modularize the FPGA-SDC
|
||||
* Keep it independent from any other outside data structures
|
||||
*/
|
||||
std::string sdc_dir_path = format_dir_path(cmd_context.option_value(cmd, opt_output_dir));
|
||||
|
||||
/* Create directories */
|
||||
create_dir_path(sdc_dir_path.c_str());
|
||||
|
||||
AnalysisSdcOption options(sdc_dir_path);
|
||||
options.set_generate_sdc_analysis(true);
|
||||
|
||||
/* Collect global ports from the circuit library:
|
||||
* TODO: should we place this in the OpenFPGA context?
|
||||
*/
|
||||
std::vector<CircuitPortId> global_ports = find_circuit_library_global_ports(openfpga_ctx.arch().circuit_lib);
|
||||
|
||||
if (true == options.generate_sdc_analysis()) {
|
||||
print_analysis_sdc(options,
|
||||
1./openfpga_ctx.arch().sim_setting.operating_clock_frequency(),
|
||||
g_vpr_ctx,
|
||||
openfpga_ctx,
|
||||
global_ports,
|
||||
openfpga_ctx.flow_manager().compress_routing());
|
||||
}
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace openfpga {
|
|||
void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
void write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,36 @@ ShellCommandId add_openfpga_write_pnr_sdc_command(openfpga::Shell<OpenfpgaContex
|
|||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: generate PnR SDC
|
||||
* - Add associated options
|
||||
* - Add command dependency
|
||||
*******************************************************************/
|
||||
static
|
||||
ShellCommandId add_openfpga_write_analysis_sdc_command(openfpga::Shell<OpenfpgaContext>& shell,
|
||||
const ShellCommandClassId& cmd_class_id,
|
||||
const std::vector<ShellCommandId>& dependent_cmds) {
|
||||
Command shell_cmd("write_analysis_sdc");
|
||||
|
||||
/* Add an option '--file' in short '-f'*/
|
||||
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for SDC files");
|
||||
shell_cmd.set_option_short_name(output_opt, "f");
|
||||
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd.add_option("verbose", false, "Enable verbose output");
|
||||
|
||||
/* Add command 'write_fabric_verilog' to the Shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate SDC files for timing analysis a PnRed FPGA fabric mapped by a benchmark");
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_execute_function(shell_cmd_id, write_analysis_sdc);
|
||||
|
||||
/* Add command dependency to the Shell */
|
||||
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
|
||||
|
||||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
void add_openfpga_sdc_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
||||
/* Get the unique id of 'build_fabric' command which is to be used in creating the dependency graph */
|
||||
const ShellCommandId& build_fabric_id = shell.command(std::string("build_fabric"));
|
||||
|
@ -77,6 +107,17 @@ void add_openfpga_sdc_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
|||
add_openfpga_write_pnr_sdc_command(shell,
|
||||
openfpga_sdc_cmd_class,
|
||||
pnr_sdc_cmd_dependency);
|
||||
|
||||
/********************************
|
||||
* Command 'write_analysis_sdc'
|
||||
*/
|
||||
/* The 'write_analysis_sdc' command should NOT be executed before 'build_fabric' */
|
||||
std::vector<ShellCommandId> analysis_sdc_cmd_dependency;
|
||||
analysis_sdc_cmd_dependency.push_back(build_fabric_id);
|
||||
add_openfpga_write_analysis_sdc_command(shell,
|
||||
openfpga_sdc_cmd_class,
|
||||
analysis_sdc_cmd_dependency);
|
||||
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -49,7 +49,7 @@ void rec_print_analysis_sdc_disable_unused_pb_graph_nodes(std::fstream& fp,
|
|||
*/
|
||||
fp << "set_disable_timing ";
|
||||
fp << hierarchy_name;
|
||||
fp << "/*";
|
||||
fp << "*";
|
||||
fp << std::endl;
|
||||
|
||||
/* Return if this is the primitive pb_type */
|
||||
|
@ -74,7 +74,7 @@ void rec_print_analysis_sdc_disable_unused_pb_graph_nodes(std::fstream& fp,
|
|||
/* Must have a valid instance name!!! */
|
||||
VTR_ASSERT(false == child_instance_name.empty());
|
||||
|
||||
std::string updated_hierarchy_name = hierarchy_name + std::string("/") + child_instance_name + std::string("/");
|
||||
std::string updated_hierarchy_name = hierarchy_name + child_instance_name + std::string("/");
|
||||
|
||||
rec_print_analysis_sdc_disable_unused_pb_graph_nodes(fp, device_annotation, module_manager, child_module, hierarchy_name,
|
||||
&(physical_pb_graph_node->child_pb_graph_nodes[physical_mode->index][ichild][inst]));
|
||||
|
@ -114,7 +114,6 @@ void disable_pb_graph_node_unused_pin(std::fstream& fp,
|
|||
|
||||
fp << "set_disable_timing ";
|
||||
fp << hierarchy_name;
|
||||
fp << "/";
|
||||
fp << generate_sdc_port(port_to_disable);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
@ -407,7 +406,7 @@ void rec_print_analysis_sdc_disable_pb_graph_node_unused_resources(std::fstream&
|
|||
/* Must have a valid instance name!!! */
|
||||
VTR_ASSERT(false == child_instance_name.empty());
|
||||
|
||||
std::string updated_hierarchy_name = hierarchy_name + std::string("/") + child_instance_name + std::string("/");
|
||||
std::string updated_hierarchy_name = hierarchy_name + child_instance_name + std::string("/");
|
||||
|
||||
rec_print_analysis_sdc_disable_pb_graph_node_unused_resources(fp, device_annotation,
|
||||
module_manager, child_module, hierarchy_name,
|
||||
|
@ -591,7 +590,7 @@ void print_analysis_sdc_disable_unused_grids(std::fstream& fp,
|
|||
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
|
||||
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
|
||||
/* We should not meet any I/O grid */
|
||||
VTR_ASSERT(false != is_io_type(grids[ix][iy].type));
|
||||
VTR_ASSERT(false == is_io_type(grids[ix][iy].type));
|
||||
|
||||
print_analysis_sdc_disable_unused_grid(fp, vtr::Point<size_t>(ix, iy),
|
||||
grids, device_annotation, cluster_annotation, place_annotation,
|
||||
|
|
|
@ -202,14 +202,14 @@ void print_analysis_sdc_disable_global_ports(std::fstream& fp,
|
|||
* Top-level function outputs a SDC file
|
||||
* that constrain a FPGA fabric (P&Red netlist) using a benchmark
|
||||
*******************************************************************/
|
||||
void print_analysis_sdc(const std::string& sdc_dir,
|
||||
void print_analysis_sdc(const AnalysisSdcOption& option,
|
||||
const float& critical_path_delay,
|
||||
const VprContext& vpr_ctx,
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
const std::vector<CircuitPortId>& global_ports,
|
||||
const bool& compact_routing_hierarchy) {
|
||||
/* Create the file name for Verilog netlist */
|
||||
std::string sdc_fname(sdc_dir + std::string(SDC_ANALYSIS_FILE_NAME));
|
||||
std::string sdc_fname(option.sdc_dir() + std::string(SDC_ANALYSIS_FILE_NAME));
|
||||
|
||||
std::string timer_message = std::string("Generating SDC for Timing/Power analysis on the mapped FPGA '")
|
||||
+ sdc_fname
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
#include "vpr_context.h"
|
||||
#include "openfpga_context.h"
|
||||
#include "analysis_sdc_option.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
|
@ -16,7 +17,7 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void print_analysis_sdc(const std::string& sdc_dir,
|
||||
void print_analysis_sdc(const AnalysisSdcOption& option,
|
||||
const float& critical_path_delay,
|
||||
const VprContext& vpr_ctx,
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
|
|
|
@ -100,7 +100,7 @@ void disable_analysis_module_input_pin_net_sinks(std::fstream& fp,
|
|||
module_manager.net_sink_pins(parent_module, module_net)[sink_id]);
|
||||
/* Get the input id that is used! Disable the unused inputs! */
|
||||
fp << "set_disable_timing ";
|
||||
fp << parent_instance_name << "/";
|
||||
fp << parent_instance_name;
|
||||
fp << sink_instance_name << "/";
|
||||
fp << generate_sdc_port(sink_port);
|
||||
fp << std::endl;
|
||||
|
@ -223,7 +223,7 @@ void disable_analysis_module_output_pin_net_sinks(std::fstream& fp,
|
|||
module_manager.net_sink_pins(parent_module, module_net)[sink_id]);
|
||||
/* Get the input id that is used! Disable the unused inputs! */
|
||||
fp << "set_disable_timing ";
|
||||
fp << parent_instance_name << "/";
|
||||
fp << parent_instance_name;
|
||||
fp << sink_instance_name << "/";
|
||||
fp << generate_sdc_port(sink_port);
|
||||
fp << std::endl;
|
||||
|
|
|
@ -52,5 +52,8 @@ write_verilog_testbench --file /var/tmp/xtang/openfpga_test_src/SRC --reference_
|
|||
# - Turn on every options here
|
||||
write_pnr_sdc --file /var/tmp/xtang/openfpga_test_src/SDC
|
||||
|
||||
# Write the SDC to run timing analysis for a mapped FPGA fabric
|
||||
write_analysis_sdc --file /var/tmp/xtang/openfpga_test_src/SDC_analysis
|
||||
|
||||
# Finish and exit OpenFPGA
|
||||
exit
|
||||
|
|
Loading…
Reference in New Issue