diff --git a/libveriuser/veriusertfs.c b/libveriuser/veriusertfs.c index 896ab3553..1fb196485 100644 --- a/libveriuser/veriusertfs.c +++ b/libveriuser/veriusertfs.c @@ -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()); } - diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index 738832fd0..091d4aa89 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -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(); diff --git a/vpi/v2005_math.c b/vpi/v2005_math.c index 582598851..942c3369c 100644 --- a/vpi/v2005_math.c +++ b/vpi/v2005_math.c @@ -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); } diff --git a/vpi/va_math.c b/vpi/va_math.c index ebd57a737..02eed55b2 100644 --- a/vpi/va_math.c +++ b/vpi/va_math.c @@ -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); }