diff --git a/vvp/array.cc b/vvp/array.cc index 1084aad27..3da139885 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -1359,6 +1359,16 @@ static void array_attach_port(vvp_array_t array, vvp_fun_arrayport*fun) assert(fun->next_ == 0); fun->next_ = array->ports_; array->ports_ = fun; + if (!array->scope->is_automatic) { + /* propagate initial values for variable arrays */ + if (array->vals4) { + vvp_vector4_t tmp(array->vals_width, BIT4_X); + schedule_init_propagate(fun->net_, tmp); + } + if (array->valsr) { + schedule_init_propagate(fun->net_, 0.0); + } + } } void array_word_change(vvp_array_t array, unsigned long addr) diff --git a/vvp/schedule.cc b/vvp/schedule.cc index 4c0fc3682..58c361a0a 100644 --- a/vvp/schedule.cc +++ b/vvp/schedule.cc @@ -323,6 +323,9 @@ unsigned long count_assign_aword_pool(void) { return array_w_heap.pool; } * vvp_net_t object. */ struct propagate_vector4_event_s : public event_s { + /* The default constructor. */ + propagate_vector4_event_s(const vvp_vector4_t&that) : val(that) { } + /* A constructor that makes the val directly. */ propagate_vector4_event_s(const vvp_vector4_t&that, unsigned adr, unsigned wid) : val(that,adr,wid) { } @@ -345,6 +348,30 @@ void propagate_vector4_event_s::single_step_display(void) cerr << "propagate_vector4_event: Propagate val=" << val << endl; } +/* + * This class supports the propagation of real outputs from a + * vvp_net_t object. + */ +struct propagate_real_event_s : public event_s { + /* Propagate the output of this net. */ + vvp_net_t*net; + /* value to propagate */ + double val; + /* Action */ + void run_run(void); + void single_step_display(void); +}; + +void propagate_real_event_s::run_run(void) +{ + net->send_real(val, 0); +} + +void propagate_real_event_s::single_step_display(void) +{ + cerr << "propagate_real_event: Propagate val=" << val << endl; +} + struct assign_array_r_word_s : public event_s { vvp_array_t mem; unsigned adr; @@ -805,6 +832,23 @@ void schedule_init_vector(vvp_net_ptr_t ptr, double bit) schedule_init_list = cur; } +void schedule_init_propagate(vvp_net_t*net, vvp_vector4_t bit) +{ + struct propagate_vector4_event_s*cur = new struct propagate_vector4_event_s(bit); + cur->net = net; + cur->next = schedule_init_list; + schedule_init_list = cur; +} + +void schedule_init_propagate(vvp_net_t*net, double bit) +{ + struct propagate_real_event_s*cur = new struct propagate_real_event_s; + cur->net = net; + cur->val = bit; + cur->next = schedule_init_list; + schedule_init_list = cur; +} + void schedule_del_thr(vthread_t thr) { struct del_thr_event_s*cur = new del_thr_event_s; diff --git a/vvp/schedule.h b/vvp/schedule.h index 5393e3417..da915c751 100644 --- a/vvp/schedule.h +++ b/vvp/schedule.h @@ -92,6 +92,13 @@ extern void schedule_set_vector(vvp_net_ptr_t ptr, double val); extern void schedule_init_vector(vvp_net_ptr_t ptr, vvp_vector4_t val); extern void schedule_init_vector(vvp_net_ptr_t ptr, vvp_vector8_t val); extern void schedule_init_vector(vvp_net_ptr_t ptr, double val); +/* + * The schedule_init_propagate function is similar to the above but + * propagates an initial value from a net output (i.e. without passing + * through the net functor). + */ +extern void schedule_init_propagate(vvp_net_t*net, vvp_vector4_t val); +extern void schedule_init_propagate(vvp_net_t*net, double val); /* * Create a generic event. This supports scheduled events that are not