diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 0b6de4289..30a023a98 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2347,7 +2347,8 @@ bool of_FORCE_V(vthread_t thr, vvp_code_t cp) if (value.size() != sig->size()) value = coerce_to_width(value, sig->size()); - sig->force_vec4(value, vvp_vector2_t(vvp_vector2_t::FILL1, sig->size())); + + net->force_vec4(value, vvp_vector2_t(vvp_vector2_t::FILL1, sig->size())); return true; } @@ -2357,10 +2358,7 @@ bool of_FORCE_WR(vthread_t thr, vvp_code_t cp) vvp_net_t*net = cp->net; double value = thr->words[cp->bit_idx[0]].w_real; - vvp_fun_signal_real*sig = reinterpret_cast(net->fun); - assert(sig); - - sig->force_real(value, vvp_vector2_t(vvp_vector2_t::FILL1, 1)); + net->force_real(value, vvp_vector2_t(vvp_vector2_t::FILL1, 1)); return true; } @@ -2400,7 +2398,7 @@ bool of_FORCE_X0(vthread_t thr, vvp_code_t cp) vvp_vector4_t value(sig->size(), BIT4_Z); value.set_vec(index, vector); - sig->force_vec4(value, mask); + net->force_vec4(value, mask); return true; } @@ -2421,7 +2419,7 @@ bool of_FORCE_X0(vthread_t thr, vvp_code_t cp) vvp_vector4_t val4(sig->size(), BIT4_Z); val4.set_vec(index, vec4); - sig->force_vec8(vvp_vector8_t(val4,6,6), mask); + net->force_vec8(vvp_vector8_t(val4,6,6), mask); return true; } diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index a433747bf..5f47ad4e1 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -1001,6 +1001,18 @@ class vvp_net_t { vvp_context_t context); void send_vec8_pv(const vvp_vector8_t&val, unsigned base, unsigned wid, unsigned vwid); + + + public: // Methods to arrange for the output of this net to be forced. + + // The intent is that all efforts at force are directed to + // operate only on the vvp_net_t whose output is to be + // forced. These methods then communicate the force to the + // attached filter to set up the actual force. + void force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); + void force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); + void force_real(double val, vvp_vector2_t mask); + private: vvp_net_ptr_t out_; diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index eb0ebb996..3c1669eeb 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -141,22 +141,32 @@ bool vvp_filter_wire_base::filter_long(long&val) return filter_mask_(val); } -void vvp_fun_signal4::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) +void vvp_fun_signal4::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) { force_mask(mask); - if (force4_.size() == 0) + if (force4_.size() == 0) { force4_ = val; + } else { + for (unsigned idx = 0; idx < mask.size() ; idx += 1) { + if (mask.value(idx) == 0) + continue; - for (unsigned idx = 0; idx < mask.size() ; idx += 1) { - if (mask.value(idx) == 0) - continue; - - force4_.set_bit(idx, val.value(idx)); + force4_.set_bit(idx, val.value(idx)); + } } } -void vvp_fun_signal8::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) +void vvp_net_t::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) +{ + vvp_fun_signal4*sig = dynamic_cast (fil); + assert(sig); + + sig->force_fil_vec4(val, mask); + send_vec4(val, 0); +} + +void vvp_fun_signal8::force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) { force_mask(mask); @@ -171,12 +181,30 @@ void vvp_fun_signal8::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) } } -void vvp_fun_signal_real::force_real(double val, vvp_vector2_t mask) +void vvp_net_t::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) +{ + vvp_fun_signal8*sig = dynamic_cast (fil); + assert(sig); + + sig->force_fil_vec8(val, mask); + send_vec8(val); +} + +void vvp_fun_signal_real::force_fil_real(double val, vvp_vector2_t mask) { force_mask(mask); force_real_ = val; } +void vvp_net_t::force_real(double val, vvp_vector2_t mask) +{ + vvp_fun_signal_real*sig = dynamic_cast (fil); + assert(sig); + + sig->force_fil_real(val, mask); + send_real(val, 0); +} + vvp_bit4_t vvp_fun_signal4::filtered_value(const vvp_vector4_t&val, unsigned idx) const { if (test_force_mask(idx)) @@ -296,7 +324,7 @@ void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, if (needs_init_ || !bits4_.eeq(bit)) { bits4_ = bit; needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_, 0); } } else { bool changed = false; @@ -309,7 +337,7 @@ void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, } if (changed) { needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_, 0); } } break; @@ -317,7 +345,7 @@ void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, case 1: // Continuous assign value bits4_ = bit; assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL1, size()); - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_, 0); break; default: @@ -347,7 +375,7 @@ void vvp_fun_signal4_sa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit bits4_.set_bit(base+idx, bit.value(idx)); } needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_,0); } else { bool changed = false; assert(bits4_.size() == assign_mask_.size()); @@ -359,7 +387,7 @@ void vvp_fun_signal4_sa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit } if (changed) { needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_,0); } } break; @@ -373,7 +401,7 @@ void vvp_fun_signal4_sa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit bits4_.set_bit(base+idx, bit.value(idx)); assign_mask_.set_bit(base+idx, 1); } - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_,0); break; default: @@ -389,12 +417,6 @@ void vvp_fun_signal4_sa::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit recv_vec4_pv(ptr, reduce4(bit), base, wid, vwid, 0); } -void vvp_fun_signal4_sa::calculate_output_(vvp_net_ptr_t ptr) -{ - ptr.ptr()->send_vec4(bits4_, 0); -} - - void vvp_fun_signal_base::deassign() { continuous_assign_active_ = false; @@ -438,7 +460,7 @@ void vvp_fun_signal4_sa::release_pv(vvp_net_ptr_t ptr, bool net, if (net) { release_mask(mask); - calculate_output_(ptr); + ptr.ptr()->send_vec4(bits4_,0); } else { bits4_ = filtered_vec4(bits4_); release_mask(mask); @@ -592,7 +614,7 @@ void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit) if (needs_init_ || !bits8_.eeq(bit)) { bits8_ = bit; needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec8(bits8_); } break; @@ -630,7 +652,7 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit, bits8_.set_bit(base+idx, bit.value(idx)); } needs_init_ = false; - calculate_output_(ptr); + ptr.ptr()->send_vec8(bits8_); break; case 1: // Continuous assign value @@ -639,7 +661,7 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit, * strength aware. */ assert(0); break; - +#if 0 case 2: // Force value { vvp_vector2_t mask (vvp_vector2_t::FILL0, vwid); vvp_vector8_t vec (vvp_vector4_t(vwid, BIT4_Z),6,6); @@ -651,7 +673,7 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit, calculate_output_(ptr); break; } - +#endif default: fprintf(stderr, "Unsupported port type %d.\n", ptr.port()); assert(0); @@ -659,11 +681,6 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit, } } -void vvp_fun_signal8::calculate_output_(vvp_net_ptr_t ptr) -{ - ptr.ptr()->send_vec8(bits8_); -} - void vvp_fun_signal8::release(vvp_net_ptr_t ptr, bool net) { vvp_vector2_t mask (vvp_vector2_t::FILL1, bits8_.size()); @@ -691,7 +708,7 @@ void vvp_fun_signal8::release_pv(vvp_net_ptr_t ptr, bool net, if (net) { release_mask(mask); - calculate_output_(ptr); + ptr.ptr()->send_vec8(bits8_); } else { bits8_ = filtered_vec8(bits8_); release_mask(mask); @@ -870,17 +887,13 @@ void vvp_fun_force::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, vvp_fun_signal4*sig = dynamic_cast (dst->fil); assert(sig); - sig->force_vec4(bit, vvp_vector2_t(vvp_vector2_t::FILL1, sig->size())); + dst->force_vec4(coerce_to_width(bit, sig->size()), 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); vvp_net_t*net = ptr.ptr(); - vvp_net_t*dst = net->port[3].ptr(); - vvp_fun_signal_real*sig = dynamic_cast (dst->fil); - assert(sig); - - sig->force_real(bit, vvp_vector2_t(vvp_vector2_t::FILL1, 1)); + dst->force_real(bit, vvp_vector2_t(vvp_vector2_t::FILL1, 1)); } diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index 72215fa85..7aa72a1d4 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -247,7 +247,7 @@ class vvp_fun_signal4 : public vvp_fun_signal_vec { public: // Enable filter force. - void force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); + void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); const vvp_vector4_t* filter_vec4(const vvp_vector4_t&val); // Test the value against the filter. vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const; @@ -289,8 +289,6 @@ class vvp_fun_signal4_sa : public vvp_fun_signal4 { unsigned base, unsigned wid); private: - void calculate_output_(vvp_net_ptr_t ptr); - vvp_vector4_t bits4_; }; @@ -364,15 +362,13 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec { public: // Enable filter force. - void force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); + void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val); // Test the value against the filter. vvp_scalar_t filtered_value(const vvp_vector8_t&val, unsigned idx) const; const vvp_vector8_t& filtered_vec8(const vvp_vector8_t&val) const; private: - void calculate_output_(vvp_net_ptr_t ptr); - vvp_vector8_t bits8_; vvp_vector8_t force8_; mutable vvp_vector8_t filter8_; @@ -390,7 +386,7 @@ class vvp_fun_signal_real : public vvp_fun_signal_base { public: // Enable filter force. - void force_real(double val, vvp_vector2_t mask); + void force_fil_real(double val, vvp_vector2_t mask); bool filter_real(double&val); // Test the value against the filter. double filtered_real(double val) const;