The vvp_wire_vec2 class didn't work out.
This class responded badly to inputs that differ only in zx0 values. It tended to suppress propagations.
This commit is contained in:
parent
c545cd3e33
commit
bad1512cb0
|
|
@ -660,7 +660,8 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
|||
if (rise_time())
|
||||
o << " #(" <<*rise_time()
|
||||
<<","<<*fall_time()
|
||||
<< "," <<*decay_time() << ")" << endl;
|
||||
<< "," <<*decay_time() << ")";
|
||||
o << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -702,11 +702,6 @@ void vvp_wire_real::get_signal_value(struct t_vpi_value*vp)
|
|||
real_signal_value(vp, real_value());
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::get_value(struct t_vpi_value*val)
|
||||
{
|
||||
get_signal_value(val);
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::get_value(struct t_vpi_value*val)
|
||||
{
|
||||
get_signal_value(val);
|
||||
|
|
|
|||
|
|
@ -600,168 +600,6 @@ vvp_wire_base::~vvp_wire_base()
|
|||
{
|
||||
}
|
||||
|
||||
vvp_wire_vec2::vvp_wire_vec2(unsigned wid)
|
||||
: bits2_(0, wid)
|
||||
{
|
||||
needs_init_ = true;
|
||||
}
|
||||
|
||||
vvp_net_fil_t::prop_t vvp_wire_vec2::filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep,
|
||||
unsigned base, unsigned vwid)
|
||||
{
|
||||
// Special case! the input bit is 0 wid. Interpret this as a
|
||||
// vector of 0 to match the width of the bits2_ vector.
|
||||
// FIXME! This is a hack to work around some buggy gate
|
||||
// implementations! This should be removed!
|
||||
if (base==0 && vwid==0) {
|
||||
vvp_vector2_t tmp (0, bits2_.size());
|
||||
if (bits2_ == tmp && !needs_init_) return STOP;
|
||||
bits2_ = tmp;
|
||||
needs_init_ = false;
|
||||
return filter_mask_(vector2_to_vector4(bits2_, bits2_.size()),
|
||||
vector2_to_vector4(force2_, bits2_.size()), rep, 0);
|
||||
}
|
||||
|
||||
if (vwid != bits2_.size()) {
|
||||
cerr << "Internal error: Input vector expected width="
|
||||
<< bits2_.size() << ", got "
|
||||
<< "bit=" << bit << ", base=" << base << ", vwid=" << vwid
|
||||
<< endl;
|
||||
}
|
||||
assert(bits2_.size() == vwid);
|
||||
|
||||
vvp_vector2_t bit2 = bit;
|
||||
|
||||
// Keep track of the value being driven from this net, even if
|
||||
// it is not ultimately what survives the force filter.
|
||||
if (base==0 && bit2.size()==vwid) {
|
||||
if (bits2_ == bit2 && !needs_init_) return STOP;
|
||||
bits2_ = bit2;
|
||||
} else {
|
||||
bits2_.set_vec(base, bit2);
|
||||
}
|
||||
|
||||
needs_init_ = false;
|
||||
return filter_mask_(vector2_to_vector4(bits2_, bits2_.size()),
|
||||
vector2_to_vector4(force2_, bits2_.size()), rep, 0);
|
||||
}
|
||||
|
||||
vvp_net_fil_t::prop_t vvp_wire_vec2::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep, unsigned base, unsigned vwid)
|
||||
{
|
||||
assert(bits2_.size() == bit.size());
|
||||
bits2_ = reduce4(bit);
|
||||
return filter_mask_(bit, vvp_vector8_t(force2_,6,6), rep, 0);
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec2::filter_size() const
|
||||
{
|
||||
return bits2_.size();
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
force_mask(mask);
|
||||
|
||||
if (force2_.size() == 0) {
|
||||
force2_ = val;
|
||||
} else {
|
||||
for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
|
||||
if (mask.value(idx) == 0)
|
||||
continue;
|
||||
|
||||
force2_.set_bit(idx, val.value(idx));
|
||||
}
|
||||
}
|
||||
run_vpi_callbacks();
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::force_fil_real(double val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::release(vvp_net_ptr_t ptr, bool net_flag)
|
||||
{
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL1, bits2_.size());
|
||||
if (net_flag) {
|
||||
// Wires revert to their unforced value after release.
|
||||
release_mask(mask);
|
||||
needs_init_ = ! (force2_ == bits2_);
|
||||
ptr.ptr()->send_vec4(vector2_to_vector4(bits2_, bits2_.size()), 0);
|
||||
run_vpi_callbacks();
|
||||
} else {
|
||||
// Variables keep the current value.
|
||||
vvp_vector4_t res (bits2_.size());
|
||||
for (unsigned idx=0; idx<bits2_.size(); idx += 1)
|
||||
res.set_bit(idx,value(idx));
|
||||
release_mask(mask);
|
||||
ptr.ptr()->fun->recv_vec4(ptr, res, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag)
|
||||
{
|
||||
assert(bits2_.size() >= base + wid);
|
||||
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL0, bits2_.size());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
mask.set_bit(base+idx, 1);
|
||||
|
||||
if (net_flag) {
|
||||
// Wires revert to their unforced value after release.
|
||||
release_mask(mask);
|
||||
needs_init_ = ! (force2_.subvalue(base,wid) == bits2_.subvalue(base,wid));
|
||||
ptr.ptr()->send_vec4_pv(vector2_to_vector4(bits2_.subvalue(base,wid),wid),
|
||||
base, wid, bits2_.size(), 0);
|
||||
run_vpi_callbacks();
|
||||
} else {
|
||||
// Variables keep the current value.
|
||||
vvp_vector4_t res (wid);
|
||||
for (unsigned idx=0; idx<wid; idx += 1)
|
||||
res.set_bit(idx,value(base+idx));
|
||||
release_mask(mask);
|
||||
ptr.ptr()->fun->recv_vec4_pv(ptr, res, base, wid, bits2_.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec2::value_size() const
|
||||
{
|
||||
return bits2_.size();
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_wire_vec2::filtered_value_(unsigned idx) const
|
||||
{
|
||||
if (test_force_mask(idx))
|
||||
return force2_.value4(idx);
|
||||
else
|
||||
return bits2_.value4(idx);
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_wire_vec2::value(unsigned idx) const
|
||||
{
|
||||
return filtered_value_(idx);
|
||||
}
|
||||
|
||||
vvp_scalar_t vvp_wire_vec2::scalar_value(unsigned idx) const
|
||||
{
|
||||
return vvp_scalar_t(value(idx),6,6);
|
||||
}
|
||||
|
||||
void vvp_wire_vec2::vec4_value(vvp_vector4_t&val) const
|
||||
{
|
||||
val = vector2_to_vector4(bits2_, bits2_.size());
|
||||
if (test_force_mask_is_zero())
|
||||
return;
|
||||
|
||||
for (unsigned idx = 0 ; idx < bits2_.size() ; idx += 1)
|
||||
val.set_bit(idx, filtered_value_(idx));
|
||||
}
|
||||
|
||||
vvp_wire_vec4::vvp_wire_vec4(unsigned wid, vvp_bit4_t init)
|
||||
: bits4_(wid, init)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -274,45 +274,6 @@ class vvp_wire_base : public vvp_net_fil_t, public vvp_signal_value {
|
|||
~vvp_wire_base();
|
||||
};
|
||||
|
||||
class vvp_wire_vec2 : public vvp_wire_base {
|
||||
|
||||
public:
|
||||
vvp_wire_vec2(unsigned wid);
|
||||
|
||||
// The main filter behavior for this class. These methods take
|
||||
// the value that the node is driven to, and applies the force
|
||||
// filters. In wires, this also saves the driven value, so
|
||||
// that when a force is released, we can revert to the driven value.
|
||||
prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep,
|
||||
unsigned base, unsigned vwid);
|
||||
prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep,
|
||||
unsigned base, unsigned vwid);
|
||||
|
||||
// Abstract methods from vvp_vpi_callback
|
||||
void get_value(struct t_vpi_value*value);
|
||||
// Abstract methods from vvp_net_fit_t
|
||||
unsigned filter_size() const;
|
||||
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);
|
||||
void release(vvp_net_ptr_t ptr, bool net_flag);
|
||||
void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag);
|
||||
|
||||
// Implementation of vvp_signal_value methods
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
void vec4_value(vvp_vector4_t&) const;
|
||||
|
||||
private:
|
||||
vvp_bit4_t filtered_value_(unsigned idx) const;
|
||||
|
||||
private:
|
||||
bool needs_init_;
|
||||
vvp_vector2_t bits2_; // The tracked driven value
|
||||
vvp_vector2_t force2_; // the value being forced
|
||||
};
|
||||
|
||||
class vvp_wire_vec4 : public vvp_wire_base {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ static void __compile_var(char*label, char*name,
|
|||
vvp_fun_signal4_aa*tmp = new vvp_fun_signal4_aa(wid);
|
||||
net->fil = tmp;
|
||||
net->fun = tmp;
|
||||
} else if (vpi_type_code == vpiIntVar) {
|
||||
net->fil = new vvp_wire_vec4(wid, BIT4_0);
|
||||
net->fun = new vvp_fun_signal4_sa(wid);
|
||||
} else {
|
||||
net->fil = new vvp_wire_vec4(wid, BIT4_X);
|
||||
net->fun = new vvp_fun_signal4_sa(wid);
|
||||
|
|
@ -252,7 +255,7 @@ static void do_compile_net(vvp_net_t*node, vvp_array_t array,
|
|||
if (vsig == 0) {
|
||||
switch (vpi_type_code) {
|
||||
case vpiIntVar:
|
||||
vsig = new vvp_wire_vec2(wid);
|
||||
vsig = new vvp_wire_vec4(wid,BIT4_0);
|
||||
break;
|
||||
case vpiLogicVar:
|
||||
vsig = new vvp_wire_vec4(wid,BIT4_Z);
|
||||
|
|
|
|||
Loading…
Reference in New Issue