Split type-specific filters into type-specific derived classes.

The wire base class cannot carry all the overhead for handling all
the different net types, so split it out into derived classes. This
will also move me closer to splitting wires away from variables.
This commit is contained in:
Stephen Williams 2009-05-23 10:55:07 -07:00
parent 6e1d7b6210
commit 9a348e2174
2 changed files with 151 additions and 136 deletions

View File

@ -50,25 +50,25 @@ vvp_filter_wire_base::~vvp_filter_wire_base()
{
}
const vvp_vector4_t* vvp_filter_wire_base::filter_vec4(const vvp_vector4_t&val)
template <class T> const T*vvp_filter_wire_base::filter_mask_(const T&val, const T&force, T&filter)
{
if (force_mask_.size()) {
bool propagate_flag = force_propagate_;
force_propagate_ = false;
assert(val.size() == force_mask_.size());
assert(val.size() == force4_.size());
assert(val.size() == force.size());
filter4_ = val;
filter = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (force_mask_.value(idx))
filter4_.set_bit(idx, force4_.value(idx));
filter.set_bit(idx, force.value(idx));
else
propagate_flag = true;
}
if (propagate_flag) {
run_vpi_callbacks();
return &filter4_;
return &filter;
} else {
return 0;
}
@ -79,83 +79,119 @@ const vvp_vector4_t* vvp_filter_wire_base::filter_vec4(const vvp_vector4_t&val)
}
}
const vvp_vector8_t* vvp_filter_wire_base::filter_vec8(const vvp_vector8_t&val)
{
if (force_mask_.size()) {
bool propagate_flag = force_propagate_;
force_propagate_ = false;
assert(val.size() == force_mask_.size());
assert(val.size() == force8_.size());
filter8_ = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (force_mask_.value(idx))
filter8_.set_bit(idx, force8_.value(idx));
else
propagate_flag = true;
}
if (propagate_flag) {
run_vpi_callbacks();
return&filter8_;
} else {
return 0;
}
} else {
run_vpi_callbacks();
return &val;
}
}
bool vvp_filter_wire_base::filter_real(double&val)
template <class T> bool vvp_filter_wire_base::filter_mask_(T&val)
{
run_vpi_callbacks();
return true;
}
bool vvp_filter_wire_base::filter_long(long&)
const vvp_vector4_t* vvp_fun_signal4::filter_vec4(const vvp_vector4_t&val)
{
run_vpi_callbacks();
return true;
return filter_mask_(val, force4_, filter4_);
}
void vvp_filter_wire_base::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
const vvp_vector8_t* vvp_fun_signal8::filter_vec8(const vvp_vector8_t&val)
{
if (force_mask_.size() == 0)
force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size());
return filter_mask_(val, force8_, filter8_);
}
bool vvp_fun_signal_real::filter_real(double&val)
{
return filter_mask_(val);
}
bool vvp_filter_wire_base::filter_long(long&val)
{
return filter_mask_(val);
}
void vvp_fun_signal4::force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
{
force_mask(mask);
if (force4_.size() == 0)
force4_ = val;
assert(force_mask_.size() == mask.size());
for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
if (mask.value(idx) == 0)
continue;
force_mask_.set_bit(idx, 1);
force4_.set_bit(idx, val.value(idx));
force_propagate_ = true;
}
}
void vvp_filter_wire_base::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask)
void vvp_fun_signal8::force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask)
{
if (force_mask_.size() == 0)
force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size());
force_mask(mask);
if (force8_.size() == 0)
force8_ = val;
assert(force_mask_.size() == mask.size());
for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
if (mask.value(idx) == 0)
continue;
force_mask_.set_bit(idx, 1);
force8_.set_bit(idx, val.value(idx));
force_propagate_ = true;
}
}
void vvp_filter_wire_base::force_real(double val, vvp_vector2_t mask)
void vvp_fun_signal_real::force_real(double val, vvp_vector2_t mask)
{
force_mask(mask);
force_real_ = val;
}
vvp_bit4_t vvp_fun_signal4::filtered_value(const vvp_vector4_t&val, unsigned idx) const
{
if (test_force_mask(idx))
return force4_.value(idx);
else
return val.value(idx);
}
vvp_scalar_t vvp_fun_signal8::filtered_value(const vvp_vector8_t&val, unsigned idx) const
{
if (test_force_mask(idx))
return force8_.value(idx);
else
return val.value(idx);
}
const vvp_vector4_t& vvp_fun_signal4::filtered_vec4(const vvp_vector4_t&val) const
{
if (test_force_mask_is_zero())
return val;
filter4_ = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (test_force_mask(idx))
filter4_.set_bit(idx, force4_.value(idx));
}
return filter4_;
}
const vvp_vector8_t& vvp_fun_signal8::filtered_vec8(const vvp_vector8_t&val) const
{
if (test_force_mask_is_zero())
return val;
filter8_ = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (test_force_mask(idx))
filter8_.set_bit(idx, force8_.value(idx));
}
return filter8_;
}
double vvp_fun_signal_real::filtered_real(double val) const
{
if (test_force_mask_is_zero())
return val;
return force_real_;
}
void vvp_filter_wire_base::force_mask(vvp_vector2_t mask)
{
if (force_mask_.size() == 0)
force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size());
@ -168,64 +204,6 @@ void vvp_filter_wire_base::force_real(double val, vvp_vector2_t mask)
force_mask_.set_bit(idx, 1);
force_propagate_ = true;
}
force_real_ = val;
}
vvp_bit4_t vvp_filter_wire_base::filtered_value(const vvp_vector4_t&val, unsigned idx) const
{
if (force_mask_.size() == 0)
return val.value(idx);
if (force_mask_.value(idx))
return force4_.value(idx);
return val.value(idx);
}
vvp_scalar_t vvp_filter_wire_base::filtered_value(const vvp_vector8_t&val, unsigned idx) const
{
if (force_mask_.size() == 0)
return val.value(idx);
if (force_mask_.value(idx))
return force8_.value(idx);
return val.value(idx);
}
const vvp_vector4_t& vvp_filter_wire_base::filtered_vec4(const vvp_vector4_t&val) const
{
if (force_mask_.size() == 0)
return val;
filter4_ = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (force_mask_.value(idx))
filter4_.set_bit(idx, force4_.value(idx));
}
return filter4_;
}
const vvp_vector8_t& vvp_filter_wire_base::filtered_vec8(const vvp_vector8_t&val) const
{
if (force_mask_.size() == 0)
return val;
filter8_ = val;
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
if (force_mask_.value(idx))
filter8_.set_bit(idx, force8_.value(idx));
}
return filter8_;
}
double vvp_filter_wire_base::filtered_real(double val) const
{
if (force_mask_.size() == 0)
return val;
if (force_mask_.value(0) == 0)
return val;
return force_real_;
}
void vvp_filter_wire_base::release_mask(vvp_vector2_t mask)

