Add vvp_wire_vec8 value get methods.

In the process, redesign the interface to the filter_vecX methods
to be more rational.
This commit is contained in:
Stephen Williams 2009-08-26 20:57:30 -07:00
parent 04490703f7
commit 912ec66d72
5 changed files with 93 additions and 65 deletions

View File

@ -761,7 +761,7 @@ void vvp_wire_vec4::get_value(struct t_vpi_value*value)
void vvp_wire_vec8::get_value(struct t_vpi_value*value) void vvp_wire_vec8::get_value(struct t_vpi_value*value)
{ {
assert(0); get_signal_value(value);
} }
void vvp_wire_real::get_value(struct t_vpi_value*value) void vvp_wire_real::get_value(struct t_vpi_value*value)

View File

@ -206,14 +206,14 @@ vvp_net_fil_t::~vvp_net_fil_t()
assert(force_link_ == 0); assert(force_link_ == 0);
} }
const vvp_vector4_t* vvp_net_fil_t::filter_vec4(const vvp_vector4_t&val) vvp_net_fil_t::prop_t vvp_net_fil_t::filter_vec4(const vvp_vector4_t&val, vvp_vector4_t&)
{ {
return &val; return PROP;
} }
const vvp_vector8_t* vvp_net_fil_t::filter_vec8(const vvp_vector8_t&val) vvp_net_fil_t::prop_t vvp_net_fil_t::filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&)
{ {
return &val; return PROP;
} }
bool vvp_net_fil_t::filter_real(double&) bool vvp_net_fil_t::filter_real(double&)

View File

