Cleanup allocated memory in the math functions and veriusertfs.
This patch cleans up the V-2005 and V-analog math functions to free their allocated memory at the end of simulation. It also modifies the veriusertfs code to do the same thing. It also closes the VCD file at EOS.
This commit is contained in:
parent
d4d7c14b36
commit
761a15515d
|
|
@ -1,6 +1,6 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com)
|
||||
* Michael Runyan (mrunyan at chiaro.com)
|
||||
* Copyright (c) 2002-2009 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
|
||||
|
|
@ -17,9 +17,6 @@
|
|||
* 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.17 2007/05/08 22:01:26 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Contains the routines required to implement veriusertfs routines
|
||||
|
|
@ -48,12 +45,34 @@ static PLI_INT32 compiletf(char *);
|
|||
static PLI_INT32 calltf(char *);
|
||||
static PLI_INT32 callback(p_cb_data);
|
||||
|
||||
/*
|
||||
* Keep a pointer to the user data so that it can be freed when the
|
||||
* simulation is finished.
|
||||
*/
|
||||
static p_pli_data* udata_store = 0;
|
||||
static unsigned udata_count = 0;
|
||||
|
||||
static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
for (idx = 0; idx < udata_count; idx += 1) {
|
||||
free(udata_store[idx]);
|
||||
}
|
||||
free(udata_store);
|
||||
udata_store = 0;
|
||||
udata_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register veriusertfs routines/wrappers. Iterate over the tfcell
|
||||
* array, registering each function.
|
||||
*/
|
||||
void veriusertfs_register_table(p_tfcell vtable)
|
||||
{
|
||||
static int need_EOS_cb = 1;
|
||||
const char*path;
|
||||
p_tfcell tf;
|
||||
s_vpi_systf_data tf_data;
|
||||
|
|
@ -86,6 +105,21 @@ void veriusertfs_register_table(p_tfcell vtable)
|
|||
/* squirrel away veriusertfs in persistent user_data */
|
||||
data = calloc(1, sizeof(s_pli_data));
|
||||
assert(data != NULL);
|
||||
udata_count += 1;
|
||||
udata_store = (p_pli_data*)realloc(udata_store,
|
||||
udata_count*sizeof(p_pli_data*));
|
||||
udata_store[udata_count-1] = data;
|
||||
if (need_EOS_cb) {
|
||||
s_cb_data cb_data;
|
||||
|
||||
cb_data.reason = cbEndOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = sys_end_of_simulation;
|
||||
cb_data.user_data = "system";
|
||||
vpi_register_cb(&cb_data);
|
||||
|
||||
need_EOS_cb = 0;
|
||||
}
|
||||
data->tf = tf;
|
||||
|
||||
/* Build a VPI system task/function structure, and point
|
||||
|
|
@ -392,4 +426,3 @@ PLI_INT32 tf_setrealdelay(double dly)
|
|||
{
|
||||
return tf_isetrealdelay(dly, tf_getinstance());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ static PLI_INT32 finish_cb(p_cb_data cause)
|
|||
fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time);
|
||||
}
|
||||
|
||||
fclose(dump_file);
|
||||
vcd_names_delete(&vcd_tab);
|
||||
vcd_names_delete(&vcd_var);
|
||||
nexus_ident_delete();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Verilog-2005 math library for Icarus Verilog
|
||||
* http://www.icarus.com/eda/verilog/
|
||||
*
|
||||
* Copyright (C) 2007-2008 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2007-2009 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -88,6 +88,36 @@ typedef struct {
|
|||
} va_double_t;
|
||||
|
||||
|
||||
/*
|
||||
* Cleanup the allocated memory at the end of simulation.
|
||||
*/
|
||||
static va_single_t** single_funcs = 0;
|
||||
static unsigned single_funcs_count = 0;
|
||||
static va_double_t** double_funcs = 0;
|
||||
static unsigned double_funcs_count = 0;
|
||||
|
||||
static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
for (idx = 0; idx < single_funcs_count; idx += 1) {
|
||||
free(single_funcs[idx]);
|
||||
}
|
||||
free(single_funcs);
|
||||
single_funcs = 0;
|
||||
single_funcs_count = 0;
|
||||
|
||||
for (idx = 0; idx < double_funcs_count; idx += 1) {
|
||||
free(double_funcs[idx]);
|
||||
}
|
||||
free(double_funcs);
|
||||
double_funcs = 0;
|
||||
double_funcs_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Standard error message routine. The format string must take one
|
||||
* string argument (the name of the function).
|
||||
|
|
@ -171,6 +201,10 @@ static PLI_INT32 va_single_argument_compiletf(PLI_BYTE8 *ud)
|
|||
fun_data->func = data->func;
|
||||
|
||||
vpi_put_userdata(callh, fun_data);
|
||||
single_funcs_count += 1;
|
||||
single_funcs = (va_single_t **)realloc(single_funcs,
|
||||
single_funcs_count*sizeof(va_single_t **));
|
||||
single_funcs[single_funcs_count-1] = fun_data;
|
||||
|
||||
/* vpi_scan() returning 0 (NULL) has already freed argv. */
|
||||
return 0;
|
||||
|
|
@ -255,6 +289,10 @@ static PLI_INT32 va_double_argument_compiletf(PLI_BYTE8 *ud)
|
|||
fun_data->func = data->func;
|
||||
|
||||
vpi_put_userdata(callh, fun_data);
|
||||
double_funcs_count += 1;
|
||||
double_funcs = (va_double_t **)realloc(double_funcs,
|
||||
double_funcs_count*sizeof(va_double_t **));
|
||||
double_funcs[double_funcs_count-1] = fun_data;
|
||||
|
||||
/* vpi_scan() returning 0 (NULL) has already freed argv. */
|
||||
return 0;
|
||||
|
|
@ -295,6 +333,7 @@ static PLI_INT32 va_double_argument_calltf(PLI_BYTE8 *ud)
|
|||
*/
|
||||
static void sys_v2005_math_register(void)
|
||||
{
|
||||
s_cb_data cb_data;
|
||||
s_vpi_systf_data tf_data;
|
||||
unsigned idx;
|
||||
|
||||
|
|
@ -323,6 +362,13 @@ static void sys_v2005_math_register(void)
|
|||
tf_data.user_data = (PLI_BYTE8 *) &va_double_data[idx];
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
/* We need to clean up the userdata. */
|
||||
cb_data.reason = cbEndOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = sys_end_of_simulation;
|
||||
cb_data.user_data = "system";
|
||||
vpi_register_cb(&cb_data);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Verilog-A math library for Icarus Verilog
|
||||
* http://www.icarus.com/eda/verilog/
|
||||
*
|
||||
* Copyright (C) 2007-2008 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2007-2009 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -120,6 +120,36 @@ typedef struct {
|
|||
} va_double_t;
|
||||
|
||||
|
||||
/*
|
||||
* Cleanup the allocated memory at the end of simulation.
|
||||
*/
|
||||
static va_single_t** single_funcs = 0;
|
||||
static unsigned single_funcs_count = 0;
|
||||
static va_double_t** double_funcs = 0;
|
||||
static unsigned double_funcs_count = 0;
|
||||
|
||||
static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
for (idx = 0; idx < single_funcs_count; idx += 1) {
|
||||
free(single_funcs[idx]);
|
||||
}
|
||||
free(single_funcs);
|
||||
single_funcs = 0;
|
||||
single_funcs_count = 0;
|
||||
|
||||
for (idx = 0; idx < double_funcs_count; idx += 1) {
|
||||
free(double_funcs[idx]);
|
||||
}
|
||||
free(double_funcs);
|
||||
double_funcs = 0;
|
||||
double_funcs_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Standard error message routine. The format string must take one
|
||||
* string argument (the name of the function).
|
||||
|
|
@ -203,6 +233,10 @@ static PLI_INT32 va_single_argument_compiletf(PLI_BYTE8 *ud)
|
|||
fun_data->func = data->func;
|
||||
|
||||
vpi_put_userdata(callh, fun_data);
|
||||
single_funcs_count += 1;
|
||||
single_funcs = (va_single_t **)realloc(single_funcs,
|
||||
single_funcs_count*sizeof(va_single_t **));
|
||||
single_funcs[single_funcs_count-1] = fun_data;
|
||||
|
||||
/* vpi_scan() returning 0 (NULL) has already freed argv. */
|
||||
return 0;
|
||||
|
|
@ -287,6 +321,10 @@ static PLI_INT32 va_double_argument_compiletf(PLI_BYTE8 *ud)
|
|||
fun_data->func = data->func;
|
||||
|
||||
vpi_put_userdata(callh, fun_data);
|
||||
double_funcs_count += 1;
|
||||
double_funcs = (va_double_t **)realloc(double_funcs,
|
||||
double_funcs_count*sizeof(va_double_t **));
|
||||
double_funcs[double_funcs_count-1] = fun_data;
|
||||
|
||||
/* vpi_scan() returning 0 (NULL) has already freed argv. */
|
||||
return 0;
|
||||
|
|
@ -327,6 +365,7 @@ static PLI_INT32 va_double_argument_calltf(PLI_BYTE8 *ud)
|
|||
*/
|
||||
static void va_math_register(void)
|
||||
{
|
||||
s_cb_data cb_data;
|
||||
s_vpi_systf_data tf_data;
|
||||
unsigned idx;
|
||||
|
||||
|
|
@ -355,6 +394,13 @@ static void va_math_register(void)
|
|||
tf_data.user_data = (PLI_BYTE8 *) &va_double_data[idx];
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
/* We need to clean up the userdata. */
|
||||
cb_data.reason = cbEndOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = sys_end_of_simulation;
|
||||
cb_data.user_data = "system";
|
||||
vpi_register_cb(&cb_data);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue