iverilog/libveriuser/veriusertfs.c

228 lines
5.9 KiB
C

/* vi:sw=6
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com)
* Michael Runyan (mrunyan at chiaro.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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: veriusertfs.c,v 1.5 2002/08/12 01:35:02 steve Exp $"
#endif
/*
* Contains the routines required to implement veriusertfs routines
* via VPI. This is extremly ugly, so don't look after eating dinner.
*/
# include <string.h>
# include <stdlib.h>
# include <assert.h>
# include "vpi_user.h"
# include "veriuser.h"
/*
* local structure used to hold the persistent veriusertfs data
* and anything else we decide to put in here, like workarea data.
*/
typedef struct t_pli_data {
p_tfcell tf; /* pointer to veriusertfs cell */
int paramvc; /* parameter number for misctf */
} s_pli_data, *p_pli_data;
static int compiletf(char *);
static int calltf(char *);
static int callback(p_cb_data);
/*
* Register veriusertfs routines/wrappers.
*/
void veriusertfs_register()
{
p_tfcell tf;
s_vpi_systf_data tf_data;
p_pli_data data;
for (tf = veriusertfs; tf; tf++) {
/* last element */
if (tf->type == 0) break;
/* force forwref true */
if (!tf->forwref) {
vpi_printf("veriusertfs: %s, forcing forwref = true\n",
tf->tfname);
}
/* squirrel away veriusertfs in persistent user_data */
data = (p_pli_data) calloc(1, sizeof(s_pli_data));
assert(data != NULL);
data->tf = tf;
/* build callback structure */
(void) memset(&tf_data, 0, sizeof(s_vpi_systf_data));
switch (tf->type) {
case usertask:
tf_data.type = vpiSysTask;
break;
case userfunction:
tf_data.type = vpiSysFunc;
break;
default:
vpi_printf("veriusertfs: %s, unsupported type %d\n",
tf->tfname, tf->type);
continue;
break;
}
tf_data.tfname = tf->tfname;
tf_data.compiletf = compiletf;
tf_data.calltf = calltf;
tf_data.sizetf = tf->sizetf;
tf_data.user_data = (char *)data;
/* register */
vpi_register_systf(&tf_data);
}
return;
}
/*
* This function calls the veriusertfs checktf and sets up all the
* callbacks misctf requires.
*/
static int compiletf(char *data)
{
p_pli_data pli;
p_tfcell tf;
s_cb_data cb_data;
vpiHandle call_h, arg_i, arg_h;
p_pli_data dp;
int paramvc = 1;
int rtn;
/* cast back from opaque */
pli = (p_pli_data)data;
tf = pli->tf;
/* get call handle */
call_h = vpi_handle(vpiSysTfCall, NULL);
/* default cb_data */
(void) memset(&cb_data, 0, sizeof(s_cb_data));
cb_data.cb_rtn = callback;
cb_data.user_data = data;
/* register EOS misctf callback */
cb_data.reason = cbEndOfSimulation;
cb_data.obj = call_h;
vpi_register_cb(&cb_data);
/* register paramvc misctf callback(s) */
cb_data.reason = cbValueChange;
arg_i = vpi_iterate(vpiArgument, call_h);
if (arg_i != NULL) {
while ((arg_h = vpi_scan(arg_i)) != NULL) {
/* replicate user_data for each instance */
dp = (p_pli_data)calloc(1, sizeof(s_pli_data));
assert(dp != NULL);
memcpy(dp, cb_data.user_data, sizeof(s_pli_data));
dp->paramvc = paramvc++;
cb_data.user_data = (char *)dp;
cb_data.obj = arg_h;
vpi_register_cb(&cb_data);
}
}
/*
* Since we are in compiletf, checktf and misctf need to
* be executed. Check runs first to match other simulators.
*/
rtn = (tf->checktf) ? tf->checktf(tf->data, reason_checktf) : 0;
if (tf->misctf) tf->misctf(tf->data, reason_endofcompile, 0);
return rtn;
}
/*
* This function is the wrapper for the veriusertfs calltf routine.
*/
static int calltf(char *data)
{
p_pli_data pli;
p_tfcell tf;
/* cast back from opaque */
pli = (p_pli_data)data;
tf = pli->tf;
/* execute calltf */
return (tf->calltf) ? tf->calltf(tf->data, reason_calltf) : 0;
}
/*
* This function is the wrapper for all the misctf callbacks
*/
extern int async_misctf_enable;
static int callback(p_cb_data data)
{
p_pli_data pli;
p_tfcell tf;
int reason;
int paramvc = 0;
/* not enabled */
if (data->reason == cbValueChange && !async_misctf_enable) return 0;
/* cast back from opaque */
pli = (p_pli_data)data->user_data;
tf = pli->tf;
switch (data->reason) {
case cbValueChange:
reason = reason_paramvc;
paramvc = pli->paramvc;
break;
case cbEndOfSimulation:
reason = reason_finish;
break;
default:
abort();
}
/* execute misctf */
return (tf->misctf) ? tf->misctf(tf->data, reason, paramvc) : 0;
}
/*
* $Log: veriusertfs.c,v $
* Revision 1.5 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/06/04 01:42:58 steve
* Add misctf support to libveriuser
*
* Revision 1.3 2002/06/03 00:08:42 steve
* Better typing for veriusertfs table.
*
* Revision 1.2 2002/05/31 18:21:39 steve
* Check for and don't dereference null pointers,
* Avoid copy of static objects.
* (mruff)
*
* Revision 1.1 2002/05/30 02:37:26 steve
* Add the veriusertf_register funciton.
*
*/