The cleanup of &A and &PV can nest and cleanup some VCD memory.
When cleaning up the &A<> and &PV<> we need to check if the handle argument is a nested call to another &A<> or &PV<> if it is then we need to also delete that construct. We also need to cleanup the vcd_info information list.
This commit is contained in:
parent
f89f3dcbaf
commit
ec1ca8509d
|
|
@ -245,6 +245,7 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
||||||
|
|
||||||
static PLI_INT32 finish_cb(p_cb_data cause)
|
static PLI_INT32 finish_cb(p_cb_data cause)
|
||||||
{
|
{
|
||||||
|
struct vcd_info *cur, *next;
|
||||||
|
|
||||||
if (finish_status != 0) return 0;
|
if (finish_status != 0) return 0;
|
||||||
|
|
||||||
|
|
@ -257,6 +258,12 @@ static PLI_INT32 finish_cb(p_cb_data cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(dump_file);
|
fclose(dump_file);
|
||||||
|
|
||||||
|
for (cur = vcd_list ; cur ; cur = next) {
|
||||||
|
next = cur->next;
|
||||||
|
free(cur->ident);
|
||||||
|
free(cur);
|
||||||
|
}
|
||||||
vcd_names_delete(&vcd_tab);
|
vcd_names_delete(&vcd_tab);
|
||||||
vcd_names_delete(&vcd_var);
|
vcd_names_delete(&vcd_var);
|
||||||
nexus_ident_delete();
|
nexus_ident_delete();
|
||||||
|
|
|
||||||
15
vvp/array.cc
15
vvp/array.cc
|
|
@ -1556,6 +1556,21 @@ void memory_delete(vpiHandle item)
|
||||||
void A_delete(vpiHandle item)
|
void A_delete(vpiHandle item)
|
||||||
{
|
{
|
||||||
struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) item;
|
struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) item;
|
||||||
|
if (obj->address_handle) {
|
||||||
|
switch (obj->address_handle->vpi_type->type_code) {
|
||||||
|
case vpiMemoryWord:
|
||||||
|
if (vpi_get(_vpiFromThr, obj->address_handle) == _vpi_at_A) {
|
||||||
|
A_delete(obj->address_handle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case vpiPartSelect:
|
||||||
|
assert(vpi_get(_vpiFromThr, obj->address_handle) ==
|
||||||
|
_vpi_at_PV);
|
||||||
|
PV_delete(obj->address_handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(obj);
|
free(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1292,6 +1292,19 @@ void vpip_part_select_value_change(struct __vpiCallback*cbh, vpiHandle ref)
|
||||||
void PV_delete(vpiHandle item)
|
void PV_delete(vpiHandle item)
|
||||||
{
|
{
|
||||||
struct __vpiPV *obj = (__vpiPV *) item;
|
struct __vpiPV *obj = (__vpiPV *) item;
|
||||||
|
if (obj->sbase) {
|
||||||
|
switch (obj->sbase->vpi_type->type_code) {
|
||||||
|
case vpiMemoryWord:
|
||||||
|
if (vpi_get(_vpiFromThr, obj->sbase) == _vpi_at_A) {
|
||||||
|
A_delete(obj->sbase);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case vpiPartSelect:
|
||||||
|
assert(vpi_get(_vpiFromThr, obj->sbase) == _vpi_at_PV);
|
||||||
|
PV_delete(obj->sbase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
vvp_fun_signal_base*sig_fun;
|
vvp_fun_signal_base*sig_fun;
|
||||||
sig_fun = (vvp_fun_signal_base*) obj->net->fun;
|
sig_fun = (vvp_fun_signal_base*) obj->net->fun;
|
||||||
sig_fun->clear_all_callbacks();
|
sig_fun->clear_all_callbacks();
|
||||||
|
|
|
||||||
|
|
@ -653,7 +653,7 @@ void vpi_call_delete(vpiHandle item)
|
||||||
thread_word_delete(obj->args[arg]);
|
thread_word_delete(obj->args[arg]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);;
|
assert(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case vpiMemoryWord:
|
case vpiMemoryWord:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue