From 70d2f7e3532ccc4478251d5f1beb22035ae5d06e Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 11 Jan 2010 21:59:34 +0000 Subject: [PATCH] Fix for pr2929913 (v0.9 backport). 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 577b8cec5..5bd6fc113 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 @@ -1209,9 +1209,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_; }; @@ -1297,23 +1299,36 @@ 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_)) { - vvp_send_real(net_->out, array_get_word_r(arr_, addr), - vthread_get_wt_context()); + vvp_send_real(net_->out, array_get_word_r(arr_, addr), context); } else { - vvp_send_vec4(net_->out, array_get_word(arr_, addr), - vthread_get_wt_context()); + vvp_send_vec4(net_->out, 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); + } + } +} + static void array_attach_port(vvp_array_t array, vvp_fun_arrayport*fun) { assert(fun->next_ == 0);