diff --git a/vvp/array.cc b/vvp/array.cc index 0d6a05bf1..7c68ce821 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -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() { } diff --git a/vvp/array_common.cc b/vvp/array_common.cc index df249a2c6..08bb11ab9 100644 --- a/vvp/array_common.cc +++ b/vvp/array_common.cc @@ -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(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); } + diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 3fb08a1a1..15efe0db8 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -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);