Handle initialization propagation of wires.

The first input through a net needs to be propagated, since this
is used as an initialization for the net. This patch also cleans
up wires to not need the width_ member, instead inferring the
width from the saved bit value.
This commit is contained in:
Stephen Williams 2009-09-12 18:46:48 -07:00
parent 03f2432f6e
commit 72ab7b6515
4 changed files with 54 additions and 18 deletions

View File

@ -24,6 +24,7 @@
# include <stdio.h>
# include <assert.h>
# include <stdlib.h>
# include <iostream>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
@ -67,7 +68,16 @@ void vvp_dff::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
break;
case 3: // Asynch-D
d_ = bit;
// FIXME! The code generator is writing an input C4<z>
// no matter what the intent of this device. This is
// almost certainly NOT correct, nor do we want to
// propagate that. But that needs to be fixed later.
if (bit.size() == 1 && bit.value(0)==BIT4_Z)
break;
if (d_.size() > bit.size())
d_ .copy_bits(bit);
else
d_ = bit;
port.ptr()->send_vec4(d_, 0);
break;
}

View File

@ -608,35 +608,57 @@ vvp_wire_base::~vvp_wire_base()
}
vvp_wire_vec4::vvp_wire_vec4(unsigned wid, vvp_bit4_t init)
: width_(wid), bits4_(wid, init)
: bits4_(wid, init)
{
needs_init_ = true;
}
vvp_net_fil_t::prop_t vvp_wire_vec4::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 BIT4_X to match the width of the bits4_ vector.
// FIXME! This is a hack to work around some buggy gate
// implementations! This should be removed!
if (base==0 && vwid==0) {
vvp_vector4_t tmp (bits4_.size(), BIT4_X);
if (bits4_ .eeq(tmp) && !needs_init_) return STOP;
bits4_ = tmp;
needs_init_ = false;
return filter_mask_(tmp, force4_, rep, 0);
}
if (vwid != bits4_.size()) {
cerr << "Internal error: Input vector expected width="
<< bits4_.size() << ", got "
<< "bit=" << bit << ", base=" << base << ", vwid=" << vwid
<< endl;
}
assert(bits4_.size() == vwid);
// Keep track of the value being driven from this net, even if
// it is not ultimately what survives the force filter.
if (base==0 && bit.size()==vwid) {
if (bits4_ .eeq( bit ) && !needs_init_) return STOP;
bits4_ = bit;
} else {
if (bits4_.size() == 0)
bits4_ = vvp_vector4_t(vwid, BIT4_Z);
assert(bits4_.size() == vwid);
bits4_.set_vec(base, bit);
}
needs_init_ = false;
return filter_mask_(bit, force4_, rep, base);
}
vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep, unsigned base, unsigned vwid)
{
assert(bits4_.size() == bit.size());
bits4_ = reduce4(bit);
return filter_mask_(bit, vvp_vector8_t(force4_,6,6), rep, 0);
}
unsigned vvp_wire_vec4::filter_size() const
{
return width_;
return bits4_.size();
}
void vvp_wire_vec4::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
@ -669,7 +691,7 @@ void vvp_wire_vec4::force_fil_real(double val, vvp_vector2_t mask)
void vvp_wire_vec4::release(vvp_net_ptr_t ptr, bool net_flag)
{
// Wires revert to their unforced value after release.
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
vvp_vector2_t mask (vvp_vector2_t::FILL1, bits4_.size());
release_mask(mask);
if (net_flag) {
ptr.ptr()->send_vec4(bits4_, 0);
@ -701,7 +723,7 @@ void vvp_wire_vec4::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, b
unsigned vvp_wire_vec4::value_size() const
{
return width_;
return bits4_.size();
}
vvp_bit4_t vvp_wire_vec4::filtered_value_(unsigned idx) const
@ -731,8 +753,9 @@ vvp_vector4_t vvp_wire_vec4::vec4_value() const
}
vvp_wire_vec8::vvp_wire_vec8(unsigned wid)
: width_(wid)
: bits8_(wid)
{
needs_init_ = true;
}
vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep,
@ -746,11 +769,13 @@ vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit, vvp_ve
if (rc == REPL)
rep = reduce4(rep8);
needs_init_ = false;
return rc;
}
vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep, unsigned base, unsigned vwid)
{
assert(vwid == bits8_.size());
// Keep track of the value being driven from this net, even if
// it is not ultimately what survives the force filter.
if (base==0 && bit.size()==vwid) {
@ -761,12 +786,13 @@ vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit, vvp_ve
assert(bits8_.size() == vwid);
bits8_.set_vec(base, bit);
}
needs_init_ = false;
return filter_mask_(bit, force8_, rep, base);
}
unsigned vvp_wire_vec8::filter_size() const
{
return width_;
return bits8_.size();
}
void vvp_wire_vec8::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
@ -799,7 +825,7 @@ void vvp_wire_vec8::force_fil_real(double val, vvp_vector2_t mask)
void vvp_wire_vec8::release(vvp_net_ptr_t ptr, bool net_flag)
{
// Wires revert to their unforced value after release.
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
vvp_vector2_t mask (vvp_vector2_t::FILL1, bits8_.size());
release_mask(mask);
if (net_flag)
ptr.ptr()->send_vec8(bits8_);
@ -809,9 +835,9 @@ void vvp_wire_vec8::release(vvp_net_ptr_t ptr, bool net_flag)
void vvp_wire_vec8::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag)
{
assert(width_ >= base + wid);
assert(bits8_.size() >= base + wid);
vvp_vector2_t mask (vvp_vector2_t::FILL0, width_);
vvp_vector2_t mask (vvp_vector2_t::FILL0, bits8_.size());
for (unsigned idx = 0 ; idx < wid ; idx += 1)
mask.set_bit(base+idx, 1);
@ -829,7 +855,7 @@ void vvp_wire_vec8::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, b
unsigned vvp_wire_vec8::value_size() const
{
return width_;
return bits8_.size();
}
vvp_scalar_t vvp_wire_vec8::filtered_value_(unsigned idx) const

View File

@ -286,7 +286,7 @@ class vvp_wire_base : public vvp_net_fil_t, public vvp_signal_value {
class vvp_wire_vec4 : public vvp_wire_base {
public:
vvp_wire_vec4(unsigned wid, vvp_bit4_t init=BIT4_X);
vvp_wire_vec4(unsigned wid, vvp_bit4_t init);
// The main filter behavior for this class. These methods take
// the value that the node is driven to, and applies the firce
@ -317,7 +317,7 @@ class vvp_wire_vec4 : public vvp_wire_base {
vvp_bit4_t filtered_value_(unsigned idx) const;
private:
unsigned width_;
bool needs_init_;
vvp_vector4_t bits4_; // The tracked driven value
vvp_vector4_t force4_; // the value being forced
};
@ -355,7 +355,7 @@ class vvp_wire_vec8 : public vvp_wire_base {
vvp_scalar_t filtered_value_(unsigned idx) const;
private:
unsigned width_;
bool needs_init_;
vvp_vector8_t bits8_;
vvp_vector8_t force8_; // the value being forced
};

View File

@ -89,7 +89,7 @@ static void __compile_var(char*label, char*name,
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_fun_signal_vec*vsig;
vvp_wire_vec4*vfil = new vvp_wire_vec4(wid);
vvp_wire_vec4*vfil = new vvp_wire_vec4(wid, BIT4_X);
if (vpip_peek_current_scope()->is_automatic) {
vsig = new vvp_fun_signal4_aa(wid);
} else {