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)
{
assert(0);
get_signal_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);
}
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&)

View File

@ -1119,14 +1119,17 @@ class vvp_net_fil_t : public vvp_vpi_callback {
virtual ~vvp_net_fil_t();
public:
enum prop_t { STOP=0, PROP, REPL };
// Return a non-empty vector if the filter allows an
// output. The output result may be different from the
// 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
// 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_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
// method will use to hold a filtered value, if needed. This
// 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
// leaves the val, or it replaces it iwth a forced value.
// (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)
{
const vvp_vector4_t*val_out = fil? fil->filter_vec4(val) : &val;
if (val_out == 0)
if (fil == 0) {
vvp_send_vec4(out_, val, context);
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,
@ -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)
{
const vvp_vector8_t*val_out = fil? fil->filter_vec8(val) : &val;
if (val_out == 0)
if (fil == 0) {
vvp_send_vec8(out_, val);
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)

View File

@ -30,7 +30,7 @@
# 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()) {
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) {
run_vpi_callbacks();
return &filter;
return REPL;
} else {
return 0;
return STOP;
}
} else {
run_vpi_callbacks();
return &val;
return PROP;
}
}
@ -75,24 +75,6 @@ double vvp_signal_value::real_value() const
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
{
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
// it is not ultimately what survives the force filter.
bits4_ = bit;
const vvp_vector4_t*tmp = filter_mask_(bit, force4_, filter4_);
return tmp;
return filter_mask_(bit, force4_, rep);
}
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);
return 0;
return PROP;
}
unsigned vvp_wire_vec4::filter_size() const
@ -951,17 +932,17 @@ unsigned vvp_wire_vec4::value_size() const
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))
return force4_.value(idx);
else
return val.value(idx);
return bits4_.value(idx);
}
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
@ -973,7 +954,7 @@ vvp_vector4_t vvp_wire_vec4::vec4_value() const
{
vvp_vector4_t tmp = bits4_;
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;
}
@ -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);
return 0;
// QUESTION: Is it really correct to propagate a vec4 if this
// 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
// it is not ultimately what survives the force filter.
bits8_ = bit;
const vvp_vector8_t*tmp = filter_mask_(bit, force8_, filter8_);
return tmp;
return filter_mask_(bit, force8_, rep);
}
unsigned vvp_wire_vec8::filter_size() const
@ -1046,19 +1033,35 @@ unsigned vvp_wire_vec8::value_size() const
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
{
assert(0);
return filtered_value_(idx).value();
}
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
{
assert(0);
return reduce4(vec8_value());
}
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_vec8(const vvp_vector8_t&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.
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_vec8(const vvp_vector8_t&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.
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;
@ -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_real(double val, vvp_vector2_t mask);
bool filter_real(double&val);
// Test the value against the filter.
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
// filters. In wires, this also saves the driven value, so
// that when a force is released, we can revert to the driven value.
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep);
prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep);
// Abstract methods from vvp_vpi_callback
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;
private:
vvp_bit4_t filtered_value_(const vvp_vector4_t&val, unsigned idx) const;
vvp_bit4_t filtered_value_(unsigned idx) const;
private:
unsigned width_;
vvp_vector4_t bits4_; // The tracked driven value
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 {
@ -396,8 +392,8 @@ class vvp_wire_vec8 : public vvp_wire_base {
vvp_wire_vec8(unsigned wid);
// The main filter behavior for this class
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep);
prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep);
// Abstract methods from vvp_vpi_callback
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_scalar_t scalar_value(unsigned idx) 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:
unsigned width_;
vvp_vector8_t bits8_;
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 {