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()
{
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) {

View File

@ -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)
{

View File

@ -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

View File

@ -41,24 +41,46 @@ template <class T> 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_;
}

View File

@ -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;
};
/*

View File

@ -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<vvp_fun_signal_base*>(new vvp_fun_signal8(wid))
: dynamic_cast<vvp_fun_signal_base*>(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);