From d497b1a694c2a96b9acc2af1f20c443a7bea66bb Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 11 Jan 2010 21:36:22 +0000 Subject: [PATCH] Fix for pr2929913. After changing an array word, vvp propagates the change to every port attached to the array. The code did not properly handle the case of an array port declared in an automatic scope with an associated array declared in a static scope. --- vvp/array.cc | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index c7695bd54..1084aad27 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -1236,9 +1236,11 @@ class vvp_fun_arrayport_aa : public vvp_fun_arrayport, public automatic_hooks_s void check_word_change(unsigned long addr); void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit, - vvp_context_t); + vvp_context_t context); private: + void check_word_change_(unsigned long addr, vvp_context_t context); + struct __vpiScope*context_scope_; unsigned context_idx_; }; @@ -1322,20 +1324,33 @@ void vvp_fun_arrayport_aa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit } } -void vvp_fun_arrayport_aa::check_word_change(unsigned long addr) +void vvp_fun_arrayport_aa::check_word_change_(unsigned long addr, + vvp_context_t context) { unsigned long*port_addr = static_cast - (vthread_get_wt_context_item(context_idx_)); + (vvp_get_context_item(context, context_idx_)); if (addr != *port_addr) return; if (vpi_array_is_real(arr_)) { - net_->send_real(array_get_word_r(arr_, addr), - vthread_get_wt_context()); + net_->send_real(array_get_word_r(arr_, addr), context); } else { - net_->send_vec4(array_get_word(arr_, addr), - vthread_get_wt_context()); + net_->send_vec4(array_get_word(arr_, addr), context); + } +} + +void vvp_fun_arrayport_aa::check_word_change(unsigned long addr) +{ + if (arr_->scope->is_automatic) { + assert(vthread_get_wt_context()); + check_word_change_(addr, vthread_get_wt_context()); + } else { + vvp_context_t context = context_scope_->live_contexts; + while (context) { + check_word_change_(addr, context); + context = vvp_get_next_context(context); + } } }