vvp: Changed get_array_word_size(vvp_array_t) to __vpiArray::get_word_size().
This commit is contained in:
parent
230c435ae7
commit
cc4c5f4998
119
vvp/array.cc
119
vvp/array.cc
|
|
@ -57,78 +57,6 @@ vvp_array_t array_find(const char*label)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The vpiArray object holds an array of vpi objects that themselves
|
|
||||||
* represent the words of the array. The vpi_array_t is a pointer to
|
|
||||||
* a struct __vpiArray.
|
|
||||||
*
|
|
||||||
* The details of the implementation depends on what this is an array
|
|
||||||
* of. The easiest case is if this is an array of nets.
|
|
||||||
*
|
|
||||||
* - Array of Nets:
|
|
||||||
* If this represents an array of nets, then the nets member points to
|
|
||||||
* an array of vpiHandle objects. Each vpiHandle is a word. This is
|
|
||||||
* done because typically each word of a net array is simultaneously
|
|
||||||
* driven and accessed by other means, so there is no advantage to
|
|
||||||
* compacting the array in any other way.
|
|
||||||
*
|
|
||||||
* - Array of vector4 words.
|
|
||||||
* In this case, the nets pointer is nil, and the vals4 member points
|
|
||||||
* to a vvl_vector4array_t object that is a compact representation of
|
|
||||||
* an array of vvp_vector4_t vectors.
|
|
||||||
*
|
|
||||||
* - Array of real variables
|
|
||||||
* The vals member points to a dynamic array objects that has an
|
|
||||||
* array of double variables. This is very much like the way the
|
|
||||||
* vector4 array works.
|
|
||||||
*/
|
|
||||||
struct __vpiArray : public __vpiArrayBase, public __vpiHandle {
|
|
||||||
int get_type_code(void) const { return vpiMemory; }
|
|
||||||
unsigned get_size() const { return array_count; }
|
|
||||||
vpiHandle get_left_range() { assert(nets == 0); return &msb; }
|
|
||||||
vpiHandle get_right_range() { assert(nets == 0); return &lsb; }
|
|
||||||
struct __vpiScope*get_scope() const { return scope; }
|
|
||||||
|
|
||||||
int get_word_size() const;
|
|
||||||
char*get_word_str(struct __vpiArrayWord*word, int code);
|
|
||||||
void get_word_value(struct __vpiArrayWord*word, p_vpi_value vp);
|
|
||||||
void put_word_value(struct __vpiArrayWord*word, p_vpi_value vp, int flags);
|
|
||||||
|
|
||||||
vpiHandle get_iter_index(struct __vpiArrayIterator*iter, int idx);
|
|
||||||
|
|
||||||
int vpi_get(int code);
|
|
||||||
char* vpi_get_str(int code);
|
|
||||||
vpiHandle vpi_handle(int code);
|
|
||||||
inline vpiHandle vpi_iterate(int code) { return vpi_array_base_iterate(code); }
|
|
||||||
vpiHandle vpi_index(int idx);
|
|
||||||
|
|
||||||
const char*name; /* Permanently allocated string */
|
|
||||||
__vpiDecConst first_addr;
|
|
||||||
__vpiDecConst last_addr;
|
|
||||||
__vpiDecConst msb;
|
|
||||||
__vpiDecConst lsb;
|
|
||||||
unsigned vals_width;
|
|
||||||
// If this is a net array, nets lists the handles.
|
|
||||||
vpiHandle*nets;
|
|
||||||
// If this is a var array, then these are used instead of nets.
|
|
||||||
vvp_vector4array_t*vals4;
|
|
||||||
vvp_darray *vals;
|
|
||||||
|
|
||||||
vvp_fun_arrayport*ports_;
|
|
||||||
struct __vpiCallback *vpi_callbacks;
|
|
||||||
bool signed_flag;
|
|
||||||
bool swap_addr;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned array_count;
|
|
||||||
struct __vpiScope*scope;
|
|
||||||
|
|
||||||
friend vpiHandle vpip_make_array(char*label, const char*name,
|
|
||||||
int first_addr, int last_addr,
|
|
||||||
bool signed_flag);
|
|
||||||
friend void compile_array_alias(char*label, char*name, char*src);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __vpiArrayVthrA : public __vpiHandle {
|
struct __vpiArrayVthrA : public __vpiHandle {
|
||||||
|
|
||||||
__vpiArrayVthrA();
|
__vpiArrayVthrA();
|
||||||
|
|
@ -217,27 +145,6 @@ struct __vpiArrayVthrAPV : public __vpiHandle {
|
||||||
unsigned part_wid;
|
unsigned part_wid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get the array word size. */
|
|
||||||
unsigned get_array_word_size(vvp_array_t array)
|
|
||||||
{
|
|
||||||
unsigned width;
|
|
||||||
|
|
||||||
assert(array->get_size() > 0);
|
|
||||||
/* For a net array we need to get the width from the first element. */
|
|
||||||
if (array->nets) {
|
|
||||||
assert(array->vals4 == 0 && array->vals == 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. */
|
|
||||||
} else {
|
|
||||||
assert(array->vals4 || array->vals);
|
|
||||||
width = array->vals_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_net_array(vpiHandle obj)
|
bool is_net_array(vpiHandle obj)
|
||||||
{
|
{
|
||||||
struct __vpiArray*rfp = dynamic_cast<__vpiArray*> (obj);
|
struct __vpiArray*rfp = dynamic_cast<__vpiArray*> (obj);
|
||||||
|
|
@ -296,18 +203,22 @@ static bool vpi_array_is_string(const vvp_array_t arr)
|
||||||
|
|
||||||
int __vpiArray::get_word_size() const
|
int __vpiArray::get_word_size() const
|
||||||
{
|
{
|
||||||
assert(nets == 0);
|
unsigned width;
|
||||||
|
|
||||||
if (vals4) {
|
assert(get_size() > 0);
|
||||||
assert(vals == 0);
|
/* For a net array we need to get the width from the first element. */
|
||||||
return (int) vals4->width();
|
if (nets) {
|
||||||
|
assert(vals4 == 0 && vals == 0);
|
||||||
|
struct __vpiSignal*vsig = dynamic_cast<__vpiSignal*>(nets[0]);
|
||||||
|
assert(vsig);
|
||||||
|
width = vpip_size(vsig);
|
||||||
|
/* For a variable array we can get the width from vals_width. */
|
||||||
} else {
|
} else {
|
||||||
assert(vals4 == 0);
|
assert(vals4 || vals);
|
||||||
return 1;
|
width = vals_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
return width;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char*__vpiArray::get_word_str(struct __vpiArrayWord*word, int code)
|
char*__vpiArray::get_word_str(struct __vpiArrayWord*word, int code)
|
||||||
|
|
@ -561,7 +472,7 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref)
|
||||||
return 0; // Not implemented for now!
|
return 0; // Not implemented for now!
|
||||||
|
|
||||||
case vpiSize:
|
case vpiSize:
|
||||||
return get_array_word_size(parent);
|
return parent->get_word_size();
|
||||||
|
|
||||||
case vpiLeftRange:
|
case vpiLeftRange:
|
||||||
return parent->msb.get_value();
|
return parent->msb.get_value();
|
||||||
|
|
@ -625,7 +536,7 @@ static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value vp)
|
||||||
vpip_string_get_value(tmp, vp);
|
vpip_string_get_value(tmp, vp);
|
||||||
} else {
|
} else {
|
||||||
vvp_vector4_t tmp = array_get_word(parent, index);
|
vvp_vector4_t tmp = array_get_word(parent, index);
|
||||||
unsigned width = get_array_word_size(parent);
|
unsigned width = parent->get_word_size();
|
||||||
vpip_vec4_get_value(tmp, width, parent->signed_flag, vp);
|
vpip_vec4_get_value(tmp, width, parent->signed_flag, vp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -645,7 +556,7 @@ static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
double val = real_from_vpi_value(vp);
|
double val = real_from_vpi_value(vp);
|
||||||
array_set_word(parent, index, val);
|
array_set_word(parent, index, val);
|
||||||
} else {
|
} else {
|
||||||
unsigned width = get_array_word_size(parent);
|
unsigned width = parent->get_word_size();
|
||||||
vvp_vector4_t val = vec4_from_vpi_value(vp, width);
|
vvp_vector4_t val = vec4_from_vpi_value(vp, width);
|
||||||
array_set_word(parent, index, 0, val);
|
array_set_word(parent, index, 0, val);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ class value_callback;
|
||||||
* table of all the arrays in the design.
|
* table of all the arrays in the design.
|
||||||
*/
|
*/
|
||||||
extern vvp_array_t array_find(const char*label);
|
extern vvp_array_t array_find(const char*label);
|
||||||
extern unsigned get_array_word_size(vvp_array_t array);
|
|
||||||
|
|
||||||
extern void array_word_change(vvp_array_t array, unsigned long addr);
|
extern void array_word_change(vvp_array_t array, unsigned long addr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
class class_type;
|
class class_type;
|
||||||
class vvp_darray;
|
class vvp_darray;
|
||||||
|
class vvp_fun_arrayport;
|
||||||
|
|
||||||
typedef struct __vpiArray* vvp_array_t;
|
typedef struct __vpiArray* vvp_array_t;
|
||||||
|
|
||||||
|
|
@ -562,6 +563,78 @@ struct __vpiArrayBase {
|
||||||
struct __vpiArrayWord*vals_words;
|
struct __vpiArrayWord*vals_words;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vpiArray object holds an array of vpi objects that themselves
|
||||||
|
* represent the words of the array. The vpi_array_t is a pointer to
|
||||||
|
* a struct __vpiArray.
|
||||||
|
*
|
||||||
|
* The details of the implementation depends on what this is an array
|
||||||
|
* of. The easiest case is if this is an array of nets.
|
||||||
|
*
|
||||||
|
* - Array of Nets:
|
||||||
|
* If this represents an array of nets, then the nets member points to
|
||||||
|
* an array of vpiHandle objects. Each vpiHandle is a word. This is
|
||||||
|
* done because typically each word of a net array is simultaneously
|
||||||
|
* driven and accessed by other means, so there is no advantage to
|
||||||
|
* compacting the array in any other way.
|
||||||
|
*
|
||||||
|
* - Array of vector4 words.
|
||||||
|
* In this case, the nets pointer is nil, and the vals4 member points
|
||||||
|
* to a vvl_vector4array_t object that is a compact representation of
|
||||||
|
* an array of vvp_vector4_t vectors.
|
||||||
|
*
|
||||||
|
* - Array of real variables
|
||||||
|
* The vals member points to a dynamic array objects that has an
|
||||||
|
* array of double variables. This is very much like the way the
|
||||||
|
* vector4 array works.
|
||||||
|
*/
|
||||||
|
struct __vpiArray : public __vpiArrayBase, public __vpiHandle {
|
||||||
|
int get_type_code(void) const { return vpiMemory; }
|
||||||
|
unsigned get_size() const { return array_count; }
|
||||||
|
vpiHandle get_left_range() { assert(nets == 0); return &msb; }
|
||||||
|
vpiHandle get_right_range() { assert(nets == 0); return &lsb; }
|
||||||
|
struct __vpiScope*get_scope() const { return scope; }
|
||||||
|
|
||||||
|
int get_word_size() const;
|
||||||
|
char*get_word_str(struct __vpiArrayWord*word, int code);
|
||||||
|
void get_word_value(struct __vpiArrayWord*word, p_vpi_value vp);
|
||||||
|
void put_word_value(struct __vpiArrayWord*word, p_vpi_value vp, int flags);
|
||||||
|
|
||||||
|
vpiHandle get_iter_index(struct __vpiArrayIterator*iter, int idx);
|
||||||
|
|
||||||
|
int vpi_get(int code);
|
||||||
|
char* vpi_get_str(int code);
|
||||||
|
vpiHandle vpi_handle(int code);
|
||||||
|
inline vpiHandle vpi_iterate(int code) { return vpi_array_base_iterate(code); }
|
||||||
|
vpiHandle vpi_index(int idx);
|
||||||
|
|
||||||
|
const char*name; /* Permanently allocated string */
|
||||||
|
__vpiDecConst first_addr;
|
||||||
|
__vpiDecConst last_addr;
|
||||||
|
__vpiDecConst msb;
|
||||||
|
__vpiDecConst lsb;
|
||||||
|
unsigned vals_width;
|
||||||
|
// If this is a net array, nets lists the handles.
|
||||||
|
vpiHandle*nets;
|
||||||
|
// If this is a var array, then these are used instead of nets.
|
||||||
|
vvp_vector4array_t*vals4;
|
||||||
|
vvp_darray *vals;
|
||||||
|
|
||||||
|
vvp_fun_arrayport*ports_;
|
||||||
|
struct __vpiCallback *vpi_callbacks;
|
||||||
|
bool signed_flag;
|
||||||
|
bool swap_addr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned array_count;
|
||||||
|
struct __vpiScope*scope;
|
||||||
|
|
||||||
|
friend vpiHandle vpip_make_array(char*label, const char*name,
|
||||||
|
int first_addr, int last_addr,
|
||||||
|
bool signed_flag);
|
||||||
|
friend void compile_array_alias(char*label, char*name, char*src);
|
||||||
|
};
|
||||||
|
|
||||||
class __vpiDarrayVar : public __vpiBaseVar, public __vpiArrayBase {
|
class __vpiDarrayVar : public __vpiBaseVar, public __vpiArrayBase {
|
||||||
public:
|
public:
|
||||||
__vpiDarrayVar(__vpiScope*scope, const char*name, vvp_net_t*net);
|
__vpiDarrayVar(__vpiScope*scope, const char*name, vvp_net_t*net);
|
||||||
|
|
|
||||||
|
|
@ -1020,7 +1020,7 @@ bool of_ASSIGN_AV(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
if (adr < 0) return true;
|
if (adr < 0) return true;
|
||||||
|
|
||||||
long vwidth = get_array_word_size(cp->array);
|
long vwidth = cp->array->get_word_size();
|
||||||
// We fell off the MSB end.
|
// We fell off the MSB end.
|
||||||
if (off >= vwidth) return true;
|
if (off >= vwidth) return true;
|
||||||
// Trim the bits after the MSB
|
// Trim the bits after the MSB
|
||||||
|
|
@ -1059,7 +1059,7 @@ bool of_ASSIGN_AVD(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
if (adr < 0) return true;
|
if (adr < 0) return true;
|
||||||
|
|
||||||
long vwidth = get_array_word_size(cp->array);
|
long vwidth = cp->array->get_word_size();
|
||||||
// We fell off the MSB end.
|
// We fell off the MSB end.
|
||||||
if (off >= vwidth) return true;
|
if (off >= vwidth) return true;
|
||||||
// Trim the bits after the MSB
|
// Trim the bits after the MSB
|
||||||
|
|
@ -1091,7 +1091,7 @@ bool of_ASSIGN_AVE(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
if (adr < 0) return true;
|
if (adr < 0) return true;
|
||||||
|
|
||||||
long vwidth = get_array_word_size(cp->array);
|
long vwidth = cp->array->get_word_size();
|
||||||
// We fell off the MSB end.
|
// We fell off the MSB end.
|
||||||
if (off >= vwidth) return true;
|
if (off >= vwidth) return true;
|
||||||
// Trim the bits after the MSB
|
// Trim the bits after the MSB
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue