diff --git a/elaborate.cc b/elaborate.cc index 85a2ceb4c..1a99c7195 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -6136,6 +6136,38 @@ bool Design::check_proc_delay() const cerr << pr->get_fileline() << ": : A runtime" << " infinite loop may be possible." << endl; } + + // The always_comb/ff/latch blocks have special delay + // rules that need to be checked. + if ((pr->type() == IVL_PR_ALWAYS_COMB) || + (pr->type() == IVL_PR_ALWAYS_FF) || + (pr->type() == IVL_PR_ALWAYS_LATCH)) { + const NetEvWait *wait = dynamic_cast (pr->statement()); + if (! wait) { + // The always_comb/latch have an event wait + // added automatically by the compiler. + assert(pr->type() == IVL_PR_ALWAYS_FF); + cerr << pr->get_fileline() << ": error: the " + << "first statement of an always_ff must " + << "be an event control." << endl; + result_flag = false; + } else if (wait->statement()->delay_type() != NO_DELAY) { + cerr << pr->get_fileline() << ": error: there " + << "must "; + + if (pr->type() == IVL_PR_ALWAYS_FF) { + cerr << "only be a single event control " + << "and no blocking delays in an " + << "always_ff process."; + } else { + cerr << "be no event controls or blocking " + << "delays in an always_comb/latch " + << "process."; + } + cerr << endl; + result_flag = false; + } + } } /* If this is a final block it must not have a delay, diff --git a/net_event.cc b/net_event.cc index f384ffccf..8c66ff1bf 100644 --- a/net_event.cc +++ b/net_event.cc @@ -442,3 +442,8 @@ NetProc* NetEvWait::statement() { return statement_; } + +const NetProc* NetEvWait::statement() const +{ + return statement_; +} diff --git a/netlist.h b/netlist.h index ad8a78f9f..ab9aa78ba 100644 --- a/netlist.h +++ b/netlist.h @@ -3406,6 +3406,7 @@ class NetEvWait : public NetProc { inline bool has_t0_trigger() const { return has_t0_trigger_; }; NetProc*statement(); + const NetProc*statement() const; virtual bool emit_proc(struct target_t*) const; bool emit_recurse(struct target_t*) const;