Ensure VPI release on net connected to island returns correct value.

This commit is contained in:
Martin Whitaker 2015-07-01 09:00:43 +01:00
parent 8d2149f5aa
commit 97c6339241
7 changed files with 31 additions and 20 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
{
}

View File

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

View File

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