Fix for pr2974294.
If a net is driven by a simple variable, an initial 'x' value is propagated to the net at time-0. The same thing should happen if a net is driven by a variable array word. This patch makes this happen by scheduling an initial event for each array port attached to a variable array.
This commit is contained in:
parent
301bbe94a0
commit
da9edeacc7
10
vvp/array.cc
10
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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue