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-03 09:44:31 -08:00 committed by Stephen Williams
parent 73a7fb09fc
commit 1782175c52
6 changed files with 153 additions and 9 deletions

View File

@ -291,6 +291,7 @@ typedef struct t_vpi_delay {
#define vpiTimeVar 63
#define vpiIndex 78
#define vpiLeftRange 79
#define vpiParent 81
#define vpiRightRange 83
#define vpiScope 84
#define vpiSysTfCall 85
@ -312,8 +313,9 @@ typedef struct t_vpi_delay {
#define vpiDefName 9
#define vpiTimeUnit 11
#define vpiTimePrecision 12
#define vpiNetType 22
#define vpiNetType 22
# define vpiWire 1
#define vpiArray 28
#define vpiConstType 40
# define vpiDecConst 1
# define vpiRealConst 2

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);
}
}

View File

@ -34,6 +34,7 @@ typedef struct __vpiArray* vvp_array_t;
extern vvp_array_t array_find(char*label);
extern const char *get_array_name(char*label);
extern const int get_array_base(char*label);
extern vpiHandle array_index_iterate(int code, vpiHandle ref);
extern void array_word_change(vvp_array_t array, unsigned long addr);

View File

@ -91,8 +91,8 @@ struct __vpirt {
int (*vpi_free_object_)(vpiHandle);
/*
This tow method are used to read/write delay
value from/into modpath record
These two methods are used to read/write delay
values from/into modpath records
*/
void (*vpi_get_delays_)(vpiHandle, p_vpi_delay);
void (*vpi_put_delays_)(vpiHandle, p_vpi_delay);
@ -190,6 +190,8 @@ extern void vpip_make_root_iterator(struct __vpiHandle**&table,
*/
struct __vpiSignal {
struct __vpiHandle base;
vpiHandle parent;
vpiHandle index;
struct __vpiScope* scope;
/* The name of this reg/net, or <name>[<index>] for array words. */
const char*name;
@ -319,6 +321,8 @@ extern void vpip_run_memory_value_change(vpiHandle ref, unsigned adr);
*/
struct __vpiRealVar {
struct __vpiHandle base;
vpiHandle parent;
vpiHandle index;
struct __vpiScope* scope;
const char*name;
vvp_net_t*net;

View File

@ -30,6 +30,18 @@
#endif
# include <assert.h>
static int real_var_get(int code, vpiHandle ref)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
if (code == vpiArray) {
return rfp->parent != 0;
}
return 0;
}
static char* real_var_get_str(int code, vpiHandle ref)
{
@ -60,6 +72,37 @@ static char* real_var_get_str(int code, vpiHandle ref)
return 0;
}
static vpiHandle real_var_get_handle(int code, vpiHandle ref)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
switch (code) {
case vpiParent:
return rfp->parent;
case vpiIndex:
return rfp->index;
}
return 0;
}
static vpiHandle real_var_iterate(int code, vpiHandle ref)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
if (code == vpiIndex) {
return (rfp->index->vpi_type->iterate_)(code, rfp->index);
}
return 0;
}
static void real_var_get_value(vpiHandle ref, s_vpi_value*vp)
{
assert(ref->vpi_type->type_code == vpiRealVar);
@ -104,13 +147,13 @@ static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp)
static const struct __vpirt vpip_real_var_rt = {
vpiRealVar,
0,
&real_var_get_str,
&real_var_get_value,
&real_var_put_value,
real_var_get,
real_var_get_str,
real_var_get_value,
real_var_put_value,
0,
0,
real_var_get_handle,
real_var_iterate,
0,
0
@ -133,6 +176,8 @@ vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net)
malloc(sizeof(struct __vpiRealVar));
obj->base.vpi_type = &vpip_real_var_rt;
obj->parent = 0;
obj->index = 0;
obj->name = vpip_name_string(name);
obj->net = net;

View File

@ -97,6 +97,9 @@ static int signal_get(int code, vpiHandle ref)
case vpiSigned:
return rfp->signed_flag != 0;
case vpiArray:
return rfp->parent != 0;
case vpiSize:
if (rfp->msb >= rfp->lsb)
return rfp->msb - rfp->lsb + 1;
@ -162,6 +165,12 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
switch (code) {
case vpiParent:
return rfp->parent;
case vpiIndex:
return rfp->index;
case vpiScope:
return &rfp->scope->base;
@ -178,6 +187,20 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
return 0;
}
static vpiHandle signal_iterate(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
if (code == vpiIndex) {
return array_index_iterate(code, rfp->index);
}
return 0;
}
static char *signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
{
@ -642,6 +665,7 @@ static const struct __vpirt vpip_reg_rt = {
signal_get_value,
signal_put_value,
signal_get_handle,
signal_iterate,
0
};
@ -652,6 +676,7 @@ static const struct __vpirt vpip_net_rt = {
signal_get_value,
signal_put_value,
signal_get_handle,
signal_iterate,
0
};
@ -710,6 +735,8 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
{
struct __vpiSignal*obj = allocate_vpiSignal();
obj->base.vpi_type = &vpip_net_rt;
obj->parent = 0;
obj->index = 0;
obj->name = name? vpip_name_string(name) : 0;
obj->msb = msb;
obj->lsb = lsb;