diff --git a/vpi_user.h b/vpi_user.h index 504c157c4..27dcbce34 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -287,6 +287,7 @@ typedef struct t_vpi_delay { #define vpiSysTaskCall 57 #define vpiTask 59 #define vpiTimeVar 63 +#define vpiUserSystf 67 #define vpiNetArray 114 #define vpiIndex 78 #define vpiLeftRange 79 @@ -360,6 +361,7 @@ typedef struct t_vpi_delay { # define vpiSysFuncReal vpiRealFunc # define vpiSysFuncTime vpiTimeFunc # define vpiSysFuncSized vpiSizedFunc +#define vpiUserDefn 49 #define vpiAutomatic 50 #define vpiConstantSelect 53 #define vpiSigned 65 @@ -382,7 +384,8 @@ typedef struct t_vpi_delay { #define vpiReturnEvent 0x1000 /* VPI FUNCTIONS */ -extern void vpi_register_systf(const struct t_vpi_systf_data*ss); +extern vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss); +extern void vpi_get_systf_info(vpiHandle obj, p_vpi_systf_data data); /* I/O routines */ extern PLI_UINT32 vpi_mcd_open(char *name); @@ -530,7 +533,10 @@ extern void vpi_get_delays(vpiHandle expr, p_vpi_delay delays); extern void vpi_put_delays(vpiHandle expr, p_vpi_delay delays); - +/* + * Check to see if two handles point to the same object. + */ +extern PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2); /* diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index 032c5ce2d..28c7d0cbe 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -132,6 +132,7 @@ const char* vpip_name_string(const char*text) return res; } + PLI_INT32 vpi_chk_error(p_vpi_error_info info) { if (vpip_last_error.state == 0) @@ -148,6 +149,42 @@ PLI_INT32 vpi_chk_error(p_vpi_error_info info) return info->level; } +PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2) +{ + assert(0); +} + +/* + * Copy the internal information to the data structure. Do not free or + * change the tfname/user_data since they are a pointer to the real + * string/data values. We also support passing a task or function handle + * instead of just a handle to a vpiUserSystf. + */ +void vpi_get_systf_info(vpiHandle ref, p_vpi_systf_data data) +{ + assert((ref->vpi_type->type_code == vpiUserSystf) || + (ref->vpi_type->type_code == vpiSysTaskCall) || + (ref->vpi_type->type_code == vpiSysFuncCall)); + + struct __vpiUserSystf* rfp; + if (ref->vpi_type->type_code == vpiUserSystf) { + rfp = (struct __vpiUserSystf*)ref; + } else { + struct __vpiSysTaskCall*call = (struct __vpiSysTaskCall*)ref; + rfp = call->defn; + } + /* Assert that vpiUserDefn is true! For now this is always true. */ + assert(1); + + data->type = rfp->info.type; + data->sysfunctype = rfp->info.sysfunctype; + data->tfname = rfp->info.tfname; + data->calltf = rfp->info.calltf; + data->compiletf = rfp->info.compiletf; + data->sizetf = rfp->info.sizetf; + data->user_data = rfp->info.user_data; +} + /* * When a task is called, this value is set so that vpi_handle can * fathom the vpi_handle(vpiSysTfCall,0) function. @@ -256,6 +293,8 @@ static const char* vpi_type_values(PLI_INT32 code) return "vpiTask"; case vpiTimeVar: return "vpiTimeVar"; + case vpiUserSystf: + return "vpiUserSystf"; default: sprintf(buf, "%d", (int)code); } diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index f717d2764..0ed434826 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2010 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 @@ -37,18 +37,8 @@ # include # include -static const struct __vpirt vpip_systask_def_rt = { - vpiSysTask, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -static const struct __vpirt vpip_sysfunc_def_rt = { - vpiSysFunc, +static const struct __vpirt vpip_systf_def_rt = { + vpiUserSystf, 0, 0, 0, @@ -67,6 +57,11 @@ static vpiHandle systask_handle(int type, vpiHandle ref) case vpiScope: return &rfp->scope->base; + case vpiUserSystf: + /* Assert that vpiUserDefn is true! */ + assert(1); + return &rfp->defn->base; + default: return 0; }; @@ -91,6 +86,10 @@ static int systask_get(int type, vpiHandle ref) case vpiLineNo: return rfp->lineno; + /* For now we always have this information. */ + case vpiUserDefn: + return 1; + default: return vpiUndefined; } @@ -110,6 +109,10 @@ static int sysfunc_get(int type, vpiHandle ref) case vpiLineNo: return rfp->lineno; + /* For now we always have this information. */ + case vpiUserDefn: + return 1; + default: return vpiUndefined; } @@ -723,16 +726,14 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref) * __vpi_userSystf to represent the definition for the calls that come * to pass later. */ -void vpi_register_systf(const struct t_vpi_systf_data*ss) +vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss) { struct __vpiUserSystf*cur = allocate_def(); assert(ss); switch (ss->type) { case vpiSysTask: - cur->base.vpi_type = &vpip_systask_def_rt; - break; case vpiSysFunc: - cur->base.vpi_type = &vpip_sysfunc_def_rt; + cur->base.vpi_type = &vpip_systf_def_rt; break; default: fprintf(stderr, "Unsupported type %d.\n", (int)ss->type); @@ -741,6 +742,8 @@ void vpi_register_systf(const struct t_vpi_systf_data*ss) cur->info = *ss; cur->info.tfname = strdup(ss->tfname); + + return &cur->base; } PLI_INT32 vpi_put_userdata(vpiHandle ref, void*data) diff --git a/vvp/vvp.def b/vvp/vvp.def index 1ec96567d..b0f334339 100644 --- a/vvp/vvp.def +++ b/vvp/vvp.def @@ -1,6 +1,7 @@ EXPORTS vpi_chk_error +vpi_compare_objects vpi_control vpi_flush vpi_fopen @@ -9,6 +10,7 @@ vpi_get vpi_get_delays vpi_get_file vpi_get_str +vpi_get_systf_info vpi_get_time vpi_get_userdata vpi_get_value