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:
parent
04490703f7
commit
912ec66d72
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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&)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue