diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index ab122c81a..829a7a537 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -504,11 +504,21 @@ void callback_execute(struct __vpiCallback*cur) vvp_vpi_callback::vvp_vpi_callback() { vpi_callbacks_ = 0; + array_ = 0; + array_word_ = 0; } vvp_vpi_callback::~vvp_vpi_callback() { assert(vpi_callbacks_ == 0); + assert(array_ == 0); +} + +void vvp_vpi_callback::attach_as_word(vvp_array_t arr, unsigned long addr) +{ + assert(array_ == 0); + array_ = arr; + array_word_ = addr; } void vvp_vpi_callback::add_vpi_callback(__vpiCallback*cb) @@ -536,6 +546,8 @@ void vvp_vpi_callback::clear_all_callbacks() */ void vvp_vpi_callback::run_vpi_callbacks() { + if (array_) array_word_change(array_, array_word_); + struct __vpiCallback *next = vpi_callbacks_; struct __vpiCallback *prev = 0; @@ -565,31 +577,6 @@ void vvp_vpi_callback::run_vpi_callbacks() } } -vvp_vpi_callback_wordable::vvp_vpi_callback_wordable() -{ - array_ = 0; - array_word_ = 0; -} - -vvp_vpi_callback_wordable::~vvp_vpi_callback_wordable() -{ - assert(array_ == 0); -} - -void vvp_vpi_callback_wordable::run_vpi_callbacks() -{ - if (array_) array_word_change(array_, array_word_); - - vvp_vpi_callback::run_vpi_callbacks(); -} - -void vvp_vpi_callback_wordable::attach_as_word(vvp_array_t arr, unsigned long addr) -{ - assert(array_ == 0); - array_ = arr; - array_word_ = addr; -} - void vvp_fun_signal4::get_value(struct t_vpi_value*vp) { switch (vp->format) { diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 27b39e96e..356d8fc73 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -194,6 +194,34 @@ void vvp_net_fun_t::operator delete(void*) assert(0); } +vvp_net_fil_t::vvp_net_fil_t() +{ +} + +vvp_net_fil_t::~vvp_net_fil_t() +{ +} + +bool vvp_net_fil_t::filter_vec4(const vvp_vector4_t&) +{ + return true; +} + +bool vvp_net_fil_t::filter_vec8(const vvp_vector8_t&) +{ + return true; +} + +bool vvp_net_fil_t::filter_real(double) +{ + return true; +} + +bool vvp_net_fil_t::filter_long(long) +{ + return true; +} + /* *** BIT operations *** */ vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c) { diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 808b61b52..75ca1f98d 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -1187,42 +1187,6 @@ class vvp_fun_extend_signed : public vvp_net_fun_t { unsigned width_; }; -/* -* Things derived from vvp_vpi_callback may also be array'ed, so it -* includes some members that arrays use. -*/ -class vvp_vpi_callback { - - public: - vvp_vpi_callback(); - virtual ~vvp_vpi_callback(); - - virtual void run_vpi_callbacks(); - void add_vpi_callback(struct __vpiCallback*); -#ifdef CHECK_WITH_VALGRIND - /* This has only been tested at EOS. */ - void clear_all_callbacks(void); -#endif - - virtual void get_value(struct t_vpi_value*value) =0; - - private: - struct __vpiCallback*vpi_callbacks_; -}; - -class vvp_vpi_callback_wordable : public vvp_vpi_callback { - public: - vvp_vpi_callback_wordable(); - ~vvp_vpi_callback_wordable(); - - void run_vpi_callbacks(); - void attach_as_word(class __vpiArray* arr, unsigned long addr); - - private: - class __vpiArray* array_; - unsigned long array_word_; -}; - /* * Wide Functors: * Wide functors represent special devices that may have more than 4 diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index cff276760..4de87eaf6 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -41,24 +41,46 @@ template T coerce_to_width(const T&that, unsigned width) return res; } -/* **** vvp_fun_signal methods **** */ - -vvp_fun_signal_base::vvp_fun_signal_base() +vvp_filter_wire_base::vvp_filter_wire_base() { - needs_init_ = true; continuous_assign_active_ = false; - force_link = 0; - cassign_link = 0; - count_functors_sig += 1; } -void vvp_fun_signal_base::deassign() +vvp_filter_wire_base::~vvp_filter_wire_base() +{ +} + +bool vvp_filter_wire_base::filter_vec4(const vvp_vector4_t&) +{ + run_vpi_callbacks(); + return true; +} + +bool vvp_filter_wire_base::filter_vec8(const vvp_vector8_t&) +{ + run_vpi_callbacks(); + return true; +} + +bool vvp_filter_wire_base::filter_real(double) +{ + run_vpi_callbacks(); + return true; +} + +bool vvp_filter_wire_base::filter_long(long) +{ + run_vpi_callbacks(); + return true; +} + +void vvp_filter_wire_base::deassign() { continuous_assign_active_ = false; assign_mask_ = vvp_vector2_t(); } -void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid) +void vvp_filter_wire_base::deassign_pv(unsigned base, unsigned wid) { for (unsigned idx = 0 ; idx < wid ; idx += 1) { assign_mask_.set_bit(base+idx, 0); @@ -69,6 +91,16 @@ void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid) } } +/* **** vvp_fun_signal methods **** */ + +vvp_fun_signal_base::vvp_fun_signal_base() +{ + needs_init_ = true; + force_link = 0; + cassign_link = 0; + count_functors_sig += 1; +} + /* * The signal functor takes commands as long values to port-3. This * method interprets those commands. @@ -294,8 +326,6 @@ void vvp_fun_signal4_sa::calculate_output_(vvp_net_ptr_t ptr) } else { ptr.ptr()->send_vec4(bits4_, 0); } - - run_vpi_callbacks(); } void vvp_fun_signal4_sa::release(vvp_net_ptr_t ptr, bool net) @@ -303,7 +333,6 @@ void vvp_fun_signal4_sa::release(vvp_net_ptr_t ptr, bool net) force_mask_ = vvp_vector2_t(); if (net) { ptr.ptr()->send_vec4(bits4_, 0); - run_vpi_callbacks(); } else { bits4_ = force_; } @@ -589,8 +618,6 @@ void vvp_fun_signal8::calculate_output_(vvp_net_ptr_t ptr) } else { ptr.ptr()->send_vec8(bits8_); } - - run_vpi_callbacks(); } void vvp_fun_signal8::release(vvp_net_ptr_t ptr, bool net) @@ -598,7 +625,6 @@ void vvp_fun_signal8::release(vvp_net_ptr_t ptr, bool net) force_mask_ = vvp_vector2_t(); if (net) { ptr.ptr()->send_vec8(bits8_); - run_vpi_callbacks(); } else { bits8_ = force_; } @@ -689,7 +715,6 @@ void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit, bits_ = bit; needs_init_ = false; ptr.ptr()->send_real(bit, 0); - run_vpi_callbacks(); } } break; @@ -698,14 +723,12 @@ void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit, continuous_assign_active_ = true; bits_ = bit; ptr.ptr()->send_real(bit, 0); - run_vpi_callbacks(); break; case 2: // Force value force_mask_ = vvp_vector2_t(1, 1); force_ = bit; ptr.ptr()->send_real(bit, 0); - run_vpi_callbacks(); break; default: @@ -720,7 +743,6 @@ void vvp_fun_signal_real_sa::release(vvp_net_ptr_t ptr, bool net) force_mask_ = vvp_vector2_t(); if (net) { ptr.ptr()->send_real(bits_, 0); - run_vpi_callbacks(); } else { bits_ = force_; } diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index ef6e6d44d..5c9802e4d 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -36,6 +36,43 @@ class ostream; using namespace std; +/* + * Things derived from vvp_vpi_callback may have callbacks + * attached. This is how vpi callbacks are attached to the vvp + * structure. + * + * Things derived from vvp_vpi_callback may also be array'ed, so it + * includes some members that arrays use. + */ +class vvp_vpi_callback { + + public: + vvp_vpi_callback(); + virtual ~vvp_vpi_callback(); + + void attach_as_word(class __vpiArray* arr, unsigned long addr); + + void add_vpi_callback(struct __vpiCallback*); +#ifdef CHECK_WITH_VALGRIND + /* This has only been tested at EOS. */ + void clear_all_callbacks(void); +#endif + + // Derived classes implement this method to provide a way for + // vpi to get at the vvp value of the object. + virtual void get_value(struct t_vpi_value*value) =0; + + protected: + // Derived classes call this method to indicate that it is + // time to call the callback. + void run_vpi_callbacks(); + + private: + struct __vpiCallback*vpi_callbacks_; + class __vpiArray* array_; + unsigned long array_word_; +}; + /* vvp_fun_signal * This node is the place holder in a vvp network for signals, * including nets of various sort. The output from a signal follows @@ -90,7 +127,33 @@ using namespace std; * propagate starting at the next input change. */ -class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_vpi_callback_wordable { + +class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback { + + public: + vvp_filter_wire_base(); + ~vvp_filter_wire_base(); + + bool filter_vec4(const vvp_vector4_t&val); + bool filter_vec8(const vvp_vector8_t&val); + bool filter_real(double val); + bool filter_long(long val); + + public: + void deassign(); + void deassign_pv(unsigned base, unsigned wid); + 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: + bool continuous_assign_active_; + vvp_vector2_t force_mask_; + vvp_vector2_t assign_mask_; + +}; + +class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_filter_wire_base { public: vvp_fun_signal_base(); @@ -110,15 +173,6 @@ class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_vpi_callback_wordab // This is true until at least one propagation happens. bool needs_init_; - bool continuous_assign_active_; - vvp_vector2_t force_mask_; - vvp_vector2_t assign_mask_; - - void deassign(); - void deassign_pv(unsigned base, unsigned wid); - 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; }; /* diff --git a/vvp/words.cc b/vvp/words.cc index 935b5bfa2..f7d5173de 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -43,6 +43,7 @@ static void __compile_var_real(char*label, char*name, } vvp_net_t*net = new vvp_net_t; net->fun = fun; + net->fil = fun; define_functor_symbol(label, net); @@ -93,6 +94,7 @@ static void __compile_var(char*label, char*name, } vvp_net_t*node = new vvp_net_t; node->fun = vsig; + node->fil = vsig; define_functor_symbol(label, node); @@ -171,6 +173,7 @@ static void __compile_net(char*label, char*name, ? dynamic_cast(new vvp_fun_signal8(wid)) : dynamic_cast(new vvp_fun_signal4_sa(wid,BIT4_Z)); node->fun = vsig; + node->fil = vsig; /* Add the label into the functor symbol table. */ define_functor_symbol(label, node); @@ -232,6 +235,7 @@ static void __compile_real(char*label, char*name, vvp_fun_signal_real*fun = new vvp_fun_signal_real_sa; net->fun = fun; + net->fil = fun; /* Add the label into the functor symbol table. */ define_functor_symbol(label, net);