add exit codes to command execution in shell context
This commit is contained in:
parent
b9ade3fcb6
commit
b9dab2baaf
|
@ -0,0 +1,27 @@
|
|||
#ifndef COMMAND_EXIT_CODES_H
|
||||
#define COMMAND_EXIT_CODES_H
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/*********************************************************************
|
||||
* Exit codes to signal success/failure status of command execution
|
||||
* Depend on the exit code, OpenFPGA shell will decide to continue or abort
|
||||
********************************************************************/
|
||||
|
||||
/* Never been executed */
|
||||
constexpr int CMD_EXEC_NONE = -1;
|
||||
|
||||
/* Everything OK */
|
||||
constexpr int CMD_EXEC_SUCCESS = 0;
|
||||
|
||||
/* Fatal error occurred, we have to abort and do not execute the rest of commands */
|
||||
constexpr int CMD_EXEC_FATAL_ERROR = 1;
|
||||
|
||||
/* See minor errors but it will not impact the downsteam. We can continue to execute the rest of commands */
|
||||
constexpr int CMD_EXEC_MINOR_ERROR = 2;
|
||||
|
||||
|
||||
} /* End namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -10,6 +10,7 @@
|
|||
#include "vtr_range.h"
|
||||
#include "command.h"
|
||||
#include "command_context.h"
|
||||
#include "command_exit_codes.h"
|
||||
#include "shell_fwd.h"
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
|
@ -88,25 +89,49 @@ class Shell {
|
|||
ShellCommandId add_command(const Command& cmd, const char* descr);
|
||||
void set_command_class(const ShellCommandId& cmd_id, const ShellCommandClassId& cmd_class_id);
|
||||
/* Link the execute function to a command
|
||||
* We support here three types of functions to be executed in the shell
|
||||
* 1. Standard function, including the data exchange <T> and commands
|
||||
* 2. Short function, including only the data exchange <T>
|
||||
* 3. Built-in function, including only the shell envoriment variables
|
||||
* 4. Marco function, which directly call a macro function without command parsing
|
||||
* We support here different types of functions to be executed in the shell
|
||||
* Users just need to specify the function object and its type will be automatically inferred
|
||||
*
|
||||
* Note that all the function should return exit codes complying to the shell_exit_code.h
|
||||
* execept the internal functions
|
||||
*/
|
||||
|
||||
/* Standard function, including the data exchange <T> and commands
|
||||
* This function requires the data exchange <T> to be constant
|
||||
* This is designed for outputting functions requiring external data than the <T>
|
||||
*/
|
||||
void set_command_const_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(const T&, const Command&, const CommandContext&)> exec_func);
|
||||
std::function<int(const T&, const Command&, const CommandContext&)> exec_func);
|
||||
|
||||
/* Standard function, including the data exchange <T> and commands
|
||||
* This function allows modification to the data exchange <T>
|
||||
* This is designed for implementing functions requiring external data than the <T>
|
||||
*/
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(T&, const Command&, const CommandContext&)> exec_func);
|
||||
std::function<int(T&, const Command&, const CommandContext&)> exec_func);
|
||||
|
||||
/* Short function, including only the data exchange <T>
|
||||
* This function requires the data exchange <T> to be constant
|
||||
* This is designed for outputting functions without external data than the <T>
|
||||
*/
|
||||
void set_command_const_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(const T&)> exec_func);
|
||||
std::function<int(const T&)> exec_func);
|
||||
|
||||
/* Short function, including only the data exchange <T>
|
||||
* This function allows modification to the data exchange <T>
|
||||
* This is designed for internal implementing functions without external data than the <T>
|
||||
*/
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(T&)> exec_func);
|
||||
std::function<int(T&)> exec_func);
|
||||
|
||||
/* Built-in function, including only the shell envoriment variables */
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void()> exec_func);
|
||||
|
||||
/* Marco function, which directly call a macro function without command parsing */
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<int(int, char**)> exec_func);
|
||||
|
||||
void set_command_dependency(const ShellCommandId& cmd_id,
|
||||
const std::vector<ShellCommandId>& cmd_dependency);
|
||||
ShellCommandClassId add_command_class(const char* name);
|
||||
|
@ -126,7 +151,7 @@ class Shell {
|
|||
/* Execute a command, the command line is the user's input to launch a command
|
||||
* The common_context is the data structure to exchange data between commands
|
||||
*/
|
||||
void execute_command(const char* cmd_line, T& common_context);
|
||||
int execute_command(const char* cmd_line, T& common_context);
|
||||
private: /* Internal data */
|
||||
/* Name of the shell, this will appear in the interactive mode */
|
||||
std::string name_;
|
||||
|
@ -162,10 +187,10 @@ class Shell {
|
|||
* 3. Built-in function, including only the shell envoriment variables
|
||||
* 4. Marco function, which directly call a macro function without command parsing
|
||||
*/
|
||||
vtr::vector<ShellCommandId, std::function<void(const T&, const Command&, const CommandContext&)>> command_const_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void(T&, const Command&, const CommandContext&)>> command_standard_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void(const T&)>> command_short_const_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void(T&)>> command_short_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<int(const T&, const Command&, const CommandContext&)>> command_const_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<int(T&, const Command&, const CommandContext&)>> command_standard_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<int(const T&)>> command_short_const_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<int(T&)>> command_short_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void()>> command_builtin_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<int(int, char**)>> command_macro_execute_functions_;
|
||||
|
||||
|
@ -175,7 +200,7 @@ class Shell {
|
|||
vtr::vector<ShellCommandId, e_exec_func_type> command_execute_function_types_;
|
||||
|
||||
/* A flag to indicate if the command has been executed */
|
||||
vtr::vector<ShellCommandId, bool> command_status_;
|
||||
vtr::vector<ShellCommandId, int> command_status_;
|
||||
|
||||
/* Dependency graph for different commands,
|
||||
* This helps the shell interface to check if a command need other commands to be run before its execution
|
||||
|
|
|
@ -131,7 +131,7 @@ ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
|
|||
command_short_execute_functions_.emplace_back();
|
||||
command_builtin_execute_functions_.emplace_back();
|
||||
command_macro_execute_functions_.emplace_back();
|
||||
command_status_.push_back(false); /* By default, the command should be marked as never executed */
|
||||
command_status_.push_back(CMD_EXEC_NONE); /* By default, the command should be marked as fatal error as it has been never executed */
|
||||
command_dependencies_.emplace_back();
|
||||
|
||||
/* Register the name in the name2id map */
|
||||
|
@ -155,7 +155,7 @@ void Shell<T>::set_command_class(const ShellCommandId& cmd_id, const ShellComman
|
|||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(const T&, const Command&, const CommandContext&)> exec_func) {
|
||||
std::function<int(const T&, const Command&, const CommandContext&)> exec_func) {
|
||||
VTR_ASSERT(true == valid_command_id(cmd_id));
|
||||
command_execute_function_types_[cmd_id] = CONST_STANDARD;
|
||||
command_const_execute_functions_[cmd_id] = exec_func;
|
||||
|
@ -163,7 +163,7 @@ void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
|
|||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(T&, const Command&, const CommandContext&)> exec_func) {
|
||||
std::function<int(T&, const Command&, const CommandContext&)> exec_func) {
|
||||
VTR_ASSERT(true == valid_command_id(cmd_id));
|
||||
command_execute_function_types_[cmd_id] = STANDARD;
|
||||
command_standard_execute_functions_[cmd_id] = exec_func;
|
||||
|
@ -171,7 +171,7 @@ void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
|
|||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(const T&)> exec_func) {
|
||||
std::function<int(const T&)> exec_func) {
|
||||
VTR_ASSERT(true == valid_command_id(cmd_id));
|
||||
command_execute_function_types_[cmd_id] = CONST_SHORT;
|
||||
command_short_const_execute_functions_[cmd_id] = exec_func;
|
||||
|
@ -179,7 +179,7 @@ void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
|
|||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(T&)> exec_func) {
|
||||
std::function<int(T&)> exec_func) {
|
||||
VTR_ASSERT(true == valid_command_id(cmd_id));
|
||||
command_execute_function_types_[cmd_id] = SHORT;
|
||||
command_short_execute_functions_[cmd_id] = exec_func;
|
||||
|
@ -341,9 +341,15 @@ void Shell<T>::run_script_mode(const char* script_file_name, T& context) {
|
|||
/* Process the command only when the full command line in ended */
|
||||
if (!cmd_line.empty()) {
|
||||
VTR_LOG("\nCommand line to execute: %s\n", cmd_line.c_str());
|
||||
execute_command(cmd_line.c_str(), context);
|
||||
int status = execute_command(cmd_line.c_str(), context);
|
||||
/* Empty the line ready to start a new line */
|
||||
cmd_line.clear();
|
||||
|
||||
/* Check the execution status of the command, if fatal error happened, we should abort immediately */
|
||||
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||
VTR_LOG("Fatal error occurred!\nAbort and enter interactive mode\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fp.close();
|
||||
|
@ -376,16 +382,49 @@ void Shell<T>::print_commands() const {
|
|||
|
||||
template <class T>
|
||||
void Shell<T>::exit() const {
|
||||
/* Check all the command status, if we see fatal errors or minor errors, we drop an error code */
|
||||
int exit_code = 0;
|
||||
for (const int& status : command_status_) {
|
||||
if ( (status == CMD_EXEC_FATAL_ERROR)
|
||||
|| (status == CMD_EXEC_MINOR_ERROR) ) {
|
||||
exit_code = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show error message if we detect any errors */
|
||||
int num_err = 0;
|
||||
if (0 != exit_code) {
|
||||
VTR_LOG("\n");
|
||||
for (const ShellCommandId& cmd : commands()) {
|
||||
if (command_status_[cmd] == CMD_EXEC_FATAL_ERROR) {
|
||||
VTR_LOG_ERROR("Command '%s' execution has fatal errors\n",
|
||||
commands_[cmd].name().c_str());
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (command_status_[cmd] == CMD_EXEC_MINOR_ERROR) {
|
||||
VTR_LOG_ERROR("Command '%s' execution has minor errors\n",
|
||||
commands_[cmd].name().c_str());
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VTR_LOG("\nFinish execution with %d errors\n",
|
||||
num_err);
|
||||
|
||||
VTR_LOG("\nThank you for using %s!\n",
|
||||
name().c_str());
|
||||
std::exit(0);
|
||||
|
||||
std::exit(exit_code);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Private executors
|
||||
***********************************************************************/
|
||||
template <class T>
|
||||
void Shell<T>::execute_command(const char* cmd_line,
|
||||
int Shell<T>::execute_command(const char* cmd_line,
|
||||
T& common_context) {
|
||||
/* Tokenize the line */
|
||||
openfpga::StringToken tokenizer(cmd_line);
|
||||
|
@ -396,17 +435,18 @@ void Shell<T>::execute_command(const char* cmd_line,
|
|||
if (ShellCommandId::INVALID() == cmd_id) {
|
||||
VTR_LOG("Try to call a command '%s' which is not defined!\n",
|
||||
tokens[0].c_str());
|
||||
return;
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the dependency graph to see if all the prequistics have been met */
|
||||
for (const ShellCommandId& dep_cmd : command_dependencies_[cmd_id]) {
|
||||
if (false == command_status_[dep_cmd]) {
|
||||
if ( (CMD_EXEC_NONE == command_status_[dep_cmd])
|
||||
|| (CMD_EXEC_FATAL_ERROR == command_status_[dep_cmd]) ) {
|
||||
VTR_LOG("Command '%s' is required to be executed before command '%s'!\n",
|
||||
commands_[dep_cmd].name().c_str(), commands_[cmd_id].name().c_str());
|
||||
/* Echo the command help desk */
|
||||
print_command_options(commands_[cmd_id]);
|
||||
return;
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,25 +461,22 @@ void Shell<T>::execute_command(const char* cmd_line,
|
|||
argv[itok] = (char*)malloc((tokens[itok].length() + 1) * sizeof(char));
|
||||
strcpy(argv[itok], tokens[itok].c_str());
|
||||
}
|
||||
/* Execute the marco function */
|
||||
command_macro_execute_functions_[cmd_id](tokens.size(), argv);
|
||||
/* Execute the marco function and record the execution status */
|
||||
command_status_[cmd_id] = command_macro_execute_functions_[cmd_id](tokens.size(), argv);
|
||||
/* Free the argv */
|
||||
for (size_t itok = 0; itok < tokens.size(); ++itok) {
|
||||
free(argv[itok]);
|
||||
}
|
||||
free(argv);
|
||||
|
||||
/* Change the status of the command */
|
||||
command_status_[cmd_id] = true;
|
||||
|
||||
/* Finish for macro command, return */
|
||||
return;
|
||||
return command_status_[cmd_id];
|
||||
}
|
||||
|
||||
if (false == parse_command(tokens, commands_[cmd_id], command_contexts_[cmd_id])) {
|
||||
/* Echo the command */
|
||||
print_command_options(commands_[cmd_id]);
|
||||
return;
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Parse succeed. Let user to confirm selected options */
|
||||
|
@ -448,31 +485,38 @@ void Shell<T>::execute_command(const char* cmd_line,
|
|||
/* Execute the command depending on the type of function ! */
|
||||
switch (command_execute_function_types_[cmd_id]) {
|
||||
case CONST_STANDARD:
|
||||
command_const_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
|
||||
command_status_[cmd_id] = command_const_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
|
||||
break;
|
||||
case STANDARD:
|
||||
command_standard_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
|
||||
command_status_[cmd_id] = command_standard_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
|
||||
break;
|
||||
case CONST_SHORT:
|
||||
command_short_const_execute_functions_[cmd_id](common_context);
|
||||
command_status_[cmd_id] = command_short_const_execute_functions_[cmd_id](common_context);
|
||||
break;
|
||||
case SHORT:
|
||||
command_short_execute_functions_[cmd_id](common_context);
|
||||
command_status_[cmd_id] = command_short_execute_functions_[cmd_id](common_context);
|
||||
break;
|
||||
case BUILTIN:
|
||||
command_builtin_execute_functions_[cmd_id]();
|
||||
/* Built-in execution is always correct */
|
||||
command_status_[cmd_id] = CMD_EXEC_SUCCESS;
|
||||
break;
|
||||
/* MACRO should be executed eariler in this function. It should not appear here */
|
||||
default:
|
||||
/* This is not allowed! Error out */
|
||||
VTR_LOG("Invalid type of execute function for command '%s'!\n",
|
||||
commands_[cmd_id].name().c_str());
|
||||
VTR_LOG_ERROR("Invalid type of execute function for command '%s'!\n",
|
||||
commands_[cmd_id].name().c_str());
|
||||
/* Exit the shell using the exit() function inside this class! */
|
||||
exit();
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Change the status of the command */
|
||||
command_status_[cmd_id] = true;
|
||||
/* Forbid users to return the status CMD_EXEC_NONE */
|
||||
if (CMD_EXEC_NONE == command_status_[cmd_id]) {
|
||||
VTR_LOG_ERROR("It is illegal to return never-executed status for an executed command!\n");
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
return command_status_[cmd_id];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
|
@ -15,16 +15,20 @@ class ShellContext {
|
|||
};
|
||||
|
||||
static
|
||||
void shell_execute_set(ShellContext& context,
|
||||
int shell_execute_set(ShellContext& context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_id = cmd.option("value");
|
||||
/* Get the value of a in the command context */
|
||||
context.a = std::atoi(cmd_context.option_value(cmd, opt_id).c_str());
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
void shell_execute_print(ShellContext& context) {
|
||||
int shell_execute_print(ShellContext& context) {
|
||||
VTR_LOG("a=%d\n", context.a);
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -35,7 +39,7 @@ int shell_execute_print_macro(int argc, char** argv) {
|
|||
VTR_LOG("\t[%d]: %s\n", iarg, argv[iarg]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from archopenfpga library */
|
||||
#include "write_xml_utils.h"
|
||||
|
||||
|
@ -213,8 +216,8 @@ void print_netlist_naming_fix_report(const std::string& fname,
|
|||
* in the users' BLIF netlist that violates the syntax of OpenFPGA
|
||||
* fabric generator, i.e., Verilog generator and SPICE generator
|
||||
*******************************************************************/
|
||||
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
vtr::ScopedStartFinishTimer timer("Check naming violations of netlist blocks and nets");
|
||||
|
||||
/* By default, we replace all the illegal characters with '_' */
|
||||
|
@ -231,7 +234,15 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
|||
num_conflicts);
|
||||
VTR_LOGV(0 == num_conflicts,
|
||||
"Check naming conflicts in the netlist passed.\n");
|
||||
return;
|
||||
|
||||
/* If we see conflicts, report minor error */
|
||||
if (0 < num_conflicts) {
|
||||
return CMD_EXEC_MINOR_ERROR;
|
||||
}
|
||||
|
||||
/* Otherwise, we should see zero conflicts */
|
||||
VTR_ASSERT(0 == num_conflicts);
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/* If the auto correction is enabled, we apply a fix */
|
||||
|
@ -248,6 +259,9 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
|||
cmd_context.option_value(cmd, opt_report).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
|
@ -22,8 +25,8 @@ namespace openfpga {
|
|||
/********************************************************************
|
||||
* A wrapper function to call the build_device_bitstream() in FPGA bitstream
|
||||
*******************************************************************/
|
||||
void fpga_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int fpga_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
CommandOptionId opt_file = cmd.option("file");
|
||||
|
@ -41,19 +44,25 @@ void fpga_bitstream(OpenfpgaContext& openfpga_ctx,
|
|||
write_arch_independent_bitstream_to_xml_file(openfpga_ctx.bitstream_manager(),
|
||||
cmd_context.option_value(cmd, opt_file));
|
||||
}
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the build_fabric_bitstream() in FPGA bitstream
|
||||
*******************************************************************/
|
||||
void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(),
|
||||
openfpga_ctx.module_graph(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void fpga_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int fpga_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "device_rr_gsb.h"
|
||||
#include "device_rr_gsb_utils.h"
|
||||
#include "build_device_module.h"
|
||||
|
@ -56,8 +59,8 @@ void compress_routing_hierarchy(OpenfpgaContext& openfpga_ctx,
|
|||
/********************************************************************
|
||||
* Build the module graph for FPGA device
|
||||
*******************************************************************/
|
||||
void build_fabric(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int build_fabric(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_compress_routing = cmd.option("compress_routing");
|
||||
CommandOptionId opt_duplicate_grid_pin = cmd.option("duplicate_grid_pin");
|
||||
|
@ -77,6 +80,9 @@ void build_fabric(OpenfpgaContext& openfpga_ctx,
|
|||
cmd_context.option_enable(cmd, opt_compress_routing),
|
||||
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void build_fabric(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int build_fabric(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from vpr library */
|
||||
#include "read_activity.h"
|
||||
|
||||
|
@ -59,8 +62,8 @@ bool is_vpr_rr_graph_supported(const RRGraph& rr_graph) {
|
|||
* - physical pb_graph nodes and pb_graph pins
|
||||
* - circuit models for global routing architecture
|
||||
*******************************************************************/
|
||||
void link_arch(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int link_arch(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture");
|
||||
|
||||
|
@ -105,7 +108,7 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
* - DeviceRRGSB
|
||||
*/
|
||||
if (false == is_vpr_rr_graph_supported(g_vpr_ctx.device().rr_graph)) {
|
||||
return;
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
annotate_device_rr_gsb(g_vpr_ctx.device(),
|
||||
|
@ -147,6 +150,9 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
annotate_simulation_setting(g_vpr_ctx.atom(),
|
||||
openfpga_ctx.net_activity(),
|
||||
openfpga_ctx.mutable_arch().sim_setting);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void link_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int link_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from vpr library */
|
||||
#include "vpr_utils.h"
|
||||
|
||||
|
@ -182,7 +185,6 @@ void update_lut_tt_with_post_packing_results(const AtomContext& atom_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Top-level function to fix up the lut truth table results after packing is done
|
||||
* The problem comes from a mismatch between the packing results and
|
||||
|
@ -194,8 +196,8 @@ void update_lut_tt_with_post_packing_results(const AtomContext& atom_ctx,
|
|||
* This function aims to fix the mess after packing so that the truth table
|
||||
* can be synchronized
|
||||
*******************************************************************/
|
||||
void lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Fix up LUT truth tables after packing optimization");
|
||||
|
||||
|
@ -206,6 +208,9 @@ void lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
|
|||
g_vpr_ctx.clustering(),
|
||||
openfpga_context.mutable_vpr_clustering_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from vpr library */
|
||||
#include "vpr_utils.h"
|
||||
|
||||
|
@ -254,8 +257,8 @@ void update_pb_pin_with_post_routing_results(const DeviceContext& device_ctx,
|
|||
* This function aims to fix the mess after routing so that the net mapping
|
||||
* can be synchronized
|
||||
*******************************************************************/
|
||||
void pb_pin_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int pb_pin_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Fix up pb pin mapping results after routing optimization");
|
||||
|
||||
|
@ -268,6 +271,9 @@ void pb_pin_fixup(OpenfpgaContext& openfpga_context,
|
|||
openfpga_context.vpr_routing_annotation(),
|
||||
openfpga_context.mutable_vpr_clustering_annotation(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void pb_pin_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int pb_pin_fixup(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
/* Headers from vtrutil library */
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from archopenfpga library */
|
||||
#include "read_xml_openfpga_arch.h"
|
||||
#include "check_circuit_library.h"
|
||||
|
@ -22,8 +25,8 @@ namespace openfpga {
|
|||
* The command will accept an option '--file' which is the architecture
|
||||
* file provided by users
|
||||
*******************************************************************/
|
||||
void read_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int read_arch(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
|
||||
|
@ -44,6 +47,9 @@ void read_arch(OpenfpgaContext& openfpga_context,
|
|||
* 3. Simulation settings (TODO)
|
||||
*/
|
||||
check_circuit_library(openfpga_context.arch().circuit_lib);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -53,8 +59,8 @@ void read_arch(OpenfpgaContext& openfpga_context,
|
|||
* The command will accept an option '--file' which is the architecture
|
||||
* file provided by users
|
||||
*******************************************************************/
|
||||
void write_arch(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int write_arch(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
|
||||
|
@ -68,6 +74,9 @@ void write_arch(const OpenfpgaContext& openfpga_context,
|
|||
VTR_LOG("Writing XML architecture to '%s'...\n",
|
||||
arch_file_name.c_str());
|
||||
write_xml_openfpga_arch(arch_file_name.c_str(), openfpga_context.arch());
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void read_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int read_arch(OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
void write_arch(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int write_arch(const OpenfpgaContext& openfpga_context,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "build_physical_truth_table.h"
|
||||
#include "repack.h"
|
||||
#include "openfpga_repack.h"
|
||||
|
@ -18,8 +21,8 @@ namespace openfpga {
|
|||
/********************************************************************
|
||||
* A wrapper function to call the fabric_verilog function of FPGA-Verilog
|
||||
*******************************************************************/
|
||||
void repack(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int repack(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
|
@ -35,6 +38,9 @@ void repack(OpenfpgaContext& openfpga_ctx,
|
|||
g_vpr_ctx.clustering(),
|
||||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.arch().circuit_lib);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void repack(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int repack(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
|
@ -22,8 +25,8 @@ namespace openfpga {
|
|||
/********************************************************************
|
||||
* A wrapper function to call the PnR SDC generator of FPGA-SDC
|
||||
*******************************************************************/
|
||||
void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_constrain_global_port = cmd.option("constrain_global_port");
|
||||
|
@ -80,13 +83,16 @@ void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
|||
global_ports,
|
||||
openfpga_ctx.flow_manager().compress_routing());
|
||||
}
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* 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) {
|
||||
int write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
|
||||
|
@ -114,6 +120,9 @@ void write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
|
|||
global_ports,
|
||||
openfpga_ctx.flow_manager().compress_routing());
|
||||
}
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int 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);
|
||||
int write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "verilog_api.h"
|
||||
#include "openfpga_verilog.h"
|
||||
|
||||
|
@ -17,8 +20,8 @@ namespace openfpga {
|
|||
/********************************************************************
|
||||
* A wrapper function to call the fabric Verilog generator of FPGA-Verilog
|
||||
*******************************************************************/
|
||||
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
|
||||
|
@ -48,13 +51,16 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
|||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
options);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the Verilog testbench generator of FPGA-Verilog
|
||||
*******************************************************************/
|
||||
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
|
||||
|
@ -87,6 +93,9 @@ void write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
|||
openfpga_ctx.arch().sim_setting,
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
options);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "write_xml_device_rr_gsb.h"
|
||||
|
||||
#include "openfpga_write_gsb.h"
|
||||
|
@ -19,8 +22,8 @@ namespace openfpga {
|
|||
* Write internal structrure of all the General Switch Blocks (GSBs)
|
||||
* to an XML file
|
||||
*******************************************************************/
|
||||
void write_gsb(const OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
int write_gsb(const OpenfpgaContext& openfpga_ctx,
|
||||
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
|
||||
|
@ -38,6 +41,9 @@ void write_gsb(const OpenfpgaContext& openfpga_ctx,
|
|||
g_vpr_ctx.device().rr_graph,
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void write_gsb(const OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
int write_gsb(const OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
Loading…
Reference in New Issue