@ -1119,14 +1119,17 @@ class vvp_net_fil_t : public vvp_vpi_callback {
virtual ~vvp_net_fil_t(); virtual ~vvp_net_fil_t();
public: public:
enum prop_t { STOP=0, PROP, REPL };
// Return a non-empty vector if the filter allows an // Return a non-empty vector if the filter allows an
// output. The output result may be different from the // output. The output result may be different from the
// input. If the output is nil, then suppress propagation. // input. If the output is nil, then suppress propagation.
virtual const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit);
virtual const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
// Return true if the value is to be propagated, or false if // Return true if the value is to be propagated, or false if
// propagation is suppressed. The value may be edited by the filter. // propagation is suppressed. The value may be edited by the
// filter, or overridden by the rep argument if present.
virtual prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep);
virtual prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep);
virtual bool filter_real(double&val); virtual bool filter_real(double&val);
virtual bool filter_long(long&val); virtual bool filter_long(long&val);
@ -1162,7 +1165,7 @@ class vvp_net_fil_t : public vvp_vpi_callback {
// currently forced value, and the buf is a value that this // currently forced value, and the buf is a value that this
// method will use to hold a filtered value, if needed. This // method will use to hold a filtered value, if needed. This
// method returns a pointer to val or buf. // method returns a pointer to val or buf.
template <class T> const T*filter_mask_(const T&val, const T&force, T&buf); template <class T> prop_t filter_mask_(const T&val, const T&force, T&rep);
// This template method is a scalar value of the above. It // This template method is a scalar value of the above. It
// leaves the val, or it replaces it iwth a forced value. // leaves the val, or it replaces it iwth a forced value.
// (Not really implemented, yet.) // (Not really implemented, yet.)
@ -1440,11 +1443,22 @@ inline void vvp_net_t::send_vec8_pv(const vvp_vector8_t&val,
inline void vvp_net_t::send_vec4(const vvp_vector4_t&val, vvp_context_t context) inline void vvp_net_t::send_vec4(const vvp_vector4_t&val, vvp_context_t context)
{ {
const vvp_vector4_t*val_out = fil? fil->filter_vec4(val) : &val; if (fil == 0) {
if (val_out == 0) vvp_send_vec4(out_, val, context);
return; return;
}
vvp_send_vec4(out_, *val_out, context); vvp_vector4_t rep;
switch (fil->filter_vec4(val, rep)) {
case vvp_net_fil_t::STOP:
break;
case vvp_net_fil_t::PROP:
vvp_send_vec4(out_, val, context);
break;
case vvp_net_fil_t::REPL:
vvp_send_vec4(out_, rep, context);
break;
}
} }
inline void vvp_net_t::send_vec4_pv(const vvp_vector4_t&val, inline void vvp_net_t::send_vec4_pv(const vvp_vector4_t&val,
@ -1456,11 +1470,22 @@ inline void vvp_net_t::send_vec4_pv(const vvp_vector4_t&val,
inline void vvp_net_t::send_vec8(const vvp_vector8_t&val) inline void vvp_net_t::send_vec8(const vvp_vector8_t&val)
{ {
const vvp_vector8_t*val_out = fil? fil->filter_vec8(val) : &val; if (fil == 0) {
if (val_out == 0) vvp_send_vec8(out_, val);
return; return;
}
vvp_send_vec8(out_, *val_out); vvp_vector8_t rep;
switch (fil->filter_vec8(val, rep)) {
case vvp_net_fil_t::STOP:
break;
case vvp_net_fil_t::PROP:
vvp_send_vec8(out_, val);
break;
case vvp_net_fil_t::REPL:
vvp_send_vec8(out_, rep);
break;
}
} }
inline void vvp_net_t::send_real(double val, vvp_context_t context) inline void vvp_net_t::send_real(double val, vvp_context_t context)

View File

@ -30,7 +30,7 @@
# include <iostream> # include <iostream>
template <class T> const T*vvp_net_fil_t::filter_mask_(const T&val, const T&force, T&filter) template <class T> vvp_net_fil_t::prop_t vvp_net_fil_t::filter_mask_(const T&val, const T&force, T&filter)
{ {
if (!test_force_mask_is_zero()) { if (!test_force_mask_is_zero()) {
bool propagate_flag = force_propagate_; bool propagate_flag = force_propagate_;
@ -48,14 +48,14 @@ template <class T> const T*vvp_net_fil_t::filter_mask_(const T&val, const T&forc
if (propagate_flag) { if (propagate_flag) {
run_vpi_callbacks(); run_vpi_callbacks();
return &filter; return REPL;
} else { } else {
return 0; return STOP;
} }
} else { } else {
run_vpi_callbacks(); run_vpi_callbacks();
return &val; return PROP;
} }
} }
@ -75,24 +75,6 @@ double vvp_signal_value::real_value() const
return 0; return 0;
} }
#if 0
const vvp_vector4_t* vvp_fun_signal4::filter_vec4(const vvp_vector4_t&val)
{
return filter_mask_(val, force4_, filter4_);
}
#endif
#if 0
const vvp_vector8_t* vvp_fun_signal8::filter_vec8(const vvp_vector8_t&val)
{
return filter_mask_(val, force8_, filter8_);
}
#endif
#if 0
bool vvp_fun_signal_real::filter_real(double&val)
{
return filter_mask_(val);
}
#endif
unsigned vvp_fun_signal_real::filter_size() const unsigned vvp_fun_signal_real::filter_size() const
{ {
return size(); return size();
@ -876,19 +858,18 @@ vvp_wire_vec4::vvp_wire_vec4(unsigned wid, vvp_bit4_t init)
{ {
} }
const vvp_vector4_t* vvp_wire_vec4::filter_vec4(const vvp_vector4_t&bit) vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep)
{ {
// Keep track of the value being driven from this net, even if // Keep track of the value being driven from this net, even if
// it is not ultimately what survives the force filter. // it is not ultimately what survives the force filter.
bits4_ = bit; bits4_ = bit;
const vvp_vector4_t*tmp = filter_mask_(bit, force4_, filter4_); return filter_mask_(bit, force4_, rep);
return tmp;
} }
const vvp_vector8_t* vvp_wire_vec4::filter_vec8(const vvp_vector8_t&bit) vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&)
{ {
assert(0); assert(0);
return 0; return PROP;
} }
unsigned vvp_wire_vec4::filter_size() const unsigned vvp_wire_vec4::filter_size() const
@ -951,17 +932,17 @@ unsigned vvp_wire_vec4::value_size() const
return width_; return width_;
} }
vvp_bit4_t vvp_wire_vec4::filtered_value_(const vvp_vector4_t&val, unsigned idx) const vvp_bit4_t vvp_wire_vec4::filtered_value_(unsigned idx) const
{ {
if (test_force_mask(idx)) if (test_force_mask(idx))
return force4_.value(idx); return force4_.value(idx);
else else
return val.value(idx); return bits4_.value(idx);
} }
vvp_bit4_t vvp_wire_vec4::value(unsigned idx) const vvp_bit4_t vvp_wire_vec4::value(unsigned idx) const
{ {
return filtered_value_(bits4_, idx); return filtered_value_(idx);
} }
vvp_scalar_t vvp_wire_vec4::scalar_value(unsigned idx) const vvp_scalar_t vvp_wire_vec4::scalar_value(unsigned idx) const
@ -973,7 +954,7 @@ vvp_vector4_t vvp_wire_vec4::vec4_value() const
{ {
vvp_vector4_t tmp = bits4_; vvp_vector4_t tmp = bits4_;
for (unsigned idx = 0 ; idx < bits4_.size() ; idx += 1) for (unsigned idx = 0 ; idx < bits4_.size() ; idx += 1)
tmp.set_bit(idx, filtered_value_(bits4_, idx)); tmp.set_bit(idx, filtered_value_(idx));
return tmp; return tmp;
} }
@ -982,19 +963,25 @@ vvp_wire_vec8::vvp_wire_vec8(unsigned wid)
{ {
} }
const vvp_vector4_t* vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit) vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep)
{ {
assert(0); // QUESTION: Is it really correct to propagate a vec4 if this
return 0; // is a vec8 node? In fact, it is really possible for a vec4
// value to get through to a vec8 filter?
vvp_vector8_t rep8;
prop_t rc = filter_vec8(vvp_vector8_t(bit,6,6), rep8);
if (rc == REPL)
rep = reduce4(rep8);
return rc;
} }
const vvp_vector8_t* vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit) vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep)
{ {
// Keep track of the value being driven from this net, even if // Keep track of the value being driven from this net, even if
// it is not ultimately what survives the force filter. // it is not ultimately what survives the force filter.
bits8_ = bit; bits8_ = bit;
const vvp_vector8_t*tmp = filter_mask_(bit, force8_, filter8_); return filter_mask_(bit, force8_, rep);
return tmp;
} }
unsigned vvp_wire_vec8::filter_size() const unsigned vvp_wire_vec8::filter_size() const
@ -1046,19 +1033,35 @@ unsigned vvp_wire_vec8::value_size() const
return width_; return width_;
} }
vvp_scalar_t vvp_wire_vec8::filtered_value_(unsigned idx) const
{
if (test_force_mask(idx))
return force8_.value(idx);
else
return bits8_.value(idx);
}
vvp_bit4_t vvp_wire_vec8::value(unsigned idx) const vvp_bit4_t vvp_wire_vec8::value(unsigned idx) const
{ {
assert(0); return filtered_value_(idx).value();
} }
vvp_scalar_t vvp_wire_vec8::scalar_value(unsigned idx) const vvp_scalar_t vvp_wire_vec8::scalar_value(unsigned idx) const
{ {
assert(0); return filtered_value_(idx);
}
vvp_vector8_t vvp_wire_vec8::vec8_value() const
{
vvp_vector8_t tmp = bits8_;
for (unsigned idx = 0 ; idx < bits8_.size() ; idx += 1)
tmp.set_bit(idx, filtered_value_(idx));
return tmp;
} }
vvp_vector4_t vvp_wire_vec8::vec4_value() const vvp_vector4_t vvp_wire_vec8::vec4_value() const
{ {
assert(0); return reduce4(vec8_value());
} }
vvp_wire_real::vvp_wire_real() vvp_wire_real::vvp_wire_real()

