diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index 42e9ab035..22f37dcc4 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -288,7 +288,16 @@ int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc) */ int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc) { - out << "always begin" << endl; + /* Check if the process has no sensitivity list and ends up with + * a final wait. If so, convert the process to an initial block. */ + const WaitStmt*wait_stmt = NULL; + if (! stmt_list().empty()) + wait_stmt = dynamic_cast(stmt_list().back()); + + if (wait_stmt && wait_stmt->type() == WaitStmt::FINAL) + out << "initial begin" << endl; + else + out << "always begin" << endl; int errors = StatementList::emit(out, ent, arc); diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 014ba0bdd..d6d7acb8f 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -2837,6 +2837,11 @@ wait_statement FILE_NAME(tmp, @1); $$ = tmp; } + | K_wait ';' + { WaitStmt*tmp = new WaitStmt(WaitStmt::FINAL, NULL); + FILE_NAME(tmp, @1); + $$ = tmp; + } ; waveform diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index 43f3ac344..612a19b73 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -332,7 +332,7 @@ class WaitForStmt : public SequentialStmt { class WaitStmt : public SequentialStmt { public: - typedef enum { ON, UNTIL } wait_type_t; + typedef enum { ON, UNTIL, FINAL } wait_type_t; WaitStmt(wait_type_t type, Expression*expression); void dump(ostream&out, int indent) const; @@ -340,6 +340,8 @@ class WaitStmt : public SequentialStmt { int emit(ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); + inline wait_type_t type() const { return type_; } + private: wait_type_t type_; Expression*expr_; diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index 7abb63d6f..ac4096568 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -199,6 +199,16 @@ void WaitForStmt::dump(ostream&out, int indent) const void WaitStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "WaitStmt at file=" << get_fileline() << endl; - out << setw(indent+3) << "" << "expression: "; - expr_->dump(out, indent+3); + out << setw(indent+3) << "type = "; + + switch(type_) { + case ON: out << "ON" << endl; break; + case UNTIL: out << "UNTIL" << endl; break; + case FINAL: out << "FINAL" << endl; break; + } + + if(type_ != FINAL) { + out << setw(indent+3) << "" << "expression: "; + expr_->dump(out, indent+3); + } } diff --git a/vhdlpp/sequential_elaborate.cc b/vhdlpp/sequential_elaborate.cc index f60eb0759..6756becaf 100644 --- a/vhdlpp/sequential_elaborate.cc +++ b/vhdlpp/sequential_elaborate.cc @@ -253,6 +253,8 @@ int WaitStmt::elaborate(Entity*ent, ScopeBase*scope) // Fill the sensitivity list expr_->visit(fill_sens_list); + } else if(type_ == FINAL) { + return 0; // nothing to be elaborated } return expr_->elaborate_expr(ent, scope, 0); diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index f5454c1f3..389063744 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -602,6 +602,10 @@ int WaitStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) out << "wait("; break; + + case FINAL: + out << "/* final wait */" << endl; + return 0; // no expression to be emitted } errors += expr_->emit(out, ent, scope); @@ -620,6 +624,10 @@ void WaitStmt::write_to_stream(std::ostream&fd) case UNTIL: fd << "wait until "; break; + + case FINAL: + fd << "wait"; + return; // no expression to be emitted } expr_->write_to_stream(fd);