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:
Cary R 2009-06-16 15:14:02 -07:00 committed by Stephen Williams
parent 95ba25b9be
commit b22dc5f621
3 changed files with 50 additions and 24 deletions

View File

@ -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;

View File

@ -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]);

View File

@ -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()