Release filter accounts for net vs variable.

When releasing a net, the release needs to propagate the driven
value. When releasing a variable, the driven value must be set
to the previously forced value.
This commit is contained in:
Stephen Williams 2009-09-04 21:37:31 -07:00
parent 3de02ede8b
commit 5be1b25726
5 changed files with 24 additions and 15 deletions

View File

@ -762,7 +762,7 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags)
assert(sig);
vvp_net_ptr_t ptr(rfp->node, 0);
sig->release(ptr);
sig->release(ptr, false);
return ref;
}

View File

@ -3925,7 +3925,7 @@ static bool do_release_vec(vthread_t thr, vvp_code_t cp, bool net_flag)
/* Do we release all or part of the net? */
vvp_net_ptr_t ptr (net, 0);
if (full_sig) {
net->fil->release(ptr);
net->fil->release(ptr, net_flag);
} else {
net->fil->release_pv(ptr, base, width);
}
@ -3955,7 +3955,7 @@ bool of_RELEASE_WR(vthread_t thr, vvp_code_t cp)
// Send a command to this signal to unforce itself.
vvp_net_ptr_t ptr (net, 0);
net->fil->release(ptr);
net->fil->release(ptr, type==0);
return true;
}

View File

@ -1133,7 +1133,7 @@ class vvp_net_fil_t : public vvp_vpi_callback {
virtual bool filter_real(double&val);
virtual bool filter_long(long&val);
virtual void release(vvp_net_ptr_t ptr) =0;
virtual void release(vvp_net_ptr_t ptr, bool net_flag) =0;
virtual void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid) =0;
// The %force/link instruction needs a place to write the

View File

@ -482,7 +482,7 @@ vvp_fun_signal_real_sa::vvp_fun_signal_real_sa()
double vvp_fun_signal_real_sa::real_value() const
{
assert(0 /* XXXX return filtered_real(bits_); */);
assert(0);
}
void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit,
@ -651,12 +651,15 @@ void vvp_wire_vec4::force_fil_real(double val, vvp_vector2_t mask)
assert(0);
}
void vvp_wire_vec4::release(vvp_net_ptr_t ptr)
void vvp_wire_vec4::release(vvp_net_ptr_t ptr, bool net_flag)
{
// Wires revert to their unforced value after release.
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
release_mask(mask);
ptr.ptr()->send_vec4(bits4_, 0);
if (net_flag)
ptr.ptr()->send_vec4(bits4_, 0);
else
ptr.ptr()->fun->recv_vec4(ptr, force4_, 0);
}
void vvp_wire_vec4::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid)
@ -748,12 +751,15 @@ void vvp_wire_vec8::force_fil_real(double val, vvp_vector2_t mask)
assert(0);
}
void vvp_wire_vec8::release(vvp_net_ptr_t ptr)
void vvp_wire_vec8::release(vvp_net_ptr_t ptr, bool net_flag)
{
// Wires revert to their unforced value after release.
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
release_mask(mask);
ptr.ptr()->send_vec8(bits8_);
if (net_flag)
ptr.ptr()->send_vec8(bits8_);
else
ptr.ptr()->fun->recv_vec8(ptr, force8_);
}
void vvp_wire_vec8::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid)
@ -841,12 +847,15 @@ void vvp_wire_real::force_fil_real(double val, vvp_vector2_t mask)
force_ = val;
}
void vvp_wire_real::release(vvp_net_ptr_t ptr)
void vvp_wire_real::release(vvp_net_ptr_t ptr, bool net_flag)
{
// Wires revert to their unforced value after release.
vvp_vector2_t mask (vvp_vector2_t::FILL1, 1);
release_mask(mask);
ptr.ptr()->send_real(bit_, 0);
if (net_flag)
ptr.ptr()->send_real(bit_, 0);
else
ptr.ptr()->fun->recv_real(ptr, force_, 0);
}
void vvp_wire_real::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid)

View File

@ -303,7 +303,7 @@ class vvp_wire_vec4 : public vvp_wire_base {
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask);
void release(vvp_net_ptr_t ptr);
void release(vvp_net_ptr_t ptr, bool net_flag);
void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid);
// Implementation of vvp_signal_value methods
@ -337,7 +337,7 @@ class vvp_wire_vec8 : public vvp_wire_base {
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask);
void release(vvp_net_ptr_t ptr);
void release(vvp_net_ptr_t ptr, bool net_flag);
void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid);
// Implementation of vvp_signal_value methods
@ -360,7 +360,7 @@ class vvp_wire_vec8 : public vvp_wire_base {
class vvp_wire_real : public vvp_wire_base {
public:
explicit vvp_wire_real();
explicit vvp_wire_real(void);
// The main filter behavior for this class
bool filter_real(double&bit);
@ -372,7 +372,7 @@ class vvp_wire_real : public vvp_wire_base {
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask);
void release(vvp_net_ptr_t ptr);
void release(vvp_net_ptr_t ptr, bool net_flag);
void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid);
// Implementation of vvp_signal_value methods