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.
This commit is contained in:
parent
6f0d8e8dda
commit
1530594b4b
54
vvp/array.cc
54
vvp/array.cc
|
|
@ -135,9 +135,16 @@ struct __vpiArrayVthrA {
|
||||||
* pointer.
|
* pointer.
|
||||||
*
|
*
|
||||||
* To then get to the parent, use word0[-1].parent.
|
* 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 __vpiArrayWord {
|
||||||
struct __vpiHandle base;
|
struct __vpiHandle as_word;
|
||||||
|
struct __vpiHandle as_index;
|
||||||
union {
|
union {
|
||||||
struct __vpiArray*parent;
|
struct __vpiArray*parent;
|
||||||
struct __vpiArrayWord*word0;
|
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_put_value(vpiHandle, p_vpi_value, int);
|
||||||
static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref);
|
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 int vpi_array_vthr_A_get(int code, vpiHandle);
|
||||||
static char*vpi_array_vthr_A_get_str(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);
|
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
|
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 = {
|
static const struct __vpirt vpip_array_vthr_A_rt = {
|
||||||
vpiMemoryWord,
|
vpiMemoryWord,
|
||||||
&vpi_array_vthr_A_get,
|
&vpi_array_vthr_A_get,
|
||||||
|
|
@ -244,6 +265,16 @@ static struct __vpiArrayWord* array_var_word_from_handle(vpiHandle ref)
|
||||||
return (struct __vpiArrayWord*) 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)
|
static struct __vpiArrayVthrA* array_vthr_a_from_handle(vpiHandle ref)
|
||||||
{
|
{
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
|
|
@ -266,7 +297,8 @@ static void array_make_vals_words(struct __vpiArray*parent)
|
||||||
|
|
||||||
struct __vpiArrayWord*words = parent->vals_words;
|
struct __vpiArrayWord*words = parent->vals_words;
|
||||||
for (unsigned idx = 0 ; idx < parent->array_count ; idx += 1) {
|
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;
|
words[idx].word0 = words;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +398,7 @@ static vpiHandle vpi_array_index(vpiHandle ref, int index)
|
||||||
if (obj->vals_words == 0)
|
if (obj->vals_words == 0)
|
||||||
array_make_vals_words(obj);
|
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)
|
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) {
|
switch (code) {
|
||||||
|
|
||||||
case vpiIndex:
|
case vpiIndex:
|
||||||
break; // Not implemented!
|
return &(obj->as_index);
|
||||||
|
|
||||||
case vpiLeftRange:
|
case vpiLeftRange:
|
||||||
return &parent->msb.base;
|
return &parent->msb.base;
|
||||||
|
|
@ -468,6 +500,18 @@ static vpiHandle vpi_array_var_word_get_handle(int code, vpiHandle ref)
|
||||||
return 0;
|
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), \
|
# define ARRAY_ITERATOR(ref) (assert(ref->vpi_type->type_code==vpiIterator), \
|
||||||
(struct __vpiArrayIterator*)ref)
|
(struct __vpiArrayIterator*)ref)
|
||||||
|
|
||||||
|
|
@ -491,7 +535,7 @@ static vpiHandle array_iterator_scan(vpiHandle ref, int)
|
||||||
if (obj->array->vals_words == 0)
|
if (obj->array->vals_words == 0)
|
||||||
array_make_vals_words(obj->array);
|
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)
|
static int array_iterator_free_object(vpiHandle ref)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue