From b22dc5f621da6a760ec0c2ebcded66682c899e56 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 16 Jun 2009 15:14:02 -0700 Subject: [PATCH] Fix real variable array and net array bugs. This patch fixes a number of bugs related to real variable and net arrays. Specifically the following: 1. When iterating over (scanning) a net array start at base index 0 not index 1. 2. Don't fail when iterating over (scanning) a real variable array. 3. Run the array_word_change() routine when a real variable array word is changed. This allows array ports and value change callbacks to work correctly. 4. Update the array_word_change() routine to work with real variable arrays. 5. Update the array port code to support real variable arrays. 6. find_name() needs to also iterate over net array words just like memory array words. 7. Initialize all real array words to 0.0 when the array is created. --- vvp/array.cc | 67 ++++++++++++++++++++++++++++++++----------------- vvp/vpi_priv.cc | 3 ++- vvp/vvp_net.cc | 4 +++ 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index 270544fce..f7678acca 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -598,13 +598,11 @@ static vpiHandle array_iterator_scan(vpiHandle ref, int) unsigned use_index = obj->next; obj->next += 1; - if (obj->array->nets) - return obj->array->nets[obj->next]; + if (obj->array->nets) return obj->array->nets[use_index]; - assert(obj->array->vals4); + assert(obj->array->vals4 || obj->array->valsr); - if (obj->array->vals_words == 0) - array_make_vals_words(obj->array); + if (obj->array->vals_words == 0) array_make_vals_words(obj->array); return &(obj->array->vals_words[use_index].as_word); } @@ -850,6 +848,7 @@ void array_set_word(vvp_array_t arr, unsigned address, double val) assert(arr->nets == 0); arr->valsr->set_word(address, val); + array_word_change(arr, address); } vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address) @@ -1144,9 +1143,12 @@ void vvp_fun_arrayport_sa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit case 0: // Address input addr_valid_flag = vector4_to_value(bit, addr_); - if (! addr_valid_flag) - addr_ = arr_->array_count; - vvp_send_vec4(port.ptr()->out, array_get_word(arr_,addr_), 0); + if (! addr_valid_flag) addr_ = arr_->array_count; + if (vpi_array_is_real(arr_)) { + vvp_send_real(net_->out, array_get_word_r(arr_, addr_), 0); + } else { + vvp_send_vec4(net_->out, array_get_word(arr_, addr_), 0); + } break; default: @@ -1157,11 +1159,13 @@ void vvp_fun_arrayport_sa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit void vvp_fun_arrayport_sa::check_word_change(unsigned long addr) { - if (addr != addr_) - return; + if (addr != addr_) return; - vvp_vector4_t bit = array_get_word(arr_, addr_); - vvp_send_vec4(net_->out, bit, 0); + if (vpi_array_is_real(arr_)) { + vvp_send_real(net_->out, array_get_word_r(arr_, addr_), 0); + } else { + vvp_send_vec4(net_->out, array_get_word(arr_, addr_), 0); + } } class vvp_fun_arrayport_aa : public vvp_fun_arrayport, public automatic_hooks_s { @@ -1243,10 +1247,16 @@ void vvp_fun_arrayport_aa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit case 0: // Address input addr_valid_flag = vector4_to_value(bit, *addr); - if (! addr_valid_flag) - *addr = arr_->array_count; - vvp_send_vec4(port.ptr()->out, array_get_word(arr_,*addr), - context); + if (! addr_valid_flag) *addr = arr_->array_count; + if (vpi_array_is_real(arr_)) { + vvp_send_real(port.ptr()->out, + array_get_word_r(arr_, *addr), + context); + } else { + vvp_send_vec4(port.ptr()->out, + array_get_word(arr_, *addr), + context); + } break; default: @@ -1270,8 +1280,13 @@ void vvp_fun_arrayport_aa::check_word_change(unsigned long addr) if (addr != *port_addr) return; - vvp_vector4_t bit = array_get_word(arr_, addr); - vvp_send_vec4(net_->out, bit, vthread_get_wt_context()); + if (vpi_array_is_real(arr_)) { + vvp_send_real(net_->out, array_get_word_r(arr_, addr), + vthread_get_wt_context()); + } else { + vvp_send_vec4(net_->out, array_get_word(arr_, addr), + vthread_get_wt_context()); + } } static void array_attach_port(vvp_array_t array, vvp_fun_arrayport*fun) @@ -1307,11 +1322,17 @@ void array_word_change(vvp_array_t array, unsigned long addr) } if (cur->cb_data.cb_rtn != 0) { - if (cur->cb_data.value) - vpip_vec4_get_value(array->vals4->get_word(addr), - array->vals_width, - array->signed_flag, - cur->cb_data.value); + if (cur->cb_data.value) { + if (vpi_array_is_real(array)) { + vpip_real_get_value(array->valsr->get_word(addr), + cur->cb_data.value); + } else { + vpip_vec4_get_value(array->vals4->get_word(addr), + array->vals_width, + array->signed_flag, + cur->cb_data.value); + } + } callback_execute(cur); prev = cur; diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index 82f82ae4a..74acb2c13 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -1002,7 +1002,8 @@ static vpiHandle find_name(const char *name, vpiHandle handle) if (!strcmp(name, nm)) { rtn = ref->intern[i]; break; - } else if (vpi_get(vpiType, ref->intern[i]) == vpiMemory) { + } else if (vpi_get(vpiType, ref->intern[i]) == vpiMemory || + vpi_get(vpiType, ref->intern[i]) == vpiNetArray) { /* We need to iterate on the words */ vpiHandle word_i, word_h; word_i = vpi_iterate(vpiMemoryWord, ref->intern[i]); diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index f4792eebf..825b8ed1f 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1344,6 +1344,10 @@ vvp_realarray_t::vvp_realarray_t(unsigned wor) : words_(wor) { array_ = new double[words_]; + // Real array words have a default value of zero. + for (unsigned idx = 0 ; idx < words_; idx += 1) { + array_[idx] = 0.0; + } } vvp_realarray_t::~vvp_realarray_t()