mirror of https://github.com/YosysHQ/yosys.git
Improved/simplified TCL bindings
This commit is contained in:
parent
83c743f717
commit
97f783e668
|
@ -149,10 +149,13 @@ static char **readline_completion(const char *text, int start, int)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *create_prompt(RTLIL::Design *design)
|
static const char *create_prompt(RTLIL::Design *design, int recursion_counter)
|
||||||
{
|
{
|
||||||
static char buffer[100];
|
static char buffer[100];
|
||||||
std::string str = "\nyosys";
|
std::string str = "\n";
|
||||||
|
if (recursion_counter > 1)
|
||||||
|
str += stringf("(%d) ", recursion_counter);
|
||||||
|
str += "yosys";
|
||||||
if (!design->selected_active_module.empty())
|
if (!design->selected_active_module.empty())
|
||||||
str += stringf(" [%s]", design->selected_active_module.c_str());
|
str += stringf(" [%s]", design->selected_active_module.c_str());
|
||||||
if (!design->selection_stack.back().full_selection) {
|
if (!design->selection_stack.back().full_selection) {
|
||||||
|
@ -168,26 +171,29 @@ static const char *create_prompt(RTLIL::Design *design)
|
||||||
|
|
||||||
static void shell(RTLIL::Design *design)
|
static void shell(RTLIL::Design *design)
|
||||||
{
|
{
|
||||||
static bool recursion_detect = false;
|
static int recursion_counter = 0;
|
||||||
|
|
||||||
if (recursion_detect) {
|
recursion_counter++;
|
||||||
log("Already in interactive shell.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
recursion_detect = true;
|
|
||||||
log_cmd_error_throw = true;
|
log_cmd_error_throw = true;
|
||||||
|
|
||||||
rl_readline_name = "yosys";
|
rl_readline_name = "yosys";
|
||||||
rl_attempted_completion_function = readline_completion;
|
rl_attempted_completion_function = readline_completion;
|
||||||
|
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
while ((command = readline(create_prompt(design))) != NULL)
|
while ((command = readline(create_prompt(design, recursion_counter))) != NULL)
|
||||||
{
|
{
|
||||||
if (command[strspn(command, " \t\r\n")] == 0)
|
if (command[strspn(command, " \t\r\n")] == 0)
|
||||||
continue;
|
continue;
|
||||||
add_history(command);
|
add_history(command);
|
||||||
|
|
||||||
|
char *p = command + strspn(command, " \t\r\n");
|
||||||
|
if (!strncmp(p, "exit", 4)) {
|
||||||
|
p += 4;
|
||||||
|
p += strspn(p, " \t\r\n");
|
||||||
|
if (*p == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert(design->selection_stack.size() == 1);
|
assert(design->selection_stack.size() == 1);
|
||||||
Pass::call(design, command);
|
Pass::call(design, command);
|
||||||
|
@ -197,8 +203,10 @@ static void shell(RTLIL::Design *design)
|
||||||
log_reset_stack();
|
log_reset_stack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (command == NULL)
|
||||||
|
printf("exit\n");
|
||||||
|
|
||||||
recursion_detect = false;
|
recursion_counter--;
|
||||||
log_cmd_error_throw = false;
|
log_cmd_error_throw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +241,7 @@ struct ShellPass : public Pass {
|
||||||
log("This command is the default action if nothing else has been specified\n");
|
log("This command is the default action if nothing else has been specified\n");
|
||||||
log("on the command line.\n");
|
log("on the command line.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Press Ctrl-D to leave the interactive shell.\n");
|
log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
|
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
|
||||||
|
@ -243,7 +251,7 @@ struct ShellPass : public Pass {
|
||||||
} ShellPass;
|
} ShellPass;
|
||||||
|
|
||||||
struct ScriptPass : public Pass {
|
struct ScriptPass : public Pass {
|
||||||
ScriptPass() : Pass("script", "execute files from script file") { }
|
ScriptPass() : Pass("script", "execute commands from script file") { }
|
||||||
virtual void help() {
|
virtual void help() {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" script <filename>\n");
|
log(" script <filename>\n");
|
||||||
|
@ -252,12 +260,45 @@ struct ScriptPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
|
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
|
||||||
if (args.size() != 2)
|
if (args.size() < 2)
|
||||||
|
log_cmd_error("Missing script file.\n");
|
||||||
|
if (args.size() > 2)
|
||||||
extra_args(args, 1, design, false);
|
extra_args(args, 1, design, false);
|
||||||
run_frontend(args[1], "script", design, NULL);
|
run_frontend(args[1], "script", design, NULL);
|
||||||
}
|
}
|
||||||
} ScriptPass;
|
} ScriptPass;
|
||||||
|
|
||||||
|
#ifdef YOSYS_ENABLE_TCL
|
||||||
|
struct TclPass : public Pass {
|
||||||
|
TclPass() : Pass("tcl", "execute a TCL script file") { }
|
||||||
|
virtual void help() {
|
||||||
|
log("\n");
|
||||||
|
log(" tcl <filename>\n");
|
||||||
|
log("\n");
|
||||||
|
log("This command executes the tcl commands in the specified file.\n");
|
||||||
|
log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n");
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
|
||||||
|
if (args.size() < 2)
|
||||||
|
log_cmd_error("Missing script file.\n");
|
||||||
|
if (args.size() > 2)
|
||||||
|
extra_args(args, 1, design, false);
|
||||||
|
if (Tcl_EvalFile(yosys_tcl, args[1].c_str()) != TCL_OK)
|
||||||
|
log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_tcl));
|
||||||
|
}
|
||||||
|
} TclPass;
|
||||||
|
|
||||||
|
static int tcl_yosys_cmd(ClientData, Tcl_Interp*, int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
std::vector<std::string> args;
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
args.push_back(argv[i]);
|
||||||
|
Pass::call(yosys_tcl_design, args);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
std::string frontend_command = "auto";
|
std::string frontend_command = "auto";
|
||||||
|
@ -271,6 +312,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
#ifdef YOSYS_ENABLE_TCL
|
#ifdef YOSYS_ENABLE_TCL
|
||||||
yosys_tcl = Tcl_CreateInterp();
|
yosys_tcl = Tcl_CreateInterp();
|
||||||
|
Tcl_CreateCommand(yosys_tcl, "yosys", tcl_yosys_cmd, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
|
@ -356,6 +398,7 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, " -c tcl_scriptfile\n");
|
fprintf(stderr, " -c tcl_scriptfile\n");
|
||||||
fprintf(stderr, " execute the commands in the tcl script file\n");
|
fprintf(stderr, " execute the commands in the tcl script file\n");
|
||||||
|
fprintf(stderr, " (use 'yosys cmd' to run the yosys command 'cmd' from tcl)\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, " -p command\n");
|
fprintf(stderr, " -p command\n");
|
||||||
fprintf(stderr, " execute the commands\n");
|
fprintf(stderr, " execute the commands\n");
|
||||||
|
|
|
@ -56,8 +56,6 @@ void Pass::run_register()
|
||||||
{
|
{
|
||||||
assert(pass_register.count(pass_name) == 0);
|
assert(pass_register.count(pass_name) == 0);
|
||||||
pass_register[pass_name] = this;
|
pass_register[pass_name] = this;
|
||||||
|
|
||||||
register_tcl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::init_register()
|
void Pass::init_register()
|
||||||
|
@ -77,25 +75,6 @@ void Pass::done_register()
|
||||||
raw_register_done = false;
|
raw_register_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef YOSYS_ENABLE_TCL
|
|
||||||
static int tcl_pass(ClientData that_vp, Tcl_Interp*, int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
Pass *that = (Pass*)that_vp;
|
|
||||||
std::vector<std::string> args;
|
|
||||||
for (int i = 0; i < argc; i++)
|
|
||||||
args.push_back(argv[i]);
|
|
||||||
that->call(yosys_tcl_design, args);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Pass::register_tcl()
|
|
||||||
{
|
|
||||||
#ifdef YOSYS_ENABLE_TCL
|
|
||||||
Tcl_CreateCommand(yosys_tcl, pass_name.c_str(), tcl_pass, (ClientData)this, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Pass::~Pass()
|
Pass::~Pass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -212,8 +191,6 @@ void Frontend::run_register()
|
||||||
|
|
||||||
assert(frontend_register.count(frontend_name) == 0);
|
assert(frontend_register.count(frontend_name) == 0);
|
||||||
frontend_register[frontend_name] = this;
|
frontend_register[frontend_name] = this;
|
||||||
|
|
||||||
register_tcl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Frontend::~Frontend()
|
Frontend::~Frontend()
|
||||||
|
@ -306,8 +283,6 @@ void Backend::run_register()
|
||||||
|
|
||||||
assert(backend_register.count(backend_name) == 0);
|
assert(backend_register.count(backend_name) == 0);
|
||||||
backend_register[backend_name] = this;
|
backend_register[backend_name] = this;
|
||||||
|
|
||||||
register_tcl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Backend::~Backend()
|
Backend::~Backend()
|
||||||
|
|
|
@ -50,7 +50,6 @@ struct Pass
|
||||||
|
|
||||||
static void init_register();
|
static void init_register();
|
||||||
static void done_register();
|
static void done_register();
|
||||||
void register_tcl();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Frontend : Pass
|
struct Frontend : Pass
|
||||||
|
|
Loading…
Reference in New Issue