diff --git a/vvp/stop.cc b/vvp/stop.cc index 6d8db6d0f..92bca18c0 100644 --- a/vvp/stop.cc +++ b/vvp/stop.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stop.cc,v 1.2 2003/02/22 06:32:36 steve Exp $" +#ident "$Id: stop.cc,v 1.3 2003/02/23 06:41:54 steve Exp $" #endif /* @@ -43,25 +43,91 @@ # include #endif -static bool interact_flag = true; +struct __vpiScope*stop_current_scope = 0; -static void invoke_systf(const char*txt) -{ - printf("**** System invocation not supported yet.\n"); -} +static bool interact_flag = true; static void cmd_call(unsigned argc, char*argv[]) { - if (argc <= 1) - return; + struct __vpiHandle**table; + unsigned ntable; - vpiHandle call_handle = vpip_build_vpi_call(argv[1], 0, 0, 0, 0); - if (call_handle == 0) - return; + if (stop_current_scope == 0) { + vpip_make_root_iterator(table, ntable); - vpip_execute_vpi_call(0, call_handle); + } else { + table = stop_current_scope->intern; + ntable = stop_current_scope->nintern; + } - vpi_free_object(call_handle); + unsigned vpi_argc = argc - 1; + vpiHandle*vpi_argv = (vpiHandle*)calloc(vpi_argc, sizeof(vpiHandle)); + + unsigned errors = 0; + + for (unsigned idx = 0 ; idx < vpi_argc ; idx += 1) { + vpiHandle handle = 0; + + /* Detect the special case that the argument is the + .(dot) string. This represents the handle for the + current scope. */ + if (stop_current_scope && (strcmp(argv[idx+1], ".") == 0)) + handle = &stop_current_scope->base; + + /* Try to find the vpiHandle within this scope that has + the name in argv[idx+2]. Look in the current scope. */ + + for (unsigned tmp = 0 ; (tmp < ntable)&& !handle ; tmp += 1) { + struct __vpiScope*scope; + struct __vpiSignal*sig; + + switch (table[tmp]->vpi_type->type_code) { + + case vpiModule: + case vpiFunction: + case vpiTask: + case vpiNamedBegin: + case vpiNamedFork: + scope = (struct __vpiScope*) table[idx]; + if (strcmp(scope->name, argv[idx+1]) == 0) + handle = table[tmp]; + break; + + case vpiReg: + case vpiNet: + sig = (struct __vpiSignal*) table[tmp]; + if (strcmp(sig->name, argv[idx+1]) == 0) + handle = table[tmp]; + break; + + } + } + + if (handle == 0) { + printf("call error: I don't know how to" + " pass %s to %s\n", argv[idx+1], argv[0]); + errors += 1; + } + + vpi_argv[idx] = handle; + } + + /* If there are no errors so far, then make up a call to the + vpi task and execute that call. Free the call structure + when we finish. */ + if (errors == 0) { + vpiHandle call_handle = vpip_build_vpi_call(argv[0], 0, 0, + vpi_argc, vpi_argv); + if (call_handle == 0) { + free(vpi_argv); + return; + } + + vpip_execute_vpi_call(0, call_handle); + vpi_free_object(call_handle); + } + + free(vpi_argv); } static void cmd_cont(unsigned, char*[]) @@ -77,12 +143,125 @@ static void cmd_finish(unsigned, char*[]) static void cmd_help(unsigned, char*[]); +static void cmd_list(unsigned, char*[]) +{ + struct __vpiHandle**table; + unsigned ntable; + + if (stop_current_scope == 0) { + vpip_make_root_iterator(table, ntable); + + } else { + table = stop_current_scope->intern; + ntable = stop_current_scope->nintern; + } + + printf("%u items in this scope:\n", ntable); + for (unsigned idx = 0 ; idx < ntable ; idx += 1) { + + struct __vpiScope*scope; + struct __vpiSignal*sig; + + switch (table[idx]->vpi_type->type_code) { + case vpiModule: + scope = (struct __vpiScope*) table[idx]; + printf("module : %s\n", scope->name); + break; + + case vpiReg: + sig = (struct __vpiSignal*) table[idx]; + if ((sig->msb == 0) && (sig->lsb == 0)) + printf("reg : %s%s\n", sig->name, + sig->signed_flag? "signed " : ""); + else + printf("reg : %s%s[%d:%d]\n", sig->name, + sig->signed_flag? "signed " : "", + sig->msb, sig->lsb); + break; + + default: + printf("%8d: \n", + table[idx]->vpi_type->type_code); + break; + } + + } +} + +static void cmd_pop(unsigned, char*[]) +{ + if (stop_current_scope != 0) + stop_current_scope = stop_current_scope->scope; +} + +static void cmd_push(unsigned argc, char* argv[]) +{ + + for (unsigned idx = 1 ; idx < argc ; idx += 1) { + struct __vpiHandle**table; + unsigned ntable; + + struct __vpiScope*child = 0; + + if (stop_current_scope) { + table = stop_current_scope->intern; + ntable = stop_current_scope->nintern; + } else { + vpip_make_root_iterator(table, ntable); + } + + child = 0; + unsigned tmp; + for (tmp = 0 ; tmp < ntable ; tmp += 1) { + if (table[tmp]->vpi_type->type_code != vpiModule) + continue; + + struct __vpiScope*cp = (struct __vpiScope*) table[tmp]; + + /* This is a scope, and the name matches, then + report that I found the child. */ + if (strcmp(cp->name, argv[idx]) == 0) { + child = cp; + break; + } + } + + if (child == 0) { + printf("Scope %s not found.\n", argv[idx]); + return; + } + + stop_current_scope = child; + } +} + static void cmd_time(unsigned, char*[]) { unsigned long ticks = schedule_simtime(); printf("%lu ticks\n", ticks); } +static void cmd_where(unsigned, char*[]) +{ + struct __vpiScope*cur = stop_current_scope; + + while (cur) { + switch (cur->base.vpi_type->type_code) { + case vpiModule: + printf("module %s\n", + cur->name); + break; + default: + printf("scope (%d) %s;\n", + cur->base.vpi_type->type_code, + cur->name); + break; + } + + cur = cur->scope; + } +} + static void cmd_unknown(unsigned, char*argv[]) { printf("Unknown command: %s\n", argv[0]); @@ -95,16 +274,24 @@ struct { void (*proc)(unsigned argc, char*argv[]); const char*summary; } cmd_table[] = { - { "call", &cmd_call, - "Call a system task"}, + { "cd", &cmd_push, + "Synonym for push."}, { "cont", &cmd_cont, "Resume (continue) the simulation"}, { "finish", &cmd_finish, "Finish the simulation."}, - { "help", &cmd_help, + { "help", &cmd_help, "Get help."}, + { "list", &cmd_list, + "List items in the current scope."}, + { "pop", &cmd_pop, + "Pop one scope from the scope stack."}, + { "push", &cmd_push, + "Descend into the named scope."}, { "time", &cmd_time, "Print the current simulation time."}, + { "where", &cmd_where, + "Show current scope, and scope hierarchy stack."}, { 0, &cmd_unknown, 0} }; @@ -116,9 +303,9 @@ static void cmd_help(unsigned argc, char*argv[]) printf("%-8s - %s\n", cmd_table[idx].name, cmd_table[idx].summary); } - printf("\nIf the command starts with a dollar ($) character, it\n" - "is taken instead to be a system task or function call\n" - "and will be parsed and invoked accordingly.\n"); + printf("\nIf the command name starts with a '$' character, it\n" + "is taken to be the name of a system task, and a call is\n" + "built up and executed.\n"); } @@ -139,14 +326,21 @@ static void invoke_command(char*txt) argc += 1; } + /* Look up the command, using argv[0] as the key. */ if (argc > 0) { - unsigned idx; - for (idx = 0 ; cmd_table[idx].name ; idx += 1) - if (strcmp(cmd_table[idx].name, argv[0]) == 0) - break; - cmd_table[idx].proc (argc, argv); + if (argv[0][0] == '$') { + cmd_call(argc, argv); + + } else { + unsigned idx; + for (idx = 0 ; cmd_table[idx].name ; idx += 1) + if (strcmp(cmd_table[idx].name, argv[0]) == 0) + break; + + cmd_table[idx].proc (argc, argv); + } } @@ -169,18 +363,7 @@ void stop_handler(int rc) while (*first && isspace(*first)) first += 1; - /* If the line starts with a $, then this is the - invocation of a system task or system function, so - call the invoke_systf function to handle - it. Otherwise, this is a simple command, so invoke - the command processor. */ - - if (*first == '$') { - invoke_systf(first); - - } else { - invoke_command(first); - } + invoke_command(first); free(input); } @@ -190,6 +373,11 @@ void stop_handler(int rc) /* * $Log: stop.cc,v $ + * Revision 1.3 2003/02/23 06:41:54 steve + * Add to interactive stop mode support for + * current scope, the ability to scan/traverse + * scopes, and the ability to call system tasks. + * * Revision 1.2 2003/02/22 06:32:36 steve * Basic support for system task calls. * diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 0216abd57..43c311486 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_priv.h,v 1.48 2003/02/10 05:20:10 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.49 2003/02/23 06:41:54 steve Exp $" #endif # include "vpi_user.h" @@ -157,6 +157,8 @@ struct __vpiScope { extern struct __vpiScope* vpip_peek_current_scope(void); extern void vpip_attach_to_current_scope(vpiHandle obj); extern vpiHandle vpip_make_root_iterator(void); +extern void vpip_make_root_iterator(struct __vpiHandle**&table, + unsigned&ntable); /* * Signals include the variable types (reg, integer, time) and are @@ -397,6 +399,11 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type); /* * $Log: vpi_priv.h,v $ + * Revision 1.49 2003/02/23 06:41:54 steve + * Add to interactive stop mode support for + * current scope, the ability to scan/traverse + * scopes, and the ability to call system tasks. + * * Revision 1.48 2003/02/10 05:20:10 steve * Add value change callbacks to real variables. * diff --git a/vvp/vpi_scope.cc b/vvp/vpi_scope.cc index 851973075..628fdb484 100644 --- a/vvp/vpi_scope.cc +++ b/vvp/vpi_scope.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_scope.cc,v 1.24 2003/02/11 05:20:45 steve Exp $" +#ident "$Id: vpi_scope.cc,v 1.25 2003/02/23 06:41:54 steve Exp $" #endif # include "compile.h" @@ -43,6 +43,12 @@ vpiHandle vpip_make_root_iterator(void) vpip_root_table_ptr, false); } +void vpip_make_root_iterator(struct __vpiHandle**&table, unsigned&ntable) +{ + table = vpip_root_table_ptr; + ntable = vpip_root_table_cnt; +} + static bool handle_is_scope(vpiHandle obj) { return (obj->vpi_type->type_code == vpiModule) @@ -448,6 +454,11 @@ void vpip_attach_to_current_scope(vpiHandle obj) /* * $Log: vpi_scope.cc,v $ + * Revision 1.25 2003/02/23 06:41:54 steve + * Add to interactive stop mode support for + * current scope, the ability to scan/traverse + * scopes, and the ability to call system tasks. + * * Revision 1.24 2003/02/11 05:20:45 steve * Include vpiRealVar objects in vpiVariables scan. *