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.
This commit is contained in:
parent
95ba25b9be
commit
b22dc5f621
67
vvp/array.cc
67
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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue