Add support for vpi scopes.
This commit is contained in:
parent
e03859b834
commit
66f7ef97da
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# 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
|
||||
|
|
@ -54,7 +54,7 @@ clean:
|
|||
distclean: clean
|
||||
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 \
|
||||
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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -112,6 +112,7 @@ static struct resolv_list_s*resolv_list = 0;
|
|||
*/
|
||||
void compile_init(void)
|
||||
{
|
||||
scope_init();
|
||||
sym_functors = new_symbol_table();
|
||||
functor_init();
|
||||
sym_codespace = new_symbol_table();
|
||||
|
|
@ -132,7 +133,11 @@ void compile_functor(char*label, char*type, unsigned init,
|
|||
{
|
||||
vvp_ipoint_t fdx = functor_allocate();
|
||||
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);
|
||||
|
||||
|
|
@ -146,7 +151,8 @@ void compile_functor(char*label, char*type, unsigned init,
|
|||
the link yet. Save the reference to be resolved later. */
|
||||
|
||||
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) {
|
||||
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
|
||||
this is done. */
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -227,6 +235,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
list that the parser supplied. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < op->argc ; idx += 1) {
|
||||
symbol_value_t tmp;
|
||||
|
||||
switch (op->argt[idx]) {
|
||||
case OA_NONE:
|
||||
break;
|
||||
|
|
@ -255,8 +265,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
break;
|
||||
}
|
||||
|
||||
code->cptr = sym_get_value(sym_codespace,
|
||||
opa->argv[idx].text);
|
||||
tmp = sym_get_value(sym_codespace, opa->argv[idx].text);
|
||||
code->cptr = tmp.num;
|
||||
if (code->cptr == 0) {
|
||||
yyerror("functor undefined");
|
||||
break;
|
||||
|
|
@ -271,8 +281,8 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
break;
|
||||
}
|
||||
|
||||
code->iptr = sym_get_value(sym_functors,
|
||||
opa->argv[idx].text);
|
||||
tmp = sym_get_value(sym_functors, opa->argv[idx].text);
|
||||
code->iptr = tmp.num;
|
||||
if (code->iptr == 0) {
|
||||
yyerror("functor undefined");
|
||||
break;
|
||||
|
|
@ -306,7 +316,9 @@ void compile_vpi_call(char*label, char*name)
|
|||
codespace pointer. Don't need the text of the label after
|
||||
this is done. */
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +341,8 @@ void compile_vpi_call(char*label, char*name)
|
|||
*/
|
||||
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) {
|
||||
yyerror("unresolved address");
|
||||
return;
|
||||
|
|
@ -347,7 +360,9 @@ void compile_thread(char*start_sym)
|
|||
void compile_variable(char*label)
|
||||
{
|
||||
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);
|
||||
obj->table = ft_var;
|
||||
|
|
@ -377,7 +392,8 @@ void compile_cleanup(void)
|
|||
|
||||
/* Try again to look up the symbol that was not defined
|
||||
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) {
|
||||
/* The symbol is defined, link the functor input
|
||||
|
|
@ -395,6 +411,8 @@ void compile_cleanup(void)
|
|||
resolv_list = res;
|
||||
}
|
||||
}
|
||||
|
||||
scope_cleanup();
|
||||
}
|
||||
|
||||
void compile_dump(FILE*fd)
|
||||
|
|
@ -405,7 +423,7 @@ void compile_dump(FILE*fd)
|
|||
functor_dump(fd);
|
||||
fprintf(fd, "UNRESOLVED PORT INPUTS:\n");
|
||||
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");
|
||||
sym_dump(sym_codespace, fd);
|
||||
|
|
@ -416,6 +434,9 @@ void compile_dump(FILE*fd)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add structures for VPI support, and all the %vpi_call
|
||||
* instruction. Get linking of VPI modules to work.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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_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 start instruction, and must already be defined.
|
||||
|
|
@ -98,6 +105,9 @@ extern void compile_dump(FILE*fd);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add structures for VPI support, and all the %vpi_call
|
||||
* instruction. Get linking of VPI modules to work.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
/* These are some keywords that are recognized. */
|
||||
".functor" { return K_FUNCTOR; }
|
||||
".scope" { return K_SCOPE; }
|
||||
".thread" { return K_THREAD; }
|
||||
".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_LABEL
|
||||
|
|
@ -79,6 +79,18 @@ statement
|
|||
| K_vpi_call T_STRING ';'
|
||||
{ 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
|
||||
starting address must already be defined. */
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "symbols.h"
|
||||
|
|
@ -52,7 +52,7 @@ struct tree_node_ {
|
|||
union {
|
||||
struct {
|
||||
char*key;
|
||||
unsigned long val;
|
||||
symbol_value_t val;
|
||||
} leaf[leaf_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
|
||||
* value. If the key is found, set the value only if the force_flag is
|
||||
* true.
|
||||
*/
|
||||
|
||||
static unsigned long find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
||||
const char*key, unsigned long val,
|
||||
static symbol_value_t find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
||||
const char*key, symbol_value_t val,
|
||||
bool force_flag)
|
||||
{
|
||||
if (cur->leaf_flag) {
|
||||
|
|
@ -218,10 +218,13 @@ static unsigned long find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
|||
}
|
||||
|
||||
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) {
|
||||
/* 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) {
|
||||
/* Handle the special case that this is the very first
|
||||
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->count = 1;
|
||||
cur->leaf[0].key = strdup(key);
|
||||
cur->leaf[0].val = 0;
|
||||
cur->leaf[0].val = def;
|
||||
|
||||
tbl->root->count = 1;
|
||||
tbl->root->child[0] = cur;
|
||||
return 0;
|
||||
return cur->leaf[0].val;
|
||||
} 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);
|
||||
for (unsigned idx = 0 ; idx < cur->count ; idx += 1) {
|
||||
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 {
|
||||
|
|
@ -288,6 +294,9 @@ void sym_dump(symbol_table_t tbl, FILE*fd)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -48,6 +48,13 @@
|
|||
*/
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* it. If the value does not exist, create it, initialize it with
|
||||
* 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.
|
||||
|
|
@ -78,6 +85,9 @@ extern void sym_dump(symbol_table_t tbl, FILE*fd);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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)
|
||||
*
|
||||
* $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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
|
@ -85,6 +85,40 @@ the arguments must be some sort of object that can be represented by a
|
|||
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)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -72,6 +72,20 @@ struct __vpiIterator {
|
|||
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
|
||||
* __vpiUserSystf object is created to hold the definition of that
|
||||
|
|
@ -89,6 +103,7 @@ struct __vpiUserSystf {
|
|||
|
||||
struct __vpiSysTaskCall {
|
||||
struct __vpiHandle base;
|
||||
vpiHandle scope;
|
||||
struct __vpiUserSystf*defn;
|
||||
unsigned nargs;
|
||||
vpiHandle*args;
|
||||
|
|
@ -119,8 +134,18 @@ extern vpiHandle vpip_build_vpi_call(const char*name);
|
|||
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 $
|
||||
* 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
|
||||
* Add structures for VPI support, and all the %vpi_call
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -33,7 +33,16 @@
|
|||
|
||||
static vpiHandle systask_handle(int type, vpiHandle ref)
|
||||
{
|
||||
return 0;
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -140,9 +149,10 @@ vpiHandle vpip_build_vpi_call(const char*name)
|
|||
calloc(1, sizeof (struct __vpiSysTaskCall));
|
||||
|
||||
obj->base.vpi_type = &vpip_systask_rt;
|
||||
obj->defn = vpip_find_systf(name);
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->defn = vpip_find_systf(name);
|
||||
obj->nargs = 0;
|
||||
obj->args = 0;
|
||||
obj->args = 0;
|
||||
|
||||
/* If there is a compiletf function, call it here. */
|
||||
if (obj->defn->info.compiletf)
|
||||
|
|
@ -182,6 +192,9 @@ void vpi_register_systf(const struct t_vpi_systf_data*ss)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add structures for VPI support, and all the %vpi_call
|
||||
* instruction. Get linking of VPI modules to work.
|
||||
|
|
|
|||
Loading…
Reference in New Issue