Add vpiArray, vpiParent, vpiIndex to VPI

Add the array related VPI calls. These will be used to generate
the array word name only as needed to conserve space. This patch
also makes scanmem3 from the vpi test work correctly after a
slight gold file update.
This commit is contained in:
Cary R
2007-12-05 18:37:58 -08:00
committed by Stephen Williams
parent 73a7fb09fc
commit 1782175c52
6 changed files with 153 additions and 9 deletions
+65
View File
@@ -69,6 +69,12 @@ struct __vpiArrayIterator {
unsigned next;
};
struct __vpiArrayIndex {
struct __vpiHandle base;
struct __vpiDecConst *index;
unsigned done;
};
const char *get_array_name(char*label)
{
vvp_array_t array = array_find(label);
@@ -94,6 +100,9 @@ static vpiHandle vpi_array_index(vpiHandle ref, int index);
static vpiHandle array_iterator_scan(vpiHandle ref, int);
static int array_iterator_free_object(vpiHandle ref);
static vpiHandle array_index_scan(vpiHandle ref, int);
static int array_index_free_object(vpiHandle ref);
static const struct __vpirt vpip_arraymem_rt = {
vpiMemory,
vpi_array_get,
@@ -117,6 +126,21 @@ static const struct __vpirt vpip_array_iterator_rt = {
&array_iterator_free_object
};
/* 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. */
static const struct __vpirt vpip_array_index_rt = {
vpiIterator,
0,
0,
0,
0,
0,
array_index_iterate,
array_index_scan,
array_index_free_object
};
# define ARRAY_HANDLE(ref) (assert(ref->vpi_type->type_code==vpiMemory), \
(struct __vpiArray*)ref)
@@ -239,6 +263,45 @@ static int array_iterator_free_object(vpiHandle ref)
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;
if (code == vpiIndex) {
struct __vpiArrayIndex*res;
res = (struct __vpiArrayIndex*) calloc(1, sizeof (*res));
res->base.vpi_type = &vpip_array_index_rt;
res->index = obj;
res->done = 0;
return &res->base;
}
return 0;
}
static vpiHandle array_index_scan(vpiHandle ref, int)
{
struct __vpiArrayIndex*obj = ARRAY_INDEX(ref);
if (obj->done == 0) {
obj->done = 1;
return &obj->index->base;
}
vpi_free_object(ref);
return 0;
}
static int array_index_free_object(vpiHandle ref)
{
struct __vpiArrayIndex*obj = ARRAY_INDEX(ref);
free(obj);
return 1;
}
void array_set_word(vvp_array_t arr,
unsigned address,
unsigned part_off,
@@ -328,6 +391,8 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
vvp_fun_signal_base*fun = dynamic_cast<vvp_fun_signal_base*>(net->fun);
assert(fun);
fun->attach_as_word(array, addr);
sig->parent = &array->base;
sig->index = vpip_make_dec_const(addr + array->first_addr.value);
}
}