Detect and handle unpropagated ufunc input.

During startup it is possible for input port to not yet be
initialized even after some other input ports trigger the
function to be evaluated. Handle this case by substituting
a vector of 'bx for the uninitialized inputs. This will shake
out when the simulation gets going, and only matters for user
defined functions in continuous assignments.

While we're at it, have vec4_unfiltered_value return a reference
to reduce copying of vectors.
This commit is contained in:
Stephen Williams 2009-11-29 09:59:51 -08:00
parent 734124e653
commit 9bcc658e37
3 changed files with 30 additions and 10 deletions

View File

@ -73,10 +73,29 @@ void ufunc_core::assign_bits_to_ports(vvp_context_t context)
for (unsigned idx = 0 ; idx < port_count() ; idx += 1) {
vvp_net_t*net = ports_[idx];
vvp_net_ptr_t pp (net, 0);
// If the port is a real variable, then simply copy the
// propagated input to the port variable.
if (vvp_fun_signal_real*tmp = dynamic_cast<vvp_fun_signal_real*>(net->fun))
tmp->recv_real(pp, value_r(idx), context);
if (vvp_fun_signal_vec*tmp = dynamic_cast<vvp_fun_signal_vec*>(net->fun))
tmp->recv_vec4(pp, value(idx), context);
// If the port is a bit4 vector, then copy the
// propagated input to the port variable. Detect the
// special case that the input vector is nil, and
// convert that to an 'bx vector that matches the width
// of the port variable. This is to handle the uncommon
// startup case where the input values have not
// propagated useful values yet.
if (vvp_fun_signal_vec*tmp = dynamic_cast<vvp_fun_signal_vec*>(net->fun)) {
const vvp_vector4_t&tmp_val = value(idx);
if (tmp_val.size() == 0) {
const vvp_vector4_t&ref = tmp->vec4_unfiltered_value();
vvp_vector4_t xxx (ref.size(), BIT4_X);
tmp->recv_vec4(pp, xxx, context);
} else {
tmp->recv_vec4(pp, tmp_val, context);
}
}
}
}

View File

@ -283,7 +283,7 @@ void automatic_signal_base::get_value(struct t_vpi_value*)
assert(0);
}
vvp_vector4_t vvp_fun_signal4_sa::vec4_unfiltered_value() const
const vvp_vector4_t& vvp_fun_signal4_sa::vec4_unfiltered_value() const
{
return bits4_;
}
@ -388,11 +388,12 @@ void vvp_fun_signal4_aa::vec4_value(vvp_vector4_t&val) const
val = *bits4;
}
vvp_vector4_t vvp_fun_signal4_aa::vec4_unfiltered_value() const
const vvp_vector4_t&vvp_fun_signal4_aa::vec4_unfiltered_value() const
{
vvp_vector4_t tmp;
vec4_value(tmp);
return tmp;
vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
(vthread_get_rd_context_item(context_idx_));
return *bits4;
}
void vvp_fun_signal4_aa::operator delete(void*)

View File

@ -111,7 +111,7 @@ class vvp_signal_value {
*/
class vvp_fun_signal_vec : public vvp_fun_signal_base {
public:
virtual vvp_vector4_t vec4_unfiltered_value() const =0;
virtual const vvp_vector4_t& vec4_unfiltered_value() const =0;
};
class automatic_signal_base : public vvp_signal_value, public vvp_net_fil_t {
@ -149,7 +149,7 @@ class vvp_fun_signal4_sa : public vvp_fun_signal_vec {
unsigned base, unsigned wid, unsigned vwid);
// Get information about the vector value.
vvp_vector4_t vec4_unfiltered_value() const;
const vvp_vector4_t& vec4_unfiltered_value() const;
private:
vvp_vector4_t bits4_;
@ -183,7 +183,7 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_ba
vvp_bit4_t value(unsigned idx) const;
vvp_scalar_t scalar_value(unsigned idx) const;
void vec4_value(vvp_vector4_t&) const;
vvp_vector4_t vec4_unfiltered_value() const;
const vvp_vector4_t& vec4_unfiltered_value() const;
public: // These objects are only permallocated.
static void* operator new(std::size_t size) { return vvp_net_fun_t::heap_.alloc(size); }