diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index 5a99f18de..9749d20af 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -50,25 +50,25 @@ vvp_filter_wire_base::~vvp_filter_wire_base() { } -const vvp_vector4_t* vvp_filter_wire_base::filter_vec4(const vvp_vector4_t&val) +template const T*vvp_filter_wire_base::filter_mask_(const T&val, const T&force, T&filter) { if (force_mask_.size()) { bool propagate_flag = force_propagate_; force_propagate_ = false; assert(val.size() == force_mask_.size()); - assert(val.size() == force4_.size()); + assert(val.size() == force.size()); - filter4_ = val; + filter = val; for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { if (force_mask_.value(idx)) - filter4_.set_bit(idx, force4_.value(idx)); + filter.set_bit(idx, force.value(idx)); else propagate_flag = true; } if (propagate_flag) { run_vpi_callbacks(); - return &filter4_; + return &filter; } else { return 0; } @@ -79,83 +79,119 @@ const vvp_vector4_t* vvp_filter_wire_base::filter_vec4(const vvp_vector4_t&val) } } -const vvp_vector8_t* vvp_filter_wire_base::filter_vec8(const vvp_vector8_t&val) -{ - if (force_mask_.size()) { - bool propagate_flag = force_propagate_; - force_propagate_ = false; - assert(val.size() == force_mask_.size()); - assert(val.size() == force8_.size()); - - filter8_ = val; - for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { - if (force_mask_.value(idx)) - filter8_.set_bit(idx, force8_.value(idx)); - else - propagate_flag = true; - } - - if (propagate_flag) { - run_vpi_callbacks(); - return&filter8_; - } else { - return 0; - } - } else { - run_vpi_callbacks(); - return &val; - } -} - -bool vvp_filter_wire_base::filter_real(double&val) +template bool vvp_filter_wire_base::filter_mask_(T&val) { run_vpi_callbacks(); return true; } -bool vvp_filter_wire_base::filter_long(long&) +const vvp_vector4_t* vvp_fun_signal4::filter_vec4(const vvp_vector4_t&val) { - run_vpi_callbacks(); - return true; + return filter_mask_(val, force4_, filter4_); } -void vvp_filter_wire_base::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) +const vvp_vector8_t* vvp_fun_signal8::filter_vec8(const vvp_vector8_t&val) { - if (force_mask_.size() == 0) - force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size()); + return filter_mask_(val, force8_, filter8_); +} + +bool vvp_fun_signal_real::filter_real(double&val) +{ + return filter_mask_(val); +} + +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) +{ + force_mask(mask); + if (force4_.size() == 0) force4_ = val; - assert(force_mask_.size() == mask.size()); for (unsigned idx = 0; idx < mask.size() ; idx += 1) { if (mask.value(idx) == 0) continue; - force_mask_.set_bit(idx, 1); force4_.set_bit(idx, val.value(idx)); - force_propagate_ = true; } } -void vvp_filter_wire_base::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) +void vvp_fun_signal8::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) { - if (force_mask_.size() == 0) - force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size()); + force_mask(mask); + if (force8_.size() == 0) force8_ = val; - assert(force_mask_.size() == mask.size()); for (unsigned idx = 0; idx < mask.size() ; idx += 1) { if (mask.value(idx) == 0) continue; - force_mask_.set_bit(idx, 1); force8_.set_bit(idx, val.value(idx)); - force_propagate_ = true; } } -void vvp_filter_wire_base::force_real(double val, vvp_vector2_t mask) +void vvp_fun_signal_real::force_real(double val, vvp_vector2_t mask) +{ + force_mask(mask); + force_real_ = val; +} + +vvp_bit4_t vvp_fun_signal4::filtered_value(const vvp_vector4_t&val, unsigned idx) const +{ + if (test_force_mask(idx)) + return force4_.value(idx); + else + return val.value(idx); +} + +vvp_scalar_t vvp_fun_signal8::filtered_value(const vvp_vector8_t&val, unsigned idx) const +{ + if (test_force_mask(idx)) + return force8_.value(idx); + else + return val.value(idx); +} + +const vvp_vector4_t& vvp_fun_signal4::filtered_vec4(const vvp_vector4_t&val) const +{ + if (test_force_mask_is_zero()) + return val; + + filter4_ = val; + for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { + if (test_force_mask(idx)) + filter4_.set_bit(idx, force4_.value(idx)); + } + return filter4_; +} + +const vvp_vector8_t& vvp_fun_signal8::filtered_vec8(const vvp_vector8_t&val) const +{ + if (test_force_mask_is_zero()) + return val; + + filter8_ = val; + for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { + if (test_force_mask(idx)) + filter8_.set_bit(idx, force8_.value(idx)); + } + return filter8_; +} + +double vvp_fun_signal_real::filtered_real(double val) const +{ + if (test_force_mask_is_zero()) + return val; + + return force_real_; +} + +void vvp_filter_wire_base::force_mask(vvp_vector2_t mask) { if (force_mask_.size() == 0) force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size()); @@ -168,64 +204,6 @@ void vvp_filter_wire_base::force_real(double val, vvp_vector2_t mask) force_mask_.set_bit(idx, 1); force_propagate_ = true; } - - force_real_ = val; -} - -vvp_bit4_t vvp_filter_wire_base::filtered_value(const vvp_vector4_t&val, unsigned idx) const -{ - if (force_mask_.size() == 0) - return val.value(idx); - if (force_mask_.value(idx)) - return force4_.value(idx); - - return val.value(idx); -} - -vvp_scalar_t vvp_filter_wire_base::filtered_value(const vvp_vector8_t&val, unsigned idx) const -{ - if (force_mask_.size() == 0) - return val.value(idx); - if (force_mask_.value(idx)) - return force8_.value(idx); - - return val.value(idx); -} - -const vvp_vector4_t& vvp_filter_wire_base::filtered_vec4(const vvp_vector4_t&val) const -{ - if (force_mask_.size() == 0) - return val; - - filter4_ = val; - for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { - if (force_mask_.value(idx)) - filter4_.set_bit(idx, force4_.value(idx)); - } - return filter4_; -} - -const vvp_vector8_t& vvp_filter_wire_base::filtered_vec8(const vvp_vector8_t&val) const -{ - if (force_mask_.size() == 0) - return val; - - filter8_ = val; - for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { - if (force_mask_.value(idx)) - filter8_.set_bit(idx, force8_.value(idx)); - } - return filter8_; -} - -double vvp_filter_wire_base::filtered_real(double val) const -{ - if (force_mask_.size() == 0) - return val; - if (force_mask_.value(0) == 0) - return val; - - return force_real_; } void vvp_filter_wire_base::release_mask(vvp_vector2_t mask) diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index 049bf9a9b..82d1f998f 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -134,11 +134,8 @@ class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback { vvp_filter_wire_base(); ~vvp_filter_wire_base(); - // These are the virtual methods that we implement to perform - // the wire-style filtering. - const vvp_vector4_t* filter_vec4(const vvp_vector4_t&val); - const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val); - bool filter_real(double&val); + // The filter_long is a placeholder here. This should be moved + // to a vvp_fun_signal_long when such a thing is implemented. bool filter_long(long&val); public: @@ -150,40 +147,49 @@ class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback { // filtering results using the filtered_* methods. The // release_mask() method releases bits of the vector. - // Enable filter 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); - - // Test the value against the filter. - vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const; - vvp_scalar_t filtered_value(const vvp_vector8_t&val, unsigned idx) const; - - const vvp_vector4_t& filtered_vec4(const vvp_vector4_t&val) const; - const vvp_vector8_t& filtered_vec8(const vvp_vector8_t&val) const; - double filtered_real(double val) const; - - // Release the force on the bits set in the mask. - void release_mask(vvp_vector2_t mask); - virtual void release(vvp_net_ptr_t ptr, bool net) =0; virtual void release_pv(vvp_net_ptr_t ptr, bool net, unsigned base, unsigned wid) =0; + protected: + // Set bits of the filter force mask + void force_mask(vvp_vector2_t mask); + // Release the force on the bits set in the mask. + void release_mask(vvp_vector2_t mask); + // Test bits of the filter force mask; + bool test_force_mask(unsigned bit) const; + bool test_force_mask_is_zero() const; + + template const T*filter_mask_(const T&val, const T&force, T&buf); + template bool filter_mask_(T&val); + private: // Forced value vvp_vector2_t force_mask_; - vvp_vector4_t force4_; - vvp_vector8_t force8_; - double force_real_; // True if the next filter must propagate. Need this to allow // the forced value to get through. bool force_propagate_; - // This is used as a static return value. - mutable vvp_vector4_t filter4_; - mutable vvp_vector8_t filter8_; }; +inline bool vvp_filter_wire_base::test_force_mask(unsigned bit) const +{ + if (bit >= force_mask_.size()) + return false; + if (force_mask_.value(bit)) + return true; + else + return false; +} + +inline bool vvp_filter_wire_base::test_force_mask_is_zero(void) const +{ + if (force_mask_.size() == 0) + return true; + if (force_mask_.is_zero()) + return true; + return false; +} + class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_filter_wire_base { public: @@ -231,6 +237,17 @@ class vvp_fun_signal4 : public vvp_fun_signal_vec { void get_value(struct t_vpi_value*value); + public: + // Enable filter force. + void force_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; + const vvp_vector4_t& filtered_vec4(const vvp_vector4_t&val) const; + + private: + vvp_vector4_t force4_; + mutable vvp_vector4_t filter4_; }; /* @@ -336,11 +353,21 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec { void get_value(struct t_vpi_value*value); + + public: + // Enable filter force. + void force_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 force_; + vvp_vector8_t force8_; + mutable vvp_vector8_t filter8_; }; class vvp_fun_signal_real : public vvp_fun_signal_base { @@ -352,6 +379,16 @@ class vvp_fun_signal_real : public vvp_fun_signal_base { virtual double real_value() const = 0; void get_value(struct t_vpi_value*value); + + public: + // Enable filter force. + void force_real(double val, vvp_vector2_t mask); + bool filter_real(double&val); + // Test the value against the filter. + double filtered_real(double val) const; + + private: + double force_real_; }; /*