diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 7b3b4212b..b6a877438 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -359,7 +359,7 @@ static void touchup_interface_for_functions(std::list*ports) %type sequential_statement if_statement signal_assignment signal_assignment_statement %type case_statement procedure_call procedure_call_statement %type loop_statement variable_assignment variable_assignment_statement -%type assertion_statement report_statement return_statement +%type assertion_statement report_statement return_statement wait_for_statement %type range %type range_list index_constraint @@ -2201,6 +2201,7 @@ sequential_statement | return_statement { $$ = $1; } | report_statement { $$ = $1; } | assertion_statement { $$ = $1; } + | wait_for_statement { $$ = $1; } | K_null ';' { $$ = 0; } | error ';' { errormsg(@1, "Syntax error in sequential statement.\n"); @@ -2631,6 +2632,14 @@ variable_declaration /* IEEE 1076-2008 P6.4.2.4 */ } ; +wait_for_statement + : K_wait K_for expression ';' + { WaitForStmt*tmp = new WaitForStmt($3); + FILE_NAME(tmp, @1); + $$ = tmp; + } + ; + waveform : waveform_elements { $$ = $1; } diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index 95497a987..b6a4c1079 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -284,3 +284,8 @@ AssertStmt::AssertStmt(Expression*condition, const char*msg, ReportStmt::severit } const std::string AssertStmt::default_msg_ = std::string("Assertion violation."); + +WaitForStmt::WaitForStmt(Expression*delay) +: delay_(delay) +{ +} diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index d561b0559..ed7bb17a8 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -308,4 +308,17 @@ class AssertStmt : public ReportStmt { static const std::string default_msg_; }; +class WaitForStmt : public SequentialStmt { + public: + WaitForStmt(Expression*delay); + + void dump(ostream&out, int indent) const; + int elaborate(Entity*ent, ScopeBase*scope); + int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); + + private: + Expression*delay_; +}; + #endif /* IVL_sequential_H */ diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index 786fa5cc6..5c40b5012 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -180,3 +180,10 @@ void AssertStmt::dump(ostream&out, int indent) const cond_->dump(out, indent+3); ReportStmt::dump(out, indent+3); } + +void WaitForStmt::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "WaitForStmt at file=" << get_fileline() << endl; + out << setw(indent+3) << "" << "delay: "; + delay_->dump(out, indent+3); +} diff --git a/vhdlpp/sequential_elaborate.cc b/vhdlpp/sequential_elaborate.cc index 2c342030b..a0cfafe6d 100644 --- a/vhdlpp/sequential_elaborate.cc +++ b/vhdlpp/sequential_elaborate.cc @@ -197,3 +197,8 @@ int AssertStmt::elaborate(Entity*ent, ScopeBase*scope) { return cond_->elaborate_expr(ent, scope, 0); } + +int WaitForStmt::elaborate(Entity*ent, ScopeBase*scope) +{ + return delay_->elaborate_expr(ent, scope, 0); +} diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 29f488b80..f0e6f0b5c 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -512,3 +512,20 @@ void AssertStmt::write_to_stream(std::ostream&fd) fd << std::endl; ReportStmt::write_to_stream(fd); } + +int WaitForStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) +{ + int errors = 0; + + out << "#("; + errors += delay_->emit(out, ent, scope); + out << ")"; + + return errors; +} + +void WaitForStmt::write_to_stream(std::ostream&fd) +{ + fd << "wait for "; + delay_->write_to_stream(fd); +}