vvp: Further extraction of common code pieces from ArrayBase.

This commit is contained in:
Maciej Suminski 2014-11-19 18:32:23 +01:00
parent 48d3701c02
commit ea7fa24f9e
3 changed files with 174 additions and 138 deletions

View File

@ -85,11 +85,15 @@ vvp_array_t array_find(const char*label)
struct __vpiArray : public __vpiArrayBase, public __vpiHandle {
int get_type_code(void) const { return vpiMemory; }
unsigned get_size() const { return array_count; }
int get_word_size() const;
int get_left_range() const { assert(nets == 0); return msb.get_value(); }
int get_right_range() const { assert(nets == 0); return lsb.get_value(); }
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);
int vpi_get(int code);
char* vpi_get_str(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.
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.
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;
}
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.
if (arr->vals4 != 0) // A bit based variable/register array.
@ -303,6 +307,79 @@ int __vpiArray::get_word_size() const
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)
{
switch (code) {
@ -377,6 +454,7 @@ int __vpiArrayWord::as_word_t::vpi_get(int code)
struct __vpiArrayWord*obj = array_var_word_from_handle(this);
assert(obj);
struct __vpiArrayBase*parent = obj->get_parent();
t_vpi_value val;
switch (code) {
case vpiLineNo:
@ -386,10 +464,16 @@ int __vpiArrayWord::as_word_t::vpi_get(int code)
return parent->get_word_size();
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:
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:
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()
{ }

View File

@ -119,6 +119,73 @@ static int array_index_free_object(vpiHandle ref)
__vpiHandle::free_object_fun_t __vpiArrayIndex::free_object_fun(void)
{ 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)
{
if (ref == 0)
@ -142,3 +209,4 @@ struct __vpiArrayWord* array_var_index_from_handle(vpiHandle ref)
assert(sizeof(__vpiHandle) == sizeof(__vpiArrayWord::as_word_t));
return (struct __vpiArrayWord*) (ref-1);
}

View File

@ -539,11 +539,16 @@ struct __vpiArrayBase {
__vpiArrayBase() : vals_words(NULL) {}
virtual unsigned get_size(void) const = 0;
virtual int get_word_size() const = 0;
virtual int get_left_range() const = 0;
virtual int get_right_range() const = 0;
virtual vpiHandle get_left_range() = 0;
virtual vpiHandle get_right_range() = 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 void make_vals_words();
@ -556,11 +561,15 @@ class __vpiDarrayVar : public __vpiBaseVar, public __vpiArrayBase {
int get_type_code() const { return vpiArrayVar; }
unsigned get_size() const;
int get_word_size() const { return 0; } // TODO
int get_left_range() const { return 0; }
int get_right_range() const { return 0; }
vpiHandle get_left_range() { return NULL; }
vpiHandle get_right_range() { return NULL; }
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);
char* vpi_get_str(int code);
vpiHandle vpi_handle(int code);