View File

@ -127,7 +127,6 @@ class vvp_fun_signal4 : public vvp_fun_signal_vec {
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask); void force_fil_real(double val, vvp_vector2_t mask);
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&val);
// Test the value against the filter. // Test the value against the filter.
vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const; vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const;
@ -246,7 +245,6 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask); void force_fil_real(double val, vvp_vector2_t mask);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
// Test the value against the filter. // Test the value against the filter.
vvp_scalar_t filtered_value(const vvp_vector8_t&val, unsigned idx) const; 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; const vvp_vector8_t& filtered_vec8(const vvp_vector8_t&val) const;
@ -274,7 +272,6 @@ class vvp_fun_signal_real : public vvp_fun_signal_base {
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_fil_real(double val, vvp_vector2_t mask); void force_fil_real(double val, vvp_vector2_t mask);
bool filter_real(double&val);
// Test the value against the filter. // Test the value against the filter.
double filtered_real(double val) const; double filtered_real(double val) const;
@ -361,8 +358,8 @@ class vvp_wire_vec4 : public vvp_wire_base {
// the value that the node is driven to, and applies the firce // the value that the node is driven to, and applies the firce
// filters. In wires, this also saves the driven value, so // filters. In wires, this also saves the driven value, so
// that when a force is released, we can revert to the driven value. // that when a force is released, we can revert to the driven value.
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit); prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val); prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep);
// Abstract methods from vvp_vpi_callback // Abstract methods from vvp_vpi_callback
void get_value(struct t_vpi_value*value); void get_value(struct t_vpi_value*value);
@ -381,13 +378,12 @@ class vvp_wire_vec4 : public vvp_wire_base {
vvp_vector4_t vec4_value() const; vvp_vector4_t vec4_value() const;
private: private:
vvp_bit4_t filtered_value_(const vvp_vector4_t&val, unsigned idx) const; vvp_bit4_t filtered_value_(unsigned idx) const;
private: private:
unsigned width_; unsigned width_;
vvp_vector4_t bits4_; // The tracked driven value vvp_vector4_t bits4_; // The tracked driven value
vvp_vector4_t force4_; // the value being forced vvp_vector4_t force4_; // the value being forced
vvp_vector4_t filter4_; // scratch space for filter_mask_ function.
}; };
class vvp_wire_vec8 : public vvp_wire_base { class vvp_wire_vec8 : public vvp_wire_base {
@ -396,8 +392,8 @@ class vvp_wire_vec8 : public vvp_wire_base {
vvp_wire_vec8(unsigned wid); vvp_wire_vec8(unsigned wid);
// The main filter behavior for this class // The main filter behavior for this class
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit); prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val); prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep);
// Abstract methods from vvp_vpi_callback // Abstract methods from vvp_vpi_callback
void get_value(struct t_vpi_value*value); void get_value(struct t_vpi_value*value);
@ -414,12 +410,16 @@ class vvp_wire_vec8 : public vvp_wire_base {
vvp_bit4_t value(unsigned idx) const; vvp_bit4_t value(unsigned idx) const;
vvp_scalar_t scalar_value(unsigned idx) const; vvp_scalar_t scalar_value(unsigned idx) const;
vvp_vector4_t vec4_value() const; vvp_vector4_t vec4_value() const;
// This is new to vvp_wire_vec8
vvp_vector8_t vec8_value() const;
private:
vvp_scalar_t filtered_value_(unsigned idx) const;
private: private:
unsigned width_; unsigned width_;
vvp_vector8_t bits8_; vvp_vector8_t bits8_;
vvp_vector8_t force8_; // the value being forced vvp_vector8_t force8_; // the value being forced
vvp_vector8_t filter8_; // scratch space for filter_mask_ function.
}; };
class vvp_wire_real : public vvp_wire_base { class vvp_wire_real : public vvp_wire_base {