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:
parent
734124e653
commit
9bcc658e37
23
vvp/ufunc.cc
23
vvp/ufunc.cc
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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*)
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
Loading…
Reference in New Issue