Add to interactive stop mode support for
current scope, the ability to scan/traverse scopes, and the ability to call system tasks.
This commit is contained in:
parent
5b7c1bc7e2
commit
7f8433148c
260
vvp/stop.cc
260
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 <malloc.h>
|
||||
#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: <vpi handle>\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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue