From a48c9c3b4a64f3bfd4b2e149f661b590cadf888a Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 19 Jan 2012 10:16:39 -0800 Subject: [PATCH] Reword __vpiHandle objects to create a class structure. Instead of C-like data structures where the __vpiHandle base is a leading member, make the __vpiHandle a derived class. Give the base class a virtual destructor so that dynamic_cast works reliably, and now pretty much all of the junk for testing if an object really is of the derived class goes away. Also, problems with casting up to a vpiHandle become trivial non-issues. --- vvp/array.cc | 314 ++++++++++++++++++++--------------------- vvp/compile.cc | 6 +- vvp/delay.cc | 83 ++++------- vvp/enum_type.cc | 60 ++++---- vvp/file_line.cc | 23 +-- vvp/schedule.cc | 4 +- vvp/stop.cc | 39 +++-- vvp/vpi_callback.cc | 27 ++-- vvp/vpi_const.cc | 200 +++++++++++--------------- vvp/vpi_event.cc | 35 +++-- vvp/vpi_iter.cc | 43 +++--- vvp/vpi_priv.cc | 172 ++++++++-------------- vvp/vpi_priv.h | 190 +++++++++++++++---------- vvp/vpi_real.cc | 64 ++++----- vvp/vpi_scope.cc | 88 +++++------- vvp/vpi_signal.cc | 159 ++++++++++----------- vvp/vpi_tasks.cc | 134 ++++++++---------- vvp/vpi_time.cc | 39 +++-- vvp/vpi_vthr_vector.cc | 74 +++++----- vvp/vthread.cc | 2 +- vvp/words.cc | 2 +- 21 files changed, 803 insertions(+), 955 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index e70e00097..5bbcba787 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2012 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 @@ -80,8 +80,8 @@ vvp_array_t array_find(const char*label) * array of double variables. This is very much line the way the * vector4 array works. */ -struct __vpiArray { - struct __vpiHandle base; +struct __vpiArray : public __vpiHandle { + __vpiArray(); struct __vpiScope*scope; const char*name; /* Permanently allocated string */ unsigned array_count; @@ -103,20 +103,23 @@ struct __vpiArray { bool swap_addr; }; -struct __vpiArrayIterator { - struct __vpiHandle base; +struct __vpiArrayIterator : public __vpiHandle { + __vpiArrayIterator(); + struct __vpiArray*array; unsigned next; }; -struct __vpiArrayIndex { - struct __vpiHandle base; +struct __vpiArrayIndex : public __vpiHandle { + __vpiArrayIndex(); struct __vpiDecConst *index; unsigned done; }; -struct __vpiArrayVthrA { - struct __vpiHandle base; +struct __vpiArrayVthrA : public __vpiHandle { + + __vpiArrayVthrA(); + struct __vpiArray*array; // If this is set, then use it to get the index value. vpiHandle address_handle; @@ -133,15 +136,15 @@ struct __vpiArrayVthrA { s_vpi_value vp; /* Check to see if the value is defined. */ vp.format = vpiVectorVal; - vpi_get_value(address_handle, &vp); - int words = (vpi_get(vpiSize, address_handle)-1)/32 + 1; + address_handle->vpi_get_value(&vp); + int words = (address_handle->vpi_get(vpiSize)-1)/32 + 1; for(int idx = 0; idx < words; idx += 1) { /* Return UINT_MAX to indicate an X base. */ if (vp.value.vector[idx].bval != 0) return UINT_MAX; } /* The value is defined so get and return it. */ vp.format = vpiIntVal; - vpi_get_value(address_handle, &vp); + address_handle->vpi_get_value(&vp); return vp.value.integer; } @@ -183,8 +186,8 @@ struct __vpiArrayVthrA { }; -struct __vpiArrayVthrAPV { - struct __vpiHandle base; +struct __vpiArrayVthrAPV : public __vpiHandle { + __vpiArrayVthrAPV(); struct __vpiArray*array; unsigned word_sel; unsigned part_bit; @@ -200,7 +203,7 @@ unsigned get_array_word_size(vvp_array_t array) /* For a net array we need to get the width from the first element. */ if (array->nets) { assert(array->vals4 == 0 && array->valsr == 0); - struct __vpiSignal*vsig = vpip_signal_from_handle(array->nets[0]); + struct __vpiSignal*vsig = dynamic_cast<__vpiSignal*>(array->nets[0]); assert(vsig); width = vpip_size(vsig); /* For a variable array we can get the width from vals_width. */ @@ -214,9 +217,9 @@ unsigned get_array_word_size(vvp_array_t array) bool is_net_array(vpiHandle obj) { - assert(obj->vpi_type->type_code == vpiMemory); + struct __vpiArray*rfp = dynamic_cast<__vpiArray*> (obj); + assert(rfp); - struct __vpiArray*rfp = (struct __vpiArray*) obj; if (rfp->nets != 0) return true; return false; } @@ -242,16 +245,23 @@ bool is_net_array(vpiHandle obj) * of vpi functions is bound to the same structure. All the details * for the word also apply when treating this as an index. */ + + struct __vpiArrayWord { - struct __vpiHandle as_word; - struct __vpiHandle as_index; + struct as_word_t : public __vpiHandle { + as_word_t(); + } as_word; + + struct as_index_t : public __vpiHandle { + as_index_t(); + } as_index; + union { struct __vpiArray*parent; struct __vpiArrayWord*word0; }; }; - static int vpi_array_get(int code, vpiHandle ref); static char*vpi_array_get_str(int code, vpiHandle ref); static vpiHandle vpi_array_get_handle(int code, vpiHandle ref); @@ -296,6 +306,11 @@ static const struct __vpirt vpip_arraymem_rt = { 0, 0 }; +inline __vpiArray::__vpiArray() +: __vpiHandle(&vpip_arraymem_rt) +{ +} + static const struct __vpirt vpip_array_iterator_rt = { vpiIterator, @@ -311,6 +326,12 @@ static const struct __vpirt vpip_array_iterator_rt = { 0 }; +inline __vpiArrayIterator::__vpiArrayIterator() +: __vpiHandle(&vpip_array_iterator_rt) +{ +} + + /* This should look a bit odd since it provides a fake iteration on * this object. This trickery is used to implement the two forms of * index access, simple handle access and iteration access. */ @@ -328,6 +349,11 @@ static const struct __vpirt vpip_array_index_rt = { 0 }; +inline __vpiArrayIndex::__vpiArrayIndex() +: __vpiHandle(&vpip_array_index_rt) +{ +} + static const struct __vpirt vpip_array_var_word_rt = { vpiMemoryWord, &vpi_array_var_word_get, @@ -341,6 +367,10 @@ static const struct __vpirt vpip_array_var_word_rt = { 0, 0 }; +inline __vpiArrayWord::as_word_t::as_word_t() +: __vpiHandle(&vpip_array_var_word_rt) +{ +} static const struct __vpirt vpip_array_var_index_rt = { vpiIndex, @@ -355,6 +385,10 @@ static const struct __vpirt vpip_array_var_index_rt = { 0, 0 }; +inline __vpiArrayWord::as_index_t::as_index_t() +: __vpiHandle(&vpip_array_var_index_rt) +{ +} static const struct __vpirt vpip_array_vthr_A_rt = { vpiMemoryWord, @@ -370,6 +404,11 @@ static const struct __vpirt vpip_array_vthr_A_rt = { 0 }; +inline __vpiArrayVthrA::__vpiArrayVthrA() +: __vpiHandle(&vpip_array_vthr_A_rt) +{ +} + static const struct __vpirt vpip_array_vthr_APV_rt = { vpiMemoryWord, &vpi_array_vthr_APV_get, @@ -384,14 +423,17 @@ static const struct __vpirt vpip_array_vthr_APV_rt = { 0 }; -# define ARRAY_HANDLE(ref) (assert(ref->vpi_type->type_code==vpiMemory), \ - (struct __vpiArray*)ref) +inline __vpiArrayVthrAPV::__vpiArrayVthrAPV() +: __vpiHandle(&vpip_array_vthr_APV_rt) +{ +} static struct __vpiArrayWord* array_var_word_from_handle(vpiHandle ref) { if (ref == 0) return 0; - if (ref->vpi_type != &vpip_array_var_word_rt) + __vpiArrayWord::as_word_t*ptr = dynamic_cast<__vpiArrayWord::as_word_t*> (ref); + if (ptr == 0) return 0; return (struct __vpiArrayWord*) ref; @@ -401,32 +443,15 @@ static struct __vpiArrayWord* array_var_index_from_handle(vpiHandle ref) { if (ref == 0) return 0; - if (ref->vpi_type != &vpip_array_var_index_rt) + __vpiArrayWord::as_index_t*ptr = dynamic_cast<__vpiArrayWord::as_index_t*> (ref); + if (ptr == 0) return 0; + assert(sizeof(__vpiHandle) == sizeof(__vpiArrayWord::as_index_t)); + assert(sizeof(__vpiHandle) == sizeof(__vpiArrayWord::as_word_t)); return (struct __vpiArrayWord*) (ref-1); } -static struct __vpiArrayVthrA* array_vthr_a_from_handle(vpiHandle ref) -{ - if (ref == 0) - return 0; - if (ref->vpi_type != &vpip_array_vthr_A_rt) - return 0; - - return (struct __vpiArrayVthrA*) ref; -} - -static struct __vpiArrayVthrAPV* array_vthr_apv_from_handle(vpiHandle ref) -{ - if (ref == 0) - return 0; - if (ref->vpi_type != &vpip_array_vthr_APV_rt) - return 0; - - return (struct __vpiArrayVthrAPV*) ref; -} - static void array_make_vals_words(struct __vpiArray*parent) { assert(parent->vals_words == 0); @@ -439,8 +464,6 @@ static void array_make_vals_words(struct __vpiArray*parent) struct __vpiArrayWord*words = parent->vals_words; for (unsigned idx = 0 ; idx < parent->array_count ; idx += 1) { - words[idx].as_word.vpi_type = &vpip_array_var_word_rt; - words[idx].as_index.vpi_type = &vpip_array_var_index_rt; words[idx].word0 = words; } } @@ -455,7 +478,7 @@ static unsigned decode_array_word_pointer(struct __vpiArrayWord*word, static int vpi_array_get(int code, vpiHandle ref) { - struct __vpiArray*obj = ARRAY_HANDLE(ref); + struct __vpiArray*obj = dynamic_cast<__vpiArray*> (ref); switch (code) { case vpiLineNo: @@ -474,31 +497,31 @@ static int vpi_array_get(int code, vpiHandle ref) static char*vpi_array_get_str(int code, vpiHandle ref) { - struct __vpiArray*obj = ARRAY_HANDLE(ref); + struct __vpiArray*obj = dynamic_cast<__vpiArray*>(ref); if (code == vpiFile) { // Not implemented for now! return simple_set_rbuf_str(file_names[0]); } - return generic_get_str(code, &obj->scope->base, obj->name, NULL); + return generic_get_str(code, obj->scope, obj->name, NULL); } static vpiHandle vpi_array_get_handle(int code, vpiHandle ref) { - struct __vpiArray*obj = ARRAY_HANDLE(ref); + struct __vpiArray*obj = dynamic_cast<__vpiArray*>(ref); switch (code) { case vpiLeftRange: - if (obj->swap_addr) return &(obj->last_addr.base); - else return &(obj->first_addr.base); + if (obj->swap_addr) return &(obj->last_addr); + else return &(obj->first_addr); case vpiRightRange: - if (obj->swap_addr) return &(obj->first_addr.base); - else return &(obj->last_addr.base); + if (obj->swap_addr) return &(obj->first_addr); + else return &(obj->last_addr); case vpiScope: - return &obj->scope->base; + return obj->scope; case vpiModule: return vpip_module(obj->scope); @@ -509,17 +532,16 @@ static vpiHandle vpi_array_get_handle(int code, vpiHandle ref) static vpiHandle vpi_array_iterate(int code, vpiHandle ref) { - struct __vpiArray*obj = ARRAY_HANDLE(ref); + struct __vpiArray*obj = dynamic_cast<__vpiArray*>(ref); switch (code) { case vpiMemoryWord: { struct __vpiArrayIterator*res; - res = (struct __vpiArrayIterator*) calloc(1, sizeof (*res)); - res->base.vpi_type = &vpip_array_iterator_rt; + res = new __vpiArrayIterator; res->array = obj; res->next = 0; - return &res->base; + return res; } } @@ -533,7 +555,7 @@ static vpiHandle vpi_array_iterate(int code, vpiHandle ref) */ static vpiHandle vpi_array_index(vpiHandle ref, int index) { - struct __vpiArray*obj = ARRAY_HANDLE(ref); + struct __vpiArray*obj = dynamic_cast<__vpiArray*>(ref); index -= obj->first_addr.value; if (index >= (long)obj->array_count) @@ -606,7 +628,7 @@ static char*vpi_array_var_word_get_str(int code, vpiHandle ref) char sidx [64]; snprintf(sidx, 63, "%d", (int)index + parent->first_addr.value); - return generic_get_str(code, &parent->scope->base, parent->name, sidx); + return generic_get_str(code, parent->scope, parent->name, sidx); } static void vpi_array_var_word_get_value(vpiHandle ref, p_vpi_value vp) @@ -649,16 +671,16 @@ static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref) return &(obj->as_index); case vpiLeftRange: - return &parent->msb.base; + return &parent->msb; case vpiRightRange: - return &parent->lsb.base; + return &parent->lsb; case vpiParent: - return &parent->base; + return parent; case vpiScope: - return &parent->scope->base; + return parent->scope; case vpiModule: return vpip_module(parent->scope); @@ -679,12 +701,9 @@ static void vpi_array_var_index_get_value(vpiHandle ref, p_vpi_value vp) vp->value.integer = index; } -# define ARRAY_ITERATOR(ref) (assert(ref->vpi_type->type_code==vpiIterator), \ - (struct __vpiArrayIterator*)ref) - static vpiHandle array_iterator_scan(vpiHandle ref, int) { - struct __vpiArrayIterator*obj = ARRAY_ITERATOR(ref); + struct __vpiArrayIterator*obj = dynamic_cast<__vpiArrayIterator*>(ref); if (obj->next >= obj->array->array_count) { vpi_free_object(ref); @@ -705,37 +724,33 @@ static vpiHandle array_iterator_scan(vpiHandle ref, int) static int array_iterator_free_object(vpiHandle ref) { - struct __vpiArrayIterator*obj = ARRAY_ITERATOR(ref); + struct __vpiArrayIterator*obj = dynamic_cast<__vpiArrayIterator*>(ref); free(obj); return 1; } -# define ARRAY_INDEX(ref) (assert(ref->vpi_type->type_code==vpiIterator), \ - (struct __vpiArrayIndex*)ref) - vpiHandle array_index_iterate(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiConstant); - struct __vpiDecConst*obj = (struct __vpiDecConst*)ref; + struct __vpiDecConst*obj = dynamic_cast<__vpiDecConst*>(ref); + assert(obj); if (code == vpiIndex) { struct __vpiArrayIndex*res; - res = (struct __vpiArrayIndex*) calloc(1, sizeof (*res)); - res->base.vpi_type = &vpip_array_index_rt; + res = new __vpiArrayIndex; res->index = obj; res->done = 0; - return &res->base; + return res; } return 0; } static vpiHandle array_index_scan(vpiHandle ref, int) { - struct __vpiArrayIndex*obj = ARRAY_INDEX(ref); + struct __vpiArrayIndex*obj = dynamic_cast<__vpiArrayIndex*>(ref); if (obj->done == 0) { obj->done = 1; - return &obj->index->base; + return obj->index; } vpi_free_object(ref); @@ -744,14 +759,14 @@ static vpiHandle array_index_scan(vpiHandle ref, int) static int array_index_free_object(vpiHandle ref) { - struct __vpiArrayIndex*obj = ARRAY_INDEX(ref); + struct __vpiArrayIndex*obj = dynamic_cast<__vpiArrayIndex*>(ref); free(obj); return 1; } static int vpi_array_vthr_A_get(int code, vpiHandle ref) { - struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref); + struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -794,7 +809,7 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref) static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref) { - struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref); + struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -804,7 +819,7 @@ static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref) char sidx [64]; snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.value); - return generic_get_str(code, &parent->scope->base, parent->name, sidx); + return generic_get_str(code, parent->scope, parent->name, sidx); } // This function return true if the underlying array words are real. @@ -817,10 +832,8 @@ static unsigned vpi_array_is_real(vvp_array_t arr) // This must be a net array so look at element 0 to find the type. assert(arr->nets != 0); assert(arr->array_count > 0); - struct __vpiRealVar*rsig = vpip_realvar_from_handle(arr->nets[0]); + struct __vpiRealVar*rsig = dynamic_cast<__vpiRealVar*>(arr->nets[0]); if (rsig) { - struct __vpiSignal*vsig = vpip_signal_from_handle(arr->nets[0]); - assert(vsig == 0); return 1U; } @@ -829,7 +842,7 @@ static unsigned vpi_array_is_real(vvp_array_t arr) static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value vp) { - struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref); + struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -848,7 +861,7 @@ static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value vp) static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int) { - struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref); + struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -871,7 +884,7 @@ static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int) static vpiHandle vpi_array_vthr_A_get_handle(int code, vpiHandle ref) { - struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref); + struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -881,16 +894,16 @@ static vpiHandle vpi_array_vthr_A_get_handle(int code, vpiHandle ref) break; // Not implemented! case vpiLeftRange: - return &parent->msb.base; + return &parent->msb; case vpiRightRange: - return &parent->lsb.base; + return &parent->lsb; case vpiParent: - return &parent->base; + return parent; case vpiScope: - return &parent->scope->base; + return parent->scope; case vpiModule: return vpip_module(parent->scope); @@ -901,7 +914,7 @@ static vpiHandle vpi_array_vthr_A_get_handle(int code, vpiHandle ref) static int vpi_array_vthr_APV_get(int code, vpiHandle ref) { - struct __vpiArrayVthrAPV*obj = array_vthr_apv_from_handle(ref); + struct __vpiArrayVthrAPV*obj = dynamic_cast<__vpiArrayVthrAPV*>(ref); struct __vpiArray*parent = obj->array; switch (code) { @@ -933,7 +946,7 @@ static int vpi_array_vthr_APV_get(int code, vpiHandle ref) static char*vpi_array_vthr_APV_get_str(int code, vpiHandle ref) { - struct __vpiArrayVthrAPV*obj = array_vthr_apv_from_handle(ref); + struct __vpiArrayVthrAPV*obj = dynamic_cast<__vpiArrayVthrAPV*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -943,12 +956,12 @@ static char*vpi_array_vthr_APV_get_str(int code, vpiHandle ref) char sidx [64]; snprintf(sidx, 63, "%u", obj->word_sel + parent->first_addr.value); - return generic_get_str(code, &parent->scope->base, parent->name, sidx); + return generic_get_str(code, parent->scope, parent->name, sidx); } static void vpi_array_vthr_APV_get_value(vpiHandle ref, p_vpi_value vp) { - struct __vpiArrayVthrAPV*obj = array_vthr_apv_from_handle(ref); + struct __vpiArrayVthrAPV*obj = dynamic_cast<__vpiArrayVthrAPV*>(ref); assert(obj); struct __vpiArray*parent = obj->array; @@ -997,7 +1010,7 @@ void array_set_word(vvp_array_t arr, // Select the word of the array that we affect. vpiHandle word = arr->nets[address]; - struct __vpiSignal*vsig = vpip_signal_from_handle(word); + struct __vpiSignal*vsig = dynamic_cast<__vpiSignal*>(word); assert(vsig); vsig->node->send_vec4_pv(val, part_off, val.size(), vpip_size(vsig), 0); @@ -1031,7 +1044,7 @@ vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address) assert(arr->array_count > 0); vpiHandle word = arr->nets[0]; assert(word); - struct __vpiSignal*vsig = vpip_signal_from_handle(word); + struct __vpiSignal*vsig = dynamic_cast<__vpiSignal*>(word); assert(vsig); vvp_signal_value*sig = dynamic_cast (vsig->node->fil); assert(sig); @@ -1039,7 +1052,7 @@ vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address) } vpiHandle word = arr->nets[address]; - struct __vpiSignal*vsig = vpip_signal_from_handle(word); + struct __vpiSignal*vsig = dynamic_cast<__vpiSignal*>(word); assert(vsig); vvp_signal_value*sig = dynamic_cast (vsig->node->fil); assert(sig); @@ -1059,7 +1072,7 @@ double array_get_word_r(vvp_array_t arr, unsigned address) assert(arr->nets); vpiHandle word = arr->nets[address]; - struct __vpiRealVar*vsig = vpip_realvar_from_handle(word); + struct __vpiRealVar*vsig = dynamic_cast<__vpiRealVar*>(word); assert(vsig); vvp_signal_value*sig = dynamic_cast (vsig->net->fil); assert(sig); @@ -1073,8 +1086,7 @@ static vpiHandle vpip_make_array(char*label, const char*name, int first_addr, int last_addr, bool signed_flag) { - struct __vpiArray*obj = (struct __vpiArray*) - malloc(sizeof(struct __vpiArray)); + struct __vpiArray*obj = new __vpiArray; obj->signed_flag = signed_flag; @@ -1092,21 +1104,18 @@ static vpiHandle vpip_make_array(char*label, const char*name, // For now, treat all arrays as memories. This is not quite // correct, as arrays are arrays with memories a special case. - obj->base.vpi_type = &vpip_arraymem_rt; obj->scope = vpip_peek_current_scope(); obj->name = vpip_name_string(name); obj->array_count = array_count; - vpip_make_dec_const(&obj->first_addr, first_addr); - vpip_make_dec_const(&obj->last_addr, last_addr); + obj->first_addr.value = first_addr; + obj->last_addr.value = last_addr; // Start off now knowing if we are nets or variables. obj->nets = 0; obj->vals4 = 0; obj->valsr = 0; obj->vals_width = 0; - vpip_make_dec_const(&obj->msb, 0); - vpip_make_dec_const(&obj->lsb, 0); obj->vals_words = 0; // Initialize (clear) the read-ports list. @@ -1123,12 +1132,12 @@ static vpiHandle vpip_make_array(char*label, const char*name, /* Add this into the table of VPI objects. This is used for contexts that try to look up VPI objects in general. (i.e. arguments to vpi_task calls.) */ - compile_vpi_symbol(label, &(obj->base)); + compile_vpi_symbol(label, obj); /* Blindly attach to the scope as an object. */ - vpip_attach_to_current_scope(&(obj->base)); + vpip_attach_to_current_scope(obj); - return &(obj->base); + return obj; } void array_alias_word(vvp_array_t array, unsigned long addr, vpiHandle word, @@ -1147,27 +1156,27 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word) assert(array->nets); array->nets[addr] = word; - if (struct __vpiSignal*sig = vpip_signal_from_handle(word)) { + if (struct __vpiSignal*sig = dynamic_cast<__vpiSignal*>(word)) { vvp_net_t*net = sig->node; assert(net); vvp_vpi_callback*fun = dynamic_cast(net->fil); assert(fun); fun->attach_as_word(array, addr); sig->is_netarray = 1; - sig->within.parent = &array->base; - sig->id.index = vpip_make_dec_const(addr + array->first_addr.value); + sig->within.parent = array; + sig->id.index = new __vpiDecConst(addr + array->first_addr.value); return; } - if (struct __vpiRealVar*sig = (struct __vpiRealVar*)word) { + if (struct __vpiRealVar*sig = dynamic_cast<__vpiRealVar*>(word)) { vvp_net_t*net = sig->net; assert(net); vvp_vpi_callback*fun = dynamic_cast(net->fil); assert(fun); fun->attach_as_word(array, addr); sig->is_netarray = 1; - sig->within.parent = &array->base; - sig->id.index = vpip_make_dec_const(addr + array->first_addr.value); + sig->within.parent = array; + sig->id.index = new __vpiDecConst(addr + array->first_addr.value); return; } } @@ -1178,7 +1187,7 @@ void compile_var_array(char*label, char*name, int last, int first, vpiHandle obj = vpip_make_array(label, name, first, last, signed_flag != 0); - struct __vpiArray*arr = ARRAY_HANDLE(obj); + struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); /* Make the words. */ arr->vals_width = labs(msb-lsb) + 1; @@ -1189,8 +1198,8 @@ void compile_var_array(char*label, char*name, int last, int first, arr->vals4 = new vvp_vector4array_sa(arr->vals_width, arr->array_count); } - vpip_make_dec_const(&arr->msb, msb); - vpip_make_dec_const(&arr->lsb, lsb); + arr->msb.value = msb; + arr->lsb.value = lsb; count_var_arrays += 1; count_var_array_words += arr->array_count; @@ -1204,7 +1213,7 @@ void compile_real_array(char*label, char*name, int last, int first, { vpiHandle obj = vpip_make_array(label, name, first, last, true); - struct __vpiArray*arr = ARRAY_HANDLE(obj); + struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); /* Make the words. */ arr->valsr = new vvp_realarray_t(arr->array_count); @@ -1224,7 +1233,7 @@ void compile_net_array(char*label, char*name, int last, int first) { vpiHandle obj = vpip_make_array(label, name, first, last, false); - struct __vpiArray*arr = ARRAY_HANDLE(obj); + struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); arr->nets = (vpiHandle*)calloc(arr->array_count, sizeof(vpiHandle)); count_net_arrays += 1; @@ -1617,11 +1626,11 @@ void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle obj) unsigned addr = decode_array_word_pointer(word, parent); cb->extra_data = addr; - } else if (struct __vpiArrayVthrA*tword = array_vthr_a_from_handle(obj)) { + } else if (struct __vpiArrayVthrA*tword = dynamic_cast<__vpiArrayVthrA*>(obj)) { parent = tword->array; cb->extra_data = tword->address; - } else if (struct __vpiArrayVthrAPV*apvword = array_vthr_apv_from_handle(obj)) { + } else if (struct __vpiArrayVthrAPV*apvword = dynamic_cast<__vpiArrayVthrAPV*>(obj)) { parent = apvword->array; cb->extra_data = apvword->word_sel; } @@ -1633,7 +1642,7 @@ void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle obj) void vpip_array_change(struct __vpiCallback*cb, vpiHandle obj) { - struct __vpiArray*arr = ARRAY_HANDLE(obj); + struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); cb->extra_data = -1; // This is a callback for every element. cb->next = arr->vpi_callbacks; arr->vpi_callbacks = cb; @@ -1668,22 +1677,20 @@ void compile_array_alias(char*label, char*name, char*src) vvp_array_t mem = array_find(src); assert(mem); - struct __vpiArray*obj = (struct __vpiArray*) - malloc(sizeof (struct __vpiArray)); + struct __vpiArray*obj = new __vpiArray; - obj->base.vpi_type = &vpip_arraymem_rt; obj->scope = vpip_peek_current_scope(); obj->name = vpip_name_string(name); obj->array_count = mem->array_count; obj->signed_flag = mem->signed_flag; // Need to set an accurate range of addresses. - vpip_make_dec_const(&obj->first_addr, mem->first_addr.value); - vpip_make_dec_const(&obj->last_addr, mem->last_addr.value); + obj->first_addr.value = mem->first_addr.value; + obj->last_addr.value = mem->last_addr.value; obj->swap_addr = mem->swap_addr; - vpip_make_dec_const(&obj->msb, mem->msb.value); - vpip_make_dec_const(&obj->lsb, mem->lsb.value); + obj->msb.value = mem->msb.value; + obj->lsb.value = mem->lsb.value; // Share the words with the source array. obj->nets = mem->nets; @@ -1699,8 +1706,8 @@ void compile_array_alias(char*label, char*name, char*src) assert(!array_find(label)); array_table->sym_set_value(label, obj); - compile_vpi_symbol(label, vpi_handle(obj)); - vpip_attach_to_current_scope(vpi_handle(obj)); + compile_vpi_symbol(label, obj); + vpip_attach_to_current_scope(obj); free(label); free(name); @@ -1715,10 +1722,7 @@ void compile_array_alias(char*label, char*name, char*src) */ vpiHandle vpip_make_vthr_A(char*label, unsigned addr) { - struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) - malloc(sizeof (struct __vpiArrayVthrA)); - - obj->base.vpi_type = &vpip_array_vthr_A_rt; + struct __vpiArrayVthrA*obj = new __vpiArrayVthrA; array_resolv_list_t*resolv_mem = new array_resolv_list_t(label); @@ -1730,7 +1734,7 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned addr) obj->address = addr; obj->wid = 0; - return vpi_handle(obj); + return obj; } /* @@ -1743,10 +1747,7 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned addr) vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid, char*is_signed) { - struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) - malloc(sizeof (struct __vpiArrayVthrA)); - - obj->base.vpi_type = &vpip_array_vthr_A_rt; + struct __vpiArrayVthrA*obj = new __vpiArrayVthrA; array_resolv_list_t*resolv_mem = new array_resolv_list_t(label); @@ -1761,7 +1762,7 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid, delete [] is_signed; - return vpi_handle(obj); + return obj; } /* @@ -1772,10 +1773,7 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid, */ vpiHandle vpip_make_vthr_A(char*label, char*symbol) { - struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) - malloc(sizeof (struct __vpiArrayVthrA)); - - obj->base.vpi_type = &vpip_array_vthr_A_rt; + struct __vpiArrayVthrA*obj = new __vpiArrayVthrA; array_resolv_list_t*resolv_mem = new array_resolv_list_t(label); @@ -1788,15 +1786,12 @@ vpiHandle vpip_make_vthr_A(char*label, char*symbol) obj->address = 0; obj->wid = 0; - return vpi_handle(obj); + return obj; } vpiHandle vpip_make_vthr_A(char*label, vpiHandle handle) { - struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) - malloc(sizeof (struct __vpiArrayVthrA)); - - obj->base.vpi_type = &vpip_array_vthr_A_rt; + struct __vpiArrayVthrA*obj = new __vpiArrayVthrA; array_resolv_list_t*resolv_mem = new array_resolv_list_t(label); @@ -1808,15 +1803,12 @@ vpiHandle vpip_make_vthr_A(char*label, vpiHandle handle) obj->address = 0; obj->wid = 0; - return vpi_handle(obj); + return obj; } vpiHandle vpip_make_vthr_APV(char*label, unsigned index, unsigned bit, unsigned wid) { - struct __vpiArrayVthrAPV*obj = (struct __vpiArrayVthrAPV*) - malloc(sizeof (struct __vpiArrayVthrAPV)); - - obj->base.vpi_type = &vpip_array_vthr_APV_rt; + struct __vpiArrayVthrAPV*obj = new __vpiArrayVthrAPV; array_resolv_list_t*resolv_mem = new array_resolv_list_t(label); @@ -1828,7 +1820,7 @@ vpiHandle vpip_make_vthr_APV(char*label, unsigned index, unsigned bit, unsigned obj->part_bit = bit; obj->part_wid = wid; - return vpi_handle(obj); + return obj; } void compile_array_cleanup(void) @@ -1856,7 +1848,7 @@ void memory_delete(vpiHandle item) if (arr->nets) { for (unsigned idx = 0; idx < arr->array_count; idx += 1) { if (struct __vpiSignal*sig = - vpip_signal_from_handle(arr->nets[idx])) { + dynamic_cast<__vpiSignal*>(arr->nets[idx])) { // Delete the individual words? constant_delete(sig->id.index); /* These should only be the real words. */ diff --git a/vvp/compile.cc b/vvp/compile.cc index 23d266b98..a424b20e8 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -287,7 +287,7 @@ vvp_net_t* vvp_net_lookup(const char*label) symbol_value_t val = sym_get_value(sym_vpi, label); if (val.ptr) { vpiHandle vpi = (vpiHandle) val.ptr; - switch (vpi->vpi_type->type_code) { + switch (vpi->get_type_code()) { case vpiNet: case vpiReg: case vpiBitVar: @@ -312,7 +312,7 @@ vvp_net_t* vvp_net_lookup(const char*label) default: fprintf(stderr, "Unsupported type %d.\n", - vpi->vpi_type->type_code); + vpi->get_type_code()); assert(0); } } @@ -1397,7 +1397,7 @@ static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path, vvp_net_t*net = new vvp_net_t; struct __vpiModPathSrc* srcobj = vpip_make_modpath_src(path, net) ; - vpip_attach_to_current_scope(vpi_handle(srcobj)); + vpip_attach_to_current_scope(srcobj); net->fun = obj; /* Save the vpiEdge directory into the input path term. */ diff --git a/vvp/delay.cc b/vvp/delay.cc index 2a37c40c1..ef5aa4807 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -737,43 +737,41 @@ bool vvp_fun_modpath_edge::test_vec4(const vvp_vector4_t&bit) */ static int modpath_src_get(int, vpiHandle ref) { - struct __vpiModPathSrc*obj = vpip_modpath_src_from_handle(ref); + struct __vpiModPathSrc*obj =dynamic_cast<__vpiModPathSrc*>(ref); assert(obj); return 0; } static void modpath_src_get_value(vpiHandle ref, p_vpi_value) { - assert((ref->vpi_type->type_code == vpiModPathIn)); - struct __vpiModPathSrc* modpathsrc = vpip_modpath_src_from_handle(ref); + struct __vpiModPathSrc* modpathsrc = dynamic_cast<__vpiModPathSrc*>(ref); assert(modpathsrc); return; } static vpiHandle modpath_src_put_value(vpiHandle ref, s_vpi_value *, int ) { - assert((ref->vpi_type->type_code == vpiModPathIn)); - struct __vpiModPathSrc* modpathsrc = vpip_modpath_src_from_handle(ref); + struct __vpiModPathSrc* modpathsrc = dynamic_cast<__vpiModPathSrc*>(ref); assert(modpathsrc); return 0; } static vpiHandle modpath_src_get_handle(int code, vpiHandle ref) { - struct __vpiModPathSrc*rfp = vpip_modpath_src_from_handle(ref); + struct __vpiModPathSrc*rfp = dynamic_cast<__vpiModPathSrc*>(ref); assert(rfp); switch (code) { case vpiScope: - return vpi_handle(rfp->dest->scope); + return rfp->dest->scope; case vpiModule: { struct __vpiScope*scope = rfp->dest->scope; - while (scope && scope->base.vpi_type->type_code != vpiModule) + while (scope && scope->get_type_code() != vpiModule) scope = scope->scope; assert(scope); - return vpi_handle(scope); + return scope; } // Handles to path term objects should really be obtained via @@ -782,17 +780,17 @@ static vpiHandle modpath_src_get_handle(int code, vpiHandle ref) // older versions of Icarus Verilog. case vpiModPathIn: - return vpi_handle(&rfp->path_term_in); + return &rfp->path_term_in; case vpiModPathOut: - return vpi_handle(&rfp->dest->path_term_out); + return &rfp->dest->path_term_out; } return 0; } static vpiHandle modpath_src_iterate(int code, vpiHandle ref) { - struct __vpiModPathSrc*rfp = vpip_modpath_src_from_handle(ref); + struct __vpiModPathSrc*rfp = dynamic_cast<__vpiModPathSrc*>(ref); assert(rfp); // Module paths with multiple sources or destinations are @@ -802,12 +800,12 @@ static vpiHandle modpath_src_iterate(int code, vpiHandle ref) switch (code) { case vpiModPathIn: { vpiHandle*args = (vpiHandle*)calloc(1, sizeof(vpiHandle*)); - args[0] = vpi_handle(&rfp->path_term_in); + args[0] = &rfp->path_term_in; return vpip_make_iterator(1, args, true); } case vpiModPathOut: { vpiHandle*args = (vpiHandle*)calloc(1, sizeof(vpiHandle*)); - args[0] = vpi_handle(&rfp->dest->path_term_out); + args[0] = &rfp->dest->path_term_out; return vpip_make_iterator(1, args, true); } } @@ -816,14 +814,14 @@ static vpiHandle modpath_src_iterate(int code, vpiHandle ref) static vpiHandle modpath_src_index ( vpiHandle ref, int) { - assert(ref->vpi_type->type_code == vpiModPathIn); + assert(ref->get_type_code() == vpiModPathIn); return 0; } static int modpath_src_free_object( vpiHandle ref ) { - assert( (ref->vpi_type->type_code == vpiModPathIn ) ); + assert( ref->get_type_code() == vpiModPathIn ); free ( ref ) ; return 1 ; } @@ -838,7 +836,7 @@ static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays) { vvp_time64_t tmp[12]; int idx; - struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ; + struct __vpiModPathSrc * src = dynamic_cast<__vpiModPathSrc*>(ref) ; assert(src) ; vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); @@ -908,7 +906,7 @@ static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays) static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) { - struct __vpiModPathSrc*src = vpip_modpath_src_from_handle( ref) ; + struct __vpiModPathSrc*src = dynamic_cast<__vpiModPathSrc*>(ref) ; assert(src); vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); @@ -944,7 +942,7 @@ static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) static int pathterm_get(int code, vpiHandle ref) { - struct __vpiModPathTerm*obj = vpip_modpath_term_from_handle(ref); + struct __vpiModPathTerm*obj = dynamic_cast<__vpiModPathTerm*>(ref); assert(obj); switch (code) { @@ -957,7 +955,7 @@ static int pathterm_get(int code, vpiHandle ref) static vpiHandle pathterm_get_handle(int code, vpiHandle ref) { - struct __vpiModPathTerm*obj = vpip_modpath_term_from_handle(ref); + struct __vpiModPathTerm*obj = dynamic_cast<__vpiModPathTerm*>(ref); assert(obj); switch (code) { @@ -987,6 +985,11 @@ static const struct __vpirt vpip_modpath_src_rt = { modpath_src_put_delays }; +inline __vpiModPathSrc::__vpiModPathSrc() +: __vpiHandle(&vpip_modpath_src_rt) +{ +} + static const struct __vpirt vpip_modpath_term_rt = { vpiPathTerm, pathterm_get, @@ -1001,9 +1004,13 @@ static const struct __vpirt vpip_modpath_term_rt = { 0 // vpi_put_delays }; +inline __vpiModPathTerm::__vpiModPathTerm() +: __vpiHandle(&vpip_modpath_term_rt) +{ +} + static void initialize_path_term(struct __vpiModPathTerm&obj) { - obj.base.vpi_type = &vpip_modpath_term_rt; obj.expr = 0; obj.edge = vpiNoEdge; } @@ -1021,7 +1028,7 @@ static unsigned mp_count = 0; struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) { - struct __vpiModPath*obj = (struct __vpiModPath *)calloc(1, sizeof ( struct __vpiModPath ) ); + struct __vpiModPath*obj = new __vpiModPath; obj->scope = vpip_peek_current_scope ( ); initialize_path_term(obj->path_term_out); @@ -1058,40 +1065,12 @@ void modpath_delete() struct __vpiModPathSrc* vpip_make_modpath_src(struct __vpiModPath*path, vvp_net_t *net) { - struct __vpiModPathSrc *obj = (struct __vpiModPathSrc *) calloc (1, sizeof ( struct __vpiModPathSrc ) ) ; + struct __vpiModPathSrc *obj = new __vpiModPathSrc; - obj->base.vpi_type = &vpip_modpath_src_rt; obj->dest = path; + obj->type = 0; obj->net = net; initialize_path_term(obj->path_term_in); return obj; } - - -/* - this routine will safely convert a modpath vpiHandle - to a struct __vpiModPath { } -*/ - -struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) -{ - if (ref->vpi_type->type_code != vpiPathTerm) - return 0; - - return (struct __vpiModPathTerm*) ref; -} - -/* - this routine will safely convert a modpathsrc vpiHandle - to a struct __vpiModPathSrc { }, This is equivalent to a - vpiModPathIn handle -*/ - -struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref) -{ - if (ref->vpi_type->type_code != vpiModPath) - return 0; - - return (struct __vpiModPathSrc *) ref; -} diff --git a/vvp/enum_type.cc b/vvp/enum_type.cc index 13ad72b4b..eacb17fc9 100644 --- a/vvp/enum_type.cc +++ b/vvp/enum_type.cc @@ -25,39 +25,25 @@ # include # include -struct enumconst_s { - struct __vpiHandle base; +struct enumconst_s : public __vpiHandle { + enumconst_s(); + const char*name; vvp_vector2_t val2; vvp_vector4_t val4; }; -static struct enumconst_s* enumconst_from_handle(vpiHandle obj) -{ - if (obj->vpi_type->type_code == vpiEnumConst) - return (struct enumconst_s*) obj; - else - return 0; -} +struct __vpiEnumTypespec : public __vpiHandle { + __vpiEnumTypespec(); -struct __vpiEnumTypespec { - struct __vpiHandle base; std::vector names; int base_type_code; bool is_signed; }; -static struct __vpiEnumTypespec* vpip_enum_typespec_from_handle(vpiHandle obj) -{ - if (obj->vpi_type->type_code == vpiEnumTypespec) - return (struct __vpiEnumTypespec*) obj; - - return 0; -} - static int enum_type_get(int code, vpiHandle obj) { - struct __vpiEnumTypespec*ref = vpip_enum_typespec_from_handle(obj); + struct __vpiEnumTypespec*ref = dynamic_cast<__vpiEnumTypespec*>(obj); assert(ref); switch (code) { @@ -84,14 +70,14 @@ static int enum_type_get(int code, vpiHandle obj) static vpiHandle enum_type_iterate(int code, vpiHandle obj) { - struct __vpiEnumTypespec*ref = vpip_enum_typespec_from_handle(obj); + struct __vpiEnumTypespec*ref = dynamic_cast<__vpiEnumTypespec*>(obj); assert(ref); if (code == vpiEnumConst) { vpiHandle*args = (vpiHandle*) calloc(ref->names.size(), sizeof(vpiHandle*)); for (size_t idx = 0 ; idx < ref->names.size() ; idx += 1) - args[idx] = vpi_handle(&ref->names[idx]); + args[idx] = &ref->names[idx]; return vpip_make_iterator(ref->names.size(), args, true); } @@ -113,9 +99,14 @@ static const struct __vpirt enum_type_rt = { 0, //enum_type_put_delays }; +inline __vpiEnumTypespec::__vpiEnumTypespec() +: __vpiHandle(&enum_type_rt) +{ +} + static int enum_name_get(int code, vpiHandle obj) { - struct enumconst_s*ref = enumconst_from_handle(obj); + struct enumconst_s*ref = dynamic_cast(obj); assert(ref); switch (code) { @@ -128,7 +119,7 @@ static int enum_name_get(int code, vpiHandle obj) static char* enum_name_get_str(int code, vpiHandle obj) { - struct enumconst_s*ref = enumconst_from_handle(obj); + struct enumconst_s*ref = dynamic_cast(obj); assert(ref); switch (code) { @@ -141,7 +132,7 @@ static char* enum_name_get_str(int code, vpiHandle obj) static void enum_name_get_value(vpiHandle obj, p_vpi_value value) { - struct enumconst_s*ref = enumconst_from_handle(obj); + struct enumconst_s*ref = dynamic_cast(obj); assert(ref); if (ref->val4.size() > 0) @@ -164,11 +155,15 @@ static const struct __vpirt enum_name_rt = { 0, //enum_name_put_delays }; +inline enumconst_s::enumconst_s() +: __vpiHandle(&enum_name_rt) +{ +} + void compile_enum2_type(char*label, long width, bool signed_flag, std::list*names) { struct __vpiEnumTypespec*spec = new struct __vpiEnumTypespec; - spec->base.vpi_type = &enum_type_rt; spec->names = std::vector (names->size()); spec->is_signed = signed_flag; spec->base_type_code = vpiBitVar; @@ -177,14 +172,13 @@ void compile_enum2_type(char*label, long width, bool signed_flag, for (list::iterator cur = names->begin() ; cur != names->end() ; ++cur, ++idx) { assert(cur->val4 == 0); - spec->names[idx].base.vpi_type = &enum_name_rt; spec->names[idx].name = cur->text; spec->names[idx].val2 = vvp_vector2_t(cur->val2, width); } assert(idx == spec->names.size()); - compile_vpi_symbol(label, vpi_handle(spec)); - vpip_attach_to_current_scope(vpi_handle(spec)); + compile_vpi_symbol(label, spec); + vpip_attach_to_current_scope(spec); free(label); delete names; @@ -194,7 +188,6 @@ void compile_enum4_type(char*label, long width, bool signed_flag, std::list*names) { struct __vpiEnumTypespec*spec = new struct __vpiEnumTypespec; - spec->base.vpi_type = &enum_type_rt; spec->names = std::vector (names->size()); spec->is_signed = signed_flag; spec->base_type_code = vpiReg; @@ -202,7 +195,6 @@ void compile_enum4_type(char*label, long width, bool signed_flag, size_t idx = 0; for (list::iterator cur = names->begin() ; cur != names->end() ; ++cur, ++idx) { - spec->names[idx].base.vpi_type = &enum_name_rt; spec->names[idx].name = cur->text; assert(cur->val4); spec->names[idx].val4 = vector4_from_text(cur->val4, width); @@ -211,8 +203,8 @@ void compile_enum4_type(char*label, long width, bool signed_flag, } assert(idx == spec->names.size()); - compile_vpi_symbol(label, vpi_handle(spec)); - vpip_attach_to_current_scope(vpi_handle(spec)); + compile_vpi_symbol(label, spec); + vpip_attach_to_current_scope(spec); free(label); delete names; @@ -221,7 +213,7 @@ void compile_enum4_type(char*label, long width, bool signed_flag, #ifdef CHECK_WITH_VALGRIND void enum_delete(vpiHandle item) { - struct __vpiEnumTypespec*obj = (struct __vpiEnumTypespec*) item; + struct __vpiEnumTypespec*obj = dynamic_cast<__vpiEnumTypespec*>(item); for (vector::iterator iter = obj->names.begin(); iter != obj->names.end(); ++ iter ) { diff --git a/vvp/file_line.cc b/vvp/file_line.cc index 924f7d710..22f95fd4b 100644 --- a/vvp/file_line.cc +++ b/vvp/file_line.cc @@ -19,8 +19,9 @@ # include "compile.h" # include "vpi_priv.h" -struct __vpiFileLine { - struct __vpiHandle base; +struct __vpiFileLine : public __vpiHandle { + __vpiFileLine(); + const char *description; unsigned file_idx; unsigned lineno; @@ -31,9 +32,8 @@ bool code_is_instrumented = false; static int file_line_get(int type, vpiHandle ref) { - struct __vpiFileLine*rfp = (struct __vpiFileLine*)ref; - - assert(ref->vpi_type->type_code == _vpiFileLine); + struct __vpiFileLine*rfp = dynamic_cast<__vpiFileLine*>(ref); + assert(rfp); switch (type) { case vpiLineNo: @@ -45,9 +45,8 @@ static int file_line_get(int type, vpiHandle ref) static char *file_line_get_str(int type, vpiHandle ref) { - struct __vpiFileLine*rfp = (struct __vpiFileLine*)ref; - - assert(ref->vpi_type->type_code == _vpiFileLine); + struct __vpiFileLine*rfp = dynamic_cast<__vpiFileLine*>(ref); + assert(rfp); switch (type) { case vpiFile: @@ -75,6 +74,11 @@ static const struct __vpirt vpip_file_line_rt = { 0 }; +inline __vpiFileLine::__vpiFileLine() +: __vpiHandle(&vpip_file_line_rt) +{ +} + vpiHandle vpip_build_file_line(char*description, long file_idx, long lineno) { struct __vpiFileLine*obj = new struct __vpiFileLine; @@ -83,11 +87,10 @@ vpiHandle vpip_build_file_line(char*description, long file_idx, long lineno) show_file_line = true; code_is_instrumented = true; - obj->base.vpi_type = &vpip_file_line_rt; if (description) obj->description = vpip_name_string(description); else obj->description = 0; obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; - return &obj->base; + return obj; } diff --git a/vvp/schedule.cc b/vvp/schedule.cc index f2ab78f54..83d627ae2 100644 --- a/vvp/schedule.cc +++ b/vvp/schedule.cc @@ -123,7 +123,7 @@ void vthread_event_s::single_step_display(void) { struct __vpiScope*scope = vthread_scope(thr); cerr << "vthread_event: Resume thread" - << " scope=" << vpip_get_str(vpiFullName, scope) + << " scope=" << scope->vpi_get_str(vpiFullName) << endl; } @@ -156,7 +156,7 @@ void del_thr_event_s::single_step_display(void) { struct __vpiScope*scope = vthread_scope(thr); cerr << "del_thr_event: Reap completed thread" - << " scope=" << vpip_get_str(vpiFullName, scope) << endl; + << " scope=" << scope->vpi_get_str(vpiFullName) << endl; } struct assign_vector4_event_s : public event_s { diff --git a/vvp/stop.cc b/vvp/stop.cc index 438a8785a..b25a432fc 100644 --- a/vvp/stop.cc +++ b/vvp/stop.cc @@ -101,7 +101,7 @@ static void cmd_call(unsigned argc, char*argv[]) .(dot) string. This represents the handle for the current scope. */ if (stop_current_scope && (strcmp(argv[idx+1], ".") == 0)) - handle = &stop_current_scope->base; + handle = stop_current_scope; /* Is the argument a quoted string? */ if (handle == 0 && argv[idx+1][0] == '"') { @@ -119,7 +119,7 @@ static void cmd_call(unsigned argc, char*argv[]) /* Is the argument a decimal constant? */ if (handle == 0 && strspn(argv[idx+1],"0123456789") == strlen(argv[idx+1])) { - handle = vpip_make_dec_const(strtol(argv[idx+1],0,10)); + handle = new __vpiDecConst(strtol(argv[idx+1],0,10)); add_to_free_list = true; } @@ -130,14 +130,14 @@ static void cmd_call(unsigned argc, char*argv[]) struct __vpiScope*scope; const char*name; - switch (table[tmp]->vpi_type->type_code) { + switch (table[tmp]->get_type_code()) { case vpiModule: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); if (strcmp(scope->name, argv[idx+1]) == 0) handle = table[tmp]; break; @@ -229,29 +229,29 @@ static void cmd_list(unsigned, char*[]) struct __vpiScope*scope; struct __vpiSignal*sig; - switch (table[idx]->vpi_type->type_code) { + switch (table[idx]->get_type_code()) { case vpiModule: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); printf("module : %s\n", scope->name); break; case vpiTask: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); printf("task : %s\n", scope->name); break; case vpiFunction: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); printf("function: %s\n", scope->name); break; case vpiNamedBegin: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); printf("block : %s\n", scope->name); break; case vpiNamedFork: - scope = (struct __vpiScope*) table[idx]; + scope = dynamic_cast<__vpiScope*>(table[idx]); printf("fork : %s\n", scope->name); break; @@ -260,7 +260,7 @@ static void cmd_list(unsigned, char*[]) break; case vpiReg: - sig = (struct __vpiSignal*) table[idx]; + sig = dynamic_cast<__vpiSignal*>(table[idx]); if ((sig->msb == 0) && (sig->lsb == 0)) printf("reg : %s%s\n", vpi_get_str(vpiName, table[idx]), @@ -273,7 +273,7 @@ static void cmd_list(unsigned, char*[]) break; case vpiNet: - sig = (struct __vpiSignal*) table[idx]; + sig = dynamic_cast<__vpiSignal*>(table[idx]); if ((sig->msb == 0) && (sig->lsb == 0)) printf("net : %s%s\n", vpi_get_str(vpiName, table[idx]), @@ -287,7 +287,7 @@ static void cmd_list(unsigned, char*[]) default: printf("%8d: \n", - table[idx]->vpi_type->type_code); + table[idx]->get_type_code()); break; } @@ -329,10 +329,10 @@ static void cmd_push(unsigned argc, char* argv[]) child = 0; unsigned tmp; for (tmp = 0 ; tmp < ntable ; tmp += 1) { - if (table[tmp]->vpi_type->type_code != vpiModule) + if (table[tmp]->get_type_code() != vpiModule) continue; - struct __vpiScope*cp = (struct __vpiScope*) table[tmp]; + struct __vpiScope*cp = dynamic_cast<__vpiScope*>(table[tmp]); /* This is a scope, and the name matches, then report that I found the child. */ @@ -392,15 +392,12 @@ static void cmd_where(unsigned, char*[]) struct __vpiScope*cur = stop_current_scope; while (cur) { - switch (cur->base.vpi_type->type_code) { + switch (cur->get_type_code()) { case vpiModule: - printf("module %s\n", - cur->name); + printf("module %s\n", cur->name); break; default: - printf("scope (%d) %s;\n", - cur->base.vpi_type->type_code, - cur->name); + printf("scope (%d) %s;\n", cur->get_type_code(), cur->name); break; } diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 1ff3b9352..5a3af8215 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -60,6 +60,11 @@ const struct __vpirt callback_rt = { 0, 0 }; +inline __vpiCallback::__vpiCallback() +: __vpiHandle(&callback_rt) +{ +} + /* * Callback handles are created when the VPI function registers a @@ -85,14 +90,12 @@ struct sync_cb : public vvp_gen_event_s { virtual void run_run(); }; - struct __vpiCallback* new_vpi_callback() { struct __vpiCallback* obj; obj = new __vpiCallback; - obj->base.vpi_type = &callback_rt; obj->cb_sync = 0; obj->next = 0; return obj; @@ -101,8 +104,6 @@ struct __vpiCallback* new_vpi_callback() void delete_vpi_callback(struct __vpiCallback* ref) { assert(ref); - assert(ref->base.vpi_type); - assert(ref->base.vpi_type->type_code == vpiCallback); delete ref->cb_sync; delete ref; } @@ -141,9 +142,8 @@ static struct __vpiCallback* make_value_change(p_cb_data data) obj->cb_data.value = &obj->cb_value; assert(data->obj); - assert(data->obj->vpi_type); - switch (data->obj->vpi_type->type_code) { + switch (data->obj->get_type_code()) { case vpiReg: case vpiNet: @@ -156,7 +156,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data) /* Attach the callback to the vvp_fun_signal node by putting it in the vpi_callbacks list. */ struct __vpiSignal*sig; - sig = reinterpret_cast<__vpiSignal*>(data->obj); + sig = dynamic_cast<__vpiSignal*>(data->obj); vvp_net_fil_t*sig_fil; sig_fil = dynamic_cast(sig->node->fil); @@ -172,7 +172,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data) case vpiNamedEvent: struct __vpiNamedEvent*nev; - nev = reinterpret_cast<__vpiNamedEvent*>(data->obj); + nev = dynamic_cast<__vpiNamedEvent*>(data->obj); obj->next = nev->callbacks; nev->callbacks = obj; break; @@ -199,7 +199,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data) default: fprintf(stderr, "make_value_change: sorry: I cannot callback " "values on type code=%d\n", - data->obj->vpi_type->type_code); + data->obj->get_type_code()); delete obj; return 0; } @@ -473,7 +473,7 @@ vpiHandle vpi_register_cb(p_cb_data data) break; } - return obj? &obj->base : 0; + return obj; } /* @@ -483,11 +483,8 @@ vpiHandle vpi_register_cb(p_cb_data data) */ PLI_INT32 vpi_remove_cb(vpiHandle ref) { - assert(ref); - assert(ref->vpi_type); - assert(ref->vpi_type->type_code == vpiCallback); - - struct __vpiCallback*obj = (struct __vpiCallback*)ref; + struct __vpiCallback*obj = dynamic_cast<__vpiCallback*>(ref); + assert(obj); obj->cb_data.cb_rtn = 0; return 1; diff --git a/vvp/vpi_const.cc b/vvp/vpi_const.cc index 82464b112..d1c639afe 100644 --- a/vvp/vpi_const.cc +++ b/vvp/vpi_const.cc @@ -35,13 +35,8 @@ static int string_get(int code, vpiHandle ref) switch (code) { case vpiSize: - rfp = (struct __vpiStringConst*)ref; - - assert((ref->vpi_type->type_code == vpiConstant) - || ((ref->vpi_type->type_code == vpiParameter))); - - //fprintf(stderr, "String:|%s|, Length: %d\n", rfp->value, strlen(rfp->value)); - return strlen(rfp->value)*8; + rfp = dynamic_cast<__vpiStringConst*>(ref); + return strlen(rfp->value)*8; case vpiSigned: return 0; @@ -69,14 +64,11 @@ static void string_value(vpiHandle ref, p_vpi_value vp) { unsigned uint_value; p_vpi_vecval vecp; - struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref; + struct __vpiStringConst*rfp = dynamic_cast<__vpiStringConst*>(ref); int size = strlen(rfp->value); char*rbuf = 0; char*cp; - assert((ref->vpi_type->type_code == vpiConstant) - || ((ref->vpi_type->type_code == vpiParameter))); - switch (vp->format) { case vpiObjTypeVal: /* String parameters by default have vpiStringVal values. */ @@ -187,11 +179,18 @@ static const struct __vpirt vpip_string_rt = { 0, 0 }; +inline __vpiStringConst::__vpiStringConst() +: __vpiHandle(&vpip_string_rt) +{ +} + +struct __vpiStringConstTEMP : public __vpiStringConst { + __vpiStringConstTEMP(); +}; static int free_temp_string(vpiHandle obj) { - struct __vpiStringConst*rfp = (struct __vpiStringConst*)obj; - assert(obj->vpi_type->type_code == vpiConstant); + struct __vpiStringConstTEMP*rfp = dynamic_cast<__vpiStringConstTEMP*>(obj); delete [] rfp->value; free(rfp); @@ -212,6 +211,11 @@ static const struct __vpirt vpip_string_temp_rt = { 0 }; +inline __vpiStringConstTEMP::__vpiStringConstTEMP() +: __vpiStringConst(&vpip_string_temp_rt) +{ +} + /* * Strings are described at the level of the vvp source as a string * with literal characters or octal escapes. No other escapes are @@ -247,20 +251,17 @@ vpiHandle vpip_make_string_const(char*text, bool persistent_flag) { struct __vpiStringConst*obj; - obj = (struct __vpiStringConst*) - malloc(sizeof (struct __vpiStringConst)); - obj->base.vpi_type = persistent_flag - ? &vpip_string_rt - : &vpip_string_temp_rt; + obj = persistent_flag? new __vpiStringConst : new __vpiStringConstTEMP; obj->value = text; obj->value_len = 0; vpip_process_string(obj); - return &obj->base; + return obj; } struct __vpiStringParam : public __vpiStringConst { + __vpiStringParam(); const char*basename; struct __vpiScope* scope; unsigned file_idx; @@ -269,9 +270,8 @@ struct __vpiStringParam : public __vpiStringConst { static int string_param_get(int code, vpiHandle ref) { - struct __vpiStringParam*rfp = (struct __vpiStringParam*)ref; - - assert(ref->vpi_type->type_code == vpiParameter); + struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(ref); + assert(ref); if (code == vpiLineNo) { return rfp->lineno; @@ -282,26 +282,24 @@ static int string_param_get(int code, vpiHandle ref) static char* string_param_get_str(int code, vpiHandle obj) { - struct __vpiStringParam*rfp = (struct __vpiStringParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(obj); + assert(rfp); if (code == vpiFile) { return simple_set_rbuf_str(file_names[rfp->file_idx]); } - return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); + return generic_get_str(code, rfp->scope, rfp->basename, NULL); } static vpiHandle string_param_handle(int code, vpiHandle obj) { - struct __vpiStringParam*rfp = (struct __vpiStringParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(obj); + assert(rfp); switch (code) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; case vpiModule: return vpip_module(rfp->scope); @@ -325,15 +323,16 @@ static const struct __vpirt vpip_string_param_rt = { 0 }; +inline __vpiStringParam::__vpiStringParam() +: __vpiStringConst(&vpip_string_param_rt) +{ +} + vpiHandle vpip_make_string_param(char*name, char*text, long file_idx, long lineno) { - struct __vpiStringParam*obj; - - obj = (struct __vpiStringParam*) - malloc(sizeof (struct __vpiStringParam)); - obj->base.vpi_type = &vpip_string_param_rt; + struct __vpiStringParam*obj = new __vpiStringParam; obj->value = text; obj->value_len = 0; obj->basename = name; @@ -343,14 +342,12 @@ vpiHandle vpip_make_string_param(char*name, char*text, vpip_process_string(obj); - return &obj->base; + return obj; } static int binary_get(int code, vpiHandle ref) { - struct __vpiBinaryConst*rfp = (struct __vpiBinaryConst*)ref; - assert(ref->vpi_type->type_code == vpiConstant - || ref->vpi_type->type_code == vpiParameter); + struct __vpiBinaryConst*rfp = dynamic_cast<__vpiBinaryConst*>(ref); switch (code) { case vpiConstType: @@ -384,11 +381,7 @@ static int binary_get(int code, vpiHandle ref) static void binary_value(vpiHandle ref, p_vpi_value vp) { - assert(ref->vpi_type->type_code == vpiConstant - || ref->vpi_type->type_code == vpiParameter); - - struct __vpiBinaryConst*rfp = (struct __vpiBinaryConst*)ref; - + struct __vpiBinaryConst*rfp = dynamic_cast<__vpiBinaryConst*>(ref); switch (vp->format) { @@ -428,6 +421,11 @@ static const struct __vpirt vpip_binary_rt = { 0 }; +inline __vpiBinaryConst::__vpiBinaryConst() +: __vpiHandle(&vpip_binary_rt) +{ +} + /* * Make a VPI constant from a vector string. The string is normally a * ASCII string, with each letter a 4-value bit. The first character @@ -435,10 +433,7 @@ static const struct __vpirt vpip_binary_rt = { */ vpiHandle vpip_make_binary_const(unsigned wid, const char*bits) { - struct __vpiBinaryConst*obj; - - obj = new __vpiBinaryConst; - obj->base.vpi_type = &vpip_binary_rt; + struct __vpiBinaryConst*obj = new __vpiBinaryConst; obj->signed_flag = 0; obj->sized_flag = 0; @@ -451,7 +446,7 @@ vpiHandle vpip_make_binary_const(unsigned wid, const char*bits) obj->bits = vector4_from_text(bp, wid); - return &(obj->base); + return obj; } vvp_vector4_t vector4_from_text(const char*bits, unsigned wid) @@ -482,6 +477,7 @@ vvp_vector4_t vector4_from_text(const char*bits, unsigned wid) } struct __vpiBinaryParam : public __vpiBinaryConst { + __vpiBinaryParam(); const char*basename; struct __vpiScope*scope; unsigned file_idx; @@ -490,9 +486,7 @@ struct __vpiBinaryParam : public __vpiBinaryConst { static int binary_param_get(int code, vpiHandle ref) { - struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)ref; - - assert(ref->vpi_type->type_code == vpiParameter); + struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(ref); if (code == vpiLineNo) { return rfp->lineno; @@ -503,26 +497,22 @@ static int binary_param_get(int code, vpiHandle ref) static char* binary_param_get_str(int code, vpiHandle obj) { - struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(obj); if (code == vpiFile) { return simple_set_rbuf_str(file_names[rfp->file_idx]); } - return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); + return generic_get_str(code, rfp->scope, rfp->basename, NULL); } static vpiHandle binary_param_handle(int code, vpiHandle obj) { - struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(obj); switch (code) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; case vpiModule: return vpip_module(rfp->scope); @@ -545,6 +535,10 @@ static const struct __vpirt vpip_binary_param_rt = { 0, 0 }; +inline __vpiBinaryParam::__vpiBinaryParam() +: __vpiBinaryConst(&vpip_binary_param_rt) +{ +} vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, bool signed_flag, @@ -552,7 +546,6 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, { struct __vpiBinaryParam*obj = new __vpiBinaryParam; - obj->base.vpi_type = &vpip_binary_param_rt; obj->bits = bits; obj->signed_flag = signed_flag? 1 : 0; obj->sized_flag = 0; @@ -561,7 +554,7 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; - return &obj->base; + return obj; } @@ -597,8 +590,7 @@ static int dec_get(int code, vpiHandle) static void dec_value(vpiHandle ref, p_vpi_value vp) { - struct __vpiDecConst*rfp = (struct __vpiDecConst*)ref; - assert(ref->vpi_type->type_code == vpiConstant); + struct __vpiDecConst*rfp = dynamic_cast<__vpiDecConst*>(ref); char*rbuf = need_result_buf(64 + 1, RBUF_VAL); char*cp = rbuf; @@ -658,25 +650,12 @@ static const struct __vpirt vpip_dec_rt = { 0, 0 }; - -vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value) +__vpiDecConst::__vpiDecConst(int val) +: __vpiHandle(&vpip_dec_rt) { - obj->base.vpi_type = &vpip_dec_rt; - obj->value = value; - - return &(obj->base); + value = val; } -vpiHandle vpip_make_dec_const(int value) -{ - struct __vpiDecConst*obj; - - obj = (struct __vpiDecConst*) - malloc(sizeof (struct __vpiDecConst)); - return vpip_make_dec_const(obj, value); -} - - static int real_get(int code, vpiHandle) { @@ -711,10 +690,7 @@ static int real_get(int code, vpiHandle) static void real_value(vpiHandle ref, p_vpi_value vp) { - struct __vpiRealConst*rfp = (struct __vpiRealConst*)ref; - assert((ref->vpi_type->type_code == vpiConstant) || - (ref->vpi_type->type_code == vpiParameter)); - + struct __vpiRealConst*rfp = dynamic_cast<__vpiRealConst*>(ref); vpip_real_get_value(rfp->value, vp); } @@ -731,22 +707,20 @@ static const struct __vpirt vpip_real_rt = { 0, 0 }; - -vpiHandle vpip_make_real_const(struct __vpiRealConst*obj, double value) +inline __vpiRealConst::__vpiRealConst() +: __vpiHandle(&vpip_real_rt) { - obj->base.vpi_type = &vpip_real_rt; - obj->value = value; - return &(obj->base); } vpiHandle vpip_make_real_const(double value) { - struct __vpiRealConst*obj; - obj =(struct __vpiRealConst*) malloc(sizeof (struct __vpiRealConst)); - return vpip_make_real_const(obj, value); + struct __vpiRealConst*obj = new __vpiRealConst; + obj->value = value; + return obj; } struct __vpiRealParam : public __vpiRealConst { + __vpiRealParam(); const char*basename; struct __vpiScope* scope; unsigned file_idx; @@ -755,9 +729,7 @@ struct __vpiRealParam : public __vpiRealConst { static int real_param_get(int code, vpiHandle ref) { - struct __vpiRealParam*rfp = (struct __vpiRealParam*)ref; - - assert(ref->vpi_type->type_code == vpiParameter); + struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(ref); if (code == vpiLineNo) { return rfp->lineno; @@ -768,26 +740,22 @@ static int real_param_get(int code, vpiHandle ref) static char* real_param_get_str(int code, vpiHandle obj) { - struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(obj); if (code == vpiFile) { return simple_set_rbuf_str(file_names[rfp->file_idx]); } - return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); + return generic_get_str(code, rfp->scope, rfp->basename, NULL); } static vpiHandle real_param_handle(int code, vpiHandle obj) { - struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj; - - assert(obj->vpi_type->type_code == vpiParameter); + struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(obj); switch (code) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; case vpiModule: return vpip_module(rfp->scope); @@ -810,22 +778,24 @@ static const struct __vpirt vpip_real_param_rt = { 0, 0 }; +inline __vpiRealParam::__vpiRealParam() +: __vpiRealConst(&vpip_real_param_rt) +{ +} + vpiHandle vpip_make_real_param(char*name, double value, long file_idx, long lineno) { - struct __vpiRealParam*obj; + struct __vpiRealParam*obj = new __vpiRealParam; - obj = (struct __vpiRealParam*) - malloc(sizeof (struct __vpiRealParam)); - obj->base.vpi_type = &vpip_real_param_rt; obj->value = value; obj->basename = name; obj->scope = vpip_peek_current_scope(); obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; - return &obj->base; + return obj; } #ifdef CHECK_WITH_VALGRIND @@ -834,20 +804,20 @@ void constant_delete(vpiHandle item) assert(item->vpi_type->type_code == vpiConstant); switch(vpi_get(vpiConstType, item)) { case vpiStringConst: { - struct __vpiStringConst*rfp = (struct __vpiStringConst*)item; + struct __vpiStringConst*rfp = dynamic_cast<__vpiStringConst*>(item); delete [] rfp->value; free(rfp); break; } case vpiDecConst: { - struct __vpiDecConst*rfp = (struct __vpiDecConst*)item; + struct __vpiDecConst*rfp = dynamic_cast<__vpiDecConst*>(item); free(rfp); break; } case vpiBinaryConst: { - struct __vpiBinaryConst*rfp = (struct __vpiBinaryConst*)item; + struct __vpiBinaryConst*rfp = dynamic_cast<__vpiBinaryConst*>(item); delete rfp; break; } case vpiRealConst: { - struct __vpiRealConst*rfp = (struct __vpiRealConst*)item; + struct __vpiRealConst*rfp = dynamic_cast<__vpiRealConst*>(item); free(rfp); break; } default: @@ -859,18 +829,18 @@ void parameter_delete(vpiHandle item) { switch(vpi_get(vpiConstType, item)) { case vpiStringConst: { - struct __vpiStringParam*rfp = (struct __vpiStringParam*)item; + struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(item); delete [] rfp->basename; delete [] rfp->value; free(rfp); break; } case vpiBinaryConst: { - struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)item; + struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(item); delete [] rfp->basename; delete rfp; break; } case vpiRealConst: { - struct __vpiRealParam*rfp = (struct __vpiRealParam*)item; + struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(item); delete [] rfp->basename; free(rfp); break; } diff --git a/vvp/vpi_event.cc b/vvp/vpi_event.cc index 49c01cab0..c28f0aa58 100644 --- a/vvp/vpi_event.cc +++ b/vvp/vpi_event.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2012 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 @@ -27,9 +27,8 @@ static int named_event_get(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNamedEvent)); - - struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref; + struct __vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(ref); + assert(obj); switch (code) { @@ -42,25 +41,23 @@ static int named_event_get(int code, vpiHandle ref) static char* named_event_get_str(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNamedEvent)); - - struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref; + struct __vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(ref); + assert(obj); if (code == vpiFile) { // Not implemented for now! return simple_set_rbuf_str(file_names[0]); } - return generic_get_str(code, &obj->scope->base, obj->name, NULL); + return generic_get_str(code, obj->scope, obj->name, NULL); } static vpiHandle named_event_get_handle(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNamedEvent)); - - struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref; + struct __vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(ref); + assert(obj); switch (code) { case vpiScope: - return &obj->scope->base; + return obj->scope; case vpiModule: return vpip_module(obj->scope); @@ -83,19 +80,21 @@ static const struct __vpirt vpip_named_event_rt = { 0, 0 }; +inline __vpiNamedEvent::__vpiNamedEvent() +: __vpiHandle(&vpip_named_event_rt) +{ +} vpiHandle vpip_make_named_event(const char*name, vvp_net_t*funct) { - struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*) - malloc(sizeof(struct __vpiNamedEvent)); + struct __vpiNamedEvent*obj = new __vpiNamedEvent; - obj->base.vpi_type = &vpip_named_event_rt; obj->name = vpip_name_string(name); obj->scope = vpip_peek_current_scope(); obj->funct = funct; obj->callbacks = 0; - return &obj->base; + return obj; } /* @@ -113,9 +112,7 @@ vpiHandle vpip_make_named_event(const char*name, vvp_net_t*funct) */ void vpip_run_named_event_callbacks(vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNamedEvent)); - - struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref; + struct __vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(ref); struct __vpiCallback*next = obj->callbacks; struct __vpiCallback*prev = 0; diff --git a/vvp/vpi_iter.cc b/vvp/vpi_iter.cc index f548e796a..229e96ca7 100644 --- a/vvp/vpi_iter.cc +++ b/vvp/vpi_iter.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2012 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 @@ -28,8 +28,8 @@ static int iterator_free_object(vpiHandle ref) { - struct __vpiIterator*hp = (struct __vpiIterator*)ref; - assert(ref->vpi_type->type_code == vpiIterator); + struct __vpiIterator*hp = dynamic_cast<__vpiIterator*>(ref); + assert(hp); if (hp->free_args_flag) free(hp->args); @@ -51,20 +51,22 @@ static const struct __vpirt vpip_iterator_rt = { 0, // vpi_get_delay 0 // vpi_put_delay }; +inline __vpiIterator::__vpiIterator() +: __vpiHandle(&vpip_iterator_rt) +{ +} vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args, bool free_args_flag) { - struct __vpiIterator*res = (struct __vpiIterator*) - calloc(1, sizeof(struct __vpiIterator)); - res->base.vpi_type = &vpip_iterator_rt; + struct __vpiIterator*res = new __vpiIterator; res->args = args; res->nargs = nargs; res->next = 0; res->free_args_flag = free_args_flag; - return &(res->base); + return res; } /* @@ -79,25 +81,14 @@ vpiHandle vpi_scan(vpiHandle ref) return 0; } - if (ref->vpi_type->type_code != vpiIterator) { - fprintf(stderr, "ERROR: vpi_scan argument is " - "inappropriate vpiType code %d\n", - ref->vpi_type->type_code); - assert(0); - return 0; + if (struct __vpiIterator*hp = dynamic_cast<__vpiIterator*>(ref)) { + if (hp->next == hp->nargs) { + vpi_free_object(ref); + return 0; + } + + return hp->args[hp->next++]; } - struct __vpiIterator*hp = (struct __vpiIterator*)ref; - assert(ref); - assert(ref->vpi_type->type_code == vpiIterator); - - if (ref->vpi_type->index_) - return (ref->vpi_type->index_(ref, 0)); - - if (hp->next == hp->nargs) { - vpi_free_object(ref); - return 0; - } - - return hp->args[hp->next++]; + return ref->vpi_index(0); } diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index f1c2ab814..b8e5f6d4d 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008-2012 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 @@ -67,11 +67,11 @@ struct __vpiScope* vpip_scope(__vpiRealVar*sig) vpiHandle vpip_module(struct __vpiScope*scope) { - while(scope && scope->base.vpi_type->type_code != vpiModule) { + while(scope && scope->get_type_code() != vpiModule) { scope = scope->scope; } assert(scope); - return &scope->base; + return scope; } const char *vpip_string(const char*str) @@ -165,17 +165,13 @@ PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2) */ 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; + struct __vpiUserSystf* rfp = dynamic_cast<__vpiUserSystf*>(ref); + if (rfp == 0) { + struct __vpiSysTaskCall*call = dynamic_cast<__vpiSysTaskCall*>(ref); + assert(call); rfp = call->defn; } + /* Assert that vpiUserDefn is true! */ assert(rfp->is_user_defn); @@ -204,10 +200,7 @@ PLI_INT32 vpi_free_object(vpiHandle ref) } assert(ref); - if (ref->vpi_type->vpi_free_object_ == 0) - rtn = 1; - else - rtn = ref->vpi_type->vpi_free_object_(ref); + rtn = __vpiHandle::vpi_free_object(ref); if (vpi_trace) fprintf(vpi_trace, " --> %d\n", rtn); @@ -327,25 +320,16 @@ PLI_INT32 vpi_get(int property, vpiHandle ref) if (property == vpiType) { if (vpi_trace) { fprintf(vpi_trace, "vpi_get(vpiType, %p) --> %s\n", - ref, vpi_type_values(ref->vpi_type->type_code)); + ref, vpi_type_values(ref->get_type_code())); } - if (ref->vpi_type->type_code == vpiMemory && is_net_array(ref)) + if (ref->get_type_code() == vpiMemory && is_net_array(ref)) return vpiNetArray; else - return ref->vpi_type->type_code; + return ref->get_type_code(); } - if (ref->vpi_type->vpi_get_ == 0) { - if (vpi_trace) { - fprintf(vpi_trace, "vpi_get(%s, %p) --X\n", - vpi_property_str(property), ref); - } - - return vpiUndefined; - } - - int res = (ref->vpi_type->vpi_get_)(property, ref); + int res = ref->vpi_get(property); if (vpi_trace) { fprintf(vpi_trace, "vpi_get(%s, %p) --> %d\n", @@ -380,30 +364,22 @@ char* vpi_get_str(PLI_INT32 property, vpiHandle ref) if (property == vpiType) { if (vpi_trace) { fprintf(vpi_trace, "vpi_get(vpiType, %p) --> %s\n", - ref, vpi_type_values(ref->vpi_type->type_code)); + ref, vpi_type_values(ref->get_type_code())); } PLI_INT32 type; - if (ref->vpi_type->type_code == vpiMemory && is_net_array(ref)) + if (ref->get_type_code() == vpiMemory && is_net_array(ref)) type = vpiNetArray; else - type = ref->vpi_type->type_code; + type = ref->get_type_code(); return (char *)vpi_type_values(type); } - if (ref->vpi_type->vpi_get_str_ == 0) { - if (vpi_trace) { - fprintf(vpi_trace, "vpi_get_str(%s, %p) --X\n", - vpi_property_str(property), ref); - } - return 0; - } - - char*res = (char*)(ref->vpi_type->vpi_get_str_)(property, ref); + char*res = ref->vpi_get_str(property); if (vpi_trace) { fprintf(vpi_trace, "vpi_get_str(%s, %p) --> %s\n", - vpi_property_str(property), ref, res); + vpi_property_str(property), ref, res? res : ""); } return res; @@ -418,24 +394,24 @@ int vpip_time_units_from_handle(vpiHandle obj) if (obj == 0) return vpip_get_time_precision(); - switch (obj->vpi_type->type_code) { + switch (obj->get_type_code()) { case vpiSysTaskCall: - task = (struct __vpiSysTaskCall*)obj; + task = dynamic_cast<__vpiSysTaskCall*>(obj); return task->scope->time_units; case vpiModule: - scope = (struct __vpiScope*)obj; + scope = dynamic_cast<__vpiScope*>(obj); return scope->time_units; case vpiNet: case vpiReg: - signal = vpip_signal_from_handle(obj); + signal = dynamic_cast<__vpiSignal*>(obj); scope = vpip_scope(signal); return scope->time_units; default: fprintf(stderr, "ERROR: vpip_time_units_from_handle called with " - "object handle type=%u\n", obj->vpi_type->type_code); + "object handle type=%u\n", obj->get_type_code()); assert(0); return 0; } @@ -450,24 +426,24 @@ int vpip_time_precision_from_handle(vpiHandle obj) if (obj == 0) return vpip_get_time_precision(); - switch (obj->vpi_type->type_code) { + switch (obj->get_type_code()) { case vpiSysTaskCall: - task = (struct __vpiSysTaskCall*)obj; + task = dynamic_cast<__vpiSysTaskCall*>(obj); return task->scope->time_precision; case vpiModule: - scope = (struct __vpiScope*)obj; + scope = dynamic_cast<__vpiScope*>(obj); return scope->time_precision; case vpiNet: case vpiReg: - signal = vpip_signal_from_handle(obj); + signal = dynamic_cast<__vpiSignal*>(obj); scope = vpip_scope(signal); return scope->time_precision; default: fprintf(stderr, "ERROR: vpip_time_precision_from_handle called " - "with object handle type=%u\n", obj->vpi_type->type_code); + "with object handle type=%u\n", obj->get_type_code()); assert(0); return 0; } @@ -879,38 +855,34 @@ void vpi_get_value(vpiHandle expr, s_vpi_value*vp) { assert(expr); assert(vp); - if (expr->vpi_type->vpi_get_value_) { - (expr->vpi_type->vpi_get_value_)(expr, vp); - if (vpi_trace) switch (vp->format) { + expr->vpi_get_value(vp); + + if (vpi_trace) switch (vp->format) { case vpiStringVal: fprintf(vpi_trace,"vpi_get_value(%p=<%d>) -> string=\"%s\"\n", - expr, expr->vpi_type->type_code, vp->value.str); + expr, expr->get_type_code(), vp->value.str); break; case vpiBinStrVal: fprintf(vpi_trace, "vpi_get_value(<%d>...) -> binstr=%s\n", - expr->vpi_type->type_code, vp->value.str); + expr->get_type_code(), vp->value.str); break; case vpiIntVal: fprintf(vpi_trace, "vpi_get_value(<%d>...) -> int=%d\n", - expr->vpi_type->type_code, (int)vp->value.integer); + expr->get_type_code(), (int)vp->value.integer); + break; + + case vpiSuppressVal: + fprintf(vpi_trace, "vpi_get_value(<%d>...) -> \n", + expr->get_type_code()); break; default: fprintf(vpi_trace, "vpi_get_value(<%d>...) -> <%d>=?\n", - expr->vpi_type->type_code, (int)vp->format); + expr->get_type_code(), (int)vp->format); } - return; - } - - if (vpi_trace) { - fprintf(vpi_trace, "vpi_get_value(<%d>...) -> \n", - expr->vpi_type->type_code); - } - - vp->format = vpiSuppressVal; } struct vpip_put_value_event : vvp_gen_event_s { @@ -923,7 +895,7 @@ struct vpip_put_value_event : vvp_gen_event_s { void vpip_put_value_event::run_run() { - handle->vpi_type->vpi_put_value_ (handle, &value, flags); + handle->vpi_put_value(&value, flags); switch (value.format) { /* Free the copied string. */ case vpiBinStrVal: @@ -947,7 +919,7 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp, { assert(obj); - if (obj->vpi_type->vpi_put_value_ == 0) + if (! obj->can_put_value()) return 0; flags &= ~vpiReturnEvent; @@ -1008,7 +980,7 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp, return 0; } - (obj->vpi_type->vpi_put_value_)(obj, vp, flags); + obj->vpi_put_value(vp, flags); return 0; } @@ -1024,11 +996,11 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle ref) if (vpi_trace) { fprintf(vpi_trace, "vpi_handle(vpiSysTfCall, 0) " - "-> %p (%s)\n", &vpip_cur_task->base, + "-> %p (%s)\n", vpip_cur_task, vpip_cur_task->defn->info.tfname); } - return &vpip_cur_task->base; + return vpip_cur_task; } if (ref == 0) { @@ -1037,18 +1009,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle ref) return 0; } - if (ref->vpi_type->handle_ == 0) { - - if (vpi_trace) { - fprintf(vpi_trace, "vpi_handle(%d, %p) -X\n", - (int)type, ref); - } - - return 0; - } - - assert(ref->vpi_type->handle_); - vpiHandle res = (ref->vpi_type->handle_)(type, ref); + vpiHandle res = ref->vpi_handle(type); if (vpi_trace) { fprintf(vpi_trace, "vpi_handle(%d, %p) -> %p\n", @@ -1099,8 +1060,8 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle ref) if (ref == 0) rtn = vpi_iterate_global(type); - else if (ref->vpi_type->iterate_) - rtn = (ref->vpi_type->iterate_)(type, ref); + else + rtn = ref->vpi_iterate(type); if (vpi_trace) { fprintf(vpi_trace, "vpi_iterate(%d, %p) ->%s\n", @@ -1113,18 +1074,13 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle ref) vpiHandle vpi_handle_by_index(vpiHandle ref, PLI_INT32 idx) { assert(ref); - - if (ref->vpi_type->index_ == 0) - return 0; - - assert(ref->vpi_type->index_); - return (ref->vpi_type->index_)(ref, idx); + return ref->vpi_index(idx); } static vpiHandle find_name(const char *name, vpiHandle handle) { vpiHandle rtn = 0; - struct __vpiScope*ref = (struct __vpiScope*)handle; + struct __vpiScope*ref = dynamic_cast<__vpiScope*>(handle); /* check module names */ if (!strcmp(name, vpi_get_str(vpiName, handle))) @@ -1260,16 +1216,12 @@ void vpi_get_delays(vpiHandle expr, p_vpi_delay delays) assert(expr); assert(delays); - if (expr->vpi_type->vpi_get_delays_) - { - (expr->vpi_type->vpi_get_delays_)(expr, delays); + expr->vpi_get_delays(delays); - if (vpi_trace) - { - fprintf(vpi_trace, - "vpi_get_delays(%p, %p) -->\n", expr, delays); - } - } + if (vpi_trace) { + fprintf(vpi_trace, + "vpi_get_delays(%p, %p) -->\n", expr, delays); + } } @@ -1278,16 +1230,12 @@ void vpi_put_delays(vpiHandle expr, p_vpi_delay delays) assert(expr ); assert(delays ); - if (expr->vpi_type->vpi_put_delays_) - { - (expr->vpi_type->vpi_put_delays_)(expr, delays); + expr->vpi_put_delays(delays); - if (vpi_trace) - { - fprintf(vpi_trace, - "vpi_put_delays(%p, %p) -->\n", expr, delays); - } - } + if (vpi_trace) { + fprintf(vpi_trace, + "vpi_put_delays(%p, %p) -->\n", expr, delays); + } } diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 224997f0e..91fa50628 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -1,7 +1,7 @@ #ifndef __vpi_priv_H #define __vpi_priv_H /* - * Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2012 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 @@ -83,15 +83,6 @@ enum vpi_mode_t { }; extern vpi_mode_t vpi_mode_flag; -/* - * This structure is the very base of a vpiHandle. Every handle - * structure starts with this structure, so that the library can - * internally pass the derived types as pointers to one of these. - */ -struct __vpiHandle { - const struct __vpirt *vpi_type; -}; - /* * Objects with this structure are used to represent a type of * vpiHandle. A specific object becomes of this type by holding a @@ -123,15 +114,56 @@ struct __vpirt { }; /* - * In general a vpi object is a structure that contains the member - * "base" that is a __vpiHandle object. This template can convert any - * of those structures into a vpiHandle object. + * This structure is the very base of a vpiHandle. Every handle + * structure is derived from this class so that the library can + * internally pass the derived types as pointers to one of these. */ -template inline vpiHandle vpi_handle(T obj) -{ return &obj->base; } +class __vpiHandle { + public: + inline __vpiHandle(const struct __vpirt *tp) : vpi_type_(tp) { } + // The descructor is virtual so that dynamic types will work. + virtual ~__vpiHandle() { } + + inline int get_type_code(void) const { return vpi_type_->type_code; } + + inline int vpi_get(int code) + { return vpi_type_->vpi_get_? vpi_type_->vpi_get_(code,this) : vpiUndefined; } + + inline char* vpi_get_str(int code) + { return vpi_type_->vpi_get_str_? vpi_type_->vpi_get_str_(code, this) : 0; } + + inline void vpi_get_value(p_vpi_value val) + { if (vpi_type_->vpi_get_value_) vpi_type_->vpi_get_value_(this, val); + else val->format = vpiSuppressVal; + } + + inline bool can_put_value() const { return vpi_type_->vpi_put_value_ != 0; } + + inline vpiHandle vpi_put_value(p_vpi_value val, int flags) + { return vpi_type_->vpi_put_value_? vpi_type_->vpi_put_value_(this, val, flags) : 0; } + + inline vpiHandle vpi_handle(int code) + { return vpi_type_->handle_? vpi_type_->handle_(code, this) : 0; } + + inline vpiHandle vpi_iterate(int code) + { return vpi_type_->iterate_? vpi_type_->iterate_(code, this) : 0; } + + inline vpiHandle vpi_index(int idx) + { return vpi_type_->index_? vpi_type_->index_(this, idx) : 0; } + + static inline int vpi_free_object(vpiHandle ref) + { return ref->vpi_type_->vpi_free_object_? ref->vpi_type_->vpi_free_object_(ref) : 1; } + + inline void vpi_get_delays(p_vpi_delay del) + { if (vpi_type_->vpi_get_delays_) vpi_type_->vpi_get_delays_(this, del); } + + inline void vpi_put_delays(p_vpi_delay del) + { if (vpi_type_->vpi_put_delays_) vpi_type_->vpi_put_delays_(this, del); } + + private: + const struct __vpirt *vpi_type_; +}; -template inline char*vpip_get_str(int code, T obj) -{ return obj->base.vpi_type->vpi_get_str_(code, vpi_handle(obj)); } /* * The vpiHandle for an iterator has this structure. The definition of @@ -144,8 +176,8 @@ template inline char*vpip_get_str(int code, T obj) * The free_args_flag member is true if when this iterator object is * released it must also free the args array. */ -struct __vpiIterator { - struct __vpiHandle base; +struct __vpiIterator : public __vpiHandle { + __vpiIterator(); vpiHandle *args; unsigned nargs; unsigned next; @@ -157,10 +189,11 @@ extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args, /* * This represents callback handles. There are some private types that - * are defined and used in vpi_callback.cc. + * are defined and used in vpi_callback.cc. The __vpiCallback are + * always used in association with vvp_vpi_callback objects. */ -struct __vpiCallback { - struct __vpiHandle base; +struct __vpiCallback : public __vpiHandle { + __vpiCallback(); // user supplied callback data struct t_cb_data cb_data; @@ -181,18 +214,32 @@ extern struct __vpiCallback* new_vpi_callback(); extern void delete_vpi_callback(struct __vpiCallback* ref); extern void callback_execute(struct __vpiCallback*cur); -struct __vpiSystemTime { - struct __vpiHandle base; - struct __vpiScope *scope; +struct __vpiSystemTime : public __vpiHandle { + __vpiSystemTime(); + struct __vpiScope*scope; + protected: + inline __vpiSystemTime(const struct __vpirt*rt) : __vpiHandle(rt) { } }; +struct __vpiScopedTime : public __vpiSystemTime { + __vpiScopedTime(); +}; +struct __vpiScopedSTime : public __vpiSystemTime { + __vpiScopedSTime(); +}; +struct __vpiScopedRealtime : public __vpiSystemTime { + __vpiScopedRealtime(); +}; + + /* * Scopes are created by .scope statements in the source. These * objects hold the items and properties that are knowingly bound to a * scope. */ -struct __vpiScope { - struct __vpiHandle base; +struct __vpiScope : public __vpiHandle { + __vpiScope(const struct __vpirt*rt) : __vpiHandle(rt) { } + struct __vpiScope *scope; /* The scope has a name. */ const char*name; @@ -204,9 +251,9 @@ struct __vpiScope { bool is_automatic; bool is_cell; /* The scope has a system time of its own. */ - struct __vpiSystemTime scoped_time; - struct __vpiSystemTime scoped_stime; - struct __vpiSystemTime scoped_realtime; + struct __vpiScopedTime scoped_time; + struct __vpiScopedSTime scoped_stime; + struct __vpiScopedRealtime scoped_realtime; /* Keep an array of internal scope items. */ struct __vpiHandle**intern; unsigned nintern; @@ -238,8 +285,8 @@ extern void vpip_make_root_iterator(struct __vpiHandle**&table, * distinguished by the vpiType code. They also have a parent scope, * a declared name and declaration indices. */ -struct __vpiSignal { - struct __vpiHandle base; +struct __vpiSignal : public __vpiHandle { + inline __vpiSignal(const struct __vpirt*rt) : __vpiHandle(rt) { } #ifdef CHECK_WITH_VALGRIND struct __vpiSignal *pool; #endif @@ -258,6 +305,13 @@ struct __vpiSignal { unsigned is_netarray : 1; // This is word of a net array /* The represented value is here. */ vvp_net_t*node; + + public: + static void*operator new(std::size_t size); + static void operator delete(void*); // not implemented + private: // Not implemented + static void*operator new[] (std::size_t size); + static void operator delete[](void*); }; extern unsigned vpip_size(__vpiSignal *sig); extern struct __vpiScope* vpip_scope(__vpiSignal*sig); @@ -268,15 +322,15 @@ extern vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec); extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*net); -extern vpiHandle vpip_make_net4(const char*name, int msb, int lsb, - bool signed_flag, vvp_net_t*node); +extern vpiHandle vpip_make_net4(const char*name, const struct __vpirt*rt, + int msb, int lsb, bool signed_flag, vvp_net_t*node); /* * This is used by system calls to represent a bit/part select of * a simple variable or constant array word. */ -struct __vpiPV { - struct __vpiHandle base; +struct __vpiPV : public __vpiHandle { + __vpiPV(); vpiHandle parent; vvp_net_t*net; vpiHandle sbase; @@ -290,26 +344,18 @@ extern vpiHandle vpip_make_PV(char*name, vpiHandle handle, int width); extern vpiHandle vpip_make_PV(char*name, int tbase, int twid, char*is_signed, int width); -extern struct __vpiPV* vpip_PV_from_handle(vpiHandle obj); extern void vpip_part_select_value_change(struct __vpiCallback*cbh, vpiHandle obj); -/* - * This function safely converts a vpiHandle back to a - * __vpiSignal. Return a nil if the type is not appropriate. - */ -extern __vpiSignal* vpip_signal_from_handle(vpiHandle obj); - - -struct __vpiModPathTerm { - struct __vpiHandle base; +struct __vpiModPathTerm : public __vpiHandle { + __vpiModPathTerm(); vpiHandle expr; /* The value returned by vpi_get(vpiEdge, ...); */ int edge; }; -struct __vpiModPathSrc { - struct __vpiHandle base; +struct __vpiModPathSrc : public __vpiHandle { + __vpiModPathSrc(); struct __vpiModPath *dest; int type; @@ -340,9 +386,6 @@ struct __vpiModPath { vvp_net_t *input_net ; }; -extern struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref); -extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref); - /* * The Function is used to create the vpiHandle @@ -360,8 +403,9 @@ extern struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) ; * passed in will be saved, so the caller must allocate it (or not * free it) after it is handed to this function. */ -struct __vpiNamedEvent { - struct __vpiHandle base; +struct __vpiNamedEvent : public __vpiHandle { + __vpiNamedEvent(); + /* base name of the event object */ const char*name; /* Parent scope of this object. */ @@ -389,8 +433,8 @@ extern bool is_net_array(vpiHandle obj); /* * These are the various variable types. */ -struct __vpiRealVar { - struct __vpiHandle base; +struct __vpiRealVar : public __vpiHandle { + __vpiRealVar(); union { // The scope or parent array that contains me. vpiHandle parent; struct __vpiScope* scope; @@ -406,7 +450,7 @@ struct __vpiRealVar { extern struct __vpiScope* vpip_scope(__vpiRealVar*sig); extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net); -extern struct __vpiRealVar* vpip_realvar_from_handle(vpiHandle obj); + /* * When a loaded VPI module announces a system task/function, one @@ -426,8 +470,8 @@ extern struct __vpiRealVar* vpip_realvar_from_handle(vpiHandle obj); * additional part is the vbit/vwid that is used by the put of the * system function call to place the values in the vthread bit space. */ -struct __vpiUserSystf { - struct __vpiHandle base; +struct __vpiUserSystf : public __vpiHandle { + __vpiUserSystf(); s_vpi_systf_data info; bool is_user_defn; }; @@ -437,8 +481,8 @@ extern vpiHandle vpip_make_systf_iterator(void); extern struct __vpiUserSystf* vpip_find_systf(const char*name); -struct __vpiSysTaskCall { - struct __vpiHandle base; +struct __vpiSysTaskCall : public __vpiHandle { + __vpiSysTaskCall(const struct __vpirt*rt) : __vpiHandle(rt) { } struct __vpiScope* scope; struct __vpiUserSystf*defn; unsigned nargs; @@ -464,23 +508,28 @@ extern struct __vpiSysTaskCall*vpip_cur_task; * handle to be persistent. This is necessary for cases where the * string handle may be reused, which is the normal case. */ -struct __vpiStringConst { - struct __vpiHandle base; +struct __vpiStringConst : public __vpiHandle { + __vpiStringConst(); + char*value; size_t value_len; + protected: + inline __vpiStringConst(const struct __vpirt*rt) : __vpiHandle(rt) { } }; vpiHandle vpip_make_string_const(char*text, bool persistent =true); vpiHandle vpip_make_string_param(char*name, char*value, long file_idx, long lineno); -struct __vpiBinaryConst { - struct __vpiHandle base; +struct __vpiBinaryConst : public __vpiHandle { + __vpiBinaryConst(); vvp_vector4_t bits; /* TRUE if this constant is signed. */ int signed_flag :1; /* TRUE if this constant has an explicit size (i.e. 19'h0 vs. 'h0) */ int sized_flag :1; + protected: + inline __vpiBinaryConst(const struct __vpirt*rt) : __vpiHandle(rt) { } }; vpiHandle vpip_make_binary_const(unsigned wid, const char*bits); @@ -488,17 +537,16 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, bool signed_flag, long file_idx, long lineno); -struct __vpiDecConst { - struct __vpiHandle base; +struct __vpiDecConst : public __vpiHandle { + __vpiDecConst(int val =0); int value; }; -vpiHandle vpip_make_dec_const(int value); -vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value); - -struct __vpiRealConst { - struct __vpiHandle base; +struct __vpiRealConst : public __vpiHandle { + __vpiRealConst(); double value; + protected: + inline __vpiRealConst(const struct __vpirt*rt) : __vpiHandle(rt) { } }; vpiHandle vpip_make_real_const(double value); diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index 72812ecca..f0b5b8bc8 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -30,20 +30,10 @@ # include # include "ivl_alloc.h" -struct __vpiRealVar* vpip_realvar_from_handle(vpiHandle obj) -{ - assert(obj); - if (obj->vpi_type->type_code == vpiRealVar) - return (struct __vpiRealVar*)obj; - else - return 0; -} - static int real_var_get(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiRealVar); - - struct __vpiRealVar*rfp = vpip_realvar_from_handle(ref); + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); switch (code) { case vpiArray: @@ -64,9 +54,8 @@ static int real_var_get(int code, vpiHandle ref) static char* real_var_get_str(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiRealVar); - - struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); if (code == vpiFile) { // Not implemented for now! return simple_set_rbuf_str(file_names[0]); @@ -84,16 +73,15 @@ static char* real_var_get_str(int code, vpiHandle ref) ixs = NULL; } - char *rbuf = generic_get_str(code, &(vpip_scope(rfp)->base), nm, ixs); + char *rbuf = generic_get_str(code, vpip_scope(rfp), nm, ixs); free(nm); return rbuf; } static vpiHandle real_var_get_handle(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiRealVar); - - struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); switch (code) { @@ -104,7 +92,7 @@ static vpiHandle real_var_get_handle(int code, vpiHandle ref) return rfp->is_netarray ? rfp->id.index : 0; case vpiScope: - return &(vpip_scope(rfp)->base); + return vpip_scope(rfp); case vpiModule: return vpip_module(vpip_scope(rfp)); @@ -115,13 +103,11 @@ static vpiHandle real_var_get_handle(int code, vpiHandle ref) static vpiHandle real_var_iterate(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiRealVar); - - struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); if (code == vpiIndex) { - return rfp->is_netarray ? (rfp->id.index->vpi_type->iterate_) - (code, rfp->id.index) : 0; + return rfp->is_netarray ? rfp->id.index->vpi_iterate(code) : 0; } return 0; @@ -129,10 +115,9 @@ static vpiHandle real_var_iterate(int code, vpiHandle ref) static void real_var_get_value(vpiHandle ref, s_vpi_value*vp) { - assert(ref->vpi_type->type_code == vpiRealVar); + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); - struct __vpiRealVar*rfp - = (struct __vpiRealVar*)ref; vvp_signal_value*fil = dynamic_cast(rfp->net->fil); @@ -141,11 +126,9 @@ static void real_var_get_value(vpiHandle ref, s_vpi_value*vp) static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiRealVar); - double result = real_from_vpi_value(vp); - struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); assert(rfp); vvp_net_ptr_t destination (rfp->net, 0); vvp_send_real(destination, result, vthread_get_wt_context()); @@ -167,12 +150,17 @@ static const struct __vpirt vpip_real_var_rt = { 0, 0 }; +inline __vpiRealVar::__vpiRealVar() +: __vpiHandle(&vpip_real_var_rt) +{ +} + void vpip_real_value_change(struct __vpiCallback*cbh, vpiHandle ref) { - struct __vpiRealVar*rfp - = (struct __vpiRealVar*)ref; + struct __vpiRealVar*rfp = dynamic_cast<__vpiRealVar*>(ref); + assert(rfp); vvp_vpi_callback*obj = dynamic_cast(rfp->net->fil); assert(obj); @@ -181,27 +169,25 @@ void vpip_real_value_change(struct __vpiCallback*cbh, vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net) { - struct __vpiRealVar*obj = (struct __vpiRealVar*) - malloc(sizeof(struct __vpiRealVar)); + struct __vpiRealVar*obj = new __vpiRealVar; - obj->base.vpi_type = &vpip_real_var_rt; obj->id.name = name ? vpip_name_string(name) : 0; obj->is_netarray = 0; obj->net = net; obj->within.scope = vpip_peek_current_scope(); - return &obj->base; + return obj; } #ifdef CHECK_WITH_VALGRIND void real_delete(vpiHandle item) { - struct __vpiRealVar*obj = (struct __vpiRealVar*) item; + struct __vpiRealVar*obj = dynamic_cast<__vpiRealVar*>(item); assert(obj->net->fil); obj->net->fil->clear_all_callbacks(); vvp_net_delete(obj->net); - free(obj); + delete obj; } #endif diff --git a/vvp/vpi_scope.cc b/vvp/vpi_scope.cc index 33bb34ace..f3e0e0086 100644 --- a/vvp/vpi_scope.cc +++ b/vvp/vpi_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2012 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 @@ -117,20 +117,10 @@ void root_table_delete(void) } #endif -static bool handle_is_scope(vpiHandle obj) -{ - return (obj->vpi_type->type_code == vpiModule) - || (obj->vpi_type->type_code == vpiFunction) - || (obj->vpi_type->type_code == vpiTask) - || (obj->vpi_type->type_code == vpiNamedBegin) - || (obj->vpi_type->type_code == vpiNamedFork); -} - static int scope_get(int code, vpiHandle obj) { - struct __vpiScope*ref = (struct __vpiScope*)obj; - - assert(handle_is_scope(obj)); + struct __vpiScope*ref = dynamic_cast<__vpiScope*>(obj); + assert(obj); switch (code) { case vpiCellInstance: @@ -189,9 +179,8 @@ static const char* scope_get_type(int code) static char* scope_get_str(int code, vpiHandle obj) { - struct __vpiScope*ref = (struct __vpiScope*)obj; - - assert(handle_is_scope(obj)); + struct __vpiScope*ref = dynamic_cast<__vpiScope*>(obj); + assert(ref); char buf[4096]; // XXX is a fixed buffer size really reliable? const char *p=0; @@ -231,21 +220,16 @@ static char* scope_get_str(int code, vpiHandle obj) static vpiHandle scope_get_handle(int code, vpiHandle obj) { - assert((obj->vpi_type->type_code == vpiModule) - || (obj->vpi_type->type_code == vpiFunction) - || (obj->vpi_type->type_code == vpiTask) - || (obj->vpi_type->type_code == vpiNamedBegin) - || (obj->vpi_type->type_code == vpiNamedFork)); - - struct __vpiScope*rfp = (struct __vpiScope*)obj; + struct __vpiScope*rfp = dynamic_cast<__vpiScope*>(obj); + assert(rfp); switch (code) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; case vpiModule: - return &rfp->scope->base; + return rfp->scope; } return 0; @@ -291,7 +275,7 @@ static vpiHandle module_iter_subset(int code, struct __vpiScope*ref) vpiHandle*args; for (unsigned idx = 0 ; idx < ref->nintern ; idx += 1) - if (compare_types(code, ref->intern[idx]->vpi_type->type_code)) + if (compare_types(code, ref->intern[idx]->get_type_code())) mcnt += 1; if (mcnt == 0) @@ -299,7 +283,7 @@ static vpiHandle module_iter_subset(int code, struct __vpiScope*ref) args = (vpiHandle*)calloc(mcnt, sizeof(vpiHandle)); for (unsigned idx = 0 ; idx < ref->nintern ; idx += 1) - if (compare_types(code, ref->intern[idx]->vpi_type->type_code)) + if (compare_types(code, ref->intern[idx]->get_type_code())) args[ncnt++] = ref->intern[idx]; assert(ncnt == mcnt); @@ -315,12 +299,8 @@ static vpiHandle module_iter_subset(int code, struct __vpiScope*ref) */ static vpiHandle module_iter(int code, vpiHandle obj) { - struct __vpiScope*ref = (struct __vpiScope*)obj; - assert((obj->vpi_type->type_code == vpiModule) - || (obj->vpi_type->type_code == vpiFunction) - || (obj->vpi_type->type_code == vpiTask) - || (obj->vpi_type->type_code == vpiNamedBegin) - || (obj->vpi_type->type_code == vpiNamedFork)); + struct __vpiScope*ref = dynamic_cast<__vpiScope*>(obj); + assert(ref); return module_iter_subset(code, ref); } @@ -429,40 +409,36 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, char*parent, long file_idx, long lineno, long def_file_idx, long def_lineno, long is_cell) { - struct __vpiScope*scope = new struct __vpiScope; count_vpi_scopes += 1; - char*base_type = 0; + char*base_type; + bool is_automatic; if (strncmp(type,"auto",4) == 0) { - scope->is_automatic = true; + is_automatic = true; base_type = &type[4]; } else { - scope->is_automatic = false; + is_automatic = false; base_type = &type[0]; } - if (is_cell) scope->is_cell = true; - else scope->is_cell = false; - + struct __vpiScope*scope; if (strcmp(base_type,"module") == 0) { - scope->base.vpi_type = &vpip_scope_module_rt; + scope = new __vpiScope(&vpip_scope_module_rt); } else if (strcmp(base_type,"function") == 0) { - scope->base.vpi_type = &vpip_scope_function_rt; + scope = new __vpiScope(&vpip_scope_function_rt); } else if (strcmp(base_type,"task") == 0) { - scope->base.vpi_type = &vpip_scope_task_rt; + scope = new __vpiScope(&vpip_scope_task_rt); } else if (strcmp(base_type,"fork") == 0) { - scope->base.vpi_type = &vpip_scope_fork_rt; + scope = new __vpiScope(&vpip_scope_fork_rt); } else if (strcmp(base_type,"begin") == 0) { - scope->base.vpi_type = &vpip_scope_begin_rt; + scope = new __vpiScope(&vpip_scope_begin_rt); } else if (strcmp(base_type,"generate") == 0) { - scope->base.vpi_type = &vpip_scope_begin_rt; + scope = new __vpiScope(&vpip_scope_begin_rt); } else { - scope->base.vpi_type = &vpip_scope_module_rt; + scope = new __vpiScope(&vpip_scope_module_rt); assert(0); } - assert(scope->base.vpi_type); - scope->name = vpip_name_string(name); if (tname) scope->tname = vpip_name_string(tname); else scope->tname = vpip_name_string(""); @@ -470,6 +446,7 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, scope->lineno = (unsigned) lineno; scope->def_file_idx = (unsigned) def_file_idx; scope->def_lineno = (unsigned) def_lineno; + scope->is_automatic = is_automatic; scope->intern = 0; scope->nintern = 0; scope->item = 0; @@ -477,9 +454,12 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, scope->live_contexts = 0; scope->free_contexts = 0; + if (is_cell) scope->is_cell = true; + else scope->is_cell = false; + current_scope = scope; - compile_vpi_symbol(label, &scope->base); + compile_vpi_symbol(label, scope); free(label); free(type); @@ -490,9 +470,9 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, static vpiHandle obj; compile_vpi_lookup(&obj, parent); assert(obj); - struct __vpiScope*sp = (struct __vpiScope*) obj; - vpip_attach_to_scope(sp, &scope->base); - scope->scope = (struct __vpiScope*)obj; + struct __vpiScope*sp = dynamic_cast<__vpiScope*>(obj); + vpip_attach_to_scope(sp, scope); + scope->scope = dynamic_cast<__vpiScope*>(obj); /* Inherit time units and precision from the parent scope. */ scope->time_units = sp->time_units; @@ -504,7 +484,7 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, unsigned cnt = vpip_root_table_cnt + 1; vpip_root_table_ptr = (vpiHandle*) realloc(vpip_root_table_ptr, cnt * sizeof(vpiHandle)); - vpip_root_table_ptr[vpip_root_table_cnt] = &scope->base; + vpip_root_table_ptr[vpip_root_table_cnt] = scope; vpip_root_table_cnt = cnt; /* Root scopes inherit time_units and precision from the diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 65011380b..4e0fbdd35 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -505,31 +505,12 @@ static void format_vpiVectorVal(vvp_signal_value*sig, int base, unsigned wid, } } -struct __vpiSignal* vpip_signal_from_handle(vpiHandle ref) -{ - switch (ref->vpi_type->type_code) { - case vpiNet: - case vpiReg: - /* This handles both reg and logic */ - case vpiIntegerVar: - case vpiByteVar: - case vpiShortIntVar: - case vpiIntVar: - case vpiLongIntVar: - case vpiBitVar: - return (struct __vpiSignal*)ref; - - default: - return 0; - } -} - /* * implement vpi_get for vpiReg objects. */ static int signal_get(int code, vpiHandle ref) { - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); switch (code) { @@ -559,7 +540,7 @@ static int signal_get(int code, vpiHandle ref) return rfp->lsb - rfp->msb + 1; case vpiNetType: - if (ref->vpi_type->type_code==vpiNet) + if (ref->get_type_code()==vpiNet) return vpiWire; else return vpiUndefined; @@ -589,7 +570,7 @@ static int signal_get(int code, vpiHandle ref) static char* signal_get_str(int code, vpiHandle ref) { - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); if (code == vpiFile) { // Not implemented for now! @@ -611,14 +592,14 @@ static char* signal_get_str(int code, vpiHandle ref) } /* The scope information is added here for vpiFullName. */ - char *rbuf = generic_get_str(code, &(vpip_scope(rfp)->base), nm, ixs); + char *rbuf = generic_get_str(code, vpip_scope(rfp), nm, ixs); free(nm); return rbuf; } static vpiHandle signal_get_handle(int code, vpiHandle ref) { - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); switch (code) { @@ -630,7 +611,7 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref) return rfp->is_netarray? rfp->id.index : 0; case vpiScope: - return &(vpip_scope(rfp)->base); + return vpip_scope(rfp); case vpiModule: return vpip_module(vpip_scope(rfp)); @@ -641,7 +622,7 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref) static vpiHandle signal_iterate(int code, vpiHandle ref) { - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); if (code == vpiIndex) { @@ -667,7 +648,7 @@ static unsigned signal_width(const struct __vpiSignal*rfp) */ static void signal_get_value(vpiHandle ref, s_vpi_value*vp) { - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); unsigned wid = signal_width(rfp); @@ -773,7 +754,7 @@ static vvp_vector4_t from_stringval(const char*str, unsigned wid) static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags) { unsigned wid; - struct __vpiSignal*rfp = vpip_signal_from_handle(ref); + struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); /* If this is a release, then we are not really putting a @@ -995,8 +976,8 @@ static const struct __vpirt vpip_longint_rt = { */ vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec) { - vpiHandle obj = vpip_make_net4(name, msb,lsb, true, vec); - obj->vpi_type = &vpip_integer_rt; + vpiHandle obj = vpip_make_net4(name, &vpip_integer_rt, + msb,lsb, true, vec); return obj; } @@ -1006,37 +987,37 @@ vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec) vpiHandle vpip_make_int2(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*vec) { - vpiHandle obj = vpip_make_net4(name, msb, lsb, signed_flag, vec); + const struct __vpirt*vpi_type; // All unsigned 2-state variables are a vpiBitVar. All 2-state // variables with a non-zero lsb are also a vpiBitVar. if ((! signed_flag) || (lsb != 0) ) { - obj->vpi_type = &vpip_bitvar_rt; + vpi_type = &vpip_bitvar_rt; } else { // These could also be bit declarations with matching // information, but for now they get the apparent type. switch (msb) { case 7: - obj->vpi_type = &vpip_byte_rt; + vpi_type = &vpip_byte_rt; break; case 15: - obj->vpi_type = &vpip_shortint_rt; + vpi_type = &vpip_shortint_rt; break; case 31: - obj->vpi_type = &vpip_int_rt; + vpi_type = &vpip_int_rt; break; case 63: - obj->vpi_type = &vpip_longint_rt; + vpi_type = &vpip_longint_rt; break; default: // Every other type of bit vector is a vpiBitVar with // array dimensions. - obj->vpi_type = &vpip_bitvar_rt; + vpi_type = &vpip_bitvar_rt; break; } } - return obj; + return vpip_make_net4(name, vpi_type, msb, lsb, signed_flag, vec); } /* @@ -1045,9 +1026,7 @@ vpiHandle vpip_make_int2(const char*name, int msb, int lsb, bool signed_flag, vpiHandle vpip_make_var4(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*vec) { - vpiHandle obj = vpip_make_net4(name, msb,lsb, signed_flag, vec); - obj->vpi_type = &vpip_reg_rt; - return obj; + return vpip_make_net4(name, &vpip_reg_rt, msb,lsb, signed_flag, vec); } #ifdef CHECK_WITH_VALGRIND @@ -1057,30 +1036,35 @@ static unsigned long signal_count = 0; static unsigned long signal_dels = 0; #endif -static struct __vpiSignal* allocate_vpiSignal(void) +struct vpiSignal_plug { + unsigned char space[sizeof (struct __vpiSignal)]; +}; + +void* __vpiSignal::operator new(size_t siz) { - static struct __vpiSignal*alloc_array = 0; + assert(siz == sizeof(struct vpiSignal_plug)); + static struct vpiSignal_plug*alloc_array = 0; static unsigned alloc_index = 0; const unsigned alloc_count = 512; if ((alloc_array == 0) || (alloc_index == alloc_count)) { - alloc_array = (struct __vpiSignal*) - calloc(alloc_count, sizeof(struct __vpiSignal)); + alloc_array = (struct vpiSignal_plug*) + calloc(alloc_count, sizeof(struct vpiSignal_plug)); alloc_index = 0; #ifdef CHECK_WITH_VALGRIND VALGRIND_MAKE_MEM_NOACCESS(alloc_array, alloc_count * - sizeof(struct __vpiSignal)); + sizeof(struct vpiSignal_plug)); VALGRIND_CREATE_MEMPOOL(alloc_array, 0, 1); signal_pool_count += 1; - signal_pool = (__vpiSignal **) realloc(signal_pool, - signal_pool_count*sizeof(__vpiSignal **)); + signal_pool = (vpiSignal_plug **) realloc(signal_pool, + signal_pool_count*sizeof(vpiSignal_plug **)); signal_pool[signal_pool_count-1] = alloc_array; #endif } - struct __vpiSignal*cur = alloc_array + alloc_index; + struct vpiSignal_plug*cur = alloc_array + alloc_index; #ifdef CHECK_WITH_VALGRIND - VALGRIND_MEMPOOL_ALLOC(alloc_array, cur, sizeof(struct __vpiSignal)); + VALGRIND_MEMPOOL_ALLOC(alloc_array, cur, sizeof(struct vpiSignal_plug)); cur->pool = alloc_array; signal_count += 1; #endif @@ -1088,6 +1072,11 @@ static struct __vpiSignal* allocate_vpiSignal(void) return cur; } +void __vpiSignal::operator delete(void*ptr) +{ + assert(0); +} + #ifdef CHECK_WITH_VALGRIND void signal_delete(vpiHandle item) { @@ -1125,11 +1114,11 @@ void signal_pool_delete() * The name is the PLI name for the object. If it is an array it is * []. */ -vpiHandle vpip_make_net4(const char*name, int msb, int lsb, - bool signed_flag, vvp_net_t*node) +vpiHandle vpip_make_net4(const char*name, const struct __vpirt*rt, + int msb, int lsb, bool signed_flag, vvp_net_t*node) { - struct __vpiSignal*obj = allocate_vpiSignal(); - obj->base.vpi_type = &vpip_net_rt; + if (rt == 0) rt = &vpip_net_rt; + struct __vpiSignal*obj = new __vpiSignal(rt); obj->id.name = name? vpip_name_string(name) : 0; obj->msb = msb; obj->lsb = lsb; @@ -1144,7 +1133,7 @@ vpiHandle vpip_make_net4(const char*name, int msb, int lsb, count_vpi_nets += 1; - return &obj->base; + return obj; } static int PV_get_base(struct __vpiPV*rfp) @@ -1205,8 +1194,8 @@ static int PV_get_base(struct __vpiPV*rfp) static int PV_get(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiPartSelect); - struct __vpiPV*rfp = (struct __vpiPV*)ref; + struct __vpiPV*rfp = dynamic_cast<__vpiPV*>(ref); + assert(rfp); int rval = 0; switch (code) { @@ -1246,8 +1235,8 @@ static int PV_get(int code, vpiHandle ref) static char* PV_get_str(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiPartSelect); - struct __vpiPV*rfp = (struct __vpiPV*)ref; + struct __vpiPV*rfp = dynamic_cast<__vpiPV*>(ref); + assert(rfp); switch (code) { case vpiFile: // Not implemented for now! @@ -1276,8 +1265,8 @@ static char* PV_get_str(int code, vpiHandle ref) static void PV_get_value(vpiHandle ref, p_vpi_value vp) { - assert(ref->vpi_type->type_code == vpiPartSelect); - struct __vpiPV*rfp = (struct __vpiPV*)ref; + struct __vpiPV*rfp = dynamic_cast<__vpiPV*>(ref); + assert(rfp); vvp_signal_value*sig = dynamic_cast(rfp->net->fil); assert(sig); @@ -1334,8 +1323,8 @@ static void PV_get_value(vpiHandle ref, p_vpi_value vp) static vpiHandle PV_put_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiPartSelect); - struct __vpiPV*rfp = (struct __vpiPV*)ref; + struct __vpiPV*rfp = dynamic_cast<__vpiPV*>(ref); + assert(rfp); vvp_signal_value*sig = dynamic_cast(rfp->net->fil); assert(sig); @@ -1382,8 +1371,8 @@ static vpiHandle PV_put_value(vpiHandle ref, p_vpi_value vp, int) static vpiHandle PV_get_handle(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code==vpiPartSelect); - struct __vpiPV*rfp = (struct __vpiPV*)ref; + struct __vpiPV*rfp = dynamic_cast<__vpiPV*>(ref); + assert(rfp); switch (code) { case vpiParent: @@ -1409,19 +1398,14 @@ static const struct __vpirt vpip_PV_rt = { 0, 0 }; - -struct __vpiPV* vpip_PV_from_handle(vpiHandle obj) +inline __vpiPV::__vpiPV() +: __vpiHandle(&vpip_PV_rt) { - if (obj->vpi_type->type_code == vpiPartSelect) - return (__vpiPV*) obj; - else - return 0; } vpiHandle vpip_make_PV(char*var, int base, int width) { - struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); - obj->base.vpi_type = &vpip_PV_rt; + struct __vpiPV*obj = new __vpiPV; obj->parent = vvp_lookup_handle(var); obj->sbase = 0; obj->tbase = base; @@ -1430,13 +1414,12 @@ vpiHandle vpip_make_PV(char*var, int base, int width) obj->net = 0; functor_ref_lookup(&obj->net, var); - return &obj->base; + return obj; } vpiHandle vpip_make_PV(char*var, char*symbol, int width) { - struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); - obj->base.vpi_type = &vpip_PV_rt; + struct __vpiPV*obj = new __vpiPV; obj->parent = vvp_lookup_handle(var); compile_vpi_lookup(&obj->sbase, symbol); obj->tbase = 0; @@ -1445,13 +1428,12 @@ vpiHandle vpip_make_PV(char*var, char*symbol, int width) obj->net = 0; functor_ref_lookup(&obj->net, var); - return &obj->base; + return obj; } vpiHandle vpip_make_PV(char*var, vpiHandle handle, int width) { - struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); - obj->base.vpi_type = &vpip_PV_rt; + struct __vpiPV*obj = new __vpiPV; obj->parent = vvp_lookup_handle(var); obj->sbase = handle; obj->tbase = 0; @@ -1460,13 +1442,12 @@ vpiHandle vpip_make_PV(char*var, vpiHandle handle, int width) obj->net = 0; functor_ref_lookup(&obj->net, var); - return &obj->base; + return obj; } vpiHandle vpip_make_PV(char*var, int tbase, int twid, char*is_signed, int width) { - struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); - obj->base.vpi_type = &vpip_PV_rt; + struct __vpiPV*obj = new __vpiPV; obj->parent = vvp_lookup_handle(var); obj->sbase = 0; obj->tbase = tbase; @@ -1478,12 +1459,18 @@ vpiHandle vpip_make_PV(char*var, int tbase, int twid, char*is_signed, int width) delete [] is_signed; - return &obj->base; + return obj; } +/* + * Attach the __vpiCallback to the object that this part select + * selects from. The part select itself is not a vvp_vpi_callback + * object, but it refers to a net that is a vvp_vpi_callback, so + * add the callback to that object. + */ void vpip_part_select_value_change(struct __vpiCallback*cbh, vpiHandle ref) { - struct __vpiPV*obj = vpip_PV_from_handle(ref); + struct __vpiPV*obj = dynamic_cast<__vpiPV*>(ref); assert(obj); vvp_vpi_callback*sig_fil; @@ -1497,7 +1484,7 @@ void vpip_part_select_value_change(struct __vpiCallback*cbh, vpiHandle ref) #ifdef CHECK_WITH_VALGRIND void PV_delete(vpiHandle item) { - struct __vpiPV *obj = (__vpiPV *) item; + struct __vpiPV *obj = dynamic_cast<__vpiPV*>(item); if (obj->sbase) { switch (obj->sbase->vpi_type->type_code) { case vpiMemoryWord: @@ -1513,6 +1500,6 @@ void PV_delete(vpiHandle item) } assert(obj->net->fil); obj->net->fil->clear_all_callbacks(); - free(obj); + delete obj; } #endif diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index 7eee8f9c7..22e91b880 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2012 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 @@ -49,20 +49,23 @@ static const struct __vpirt vpip_systf_def_rt = { 0 }; +inline __vpiUserSystf::__vpiUserSystf() +: __vpiHandle(&vpip_systf_def_rt) +{ +} + static vpiHandle systask_handle(int type, vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); switch (type) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; case vpiUserSystf: /* Assert that vpiUserDefn is true! */ assert(rfp->defn->is_user_defn); - return &rfp->defn->base; + return rfp->defn; default: return 0; @@ -71,10 +74,7 @@ static vpiHandle systask_handle(int type, vpiHandle ref) static int systask_get(int type, vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); switch (type) { /* This is not the correct way to get this information, but @@ -99,9 +99,7 @@ static int systask_get(int type, vpiHandle ref) // support getting vpiSize for a system function call static int sysfunc_get(int type, vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - - assert(ref->vpi_type->type_code == vpiSysFuncCall); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); switch (type) { case vpiSize: @@ -124,10 +122,7 @@ static int sysfunc_get(int type, vpiHandle ref) static char *systask_get_str(int type, vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); switch (type) { case vpiFile: @@ -147,9 +142,7 @@ static char *systask_get_str(int type, vpiHandle ref) */ static vpiHandle systask_iter(int, vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); if (rfp->nargs == 0) return 0; @@ -171,7 +164,6 @@ static const struct __vpirt vpip_systask_rt = { 0 }; - /* * A value *can* be put to a vpiSysFuncCall object. This is how the * return value is set. The value that is given should be converted to @@ -180,9 +172,7 @@ static const struct __vpirt vpip_systask_rt = { */ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiSysFuncCall); - - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); rfp->put_value = true; @@ -310,9 +300,7 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int) static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiSysFuncCall); - - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); rfp->put_value = true; @@ -338,9 +326,7 @@ static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp, int) static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiSysFuncCall); - - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); rfp->put_value = true; @@ -443,9 +429,7 @@ static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp, int) static vpiHandle sysfunc_put_rnet_value(vpiHandle ref, p_vpi_value vp, int) { - assert(ref->vpi_type->type_code == vpiSysFuncCall); - - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); rfp->put_value = true; @@ -467,10 +451,8 @@ static vpiHandle sysfunc_put_rnet_value(vpiHandle ref, p_vpi_value vp, int) return 0; } -static vpiHandle sysfunc_put_no_value(vpiHandle ref, p_vpi_value, int) +static vpiHandle sysfunc_put_no_value(vpiHandle, p_vpi_value, int) { - assert(ref->vpi_type->type_code == vpiSysFuncCall); - return 0; } @@ -547,6 +529,13 @@ static const struct __vpirt vpip_sysfunc_no_rt = { /* **** Manipulate the internal data structures. **** */ +/* + * We keep a table of all the __vpiUserSystf objects that are created + * so that the user can iterate over them. The def_table is an array + * of pointers to __vpiUserSystf objects. This table can be searched + * by name using the vpi_find_systf function, and they can be + * collected into an iterator using the vpip_make_systf_iterator function. + */ static struct __vpiUserSystf**def_table = 0; static unsigned def_count = 0; @@ -556,8 +545,7 @@ static struct __vpiUserSystf* allocate_def(void) def_table = (struct __vpiUserSystf**) malloc(sizeof (struct __vpiUserSystf*)); - def_table[0] = (struct __vpiUserSystf*) - calloc(1, sizeof(struct __vpiUserSystf)); + def_table[0] = new __vpiUserSystf; def_count = 1; return def_table[0]; @@ -566,8 +554,7 @@ static struct __vpiUserSystf* allocate_def(void) def_table = (struct __vpiUserSystf**) realloc(def_table, (def_count+1)*sizeof (struct __vpiUserSystf*)); - def_table[def_count] = (struct __vpiUserSystf*) - calloc(1, sizeof(struct __vpiUserSystf)); + def_table[def_count] = new __vpiUserSystf; return def_table[def_count++]; } @@ -577,7 +564,7 @@ void def_table_delete(void) { for (unsigned idx = 0; idx < def_count; idx += 1) { free(const_cast(def_table[idx]->info.tfname)); - free(def_table[idx]); + delete def_table[idx]; } free(def_table); def_table = 0; @@ -585,15 +572,14 @@ void def_table_delete(void) } #endif -struct __vpiSystfIterator { - struct __vpiHandle base; +struct __vpiSystfIterator : public __vpiHandle { + __vpiSystfIterator(); unsigned next; }; static vpiHandle systf_iterator_scan(vpiHandle ref, int) { - assert(ref->vpi_type->type_code == vpiIterator); - struct __vpiSystfIterator*obj = (struct __vpiSystfIterator*) ref; + struct __vpiSystfIterator*obj = dynamic_cast<__vpiSystfIterator*>(ref); if (obj->next >= def_count) { vpi_free_object(ref); @@ -610,14 +596,13 @@ static vpiHandle systf_iterator_scan(vpiHandle ref, int) } } obj->next += 1; - return &(def_table[use_index])->base; + return def_table[use_index]; } static int systf_iterator_free_object(vpiHandle ref) { - assert(ref->vpi_type->type_code == vpiIterator); - struct __vpiSystfIterator*obj = (struct __vpiSystfIterator*) ref; - free(obj); + struct __vpiSystfIterator*obj = dynamic_cast<__vpiSystfIterator*>(ref); + delete obj; return 1; } @@ -634,6 +619,10 @@ static const struct __vpirt vpip_systf_iterator_rt = { 0, 0 }; +inline __vpiSystfIterator::__vpiSystfIterator() +: __vpiHandle(&vpip_systf_iterator_rt) +{ +} vpiHandle vpip_make_systf_iterator(void) { @@ -648,11 +637,9 @@ vpiHandle vpip_make_systf_iterator(void) } if (!have_user_defn) return 0; - struct __vpiSystfIterator*res; - res = (struct __vpiSystfIterator*) calloc(1, sizeof (*res)); - res->base.vpi_type = &vpip_systf_iterator_rt; + struct __vpiSystfIterator*res = new __vpiSystfIterator; res->next = idx; - return &res->base; + return res; } struct __vpiUserSystf* vpip_find_systf(const char*name) @@ -667,8 +654,8 @@ struct __vpiUserSystf* vpip_find_systf(const char*name) void vpip_make_systf_system_defined(vpiHandle ref) { assert(ref); - assert(ref->vpi_type->type_code == vpiUserSystf); - struct __vpiUserSystf*obj = (__vpiUserSystf*) ref; + struct __vpiUserSystf*obj = dynamic_cast<__vpiUserSystf*>(ref); + assert(obj); obj->is_user_defn = false; } @@ -821,28 +808,28 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid, assert(0); } - struct __vpiSysTaskCall*obj = new struct __vpiSysTaskCall; + struct __vpiSysTaskCall*obj = 0; switch (defn->info.type) { case vpiSysTask: - obj->base.vpi_type = &vpip_systask_rt; + obj = new __vpiSysTaskCall(&vpip_systask_rt); break; case vpiSysFunc: if (fnet && vwid == -vpiRealConst) { - obj->base.vpi_type = &vpip_sysfunc_rnet_rt; + obj = new __vpiSysTaskCall(&vpip_sysfunc_rnet_rt); } else if (fnet && vwid > 0) { - obj->base.vpi_type = &vpip_sysfunc_4net_rt; + obj = new __vpiSysTaskCall(&vpip_sysfunc_4net_rt); } else if (vwid == -vpiRealConst) { - obj->base.vpi_type = &vpip_sysfunc_real_rt; + obj = new __vpiSysTaskCall(&vpip_sysfunc_real_rt); } else if (vwid > 0) { - obj->base.vpi_type = &vpip_sysfunc_rt; + obj = new __vpiSysTaskCall(&vpip_sysfunc_rt); } else if (vwid == 0 && fnet == 0) { - obj->base.vpi_type = &vpip_sysfunc_no_rt; + obj = new __vpiSysTaskCall(&vpip_sysfunc_no_rt); } else { assert(0); @@ -864,7 +851,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid, compile_compiletf(obj); - return &obj->base; + return obj; } #ifdef CHECK_WITH_VALGRIND @@ -918,10 +905,7 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref) { vpip_current_vthread = thr; - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); - - vpip_cur_task = (struct __vpiSysTaskCall*)ref; + vpip_cur_task = dynamic_cast<__vpiSysTaskCall*>(ref); if (vpip_cur_task->defn->info.calltf) { assert(vpi_mode_flag == VPI_MODE_NONE); @@ -931,7 +915,7 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref) vpi_mode_flag = VPI_MODE_NONE; /* If the function call did not set a value then put a * default value (0). */ - if (ref->vpi_type->type_code == vpiSysFuncCall && + if (ref->get_type_code() == vpiSysFuncCall && !vpip_cur_task->put_value) { s_vpi_value val; if (vpip_cur_task->vwid == -vpiRealConst) { @@ -959,7 +943,6 @@ vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss) switch (ss->type) { case vpiSysTask: case vpiSysFunc: - cur->base.vpi_type = &vpip_systf_def_rt; break; default: fprintf(stderr, "Unsupported type %d.\n", (int)ss->type); @@ -970,26 +953,23 @@ vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss) cur->info.tfname = strdup(ss->tfname); cur->is_user_defn = true; - return &cur->base; + return cur; } PLI_INT32 vpi_put_userdata(vpiHandle ref, void*data) { - if (ref->vpi_type->type_code != vpiSysTaskCall - && ref->vpi_type->type_code != vpiSysFuncCall) + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); + if (rfp == 0) return 0; - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - rfp->userdata = data; return 1; } void* vpi_get_userdata(vpiHandle ref) { - struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; - assert((ref->vpi_type->type_code == vpiSysTaskCall) - || (ref->vpi_type->type_code == vpiSysFuncCall)); + struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref); + assert(rfp); return rfp->userdata; } diff --git a/vvp/vpi_time.cc b/vvp/vpi_time.cc index 167fbe6d8..e298d9b8b 100644 --- a/vvp/vpi_time.cc +++ b/vvp/vpi_time.cc @@ -199,12 +199,11 @@ static int timevar_realtime_get(int code, vpiHandle) static vpiHandle timevar_handle(int code, vpiHandle ref) { - struct __vpiSystemTime*rfp - = reinterpret_cast(ref); + struct __vpiSystemTime*rfp = dynamic_cast<__vpiSystemTime*>(ref); switch (code) { case vpiScope: - return &rfp->scope->base; + return rfp->scope; default: return 0; } @@ -217,8 +216,7 @@ static void timevar_get_value(vpiHandle ref, s_vpi_value*vp, bool is_int_func, the caller. */ static struct t_vpi_time time_value; - struct __vpiSystemTime*rfp - = reinterpret_cast(ref); + struct __vpiSystemTime*rfp = dynamic_cast<__vpiSystemTime*>(ref); unsigned long num_bits; vvp_time64_t x, simtime = schedule_simtime(); int units = rfp->scope? rfp->scope->time_units : vpi_time_precision; @@ -326,6 +324,10 @@ static const struct __vpirt vpip_system_time_rt = { 0, 0 }; +__vpiScopedTime::__vpiScopedTime() +: __vpiSystemTime(&vpip_system_time_rt) +{ +} static const struct __vpirt vpip_system_stime_rt = { vpiSysFuncCall, @@ -340,6 +342,10 @@ static const struct __vpirt vpip_system_stime_rt = { 0, 0 }; +__vpiScopedSTime::__vpiScopedSTime() +: __vpiSystemTime(&vpip_system_stime_rt) +{ +} static const struct __vpirt vpip_system_simtime_rt = { vpiSysFuncCall, @@ -354,6 +360,11 @@ static const struct __vpirt vpip_system_simtime_rt = { 0, 0 }; +__vpiSystemTime::__vpiSystemTime() +: __vpiHandle(&vpip_system_simtime_rt) +{ + scope = 0; +} static const struct __vpirt vpip_system_realtime_rt = { vpiSysFuncCall, @@ -368,6 +379,11 @@ static const struct __vpirt vpip_system_realtime_rt = { 0, 0 }; +__vpiScopedRealtime::__vpiScopedRealtime() +: __vpiSystemTime(&vpip_system_realtime_rt) +{ +} + /* * Create a handle to represent a call to $time/$stime/$simtime. The @@ -378,26 +394,21 @@ vpiHandle vpip_sim_time(struct __vpiScope*scope, bool is_stime) { if (scope) { if (is_stime) { - scope->scoped_stime.base.vpi_type = &vpip_system_stime_rt; scope->scoped_stime.scope = scope; - return &scope->scoped_stime.base; + return &scope->scoped_stime; } else { - scope->scoped_time.base.vpi_type = &vpip_system_time_rt; scope->scoped_time.scope = scope; - return &scope->scoped_time.base; + return &scope->scoped_time; } } else { - global_simtime.base.vpi_type = &vpip_system_simtime_rt; - global_simtime.scope = 0; - return &global_simtime.base; + return &global_simtime; } } vpiHandle vpip_sim_realtime(struct __vpiScope*scope) { - scope->scoped_realtime.base.vpi_type = &vpip_system_realtime_rt; scope->scoped_realtime.scope = scope; - return &scope->scoped_realtime.base; + return &scope->scoped_realtime; } int vpip_get_time_precision(void) diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index 785ccbbe1..b4abc871c 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it @@ -35,8 +35,8 @@ # include # include "ivl_alloc.h" -struct __vpiVThrVec { - struct __vpiHandle base; +struct __vpiVThrVec : public __vpiHandle { + __vpiVThrVec(); unsigned bas; unsigned wid; unsigned signed_flag : 1; @@ -77,11 +77,8 @@ extern const char oct_digits[64]; */ static int vthr_vec_get(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNet) - || (ref->vpi_type->type_code==vpiReg) - || (ref->vpi_type->type_code==vpiConstant)); - - struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref; + struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); + assert(rfp); switch (code) { @@ -106,11 +103,8 @@ static int vthr_vec_get(int code, vpiHandle ref) static char* vthr_vec_get_str(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code==vpiNet) - || (ref->vpi_type->type_code==vpiReg) - || (ref->vpi_type->type_code==vpiConstant)); - - struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref; + struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); + assert(rfp); switch (code) { @@ -177,11 +171,8 @@ static void vthr_vec_StringVal(struct __vpiVThrVec*rfp, s_vpi_value*vp) */ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp) { - assert((ref->vpi_type->type_code==vpiNet) - || (ref->vpi_type->type_code==vpiReg) - || (ref->vpi_type->type_code==vpiConstant)); - - struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref; + struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); + assert(rfp); char *rbuf; unsigned wid = rfp->wid; @@ -363,10 +354,8 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp) */ static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp, int) { - assert((ref->vpi_type->type_code==vpiNet) - || (ref->vpi_type->type_code==vpiReg)); - - struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref; + struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); + assert(rfp); unsigned wid = rfp->wid; @@ -456,6 +445,11 @@ static const struct __vpirt vpip_vthr_const_rt = { 0, 0 }; +__vpiVThrVec::__vpiVThrVec() +: __vpiHandle(&vpip_vthr_const_rt) +{ +} + /* * Construct a vpiReg object. Give the object specified dimensions, @@ -463,9 +457,7 @@ static const struct __vpirt vpip_vthr_const_rt = { */ vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag) { - struct __vpiVThrVec*obj = (struct __vpiVThrVec*) - malloc(sizeof(struct __vpiVThrVec)); - obj->base.vpi_type = &vpip_vthr_const_rt; + struct __vpiVThrVec*obj = new __vpiVThrVec; assert(base < 65536); obj->bas = base; assert(wid < 65536); @@ -473,7 +465,7 @@ vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag) obj->signed_flag = signed_flag? 1 : 0; obj->name = vpip_name_string("T<>"); - return &obj->base; + return obj; } #ifdef CHECK_WITH_VALGRIND @@ -486,13 +478,13 @@ void thread_vthr_delete(vpiHandle item) static void thread_vthr_delete_real(vpiHandle item) { - struct __vpiVThrVec*obj = (struct __vpiVThrVec*)item; - free (obj); + struct __vpiVThrVec*obj = dynamic_cast<__vpiVThrVec*>(item); + delete obj; } #endif -struct __vpiVThrWord { - struct __vpiHandle base; +struct __vpiVThrWord : public __vpiHandle { + __vpiVThrWord(); const char* name; int subtype; unsigned index; @@ -500,9 +492,7 @@ struct __vpiVThrWord { static int vthr_word_get(int code, vpiHandle ref) { - assert(ref->vpi_type->type_code==vpiConstant); - - struct __vpiVThrWord*rfp = (struct __vpiVThrWord*)ref; + struct __vpiVThrWord*rfp = dynamic_cast<__vpiVThrWord*>(ref); switch (code) { @@ -521,9 +511,7 @@ static int vthr_word_get(int code, vpiHandle ref) static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp) { - assert(ref->vpi_type->type_code==vpiConstant); - - struct __vpiVThrWord*obj = (struct __vpiVThrWord*)ref; + struct __vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(ref); char *rbuf = need_result_buf(66, RBUF_VAL); double val = 0.0; @@ -604,21 +592,23 @@ static const struct __vpirt vpip_vthr_const_real_rt = { 0, 0 }; +inline __vpiVThrWord::__vpiVThrWord() +: __vpiHandle(&vpip_vthr_const_real_rt) +{ +} vpiHandle vpip_make_vthr_word(unsigned base, const char*type) { - struct __vpiVThrWord*obj = (struct __vpiVThrWord*) - malloc(sizeof(struct __vpiVThrWord)); + struct __vpiVThrWord*obj = new __vpiVThrWord; assert(type[0] == 'r'); - obj->base.vpi_type = &vpip_vthr_const_real_rt; obj->name = vpip_name_string("W<>"); obj->subtype = vpiRealConst; assert(base < 65536); obj->index = base; - return &obj->base; + return obj; } #ifdef CHECK_WITH_VALGRIND @@ -629,8 +619,8 @@ void thread_word_delete(vpiHandle item) static void thread_word_delete_real(vpiHandle item) { - struct __vpiVThrWord*obj = (struct __vpiVThrWord*)item; - free(obj); + struct __vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(item); + delete obj; } void vpi_handle_delete() diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 3fd4c0719..31695764d 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2549,7 +2549,7 @@ bool of_FORK(vthread_t thr, vvp_code_t cp) /* If the new child was created to evaluate a function, run it immediately, then return to this thread. */ - if (cp->scope->base.vpi_type->type_code == vpiFunction) { + if (cp->scope->get_type_code() == vpiFunction) { child->is_scheduled = 1; vthread_run(child); running_thread = thr; diff --git a/vvp/words.cc b/vvp/words.cc index 2cfdcd3dc..22fa2bede 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -258,7 +258,7 @@ static void do_compile_net(vvp_net_t*node, vvp_array_t array, vpiHandle obj = 0; if (! local_flag) { /* Make the vpiHandle for the reg. */ - obj = vpip_make_net4(name, msb, lsb, signed_flag, node); + obj = vpip_make_net4(name, 0, msb, lsb, signed_flag, node); /* This attaches the label to the vpiHandle */ compile_vpi_symbol(my_label, obj); }