View File

@ -134,11 +134,8 @@ class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback {
vvp_filter_wire_base();
~vvp_filter_wire_base();
// These are the virtual methods that we implement to perform
// the wire-style filtering.
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&val);
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
bool filter_real(double&val);
// The filter_long is a placeholder here. This should be moved
// to a vvp_fun_signal_long when such a thing is implemented.
bool filter_long(long&val);
public:
@ -150,40 +147,49 @@ class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback {
// filtering results using the filtered_* methods. The
// release_mask() method releases bits of the vector.
// Enable filter force.
void force_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
void force_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
void force_real(double val, vvp_vector2_t mask);
// Test the value against the filter.
vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const;
vvp_scalar_t filtered_value(const vvp_vector8_t&val, unsigned idx) const;
const vvp_vector4_t& filtered_vec4(const vvp_vector4_t&val) const;
const vvp_vector8_t& filtered_vec8(const vvp_vector8_t&val) const;
double filtered_real(double val) const;
// Release the force on the bits set in the mask.
void release_mask(vvp_vector2_t mask);
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:
// Set bits of the filter force mask
void force_mask(vvp_vector2_t mask);
// Release the force on the bits set in the mask.
void release_mask(vvp_vector2_t mask);
// Test bits of the filter force mask;
bool test_force_mask(unsigned bit) const;
bool test_force_mask_is_zero() const;
template <class T> const T*filter_mask_(const T&val, const T&force, T&buf);
template <class T> bool filter_mask_(T&val);
private:
// Forced value
vvp_vector2_t force_mask_;
vvp_vector4_t force4_;
vvp_vector8_t force8_;
double force_real_;
// True if the next filter must propagate. Need this to allow
// the forced value to get through.
bool force_propagate_;
// This is used as a static return value.
mutable vvp_vector4_t filter4_;
mutable vvp_vector8_t filter8_;
};
inline bool vvp_filter_wire_base::test_force_mask(unsigned bit) const
{
if (bit >= force_mask_.size())
return false;
if (force_mask_.value(bit))
return true;
else
return false;
}
inline bool vvp_filter_wire_base::test_force_mask_is_zero(void) const
{
if (force_mask_.size() == 0)
return true;
if (force_mask_.is_zero())
return true;
return false;
}
class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_filter_wire_base {
public:
@ -231,6 +237,17 @@ class vvp_fun_signal4 : public vvp_fun_signal_vec {
void get_value(struct t_vpi_value*value);
public:
// Enable filter force.
void force_vec4(const vvp_vector4_t&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;
const vvp_vector4_t& filtered_vec4(const vvp_vector4_t&val) const;
private:
vvp_vector4_t force4_;
mutable vvp_vector4_t filter4_;
};
/*
@ -336,11 +353,21 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
void get_value(struct t_vpi_value*value);
public:
// Enable filter force.
void force_vec8(const vvp_vector8_t&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;
private:
void calculate_output_(vvp_net_ptr_t ptr);
vvp_vector8_t bits8_;
vvp_vector8_t force_;
vvp_vector8_t force8_;
mutable vvp_vector8_t filter8_;
};
class vvp_fun_signal_real : public vvp_fun_signal_base {
@ -352,6 +379,16 @@ class vvp_fun_signal_real : public vvp_fun_signal_base {
virtual double real_value() const = 0;
void get_value(struct t_vpi_value*value);
public:
// Enable filter force.
void force_real(double val, vvp_vector2_t mask);
bool filter_real(double&val);
// Test the value against the filter.
double filtered_real(double val) const;
private:
double force_real_;
};
/*