From 97c6339241d6a0667ec4d57b9d7b275699e8e110 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Wed, 1 Jul 2015 09:00:43 +0100 Subject: [PATCH] Ensure VPI release on net connected to island returns correct value. --- vvp/vpi_signal.cc | 14 ++++++++++---- vvp/vthread.cc | 2 +- vvp/vvp_island.cc | 9 ++++++--- vvp/vvp_island.h | 8 +++++--- vvp/vvp_net.cc | 4 ++-- vvp/vvp_net.h | 6 +++--- vvp/vvp_net_sig.cc | 8 ++++---- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index c0f2f07b5..04e677430 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -809,12 +809,15 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags) /* If this is a release, then we are not really putting a value. Instead, issue a release "command" to the signal - node to cause it to release a forced value. */ + node to cause it to release a forced value. Note that + if this net is attached to an island, we need to rerun + the calculations immediately so we can return the + released value. */ if (flags == vpiReleaseFlag) { assert(rfp->node->fil); rfp->node->fil->force_unlink(); rfp->node->fil->release(dest, net_flag); - rfp->node->fun->force_flag(); + rfp->node->fun->force_flag(true); signal_get_value(ref, vp); return ref; } @@ -1342,7 +1345,10 @@ static vpiHandle PV_put_value(vpiHandle ref, p_vpi_value vp, int flags) /* If this is a release, then we are not really putting a value. Instead, issue a release "command" to the signal - node to cause it to release a forced value. */ + node to cause it to release a forced value. Note that + if this net is attached to an island, we need to rerun + the calculations immediately so we can return the + released value.*/ if (flags == vpiReleaseFlag) { assert(rfp->net->fil); // XXXX Can't really do this if this is a partial release? @@ -1352,7 +1358,7 @@ static vpiHandle PV_put_value(vpiHandle ref, p_vpi_value vp, int flags) } else { rfp->net->fil->release_pv(dest, base, width, net_flag); } - rfp->net->fun->force_flag(); + rfp->net->fun->force_flag(true); PV_get_value(ref, vp); return ref; } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 946eac9a3..8a9eb8254 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -4802,7 +4802,7 @@ static bool do_release_vec(vvp_code_t cp, bool net_flag) } else { net->fil->release_pv(ptr, base, width, net_flag); } - net->fun->force_flag(); + net->fun->force_flag(false); return true; } diff --git a/vvp/vvp_island.cc b/vvp/vvp_island.cc index 90574e477..43d981f3d 100644 --- a/vvp/vvp_island.cc +++ b/vvp/vvp_island.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010,2012 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008-2015 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 @@ -217,9 +217,12 @@ void vvp_island_port::recv_vec8_pv(vvp_net_ptr_t, const vvp_vector8_t&bit, island_->flag_island(); } -void vvp_island_port::force_flag(void) +void vvp_island_port::force_flag(bool run_now) { - island_->flag_island(); + if (run_now) + island_->run_island(); + else + island_->flag_island(); } vvp_island_branch::~vvp_island_branch() diff --git a/vvp/vvp_island.h b/vvp/vvp_island.h index 46d8fcedc..1c5c7f3c6 100644 --- a/vvp/vvp_island.h +++ b/vvp/vvp_island.h @@ -1,7 +1,7 @@ #ifndef IVL_vvp_island_H #define IVL_vvp_island_H /* - * Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008-2015 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 @@ -137,8 +137,10 @@ class vvp_island_port : public vvp_net_fun_t { // This is painful, but necessary. If the island is connected // to a forced net, we need to rerun the calculations whenever - // a force/release happens to the net. - virtual void force_flag(void); + // a force/release happens to the net. If run_now is true, we + // rerun immediately, otherwise we schedule it for the end of + // the current time slot. + virtual void force_flag(bool run_now); public: vvp_vector8_t invalue; diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 380d4786b..1cdca15aa 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2004-2015 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 @@ -3305,7 +3305,7 @@ void vvp_net_fun_t::recv_object(vvp_net_ptr_t, vvp_object_t, vvp_context_t) assert(0); } -void vvp_net_fun_t::force_flag(void) +void vvp_net_fun_t::force_flag(bool) { } diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 6e89a1850..ddc0f0164 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -1,7 +1,7 @@ #ifndef IVL_vvp_net_H #define IVL_vvp_net_H /* - * Copyright (c) 2004-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2004-2015 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 @@ -1221,11 +1221,11 @@ class vvp_net_fun_t { virtual void recv_long_pv(vvp_net_ptr_t port, long bit, unsigned base, unsigned wid); - // This method is called when the net it forced or + // This method is called when the net is forced or // released. This is very rarely needed; island ports use it // to know that the net is being forced and that it needs to // do something about it. - virtual void force_flag(void); + virtual void force_flag(bool run_now); public: // These objects are only permallocated. static void* operator new(std::size_t size) { return heap_.alloc(size); } diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index 82c570df5..fc1bd122e 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2004-2015 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 @@ -121,7 +121,7 @@ void vvp_net_t::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) { assert(fil); fil->force_fil_vec4(val, mask); - fun->force_flag(); + fun->force_flag(false); vvp_send_vec4(out_, val, 0); } @@ -129,7 +129,7 @@ void vvp_net_t::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) { assert(fil); fil->force_fil_vec8(val, mask); - fun->force_flag(); + fun->force_flag(false); vvp_send_vec8(out_, val); } @@ -137,7 +137,7 @@ void vvp_net_t::force_real(double val, vvp_vector2_t mask) { assert(fil); fil->force_fil_real(val, mask); - fun->force_flag(); + fun->force_flag(false); vvp_send_real(out_, val, 0); }