From 1530594b4b5c07f1eb97f8e625d2f1d0aa7f59ca Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 13 Jun 2008 22:05:19 -0700 Subject: [PATCH] Implement vpiIndex for vpiMemoryWord objects. The vpiIndex is really just a different view into the same object, so implement the trickery needed to support a vpiIndex with the absolute minimum memory cost. --- vvp/array.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index b29487df9..a256acafe 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -135,9 +135,16 @@ struct __vpiArrayVthrA { * pointer. * * To then get to the parent, use word0[-1].parent. + * + * The vpiArrayWord is also used as a handle for the index (vpiIndex) + * for the word. To make that work, return the pointer to the as_index + * member instead of the as_word member. The result is a different set + * 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 base; + struct __vpiHandle as_word; + struct __vpiHandle as_index; union { struct __vpiArray*parent; struct __vpiArrayWord*word0; @@ -163,6 +170,8 @@ static void vpi_array_var_word_get_value(vpiHandle, p_vpi_value); static vpiHandle vpi_array_var_word_put_value(vpiHandle, p_vpi_value, int); static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref); +static void vpi_array_var_index_get_value(vpiHandle, p_vpi_value); + static int vpi_array_vthr_A_get(int code, vpiHandle); static char*vpi_array_vthr_A_get_str(int code, vpiHandle); static void vpi_array_vthr_A_get_value(vpiHandle, p_vpi_value); @@ -219,6 +228,18 @@ static const struct __vpirt vpip_array_var_word_rt = { 0 }; +static const struct __vpirt vpip_array_var_index_rt = { + vpiIndex, + 0, + 0, + &vpi_array_var_index_get_value, + 0, + 0, + 0, + 0, + 0 +}; + static const struct __vpirt vpip_array_vthr_A_rt = { vpiMemoryWord, &vpi_array_vthr_A_get, @@ -244,6 +265,16 @@ static struct __vpiArrayWord* array_var_word_from_handle(vpiHandle ref) return (struct __vpiArrayWord*) ref; } +static struct __vpiArrayWord* array_var_index_from_handle(vpiHandle ref) +{ + if (ref == 0) + return 0; + if (ref->vpi_type != &vpip_array_var_index_rt) + return 0; + + return (struct __vpiArrayWord*) (ref-1); +} + static struct __vpiArrayVthrA* array_vthr_a_from_handle(vpiHandle ref) { if (ref == 0) @@ -266,7 +297,8 @@ 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].base.vpi_type = &vpip_array_var_word_rt; + 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; } } @@ -366,7 +398,7 @@ static vpiHandle vpi_array_index(vpiHandle ref, int index) if (obj->vals_words == 0) array_make_vals_words(obj); - return &(obj->vals_words[index].base); + return &(obj->vals_words[index].as_word); } static int vpi_array_var_word_get(int code, vpiHandle ref) @@ -450,7 +482,7 @@ static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref) switch (code) { case vpiIndex: - break; // Not implemented! + return &(obj->as_index); case vpiLeftRange: return &parent->msb.base; @@ -468,6 +500,18 @@ static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref) return 0; } +static void vpi_array_var_index_get_value(vpiHandle ref, p_vpi_value value) +{ + struct __vpiArrayWord*obj = array_var_index_from_handle(ref); + struct __vpiArray*parent; + + assert(obj); + unsigned index = decode_array_word_pointer(obj, parent); + + assert(value->format == vpiIntVal); + value->value.integer = index; +} + # define ARRAY_ITERATOR(ref) (assert(ref->vpi_type->type_code==vpiIterator), \ (struct __vpiArrayIterator*)ref) @@ -491,7 +535,7 @@ static vpiHandle array_iterator_scan(vpiHandle ref, int) if (obj->array->vals_words == 0) array_make_vals_words(obj->array); - return &(obj->array->vals_words[use_index].base); + return &(obj->array->vals_words[use_index].as_word); } static int array_iterator_free_object(vpiHandle ref)