vvp: Further extraction of common code pieces from ArrayBase.
This commit is contained in:
parent
48d3701c02
commit
ea7fa24f9e
223
vvp/array.cc
223
vvp/array.cc
|
|
@ -85,11 +85,15 @@ vvp_array_t array_find(const char*label)
|
||||||
struct __vpiArray : public __vpiArrayBase, public __vpiHandle {
|
struct __vpiArray : public __vpiArrayBase, public __vpiHandle {
|
||||||
int get_type_code(void) const { return vpiMemory; }
|
int get_type_code(void) const { return vpiMemory; }
|
||||||
unsigned get_size() const { return array_count; }
|
unsigned get_size() const { return array_count; }
|
||||||
int get_word_size() const;
|
vpiHandle get_left_range() { assert(nets == 0); return &msb; }
|
||||||
int get_left_range() const { assert(nets == 0); return msb.get_value(); }
|
vpiHandle get_right_range() { assert(nets == 0); return &lsb; }
|
||||||
int get_right_range() const { assert(nets == 0); return lsb.get_value(); }
|
|
||||||
struct __vpiScope*get_scope() const { return scope; }
|
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);
|
||||||
|
|
||||||
int vpi_get(int code);
|
int vpi_get(int code);
|
||||||
char* vpi_get_str(int code);
|
char* vpi_get_str(int code);
|
||||||
vpiHandle vpi_handle(int code);
|
vpiHandle vpi_handle(int code);
|
||||||
|
|
@ -252,7 +256,7 @@ static void vpi_array_vthr_APV_get_value(vpiHandle ref, p_vpi_value vp);
|
||||||
|
|
||||||
|
|
||||||
// This function return true if the underlying array words are real.
|
// This function return true if the underlying array words are real.
|
||||||
static bool vpi_array_is_real(vvp_array_t arr)
|
static bool vpi_array_is_real(const vvp_array_t arr)
|
||||||
{
|
{
|
||||||
// Check to see if this is a variable/register array.
|
// Check to see if this is a variable/register array.
|
||||||
if (arr->vals4 != 0) // A bit based variable/register array.
|
if (arr->vals4 != 0) // A bit based variable/register array.
|
||||||
|
|
@ -275,7 +279,7 @@ static bool vpi_array_is_real(vvp_array_t arr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vpi_array_is_string(vvp_array_t arr)
|
static bool vpi_array_is_string(const vvp_array_t arr)
|
||||||
{
|
{
|
||||||
// Check to see if this is a variable/register array.
|
// Check to see if this is a variable/register array.
|
||||||
if (arr->vals4 != 0) // A bit based variable/register array.
|
if (arr->vals4 != 0) // A bit based variable/register array.
|
||||||
|
|
@ -303,6 +307,79 @@ int __vpiArray::get_word_size() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*__vpiArray::get_word_str(struct __vpiArrayWord*word, int code)
|
||||||
|
{
|
||||||
|
unsigned index = word->get_index();
|
||||||
|
|
||||||
|
if (code == vpiFile) { // Not implemented for now!
|
||||||
|
return simple_set_rbuf_str(file_names[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char sidx [64];
|
||||||
|
snprintf(sidx, 63, "%d", (int)index + first_addr.get_value());
|
||||||
|
return generic_get_str(code, get_scope(), name, sidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __vpiArray::get_word_value(struct __vpiArrayWord*word, p_vpi_value vp)
|
||||||
|
{
|
||||||
|
unsigned index = word->get_index();
|
||||||
|
|
||||||
|
// Determine the appropriate format (The Verilog PLI Handbook 5.2.10)
|
||||||
|
if(vp->format == vpiObjTypeVal) {
|
||||||
|
if(vpi_array_is_real(this))
|
||||||
|
vp->format = vpiRealVal;
|
||||||
|
else if(vpi_array_is_string(this))
|
||||||
|
vp->format = vpiStringVal;
|
||||||
|
else
|
||||||
|
vp->format = vpiIntVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vals4) {
|
||||||
|
vpip_vec4_get_value(vals4->get_word(index),
|
||||||
|
vals4->width(), signed_flag, vp);
|
||||||
|
} else if(vals) {
|
||||||
|
switch(vp->format) {
|
||||||
|
case vpiIntVal:
|
||||||
|
case vpiVectorVal:
|
||||||
|
{
|
||||||
|
vvp_vector4_t v;
|
||||||
|
vals->get_word(index, v);
|
||||||
|
vpip_vec2_get_value(v, vals_width, signed_flag, vp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiRealVal:
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
vals->get_word(index, d);
|
||||||
|
vpip_real_get_value(d, vp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiStringVal:
|
||||||
|
{
|
||||||
|
string s;
|
||||||
|
vals->get_word(index, s);
|
||||||
|
vpip_string_get_value(s, vp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO *StrVal variants
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "vpi sorry: format is not implemented");
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __vpiArray::put_word_value(struct __vpiArrayWord*word, p_vpi_value vp, int)
|
||||||
|
{
|
||||||
|
unsigned index = word->get_index();
|
||||||
|
vvp_vector4_t val = vec4_from_vpi_value(vp, vals_width);
|
||||||
|
array_set_word(this, index, 0, val);
|
||||||
|
}
|
||||||
|
|
||||||
int __vpiArray::vpi_get(int code)
|
int __vpiArray::vpi_get(int code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
@ -377,6 +454,7 @@ int __vpiArrayWord::as_word_t::vpi_get(int code)
|
||||||
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
||||||
assert(obj);
|
assert(obj);
|
||||||
struct __vpiArrayBase*parent = obj->get_parent();
|
struct __vpiArrayBase*parent = obj->get_parent();
|
||||||
|
t_vpi_value val;
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case vpiLineNo:
|
case vpiLineNo:
|
||||||
|
|
@ -386,10 +464,16 @@ int __vpiArrayWord::as_word_t::vpi_get(int code)
|
||||||
return parent->get_word_size();
|
return parent->get_word_size();
|
||||||
|
|
||||||
case vpiLeftRange:
|
case vpiLeftRange:
|
||||||
return parent->get_left_range();
|
val.format = vpiIntVal;
|
||||||
|
parent->get_left_range()->vpi_get_value(&val);
|
||||||
|
assert(val.format == vpiIntVal);
|
||||||
|
return val.value.integer;
|
||||||
|
|
||||||
case vpiRightRange:
|
case vpiRightRange:
|
||||||
return parent->get_right_range();
|
val.format = vpiIntVal;
|
||||||
|
parent->get_right_range()->vpi_get_value(&val);
|
||||||
|
assert(val.format == vpiIntVal);
|
||||||
|
return val.value.integer;
|
||||||
|
|
||||||
case vpiAutomatic:
|
case vpiAutomatic:
|
||||||
return (int) parent->get_scope()->is_automatic;
|
return (int) parent->get_scope()->is_automatic;
|
||||||
|
|
@ -404,131 +488,6 @@ int __vpiArrayWord::as_word_t::vpi_get(int code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make generic version of the following methods and move them to array_common
|
|
||||||
char* __vpiArrayWord::as_word_t::vpi_get_str(int code)
|
|
||||||
{
|
|
||||||
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
|
||||||
assert(obj);
|
|
||||||
struct __vpiArray*parent = (__vpiArray*) obj->get_parent();
|
|
||||||
unsigned index = obj->get_index();
|
|
||||||
|
|
||||||
if (code == vpiFile) { // Not implemented for now!
|
|
||||||
return simple_set_rbuf_str(file_names[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char sidx [64];
|
|
||||||
snprintf(sidx, 63, "%d", (int)index + parent->first_addr.get_value());
|
|
||||||
return generic_get_str(code, parent->get_scope(), parent->name, sidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __vpiArrayWord::as_word_t::vpi_get_value(p_vpi_value vp)
|
|
||||||
{
|
|
||||||
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
|
||||||
assert(obj);
|
|
||||||
struct __vpiArray*parent = (__vpiArray*) obj->get_parent();
|
|
||||||
unsigned index = obj->get_index();
|
|
||||||
|
|
||||||
// Determine the appropriate format (The Verilog PLI Handbook 5.2.10)
|
|
||||||
if(vp->format == vpiObjTypeVal) {
|
|
||||||
if(vpi_array_is_real(parent))
|
|
||||||
vp->format = vpiRealVal;
|
|
||||||
else if(vpi_array_is_string(parent))
|
|
||||||
vp->format = vpiStringVal;
|
|
||||||
else
|
|
||||||
vp->format = vpiIntVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent->vals4) {
|
|
||||||
vpip_vec4_get_value(parent->vals4->get_word(index),
|
|
||||||
parent->vals4->width(), parent->signed_flag, vp);
|
|
||||||
} else if(parent->vals) {
|
|
||||||
switch(vp->format) {
|
|
||||||
case vpiIntVal:
|
|
||||||
case vpiVectorVal:
|
|
||||||
{
|
|
||||||
vvp_vector4_t v;
|
|
||||||
parent->vals->get_word(index, v);
|
|
||||||
vpip_vec2_get_value(v, parent->vals_width, parent->signed_flag, vp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vpiRealVal:
|
|
||||||
{
|
|
||||||
double d;
|
|
||||||
parent->vals->get_word(index, d);
|
|
||||||
vpip_real_get_value(d, vp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vpiStringVal:
|
|
||||||
{
|
|
||||||
string s;
|
|
||||||
parent->vals->get_word(index, s);
|
|
||||||
vpip_string_get_value(s, vp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// TODO *StrVal variants
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "vpi sorry: format is not implemented");
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vpiHandle __vpiArrayWord::as_word_t::vpi_put_value(p_vpi_value vp, int)
|
|
||||||
{
|
|
||||||
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
|
||||||
assert(obj);
|
|
||||||
struct __vpiArray*parent = (__vpiArray*) obj->get_parent();
|
|
||||||
unsigned index = obj->get_index();
|
|
||||||
|
|
||||||
vvp_vector4_t val = vec4_from_vpi_value(vp, parent->vals_width);
|
|
||||||
array_set_word(parent, index, 0, val);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpiHandle __vpiArrayWord::as_word_t::vpi_handle(int code)
|
|
||||||
{
|
|
||||||
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
|
||||||
assert(obj);
|
|
||||||
struct __vpiArray*parent = (__vpiArray*) obj->get_parent();
|
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
|
|
||||||
case vpiIndex:
|
|
||||||
return &(obj->as_index);
|
|
||||||
|
|
||||||
case vpiLeftRange:
|
|
||||||
return &parent->msb;
|
|
||||||
|
|
||||||
case vpiRightRange:
|
|
||||||
return &parent->lsb;
|
|
||||||
|
|
||||||
case vpiParent:
|
|
||||||
return parent;
|
|
||||||
|
|
||||||
case vpiScope:
|
|
||||||
return parent->get_scope();
|
|
||||||
|
|
||||||
case vpiModule:
|
|
||||||
return vpip_module(parent->get_scope());
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __vpiArrayWord::as_index_t::vpi_get_value(p_vpi_value vp)
|
|
||||||
{
|
|
||||||
struct __vpiArrayWord*obj = array_var_index_from_handle(this);
|
|
||||||
assert(obj);
|
|
||||||
unsigned index = obj->get_index();
|
|
||||||
|
|
||||||
assert(vp->format == vpiIntVal);
|
|
||||||
vp->value.integer = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline __vpiArrayVthrA::__vpiArrayVthrA()
|
inline __vpiArrayVthrA::__vpiArrayVthrA()
|
||||||
{ }
|
{ }
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,73 @@ static int array_index_free_object(vpiHandle ref)
|
||||||
__vpiHandle::free_object_fun_t __vpiArrayIndex::free_object_fun(void)
|
__vpiHandle::free_object_fun_t __vpiArrayIndex::free_object_fun(void)
|
||||||
{ return &array_index_free_object; }
|
{ return &array_index_free_object; }
|
||||||
|
|
||||||
|
char* __vpiArrayWord::as_word_t::vpi_get_str(int code)
|
||||||
|
{
|
||||||
|
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
||||||
|
assert(obj);
|
||||||
|
struct __vpiArrayBase*parent = obj->get_parent();
|
||||||
|
return parent->get_word_str(obj, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __vpiArrayWord::as_word_t::vpi_get_value(p_vpi_value vp)
|
||||||
|
{
|
||||||
|
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
||||||
|
assert(obj);
|
||||||
|
struct __vpiArrayBase*parent = obj->get_parent();
|
||||||
|
return parent->get_word_value(obj, vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle __vpiArrayWord::as_word_t::vpi_put_value(p_vpi_value vp, int flags)
|
||||||
|
{
|
||||||
|
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
||||||
|
assert(obj);
|
||||||
|
struct __vpiArrayBase*parent = obj->get_parent();
|
||||||
|
parent->put_word_value(obj, vp, flags);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle __vpiArrayWord::as_word_t::vpi_handle(int code)
|
||||||
|
{
|
||||||
|
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
|
||||||
|
assert(obj);
|
||||||
|
struct __vpiArrayBase*parent = obj->get_parent();
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
|
||||||
|
case vpiIndex:
|
||||||
|
return &(obj->as_index);
|
||||||
|
|
||||||
|
case vpiLeftRange:
|
||||||
|
return parent->get_left_range();
|
||||||
|
|
||||||
|
case vpiRightRange:
|
||||||
|
return parent->get_right_range();
|
||||||
|
|
||||||
|
case vpiParent:
|
||||||
|
return dynamic_cast<vpiHandle>(parent);
|
||||||
|
|
||||||
|
case vpiScope:
|
||||||
|
return parent->get_scope();
|
||||||
|
|
||||||
|
case vpiModule:
|
||||||
|
return vpip_module(parent->get_scope());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __vpiArrayWord::as_index_t::vpi_get_value(p_vpi_value vp)
|
||||||
|
{
|
||||||
|
struct __vpiArrayWord*obj = array_var_index_from_handle(this);
|
||||||
|
assert(obj);
|
||||||
|
unsigned index = obj->get_index();
|
||||||
|
|
||||||
|
assert(vp->format == vpiIntVal);
|
||||||
|
vp->value.integer = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct __vpiArrayWord*array_var_word_from_handle(vpiHandle ref)
|
struct __vpiArrayWord*array_var_word_from_handle(vpiHandle ref)
|
||||||
{
|
{
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
|
|
@ -142,3 +209,4 @@ struct __vpiArrayWord* array_var_index_from_handle(vpiHandle ref)
|
||||||
assert(sizeof(__vpiHandle) == sizeof(__vpiArrayWord::as_word_t));
|
assert(sizeof(__vpiHandle) == sizeof(__vpiArrayWord::as_word_t));
|
||||||
return (struct __vpiArrayWord*) (ref-1);
|
return (struct __vpiArrayWord*) (ref-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -539,11 +539,16 @@ struct __vpiArrayBase {
|
||||||
__vpiArrayBase() : vals_words(NULL) {}
|
__vpiArrayBase() : vals_words(NULL) {}
|
||||||
|
|
||||||
virtual unsigned get_size(void) const = 0;
|
virtual unsigned get_size(void) const = 0;
|
||||||
virtual int get_word_size() const = 0;
|
virtual vpiHandle get_left_range() = 0;
|
||||||
virtual int get_left_range() const = 0;
|
virtual vpiHandle get_right_range() = 0;
|
||||||
virtual int get_right_range() const = 0;
|
|
||||||
virtual struct __vpiScope*get_scope() const = 0;
|
virtual struct __vpiScope*get_scope() const = 0;
|
||||||
|
|
||||||
|
virtual int get_word_size() const = 0;
|
||||||
|
virtual char*get_word_str(struct __vpiArrayWord*word, int code) = 0;
|
||||||
|
virtual void get_word_value(struct __vpiArrayWord*word, p_vpi_value vp) = 0;
|
||||||
|
virtual void put_word_value(struct __vpiArrayWord*word, p_vpi_value vp,
|
||||||
|
int flags) = 0;
|
||||||
|
|
||||||
virtual vpiHandle vpi_iterate(int code);
|
virtual vpiHandle vpi_iterate(int code);
|
||||||
virtual void make_vals_words();
|
virtual void make_vals_words();
|
||||||
|
|
||||||
|
|
@ -556,11 +561,15 @@ class __vpiDarrayVar : public __vpiBaseVar, public __vpiArrayBase {
|
||||||
|
|
||||||
int get_type_code() const { return vpiArrayVar; }
|
int get_type_code() const { return vpiArrayVar; }
|
||||||
unsigned get_size() const;
|
unsigned get_size() const;
|
||||||
int get_word_size() const { return 0; } // TODO
|
vpiHandle get_left_range() { return NULL; }
|
||||||
int get_left_range() const { return 0; }
|
vpiHandle get_right_range() { return NULL; }
|
||||||
int get_right_range() const { return 0; }
|
|
||||||
struct __vpiScope*get_scope() const { return scope_; }
|
struct __vpiScope*get_scope() const { return scope_; }
|
||||||
|
|
||||||
|
int get_word_size() const { return 0; } // TODO
|
||||||
|
char*get_word_str(struct __vpiArrayWord*word, int code) { return NULL; }
|
||||||
|
void get_word_value(struct __vpiArrayWord*word, p_vpi_value vp) {}
|
||||||
|
void put_word_value(struct __vpiArrayWord*word, p_vpi_value vp, int flags) {}
|
||||||
|
|
||||||
int vpi_get(int code);
|
int vpi_get(int code);
|
||||||
char* vpi_get_str(int code);
|
char* vpi_get_str(int code);
|
||||||
vpiHandle vpi_handle(int code);
|
vpiHandle vpi_handle(int code);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue