diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index a66e834bb..eb0ebb996 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -28,6 +28,8 @@ # include #endif +# include + vvp_filter_wire_base::vvp_filter_wire_base() { force_propagate_ = false; @@ -68,6 +70,19 @@ template const T*vvp_filter_wire_base::filter_mask_(const T&val, const } } +/* + * Force link/unlink uses a thunk vvp_net_t node with a vvp_fun_force + * functor to translate the net values to filter commands. The ports + * of this vvp_net_t object are use a little differently: + * + * port[3] - Point to the destination node where the forced + * filter resides. + * + * port[2] - Point to the input node that drives port[0] for use + * by the unlink method. + * + * port[0] - This is the normal input. + */ void vvp_filter_wire_base::force_link(vvp_net_t*dst, vvp_net_t*src) { assert(dst->fil == this); @@ -80,6 +95,9 @@ void vvp_filter_wire_base::force_link(vvp_net_t*dst, vvp_net_t*src) force_link_->fun = new vvp_fun_force; } + force_unlink(); + assert(force_link_->port[2] == vvp_net_ptr_t(0,0)); + // Use port[2] to hold the force source. force_link_->port[2] = vvp_net_ptr_t(src,0); @@ -842,6 +860,19 @@ vvp_fun_force::~vvp_fun_force() { } +void vvp_fun_force::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, + vvp_context_t) +{ + assert(ptr.port() == 0); + vvp_net_t*net = ptr.ptr(); + + vvp_net_t*dst = net->port[3].ptr(); + vvp_fun_signal4*sig = dynamic_cast (dst->fil); + assert(sig); + + sig->force_vec4(bit, vvp_vector2_t(vvp_vector2_t::FILL1, sig->size())); +} + void vvp_fun_force::recv_real(vvp_net_ptr_t ptr, double bit, vvp_context_t) { assert(ptr.port() == 0); diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index bf88a02aa..72215fa85 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -457,6 +457,11 @@ class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_hook * The vvp_fun_force class objects are net functors that use their input * to force the associated filter. They do not actually have an * output, they instead drive the force_* methods of the net filter. + * + * This functor is also special in that we know a priori that only + * port-0 is used, so we can use ports 1-3 for local storage. See the + * implementation of vvp_filter_wire_base::force_link in + * vvp_net_sig.cc for details. */ class vvp_fun_force : public vvp_net_fun_t { @@ -464,6 +469,8 @@ class vvp_fun_force : public vvp_net_fun_t { vvp_fun_force(); ~vvp_fun_force(); + void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit, + vvp_context_t context); void recv_real(vvp_net_ptr_t port, double bit, vvp_context_t); };