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:
parent
53051be2d4
commit
7e9e50d3b0
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue