Fix the always zero delay check to happen after elaboration.
This patch moves the always zero or possibly zero delay checks to a point after the circuit is full elaborated. Before it could try to check tasks that had not already been evaluated resulting in a crash.
This commit is contained in:
parent
d15e2a2f73
commit
8c38872b4b
62
elaborate.cc
62
elaborate.cc
|
|
@ -3381,29 +3381,6 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
|
||||||
verinum(1));
|
verinum(1));
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
/* If this is an always block and we have no or zero delay then
|
|
||||||
* a runtime infinite loop will happen. If we possible have some
|
|
||||||
* delay then print a warning that an infinite loop is possible.
|
|
||||||
*/
|
|
||||||
if (type() == PProcess::PR_ALWAYS) {
|
|
||||||
DelayType dly_type = top->statement()->delay_type();
|
|
||||||
|
|
||||||
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
|
||||||
cerr << get_fileline() << ": error: always statement"
|
|
||||||
<< " does not have any delay." << endl;
|
|
||||||
cerr << get_fileline() << ": : A runtime infinite"
|
|
||||||
<< " loop will occur." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
|
||||||
cerr << get_fileline() << ": warning: always statement"
|
|
||||||
<< " may not have any delay." << endl;
|
|
||||||
cerr << get_fileline() << ": : A runtime infinite"
|
|
||||||
<< " loop may be possible." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3871,6 +3848,37 @@ class later_defparams : public elaborator_work_item_t {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool Design::check_always_delay() const
|
||||||
|
{
|
||||||
|
bool result_flag = true;
|
||||||
|
|
||||||
|
for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) {
|
||||||
|
/* If this is an always block and we have no or zero delay then
|
||||||
|
* a runtime infinite loop will happen. If we possible have some
|
||||||
|
* delay then print a warning that an infinite loop is possible.
|
||||||
|
*/
|
||||||
|
if (pr->type() == NetProcTop::KALWAYS) {
|
||||||
|
DelayType dly_type = pr->statement()->delay_type();
|
||||||
|
|
||||||
|
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
||||||
|
cerr << pr->get_fileline() << ": error: always"
|
||||||
|
<< " statement does not have any delay." << endl;
|
||||||
|
cerr << pr->get_fileline() << ": : A runtime"
|
||||||
|
<< " infinite loop will occur." << endl;
|
||||||
|
result_flag = false;
|
||||||
|
|
||||||
|
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
||||||
|
cerr << pr->get_fileline() << ": warning: always"
|
||||||
|
<< " statement may not have any delay." << endl;
|
||||||
|
cerr << pr->get_fileline() << ": : A runtime"
|
||||||
|
<< " infinite loop may be possible." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_flag;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is the root of all elaboration. The input is the list
|
* This function is the root of all elaboration. The input is the list
|
||||||
* of root module names. The function locates the Module definitions
|
* of root module names. The function locates the Module definitions
|
||||||
|
|
@ -3997,8 +4005,14 @@ Design* elaborate(list<perm_string>roots)
|
||||||
rc &= rmod->elaborate(des, scope);
|
rc &= rmod->elaborate(des, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (rc == false) {
|
if (rc == false) {
|
||||||
|
delete des;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that everything is fully elaborated verify that we do
|
||||||
|
// not have an always block with no delay (an infinite loop).
|
||||||
|
if (des->check_always_delay() == false) {
|
||||||
delete des;
|
delete des;
|
||||||
des = 0;
|
des = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2610,7 +2610,9 @@ DelayType NetCondit::delay_type() const
|
||||||
if (else_) {
|
if (else_) {
|
||||||
result = combine_delays(if_->delay_type(), else_->delay_type());
|
result = combine_delays(if_->delay_type(), else_->delay_type());
|
||||||
} else {
|
} else {
|
||||||
result = if_->delay_type();
|
/* Because of the indeterminate conditional value the
|
||||||
|
* best we can have for this case is a possible delay. */
|
||||||
|
result = combine_delays(if_->delay_type(), NO_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -2650,7 +2652,6 @@ DelayType NetRepeat::delay_type() const
|
||||||
|
|
||||||
DelayType NetTaskDef::delay_type() const
|
DelayType NetTaskDef::delay_type() const
|
||||||
{
|
{
|
||||||
if (proc_ == 0) return NO_DELAY;
|
|
||||||
return proc_->delay_type();
|
return proc_->delay_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3715,6 +3715,7 @@ class Design {
|
||||||
// PROCESSES
|
// PROCESSES
|
||||||
void add_process(NetProcTop*);
|
void add_process(NetProcTop*);
|
||||||
void delete_process(NetProcTop*);
|
void delete_process(NetProcTop*);
|
||||||
|
bool check_always_delay() const;
|
||||||
|
|
||||||
// Iterate over the design...
|
// Iterate over the design...
|
||||||
void dump(ostream&) const;
|
void dump(ostream&) const;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue