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:
Martin Whitaker 2010-04-03 14:54:40 +01:00 committed by Stephen Williams
parent 301bbe94a0
commit da9edeacc7
3 changed files with 61 additions and 0 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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