diff --git a/elaborate.cc b/elaborate.cc index e04189f3f..f2927719e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3381,29 +3381,6 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const verinum(1)); } 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; } @@ -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 * of root module names. The function locates the Module definitions @@ -3997,8 +4005,14 @@ Design* elaborate(listroots) rc &= rmod->elaborate(des, scope); } - 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; des = 0; } diff --git a/netlist.cc b/netlist.cc index e895b2fb7..fe09e0a7e 100644 --- a/netlist.cc +++ b/netlist.cc @@ -2610,7 +2610,9 @@ DelayType NetCondit::delay_type() const if (else_) { result = combine_delays(if_->delay_type(), else_->delay_type()); } 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; @@ -2650,7 +2652,6 @@ DelayType NetRepeat::delay_type() const DelayType NetTaskDef::delay_type() const { - if (proc_ == 0) return NO_DELAY; return proc_->delay_type(); } diff --git a/netlist.h b/netlist.h index 141c3d909..b962b9e3c 100644 --- a/netlist.h +++ b/netlist.h @@ -3715,6 +3715,7 @@ class Design { // PROCESSES void add_process(NetProcTop*); void delete_process(NetProcTop*); + bool check_always_delay() const; // Iterate over the design... void dump(ostream&) const;