The vvp_vpi_callback belongs with the vvp_set_sig stuff.

Move the vvp_vpi_callback to the vvp_net_sig.h header file, and
collapse some useless hierarchy. (Specifically, all callbackable
items are also wordable.)

Move the run_vpi_callback invocation for wires/variables from the
output generator to the newly implemented filter object. This is
starting to get the filter class working.
This commit is contained in:
Stephen Williams 2009-04-24 21:50:00 -07:00
parent 53051be2d4
commit 7e9e50d3b0
6 changed files with 149 additions and 90 deletions

View File

@ -504,11 +504,21 @@ void callback_execute(struct __vpiCallback*cur)
vvp_vpi_callback::vvp_vpi_callback() vvp_vpi_callback::vvp_vpi_callback()
{ {
vpi_callbacks_ = 0; vpi_callbacks_ = 0;
array_ = 0;
array_word_ = 0;
} }
vvp_vpi_callback::~vvp_vpi_callback() vvp_vpi_callback::~vvp_vpi_callback()
{ {
assert(vpi_callbacks_ == 0); 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) 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() void vvp_vpi_callback::run_vpi_callbacks()
{ {
if (array_) array_word_change(array_, array_word_);
struct __vpiCallback *next = vpi_callbacks_; struct __vpiCallback *next = vpi_callbacks_;
struct __vpiCallback *prev = 0; 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) void vvp_fun_signal4::get_value(struct t_vpi_value*vp)
{ {
switch (vp->format) { switch (vp->format) {

View File

@ -194,6 +194,34 @@ void vvp_net_fun_t::operator delete(void*)
assert(0); 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 *** */ /* *** BIT operations *** */
vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c) vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c)
{ {

View File

@ -1187,42 +1187,6 @@ class vvp_fun_extend_signed : public vvp_net_fun_t {
unsigned width_; 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:
* Wide functors represent special devices that may have more than 4 * Wide functors represent special devices that may have more than 4

View File

@ -41,24 +41,46 @@ template <class T> T coerce_to_width(const T&that, unsigned width)
return res; return res;
} }
/* **** vvp_fun_signal methods **** */ vvp_filter_wire_base::vvp_filter_wire_base()
vvp_fun_signal_base::vvp_fun_signal_base()
{ {
needs_init_ = true;
continuous_assign_active_ = false; 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; continuous_assign_active_ = false;
assign_mask_ = vvp_vector2_t(); 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) { for (unsigned idx = 0 ; idx < wid ; idx += 1) {
assign_mask_.set_bit(base+idx, 0); 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 * The signal functor takes commands as long values to port-3. This
* method interprets those commands. * method interprets those commands.
@ -294,8 +326,6 @@ void vvp_fun_signal4_sa::calculate_output_(vvp_net_ptr_t ptr)
} else { } else {
ptr.ptr()->send_vec4(bits4_, 0); ptr.ptr()->send_vec4(bits4_, 0);
} }
run_vpi_callbacks();
} }
void vvp_fun_signal4_sa::release(vvp_net_ptr_t ptr, bool net) 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(); force_mask_ = vvp_vector2_t();
if (net) { if (net) {
ptr.ptr()->send_vec4(bits4_, 0); ptr.ptr()->send_vec4(bits4_, 0);
run_vpi_callbacks();
} else { } else {
bits4_ = force_; bits4_ = force_;
} }
@ -589,8 +618,6 @@ void vvp_fun_signal8::calculate_output_(vvp_net_ptr_t ptr)
} else { } else {
ptr.ptr()->send_vec8(bits8_); ptr.ptr()->send_vec8(bits8_);
} }
run_vpi_callbacks();
} }
void vvp_fun_signal8::release(vvp_net_ptr_t ptr, bool net) 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(); force_mask_ = vvp_vector2_t();
if (net) { if (net) {
ptr.ptr()->send_vec8(bits8_); ptr.ptr()->send_vec8(bits8_);
run_vpi_callbacks();
} else { } else {
bits8_ = force_; bits8_ = force_;
} }
@ -689,7 +715,6 @@ void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit,
bits_ = bit; bits_ = bit;
needs_init_ = false; needs_init_ = false;
ptr.ptr()->send_real(bit, 0); ptr.ptr()->send_real(bit, 0);
run_vpi_callbacks();
} }
} }
break; break;
@ -698,14 +723,12 @@ void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit,
continuous_assign_active_ = true; continuous_assign_active_ = true;
bits_ = bit; bits_ = bit;
ptr.ptr()->send_real(bit, 0); ptr.ptr()->send_real(bit, 0);
run_vpi_callbacks();
break; break;
case 2: // Force value case 2: // Force value
force_mask_ = vvp_vector2_t(1, 1); force_mask_ = vvp_vector2_t(1, 1);
force_ = bit; force_ = bit;
ptr.ptr()->send_real(bit, 0); ptr.ptr()->send_real(bit, 0);
run_vpi_callbacks();
break; break;
default: default:
@ -720,7 +743,6 @@ void vvp_fun_signal_real_sa::release(vvp_net_ptr_t ptr, bool net)
force_mask_ = vvp_vector2_t(); force_mask_ = vvp_vector2_t();
if (net) { if (net) {
ptr.ptr()->send_real(bits_, 0); ptr.ptr()->send_real(bits_, 0);
run_vpi_callbacks();
} else { } else {
bits_ = force_; bits_ = force_;
} }

View File

@ -36,6 +36,43 @@ class ostream;
using namespace std; 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 /* vvp_fun_signal
* This node is the place holder in a vvp network for signals, * This node is the place holder in a vvp network for signals,
* including nets of various sort. The output from a signal follows * 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. * 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: public:
vvp_fun_signal_base(); 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. // This is true until at least one propagation happens.
bool needs_init_; 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;
}; };
/* /*

View File

@ -43,6 +43,7 @@ static void __compile_var_real(char*label, char*name,
} }
vvp_net_t*net = new vvp_net_t; vvp_net_t*net = new vvp_net_t;
net->fun = fun; net->fun = fun;
net->fil = fun;
define_functor_symbol(label, net); 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; vvp_net_t*node = new vvp_net_t;
node->fun = vsig; node->fun = vsig;
node->fil = vsig;
define_functor_symbol(label, node); define_functor_symbol(label, node);
@ -171,6 +173,7 @@ static void __compile_net(char*label, char*name,
? dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal8(wid)) ? dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal8(wid))
: dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal4_sa(wid,BIT4_Z)); : dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal4_sa(wid,BIT4_Z));
node->fun = vsig; node->fun = vsig;
node->fil = vsig;
/* Add the label into the functor symbol table. */ /* Add the label into the functor symbol table. */
define_functor_symbol(label, node); 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; vvp_fun_signal_real*fun = new vvp_fun_signal_real_sa;
net->fun = fun; net->fun = fun;
net->fil = fun;
/* Add the label into the functor symbol table. */ /* Add the label into the functor symbol table. */
define_functor_symbol(label, net); define_functor_symbol(label, net);