Fix for br1019 - allow multiple array words to be attached to a vpi callback.

Normally there is at most one signal attached to a vvp functor, but
due to port collapsing, there can be more than one. If these signals
are array words, we need to trigger vpi callbacks on all the associated
arrays when the functor value changes.

(cherry picked from commit ac87138c44)
This commit is contained in:
Martin Whitaker 2017-08-12 12:23:43 +01:00
parent 306d2fb53b
commit 8cd697fd24
2 changed files with 30 additions and 9 deletions

View File

@ -642,24 +642,37 @@ void callback_execute(struct __vpiCallback*cur)
vpi_mode_flag = save_mode;
}
/*
* Usually there is at most one array word associated with a vvp signal, but
* due to port collapsing, there may be more. Using a linked list to record
* the array words minimises memory use for the most common case (no array
* words) or next most common case (one array word).
*/
struct __vpi_array_word {
struct __vpi_array_word* next;
struct __vpiArray* array;
unsigned long word;
};
vvp_vpi_callback::vvp_vpi_callback()
{
vpi_callbacks_ = 0;
array_ = 0;
array_word_ = 0;
array_words_ = 0;
}
vvp_vpi_callback::~vvp_vpi_callback()
{
assert(vpi_callbacks_ == 0);
assert(array_ == 0);
assert(array_words_ == 0);
}
void vvp_vpi_callback::attach_as_word(vvp_array_t arr, unsigned long addr)
{
assert(array_ == 0);
array_ = arr;
array_word_ = addr;
struct __vpi_array_word*tmp = new __vpi_array_word;
tmp->array = arr;
tmp->word = addr;
tmp->next = array_words_;
array_words_ = tmp;
}
void vvp_vpi_callback::add_vpi_callback(value_callback*cb)
@ -677,6 +690,11 @@ void vvp_vpi_callback::clear_all_callbacks()
delete vpi_callbacks_;
vpi_callbacks_ = tmp;
}
while (array_words_) {
struct __vpi_array_word*tmp = array_words_->next;
delete array_words_;
array_words_ = tmp;
}
}
#endif
@ -688,7 +706,11 @@ void vvp_vpi_callback::clear_all_callbacks()
*/
void vvp_vpi_callback::run_vpi_callbacks()
{
if (array_) array_->word_change(array_word_);
struct __vpi_array_word*array_word = array_words_;
while (array_word) {
array_word->array->word_change(array_word->word);
array_word = array_word->next;
}
value_callback *next = vpi_callbacks_;
value_callback *prev = 0;

View File

@ -57,8 +57,7 @@ class vvp_vpi_callback {
private:
value_callback*vpi_callbacks_;
struct __vpiArray* array_;
unsigned long array_word_;
struct __vpi_array_word*array_words_;
};