Add support for vpi scopes.
This commit is contained in:
parent
e03859b834
commit
66f7ef97da
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.4 2001/03/16 01:44:34 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.5 2001/03/18 00:37:55 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -54,7 +54,7 @@ clean:
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f config.h Makefile config.cache config.log config.status
|
rm -f config.h Makefile config.cache config.log config.status
|
||||||
|
|
||||||
V = vpi_modules.o vpi_iter.o vpi_mcd.o vpi_priv.o vpi_tasks.o
|
V = vpi_modules.o vpi_iter.o vpi_mcd.o vpi_priv.o vpi_scope.o vpi_tasks.o
|
||||||
|
|
||||||
O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \
|
O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \
|
||||||
codes.o vthread.o schedule.o tables.o $V
|
codes.o vthread.o schedule.o tables.o $V
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: compile.cc,v 1.4 2001/03/16 01:44:34 steve Exp $"
|
#ident "$Id: compile.cc,v 1.5 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "compile.h"
|
# include "compile.h"
|
||||||
|
|
@ -112,6 +112,7 @@ static struct resolv_list_s*resolv_list = 0;
|
||||||
*/
|
*/
|
||||||
void compile_init(void)
|
void compile_init(void)
|
||||||
{
|
{
|
||||||
|
scope_init();
|
||||||
sym_functors = new_symbol_table();
|
sym_functors = new_symbol_table();
|
||||||
functor_init();
|
functor_init();
|
||||||
sym_codespace = new_symbol_table();
|
sym_codespace = new_symbol_table();
|
||||||
|
|
@ -132,7 +133,11 @@ void compile_functor(char*label, char*type, unsigned init,
|
||||||
{
|
{
|
||||||
vvp_ipoint_t fdx = functor_allocate();
|
vvp_ipoint_t fdx = functor_allocate();
|
||||||
functor_t obj = functor_index(fdx);
|
functor_t obj = functor_index(fdx);
|
||||||
sym_set_value(sym_functors, label, fdx);
|
|
||||||
|
{ symbol_value_t val;
|
||||||
|
val.num = fdx;
|
||||||
|
sym_set_value(sym_functors, label, val);
|
||||||
|
}
|
||||||
|
|
||||||
assert(argc <= 4);
|
assert(argc <= 4);
|
||||||
|
|
||||||
|
|
@ -146,7 +151,8 @@ void compile_functor(char*label, char*type, unsigned init,
|
||||||
the link yet. Save the reference to be resolved later. */
|
the link yet. Save the reference to be resolved later. */
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < argc ; idx += 1) {
|
for (unsigned idx = 0 ; idx < argc ; idx += 1) {
|
||||||
vvp_ipoint_t tmp = sym_get_value(sym_functors, argv[idx]);
|
symbol_value_t val = sym_get_value(sym_functors, argv[idx]);
|
||||||
|
vvp_ipoint_t tmp = val.num;
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
functor_t fport = functor_index(tmp);
|
functor_t fport = functor_index(tmp);
|
||||||
|
|
@ -198,7 +204,9 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
||||||
codespace pointer. Don't need the text of the label after
|
codespace pointer. Don't need the text of the label after
|
||||||
this is done. */
|
this is done. */
|
||||||
if (label) {
|
if (label) {
|
||||||
sym_set_value(sym_codespace, label, ptr);
|
symbol_value_t val;
|
||||||
|
val.num = ptr;
|
||||||
|
sym_set_value(sym_codespace, label, val);
|
||||||
free(label);
|
free(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,6 +235,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
||||||
list that the parser supplied. */
|
list that the parser supplied. */
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < op->argc ; idx += 1) {
|
for (unsigned idx = 0 ; idx < op->argc ; idx += 1) {
|
||||||
|
symbol_value_t tmp;
|
||||||
|
|
||||||
switch (op->argt[idx]) {
|
switch (op->argt[idx]) {
|
||||||
case OA_NONE:
|
case OA_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
@ -255,8 +265,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
code->cptr = sym_get_value(sym_codespace,
|
tmp = sym_get_value(sym_codespace, opa->argv[idx].text);
|
||||||
opa->argv[idx].text);
|
code->cptr = tmp.num;
|
||||||
if (code->cptr == 0) {
|
if (code->cptr == 0) {
|
||||||
yyerror("functor undefined");
|
yyerror("functor undefined");
|
||||||
break;
|
break;
|
||||||
|
|
@ -271,8 +281,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
code->iptr = sym_get_value(sym_functors,
|
tmp = sym_get_value(sym_functors, opa->argv[idx].text);
|
||||||
opa->argv[idx].text);
|
code->iptr = tmp.num;
|
||||||
if (code->iptr == 0) {
|
if (code->iptr == 0) {
|
||||||
yyerror("functor undefined");
|
yyerror("functor undefined");
|
||||||
break;
|
break;
|
||||||
|
|
@ -306,7 +316,9 @@ void compile_vpi_call(char*label, char*name)
|
||||||
codespace pointer. Don't need the text of the label after
|
codespace pointer. Don't need the text of the label after
|
||||||
this is done. */
|
this is done. */
|
||||||
if (label) {
|
if (label) {
|
||||||
sym_set_value(sym_codespace, label, ptr);
|
symbol_value_t val;
|
||||||
|
val.num = ptr;
|
||||||
|
sym_set_value(sym_codespace, label, val);
|
||||||
free(label);
|
free(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,7 +341,8 @@ void compile_vpi_call(char*label, char*name)
|
||||||
*/
|
*/
|
||||||
void compile_thread(char*start_sym)
|
void compile_thread(char*start_sym)
|
||||||
{
|
{
|
||||||
vvp_cpoint_t pc = sym_get_value(sym_codespace, start_sym);
|
symbol_value_t tmp = sym_get_value(sym_codespace, start_sym);
|
||||||
|
vvp_cpoint_t pc = tmp.num;
|
||||||
if (pc == 0) {
|
if (pc == 0) {
|
||||||
yyerror("unresolved address");
|
yyerror("unresolved address");
|
||||||
return;
|
return;
|
||||||
|
|
@ -347,7 +360,9 @@ void compile_thread(char*start_sym)
|
||||||
void compile_variable(char*label)
|
void compile_variable(char*label)
|
||||||
{
|
{
|
||||||
vvp_ipoint_t fdx = functor_allocate();
|
vvp_ipoint_t fdx = functor_allocate();
|
||||||
sym_set_value(sym_functors, label, fdx);
|
symbol_value_t val;
|
||||||
|
val.num = fdx;
|
||||||
|
sym_set_value(sym_functors, label, val);
|
||||||
|
|
||||||
functor_t obj = functor_index(fdx);
|
functor_t obj = functor_index(fdx);
|
||||||
obj->table = ft_var;
|
obj->table = ft_var;
|
||||||
|
|
@ -377,7 +392,8 @@ void compile_cleanup(void)
|
||||||
|
|
||||||
/* Try again to look up the symbol that was not defined
|
/* Try again to look up the symbol that was not defined
|
||||||
the first time around. */
|
the first time around. */
|
||||||
vvp_ipoint_t tmp = sym_get_value(sym_functors, res->source);
|
symbol_value_t val = sym_get_value(sym_functors, res->source);
|
||||||
|
vvp_ipoint_t tmp = val.num;
|
||||||
|
|
||||||
if (tmp != 0) {
|
if (tmp != 0) {
|
||||||
/* The symbol is defined, link the functor input
|
/* The symbol is defined, link the functor input
|
||||||
|
|
@ -395,6 +411,8 @@ void compile_cleanup(void)
|
||||||
resolv_list = res;
|
resolv_list = res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_dump(FILE*fd)
|
void compile_dump(FILE*fd)
|
||||||
|
|
@ -405,7 +423,7 @@ void compile_dump(FILE*fd)
|
||||||
functor_dump(fd);
|
functor_dump(fd);
|
||||||
fprintf(fd, "UNRESOLVED PORT INPUTS:\n");
|
fprintf(fd, "UNRESOLVED PORT INPUTS:\n");
|
||||||
for (struct resolv_list_s*cur = resolv_list ; cur ; cur = cur->next)
|
for (struct resolv_list_s*cur = resolv_list ; cur ; cur = cur->next)
|
||||||
fprintf(fd, " %p: %s\n", cur->port, cur->source);
|
fprintf(fd, " %p: %s\n", (void*)cur->port, cur->source);
|
||||||
|
|
||||||
fprintf(fd, "CODE SPACE SYMBOL TABLE:\n");
|
fprintf(fd, "CODE SPACE SYMBOL TABLE:\n");
|
||||||
sym_dump(sym_codespace, fd);
|
sym_dump(sym_codespace, fd);
|
||||||
|
|
@ -416,6 +434,9 @@ void compile_dump(FILE*fd)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compile.cc,v $
|
* $Log: compile.cc,v $
|
||||||
|
* Revision 1.5 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.4 2001/03/16 01:44:34 steve
|
* Revision 1.4 2001/03/16 01:44:34 steve
|
||||||
* Add structures for VPI support, and all the %vpi_call
|
* Add structures for VPI support, and all the %vpi_call
|
||||||
* instruction. Get linking of VPI modules to work.
|
* instruction. Get linking of VPI modules to work.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: compile.h,v 1.3 2001/03/16 01:44:34 steve Exp $"
|
#ident "$Id: compile.h,v 1.4 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
@ -79,6 +79,13 @@ typedef struct comp_operands_s*comp_operands_t;
|
||||||
extern void compile_code(char*label, char*mnem, comp_operands_t opa);
|
extern void compile_code(char*label, char*mnem, comp_operands_t opa);
|
||||||
extern void compile_vpi_call(char*label, char*name);
|
extern void compile_vpi_call(char*label, char*name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parser uses these functions to compile .scope statements.
|
||||||
|
* The implementations of these live in the vpi_scope.cc file.
|
||||||
|
*/
|
||||||
|
extern void compile_scope_decl(char*lab, char*nam, char*par);
|
||||||
|
extern void compile_scope_recall(char*sym);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The parser uses this function to declare a thread. The start_sym is
|
* The parser uses this function to declare a thread. The start_sym is
|
||||||
* the start instruction, and must already be defined.
|
* the start instruction, and must already be defined.
|
||||||
|
|
@ -98,6 +105,9 @@ extern void compile_dump(FILE*fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compile.h,v $
|
* $Log: compile.h,v $
|
||||||
|
* Revision 1.4 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.3 2001/03/16 01:44:34 steve
|
* Revision 1.3 2001/03/16 01:44:34 steve
|
||||||
* Add structures for VPI support, and all the %vpi_call
|
* Add structures for VPI support, and all the %vpi_call
|
||||||
* instruction. Get linking of VPI modules to work.
|
* instruction. Get linking of VPI modules to work.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
/* These are some keywords that are recognized. */
|
/* These are some keywords that are recognized. */
|
||||||
".functor" { return K_FUNCTOR; }
|
".functor" { return K_FUNCTOR; }
|
||||||
|
".scope" { return K_SCOPE; }
|
||||||
".thread" { return K_THREAD; }
|
".thread" { return K_THREAD; }
|
||||||
".var" { return K_VAR; }
|
".var" { return K_VAR; }
|
||||||
|
|
||||||
|
|
|
||||||
14
vvp/parse.y
14
vvp/parse.y
|
|
@ -21,7 +21,7 @@ extern FILE*yyin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
%token K_FUNCTOR K_THREAD K_VAR K_vpi_call
|
%token K_FUNCTOR K_SCOPE K_THREAD K_VAR K_vpi_call
|
||||||
|
|
||||||
%token <text> T_INSTR
|
%token <text> T_INSTR
|
||||||
%token <text> T_LABEL
|
%token <text> T_LABEL
|
||||||
|
|
@ -79,6 +79,18 @@ statement
|
||||||
| K_vpi_call T_STRING ';'
|
| K_vpi_call T_STRING ';'
|
||||||
{ compile_vpi_call(0, $2); }
|
{ compile_vpi_call(0, $2); }
|
||||||
|
|
||||||
|
/* Scope statements come in two forms. There are the scope
|
||||||
|
declaration and the scope recall. */
|
||||||
|
|
||||||
|
| T_LABEL K_SCOPE T_STRING ';'
|
||||||
|
{ compile_scope_decl($1, $3, 0); }
|
||||||
|
|
||||||
|
| T_LABEL K_SCOPE T_STRING ',' T_SYMBOL ';'
|
||||||
|
{ compile_scope_decl($1, $3, $5); }
|
||||||
|
|
||||||
|
| K_SCOPE T_SYMBOL ';'
|
||||||
|
{ compile_scope_recall($2); }
|
||||||
|
|
||||||
/* Thread statements declare a thread with its starting address. The
|
/* Thread statements declare a thread with its starting address. The
|
||||||
starting address must already be defined. */
|
starting address must already be defined. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: symbols.cc,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
#ident "$Id: symbols.cc,v 1.2 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "symbols.h"
|
# include "symbols.h"
|
||||||
|
|
@ -52,7 +52,7 @@ struct tree_node_ {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
char*key;
|
char*key;
|
||||||
unsigned long val;
|
symbol_value_t val;
|
||||||
} leaf[leaf_width];
|
} leaf[leaf_width];
|
||||||
|
|
||||||
struct tree_node_*child[node_width];
|
struct tree_node_*child[node_width];
|
||||||
|
|
@ -142,14 +142,14 @@ static struct tree_node_* split_leaf_(struct tree_node_*cur)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thid function searches tree recursively for the key. If the value
|
* This function searches tree recursively for the key. If the value
|
||||||
* is not found (and we are at a leaf) then set the key with the given
|
* is not found (and we are at a leaf) then set the key with the given
|
||||||
* value. If the key is found, set the value only if the force_flag is
|
* value. If the key is found, set the value only if the force_flag is
|
||||||
* true.
|
* true.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned long find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
static symbol_value_t find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
||||||
const char*key, unsigned long val,
|
const char*key, symbol_value_t val,
|
||||||
bool force_flag)
|
bool force_flag)
|
||||||
{
|
{
|
||||||
if (cur->leaf_flag) {
|
if (cur->leaf_flag) {
|
||||||
|
|
@ -218,10 +218,13 @@ static unsigned long find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
{ symbol_value_t tmp;
|
||||||
|
tmp.num = 0;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_set_value(symbol_table_t tbl, const char*key, unsigned long val)
|
void sym_set_value(symbol_table_t tbl, const char*key, symbol_value_t val)
|
||||||
{
|
{
|
||||||
if (tbl->root->count == 0) {
|
if (tbl->root->count == 0) {
|
||||||
/* Handle the special case that this is the very first
|
/* Handle the special case that this is the very first
|
||||||
|
|
@ -241,8 +244,11 @@ void sym_set_value(symbol_table_t tbl, const char*key, unsigned long val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long sym_get_value(symbol_table_t tbl, const char*key)
|
symbol_value_t sym_get_value(symbol_table_t tbl, const char*key)
|
||||||
{
|
{
|
||||||
|
symbol_value_t def;
|
||||||
|
def.num = 0;
|
||||||
|
|
||||||
if (tbl->root->count == 0) {
|
if (tbl->root->count == 0) {
|
||||||
/* Handle the special case that this is the very first
|
/* Handle the special case that this is the very first
|
||||||
value in the symbol table. Create the first leaf node
|
value in the symbol table. Create the first leaf node
|
||||||
|
|
@ -252,13 +258,13 @@ unsigned long sym_get_value(symbol_table_t tbl, const char*key)
|
||||||
cur->parent = tbl->root;
|
cur->parent = tbl->root;
|
||||||
cur->count = 1;
|
cur->count = 1;
|
||||||
cur->leaf[0].key = strdup(key);
|
cur->leaf[0].key = strdup(key);
|
||||||
cur->leaf[0].val = 0;
|
cur->leaf[0].val = def;
|
||||||
|
|
||||||
tbl->root->count = 1;
|
tbl->root->count = 1;
|
||||||
tbl->root->child[0] = cur;
|
tbl->root->child[0] = cur;
|
||||||
return 0;
|
return cur->leaf[0].val;
|
||||||
} else {
|
} else {
|
||||||
return find_value_(tbl, tbl->root, key, 0, false);
|
return find_value_(tbl, tbl->root, key, def, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,7 +276,7 @@ static void dump_tree(struct tree_node_*cur, unsigned ind, FILE*fd)
|
||||||
fprintf(fd, "%*s%p: %u keys\n", ind, "", cur, cur->count);
|
fprintf(fd, "%*s%p: %u keys\n", ind, "", cur, cur->count);
|
||||||
for (unsigned idx = 0 ; idx < cur->count ; idx += 1) {
|
for (unsigned idx = 0 ; idx < cur->count ; idx += 1) {
|
||||||
fprintf(fd, "%*s %3d: key=%s, val=0x%lx\n", ind, "",
|
fprintf(fd, "%*s %3d: key=%s, val=0x%lx\n", ind, "",
|
||||||
idx, cur->leaf[idx].key, cur->leaf[idx].val);
|
idx, cur->leaf[idx].key, cur->leaf[idx].val.num);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -288,6 +294,9 @@ void sym_dump(symbol_table_t tbl, FILE*fd)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: symbols.cc,v $
|
* $Log: symbols.cc,v $
|
||||||
|
* Revision 1.2 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||||
* Add the vvp engine to cvs.
|
* Add the vvp engine to cvs.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: symbols.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
#ident "$Id: symbols.h,v 1.2 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -48,6 +48,13 @@
|
||||||
*/
|
*/
|
||||||
typedef struct symbol_table_s *symbol_table_t;
|
typedef struct symbol_table_s *symbol_table_t;
|
||||||
|
|
||||||
|
typedef struct symbol_value_s {
|
||||||
|
union {
|
||||||
|
unsigned long num;
|
||||||
|
void*ptr;
|
||||||
|
};
|
||||||
|
} symbol_value_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new symbol table or release an existing one. A new symbol
|
* Create a new symbol table or release an existing one. A new symbol
|
||||||
* table has no keys and no values. As a symbol table is built up, it
|
* table has no keys and no values. As a symbol table is built up, it
|
||||||
|
|
@ -62,14 +69,14 @@ extern void delete_symbol_table(symbol_table_t tbl);
|
||||||
* This method locates the value in the symbol table and sets its
|
* This method locates the value in the symbol table and sets its
|
||||||
* value. If the key doesn't yet exist, create it.
|
* value. If the key doesn't yet exist, create it.
|
||||||
*/
|
*/
|
||||||
void sym_set_value(symbol_table_t tbl, const char*key, unsigned long val);
|
void sym_set_value(symbol_table_t tbl, const char*key, symbol_value_t val);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method locates the value in the symbol table and returns
|
* This method locates the value in the symbol table and returns
|
||||||
* it. If the value does not exist, create it, initialize it with
|
* it. If the value does not exist, create it, initialize it with
|
||||||
* zero and return the zero value.
|
* zero and return the zero value.
|
||||||
*/
|
*/
|
||||||
unsigned long sym_get_value(symbol_table_t tbl, const char*key);
|
symbol_value_t sym_get_value(symbol_table_t tbl, const char*key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Diagnostic dump of the symbol table.
|
* Diagnostic dump of the symbol table.
|
||||||
|
|
@ -78,6 +85,9 @@ extern void sym_dump(symbol_table_t tbl, FILE*fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: symbols.h,v $
|
* $Log: symbols.h,v $
|
||||||
|
* Revision 1.2 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||||
* Add the vvp engine to cvs.
|
* Add the vvp engine to cvs.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
38
vvp/vpi.txt
38
vvp/vpi.txt
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* $Id: vpi.txt,v 1.2 2001/03/16 01:44:34 steve Exp $
|
* $Id: vpi.txt,v 1.3 2001/03/18 00:37:55 steve Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ thus be caught before the simulation is run.
|
||||||
Verilog.
|
Verilog.
|
||||||
|
|
||||||
The handle that the vvp threads have to the VPI are the vpiHandles of
|
The handle that the vvp threads have to the VPI are the vpiHandles of
|
||||||
the system tasks and functions. The %stask instruction, once compiled,
|
the system tasks and functions. The %vpi_call instruction, once compiled,
|
||||||
carries the vpiHandle of the system task.
|
carries the vpiHandle of the system task.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -85,6 +85,40 @@ the arguments must be some sort of object that can be represented by a
|
||||||
vpiHandle at compile time.
|
vpiHandle at compile time.
|
||||||
|
|
||||||
|
|
||||||
|
SCOPES
|
||||||
|
|
||||||
|
VPI can access scopes as objects of type vpiScope. Scopes have names
|
||||||
|
and can also contain other sub-scopes, all of which the VPI function
|
||||||
|
can access by the vpiInternalScope reference. Therefore, the run-time
|
||||||
|
needs to form a tree of scopes into which other scoped VPI objects are
|
||||||
|
placed.
|
||||||
|
|
||||||
|
A scope is created with a .scope directive, like so:
|
||||||
|
|
||||||
|
<label> .scope "name" [, <parent>];
|
||||||
|
|
||||||
|
The scope takes a string name as the first parameter. If there is an
|
||||||
|
additional parameter, it is a label of the directive for the parent
|
||||||
|
scope. Scopes that have no parent are root scopes. It is an error to
|
||||||
|
declare a scope with the same name more then once in a parent scope.
|
||||||
|
|
||||||
|
The name string given when creating the scope is the basename for the
|
||||||
|
scope. The vvp automatically constructs full names from the scope
|
||||||
|
hierarchy, and runtime VPI code can access that full name with the
|
||||||
|
vpiFullname reference.
|
||||||
|
|
||||||
|
Objects that place themselves in a scope place themselves in the
|
||||||
|
current scope. The current scope is the one that was last mentioned by
|
||||||
|
a .scope directive. If the wrong scope is current, the label on a
|
||||||
|
scope directive can be used to resume a scope. The syntax works like
|
||||||
|
this:
|
||||||
|
|
||||||
|
.scope <symbol>;
|
||||||
|
|
||||||
|
In this case, the <symbol> is the label of a previous scope directive,
|
||||||
|
and is used to identify the scope to be resumed. A scope resume
|
||||||
|
directive cannot have a label.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vpi_priv.h,v 1.1 2001/03/16 01:44:34 steve Exp $"
|
#ident "$Id: vpi_priv.h,v 1.2 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vpi_user.h"
|
# include "vpi_user.h"
|
||||||
|
|
@ -72,6 +72,20 @@ struct __vpiIterator {
|
||||||
unsigned next;
|
unsigned next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scopes are created by .scope statements in the source.
|
||||||
|
*/
|
||||||
|
struct __vpiScope {
|
||||||
|
struct __vpiHandle base;
|
||||||
|
/* The scope has a name. */
|
||||||
|
char*name;
|
||||||
|
/* Keep an array of internal scope items. */
|
||||||
|
struct __vpiHandle**intern;
|
||||||
|
unsigned nintern;
|
||||||
|
};
|
||||||
|
extern vpiHandle vpip_peek_current_scope(void);
|
||||||
|
extern void vpip_attach_to_current_scope(vpiHandle obj);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a loaded VPI module announces a system task/function, one
|
* When a loaded VPI module announces a system task/function, one
|
||||||
* __vpiUserSystf object is created to hold the definition of that
|
* __vpiUserSystf object is created to hold the definition of that
|
||||||
|
|
@ -89,6 +103,7 @@ struct __vpiUserSystf {
|
||||||
|
|
||||||
struct __vpiSysTaskCall {
|
struct __vpiSysTaskCall {
|
||||||
struct __vpiHandle base;
|
struct __vpiHandle base;
|
||||||
|
vpiHandle scope;
|
||||||
struct __vpiUserSystf*defn;
|
struct __vpiUserSystf*defn;
|
||||||
unsigned nargs;
|
unsigned nargs;
|
||||||
vpiHandle*args;
|
vpiHandle*args;
|
||||||
|
|
@ -119,8 +134,18 @@ extern vpiHandle vpip_build_vpi_call(const char*name);
|
||||||
extern void vpip_execute_vpi_call(vpiHandle obj);
|
extern void vpip_execute_vpi_call(vpiHandle obj);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are functions used by the compiler to prepare for compilation
|
||||||
|
* and to finish compilation in preparation for execution.
|
||||||
|
*/
|
||||||
|
extern void scope_init(void);
|
||||||
|
extern void scope_cleanup(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vpi_priv.h,v $
|
* $Log: vpi_priv.h,v $
|
||||||
|
* Revision 1.2 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.1 2001/03/16 01:44:34 steve
|
* Revision 1.1 2001/03/16 01:44:34 steve
|
||||||
* Add structures for VPI support, and all the %vpi_call
|
* Add structures for VPI support, and all the %vpi_call
|
||||||
* instruction. Get linking of VPI modules to work.
|
* instruction. Get linking of VPI modules to work.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: vpi_scope.cc,v 1.1 2001/03/18 00:37:55 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# include "compile.h"
|
||||||
|
# include "vpi_priv.h"
|
||||||
|
# include "symbols.h"
|
||||||
|
# include <malloc.h>
|
||||||
|
# include <assert.h>
|
||||||
|
|
||||||
|
static symbol_table_t scope_table = 0;
|
||||||
|
static struct __vpiScope*current_scope = 0;
|
||||||
|
|
||||||
|
static void attach_to_scope_(struct __vpiScope*scope, vpiHandle obj)
|
||||||
|
{
|
||||||
|
assert(scope);
|
||||||
|
unsigned idx = scope->nintern++;
|
||||||
|
|
||||||
|
if (scope->intern == 0)
|
||||||
|
scope->intern = (vpiHandle*)
|
||||||
|
malloc(sizeof(vpiHandle));
|
||||||
|
else
|
||||||
|
scope->intern = (vpiHandle*)
|
||||||
|
realloc(scope->intern, sizeof(vpiHandle)*scope->nintern);
|
||||||
|
|
||||||
|
scope->intern[idx] = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the compiler encounters a scope declaration, this function
|
||||||
|
* creates and initializes a __vpiScope object with the requested name
|
||||||
|
* and within the addressed parent. The label is used as a key in the
|
||||||
|
* symbol table and the name is used to construct the actual object.
|
||||||
|
*/
|
||||||
|
void compile_scope_decl(char*label, char*name, char*parent)
|
||||||
|
{
|
||||||
|
struct __vpiScope*scope = (struct __vpiScope*)
|
||||||
|
malloc(sizeof(struct __vpiScope));
|
||||||
|
scope->name = name;
|
||||||
|
scope->intern = 0;
|
||||||
|
scope->nintern = 0;
|
||||||
|
|
||||||
|
current_scope = scope;
|
||||||
|
|
||||||
|
symbol_value_t val;
|
||||||
|
val.ptr = scope;
|
||||||
|
sym_set_value(scope_table, label, val);
|
||||||
|
free(label);
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
val = sym_get_value(scope_table, parent);
|
||||||
|
struct __vpiScope*sp = (struct __vpiScope*) val.ptr;
|
||||||
|
attach_to_scope_(sp, &scope->base);
|
||||||
|
free(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compile_scope_recall(char*symbol)
|
||||||
|
{
|
||||||
|
symbol_value_t val = sym_get_value(scope_table, symbol);
|
||||||
|
current_scope = (struct __vpiScope*)val.ptr;
|
||||||
|
free(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle vpip_peek_current_scope(void)
|
||||||
|
{
|
||||||
|
return ¤t_scope->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpip_attach_to_current_scope(vpiHandle obj)
|
||||||
|
{
|
||||||
|
attach_to_scope_(current_scope, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scope_init(void)
|
||||||
|
{
|
||||||
|
scope_table = new_symbol_table();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scope_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: vpi_scope.cc,v $
|
||||||
|
* Revision 1.1 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vpi_tasks.cc,v 1.1 2001/03/16 01:44:34 steve Exp $"
|
#ident "$Id: vpi_tasks.cc,v 1.2 2001/03/18 00:37:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -33,7 +33,16 @@
|
||||||
|
|
||||||
static vpiHandle systask_handle(int type, vpiHandle ref)
|
static vpiHandle systask_handle(int type, vpiHandle ref)
|
||||||
{
|
{
|
||||||
|
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
|
||||||
|
assert((ref->vpi_type->type_code == vpiSysTaskCall)
|
||||||
|
|| (ref->vpi_type->type_code == vpiSysFuncCall));
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case vpiScope:
|
||||||
|
return rfp->scope;
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -140,6 +149,7 @@ vpiHandle vpip_build_vpi_call(const char*name)
|
||||||
calloc(1, sizeof (struct __vpiSysTaskCall));
|
calloc(1, sizeof (struct __vpiSysTaskCall));
|
||||||
|
|
||||||
obj->base.vpi_type = &vpip_systask_rt;
|
obj->base.vpi_type = &vpip_systask_rt;
|
||||||
|
obj->scope = vpip_peek_current_scope();
|
||||||
obj->defn = vpip_find_systf(name);
|
obj->defn = vpip_find_systf(name);
|
||||||
obj->nargs = 0;
|
obj->nargs = 0;
|
||||||
obj->args = 0;
|
obj->args = 0;
|
||||||
|
|
@ -182,6 +192,9 @@ void vpi_register_systf(const struct t_vpi_systf_data*ss)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vpi_tasks.cc,v $
|
* $Log: vpi_tasks.cc,v $
|
||||||
|
* Revision 1.2 2001/03/18 00:37:55 steve
|
||||||
|
* Add support for vpi scopes.
|
||||||
|
*
|
||||||
* Revision 1.1 2001/03/16 01:44:34 steve
|
* Revision 1.1 2001/03/16 01:44:34 steve
|
||||||
* Add structures for VPI support, and all the %vpi_call
|
* Add structures for VPI support, and all the %vpi_call
|
||||||
* instruction. Get linking of VPI modules to work.
|
* instruction. Get linking of VPI modules to work.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue