Add support for system function calls.
This commit is contained in:
parent
983bf5cbab
commit
224af78463
|
|
@ -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.64 2001/05/13 21:05:06 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.65 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -910,7 +910,37 @@ void compile_vpi_call(char*label, char*name, unsigned argc, vpiHandle*argv)
|
|||
|
||||
/* Create a vpiHandle that bundles the call information, and
|
||||
store that handle in the instruction. */
|
||||
code->handle = vpip_build_vpi_call(name, argc, argv);
|
||||
code->handle = vpip_build_vpi_call(name, 0, 0, argc, argv);
|
||||
if (code->handle == 0)
|
||||
compile_errors += 1;
|
||||
|
||||
/* Done with the lexor-allocated name string. */
|
||||
free(name);
|
||||
}
|
||||
|
||||
void compile_vpi_func_call(char*label, char*name,
|
||||
unsigned vbit, unsigned vwid,
|
||||
unsigned argc, vpiHandle*argv)
|
||||
{
|
||||
vvp_cpoint_t ptr = codespace_allocate();
|
||||
|
||||
/* First, I can give the label a value that is the current
|
||||
codespace pointer. Don't need the text of the label after
|
||||
this is done. */
|
||||
if (label) {
|
||||
symbol_value_t val;
|
||||
val.num = ptr;
|
||||
sym_set_value(sym_codespace, label, val);
|
||||
free(label);
|
||||
}
|
||||
|
||||
/* Create an instruction in the code space. */
|
||||
vvp_code_t code = codespace_index(ptr);
|
||||
code->opcode = &of_VPI_CALL;
|
||||
|
||||
/* Create a vpiHandle that bundles the call information, and
|
||||
store that handle in the instruction. */
|
||||
code->handle = vpip_build_vpi_call(name, vbit, vwid, argc, argv);
|
||||
if (code->handle == 0)
|
||||
compile_errors += 1;
|
||||
|
||||
|
|
@ -1163,6 +1193,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.65 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.64 2001/05/13 21:05:06 steve
|
||||
* calculate the output of resolvers.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.22 2001/05/09 04:23:18 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.23 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -145,8 +145,14 @@ typedef struct comp_operands_s*comp_operands_t;
|
|||
|
||||
extern void compile_code(char*label, char*mnem, comp_operands_t opa);
|
||||
extern void compile_disable(char*label, struct symb_s symb);
|
||||
|
||||
extern void compile_vpi_call(char*label, char*name,
|
||||
unsigned argc, vpiHandle*argv);
|
||||
|
||||
extern void compile_vpi_func_call(char*label, char*name,
|
||||
unsigned vbit, unsigned vwid,
|
||||
unsigned argc, vpiHandle*argv);
|
||||
|
||||
extern void compile_fork(char*label, struct symb_s targ_s,
|
||||
struct symb_s scope_s);
|
||||
extern void compile_codelabel(char*label);
|
||||
|
|
@ -176,6 +182,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.23 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.22 2001/05/09 04:23:18 steve
|
||||
* Now that the interactive debugger exists,
|
||||
* there is no use for the output dump.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: lexor.lex,v 1.17 2001/05/10 00:26:53 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.18 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -87,6 +87,7 @@
|
|||
exceptional parameter requirements) are listed first. */
|
||||
|
||||
"%vpi_call" { return K_vpi_call; }
|
||||
"%vpi_func" { return K_vpi_func; }
|
||||
"%disable" { return K_disable; }
|
||||
"%fork" { return K_fork; }
|
||||
|
||||
|
|
@ -139,6 +140,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.18 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.17 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: opcodes.txt,v 1.20 2001/05/08 23:59:33 steve Exp $
|
||||
* $Id: opcodes.txt,v 1.21 2001/05/20 00:46:12 steve Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -283,10 +283,19 @@ See also the %add instruction.
|
|||
|
||||
* %vpi_call <name> [, ...]
|
||||
|
||||
This instruction makes a call to a system task or function that was
|
||||
declared using VPI. The operands are compiled down to a vpiHandle for
|
||||
the call. The instruction contains only the vpiHandle for the
|
||||
call. See the vpi.txt file for more on system task/function calls.
|
||||
This instruction makes a call to a system task that was declared using
|
||||
VPI. The operands are compiled down to a vpiHandle for the call. The
|
||||
instruction contains only the vpiHandle for the call. See the vpi.txt
|
||||
file for more on system task/function calls.
|
||||
|
||||
|
||||
* %vpi_func <name>, <dst>, <wid> [, ...]
|
||||
|
||||
This instruction is similar to %vpi_call, except that it is for
|
||||
calling system functions. The difference here is the <dst> and <wid>
|
||||
parameters that specify where the return value is to go. The normal
|
||||
means that the VPI code uses to write the return value causes those
|
||||
bits to go here.
|
||||
|
||||
|
||||
* %wait <functor-label>
|
||||
|
|
|
|||
15
vvp/parse.y
15
vvp/parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse.y,v 1.26 2001/05/09 02:53:25 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.27 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -57,7 +57,7 @@ extern FILE*yyin;
|
|||
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_RESOLV K_SCOPE K_THREAD
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
%token K_MEM K_MEM_P K_MEM_I
|
||||
%token K_VAR K_VAR_S K_vpi_call K_disable K_fork
|
||||
%token K_VAR K_VAR_S K_vpi_call K_vpi_func K_disable K_fork
|
||||
%token K_vpi_module
|
||||
|
||||
%token <text> T_INSTR
|
||||
|
|
@ -182,11 +182,17 @@ statement
|
|||
{ compile_codelabel($1); }
|
||||
|
||||
/* %vpi_call statements are instructions that have unusual operand
|
||||
requirements so are handled by their own rules. */
|
||||
requirements so are handled by their own rules. The %vpi_func
|
||||
statement is a variant of %vpi_call that includes a thread vector
|
||||
after the name, and is used for function calls. */
|
||||
|
||||
| label_opt K_vpi_call T_STRING argument_opt ';'
|
||||
{ compile_vpi_call($1, $3, $4.argc, $4.argv); }
|
||||
|
||||
| label_opt K_vpi_func T_STRING ','
|
||||
T_NUMBER ',' T_NUMBER argument_opt ';'
|
||||
{ compile_vpi_func_call($1, $3, $5, $7, $8.argc, $8.argv); }
|
||||
|
||||
/* %disable statements are instructions that takes a scope reference
|
||||
as an operand. It therefore is parsed uniquely. */
|
||||
|
||||
|
|
@ -438,6 +444,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.27 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.26 2001/05/09 02:53:25 steve
|
||||
* Implement the .resolv syntax.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.15 2001/05/10 00:26:53 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.16 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -127,12 +127,20 @@ extern vpiHandle vpip_make_memory(vvp_memory_t mem);
|
|||
/*
|
||||
* When a loaded VPI module announces a system task/function, one
|
||||
* __vpiUserSystf object is created to hold the definition of that
|
||||
* task/function.
|
||||
* task/function. The distinction between task and function is stored
|
||||
* in the vpi_systf_data structure data that was supplied by the
|
||||
* external module.
|
||||
*
|
||||
* When the compiler encounters a %vpi_call statement, it creates a
|
||||
* __vpiSysTaskCall to represent that particular call. The call refers
|
||||
* to the definition handle so that when the %vpi_call instruction is
|
||||
* encountered at run-time, the definition can be located and used.
|
||||
*
|
||||
* The vpiSysTaskCall handles both functions and tasks, as the two are
|
||||
* extremely similar. The different VPI type is reflected in a
|
||||
* different vpi_type pointer in the base structure. The only
|
||||
* additional part is the vbit/vwid that is used by the put of the
|
||||
* system function call to place the values in the vthread bit space.
|
||||
*/
|
||||
struct __vpiUserSystf {
|
||||
struct __vpiHandle base;
|
||||
|
|
@ -145,6 +153,9 @@ struct __vpiSysTaskCall {
|
|||
struct __vpiUserSystf*defn;
|
||||
unsigned nargs;
|
||||
vpiHandle*args;
|
||||
|
||||
/* These represent where in the vthread to put the return value. */
|
||||
unsigned short vbit, vwid;
|
||||
};
|
||||
|
||||
extern struct __vpiSysTaskCall*vpip_cur_task;
|
||||
|
|
@ -194,10 +205,15 @@ extern void vpip_load_module(const char*name, const char*path);
|
|||
* call. However, the vpiSysTaskCall that is the returned handle,
|
||||
* holds a parameter argument list that is passed in here.
|
||||
*
|
||||
* Note that the argv array is saved in the handle, should should not
|
||||
* be released by the caller.
|
||||
* The vbit and vwid fields are used if this turns out to be a system
|
||||
* function. In that case, the vbit and vwid are used to address the
|
||||
* vector is thread bit space where the result is supposed to go.
|
||||
*
|
||||
* Note that the argv array is saved in the handle, and should should
|
||||
* not be released by the caller.
|
||||
*/
|
||||
extern vpiHandle vpip_build_vpi_call(const char*name,
|
||||
unsigned vbit, unsigned vwid,
|
||||
unsigned argc,
|
||||
vpiHandle*argv);
|
||||
|
||||
|
|
@ -215,6 +231,9 @@ vpiHandle vpip_sim_time(void);
|
|||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.16 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.15 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
|
|
|
|||
129
vvp/vpi_tasks.cc
129
vvp/vpi_tasks.cc
|
|
@ -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.6 2001/05/10 00:26:53 steve Exp $"
|
||||
#ident "$Id: vpi_tasks.cc,v 1.7 2001/05/20 00:46:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -25,7 +25,8 @@
|
|||
* built up before the input source file is parsed, and is used by the
|
||||
* compiler when %vpi_call statements are encountered.
|
||||
*/
|
||||
# include "vpi_priv.h"
|
||||
# include "vpi_priv.h"
|
||||
# include "vthread.h"
|
||||
# include <stdio.h>
|
||||
# include <malloc.h>
|
||||
# include <string.h>
|
||||
|
|
@ -75,15 +76,77 @@ static const struct __vpirt vpip_systask_rt = {
|
|||
/*
|
||||
* A value *can* be put to a vpiSysFuncCall object. This is how the
|
||||
* return value is set. The value that is given should be converted to
|
||||
* bits and set into the return value bit array.
|
||||
* bits and set into the thread space bits that were selected at
|
||||
* compile time.
|
||||
*/
|
||||
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value val,
|
||||
p_vpi_time t, int flag)
|
||||
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp,
|
||||
p_vpi_time t, int flags)
|
||||
{
|
||||
assert(0);
|
||||
assert(ref->vpi_type->type_code == vpiSysFuncCall);
|
||||
|
||||
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
|
||||
|
||||
/* delays are not allowed. */
|
||||
assert(flags == vpiNoDelay);
|
||||
|
||||
assert(rfp->vbit >= 4);
|
||||
|
||||
switch (vp->format) {
|
||||
|
||||
case vpiIntVal: {
|
||||
long val = vp->value.integer;
|
||||
for (unsigned idx = 0 ; idx < rfp->vwid ; idx += 1) {
|
||||
vthread_put_bit(vpip_current_vthread,
|
||||
rfp->vbit+idx, val&1);
|
||||
val >>= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiScalarVal:
|
||||
switch (vp->value.scalar) {
|
||||
case vpi0:
|
||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, 0);
|
||||
break;
|
||||
case vpi1:
|
||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, 1);
|
||||
break;
|
||||
case vpiX:
|
||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, 2);
|
||||
break;
|
||||
case vpiZ:
|
||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, 3);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case vpiVectorVal: {
|
||||
assert(rfp->vwid <= sizeof (unsigned long));
|
||||
|
||||
unsigned long aval = vp->value.vector->aval;
|
||||
unsigned long bval = vp->value.vector->bval;
|
||||
for (unsigned idx = 0 ; idx < rfp->vwid ; idx += 1) {
|
||||
int bit = (aval&1) | (((bval^aval)<<1)&2);
|
||||
|
||||
vthread_put_bit(vpip_current_vthread,
|
||||
rfp->vbit+idx, bit);
|
||||
|
||||
aval >>= 1;
|
||||
bval >>= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct __vpirt vpip_sysfunc_rt = {
|
||||
vpiSysFuncCall,
|
||||
0,
|
||||
|
|
@ -139,26 +202,46 @@ static struct __vpiUserSystf* vpip_find_systf(const char*name)
|
|||
* describes the call, and return it. The %vpi_call instruction will
|
||||
* store this handle for when it is executed.
|
||||
*/
|
||||
vpiHandle vpip_build_vpi_call(const char*name,
|
||||
unsigned argc,
|
||||
vpiHandle*argv)
|
||||
vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, unsigned vwid,
|
||||
unsigned argc, vpiHandle*argv)
|
||||
{
|
||||
struct __vpiSysTaskCall*obj = (struct __vpiSysTaskCall*)
|
||||
calloc(1, sizeof (struct __vpiSysTaskCall));
|
||||
|
||||
obj->base.vpi_type = &vpip_systask_rt;
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->defn = vpip_find_systf(name);
|
||||
obj->nargs = argc;
|
||||
obj->args = argv;
|
||||
|
||||
if (obj->defn == 0) {
|
||||
struct __vpiUserSystf*defn = vpip_find_systf(name);
|
||||
if (defn == 0) {
|
||||
fprintf(stderr, "%s: This task not defined "
|
||||
"by any modules. I cannot compile it.\n", name);
|
||||
free(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct __vpiSysTaskCall*obj = new struct __vpiSysTaskCall;
|
||||
|
||||
switch (defn->info.type) {
|
||||
case vpiSysTask:
|
||||
obj->base.vpi_type = &vpip_systask_rt;
|
||||
assert(vbit == 0);
|
||||
assert(vwid == 0);
|
||||
obj->vbit = 0;
|
||||
obj->vwid = 0;
|
||||
break;
|
||||
|
||||
case vpiSysFunc:
|
||||
obj->base.vpi_type = &vpip_sysfunc_rt;
|
||||
assert(vbit >= 4);
|
||||
assert(vwid > 0);
|
||||
obj->vbit = vbit;
|
||||
obj->vwid = vwid;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->defn = defn;
|
||||
obj->nargs = argc;
|
||||
obj->args = argv;
|
||||
|
||||
/* If there is a compiletf function, call it here. */
|
||||
if (obj->defn->info.compiletf)
|
||||
obj->defn->info.compiletf (obj->defn->info.user_data);
|
||||
|
|
@ -179,7 +262,8 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref)
|
|||
{
|
||||
vpip_current_vthread = thr;
|
||||
|
||||
assert(ref->vpi_type->type_code == vpiSysTaskCall);
|
||||
assert((ref->vpi_type->type_code == vpiSysTaskCall)
|
||||
|| (ref->vpi_type->type_code == vpiSysFuncCall));
|
||||
|
||||
vpip_cur_task = (struct __vpiSysTaskCall*)ref;
|
||||
|
||||
|
|
@ -202,6 +286,9 @@ void vpi_register_systf(const struct t_vpi_systf_data*ss)
|
|||
|
||||
/*
|
||||
* $Log: vpi_tasks.cc,v $
|
||||
* Revision 1.7 2001/05/20 00:46:12 steve
|
||||
* Add support for system function calls.
|
||||
*
|
||||
* Revision 1.6 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
|
|
|
|||
Loading…
Reference in New Issue