vhdlpp: 'wait on' and 'wait until' statements.

This commit is contained in:
Maciej Suminski 2015-05-29 10:54:29 +02:00
parent 4a31f36646
commit 29ddd5208f
6 changed files with 115 additions and 5 deletions

View File

@ -359,7 +359,7 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
%type <sequ> sequential_statement if_statement signal_assignment signal_assignment_statement
%type <sequ> case_statement procedure_call procedure_call_statement
%type <sequ> loop_statement variable_assignment variable_assignment_statement
%type <sequ> assertion_statement report_statement return_statement wait_for_statement
%type <sequ> assertion_statement report_statement return_statement wait_statement
%type <range> range
%type <range_list> range_list index_constraint
@ -2201,7 +2201,7 @@ sequential_statement
| return_statement { $$ = $1; }
| report_statement { $$ = $1; }
| assertion_statement { $$ = $1; }
| wait_for_statement { $$ = $1; }
| wait_statement { $$ = $1; }
| K_null ';' { $$ = 0; }
| error ';'
{ errormsg(@1, "Syntax error in sequential statement.\n");
@ -2632,12 +2632,22 @@ variable_declaration /* IEEE 1076-2008 P6.4.2.4 */
}
;
wait_for_statement
wait_statement
: K_wait K_for expression ';'
{ WaitForStmt*tmp = new WaitForStmt($3);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_wait K_on expression ';'
{ WaitStmt*tmp = new WaitStmt(WaitStmt::ON, $3);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_wait K_until expression ';'
{ WaitStmt*tmp = new WaitStmt(WaitStmt::UNTIL, $3);
FILE_NAME(tmp, @1);
$$ = tmp;
}
;
waveform

View File

@ -289,3 +289,8 @@ WaitForStmt::WaitForStmt(Expression*delay)
: delay_(delay)
{
}
WaitStmt::WaitStmt(wait_type_t type, Expression*expr)
: type_(type), expr_(expr)
{
}

View File

@ -22,8 +22,7 @@
# include "LineInfo.h"
# include "parse_types.h"
# include <list>
# include <functional>
# include <set>
class ScopeBase;
class Entity;
@ -321,4 +320,21 @@ class WaitForStmt : public SequentialStmt {
Expression*delay_;
};
class WaitStmt : public SequentialStmt {
public:
typedef enum { ON, UNTIL } wait_type_t;
WaitStmt(wait_type_t type, Expression*expression);
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:
wait_type_t type_;
Expression*expr_;
// Sensitivity list for 'wait until' statement
std::set<ExpName*> sens_list_;
};
#endif /* IVL_sequential_H */

View File

@ -187,3 +187,10 @@ void WaitForStmt::dump(ostream&out, int indent) const
out << setw(indent+3) << "" << "delay: ";
delay_->dump(out, indent+3);
}
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);
}

View File

@ -19,6 +19,7 @@
# include "sequential.h"
# include "expression.h"
# include "scope.h"
int SequentialStmt::elaborate(Entity*, ScopeBase*)
{
@ -202,3 +203,26 @@ int WaitForStmt::elaborate(Entity*ent, ScopeBase*scope)
{
return delay_->elaborate_expr(ent, scope, 0);
}
int WaitStmt::elaborate(Entity*ent, ScopeBase*scope)
{
if(type_ == UNTIL) {
struct fill_sens_list_t : public ExprVisitor {
fill_sens_list_t(set<ExpName*>& sig_list)
: sig_list_(sig_list) {};
void operator() (Expression*s) {
if(ExpName*name = dynamic_cast<ExpName*>(s))
sig_list_.insert(name);
}
private:
set<ExpName*>& sig_list_;
} fill_sens_list(sens_list_);
// Fill the sensitivity list
expr_->visit(fill_sens_list);
}
return expr_->elaborate_expr(ent, scope, 0);
}

View File

@ -529,3 +529,51 @@ void WaitForStmt::write_to_stream(std::ostream&fd)
fd << "wait for ";
delay_->write_to_stream(fd);
}
int WaitStmt::emit(ostream&out, Entity*ent, ScopeBase*scope)
{
int errors = 0;
switch(type_) {
case ON:
out << "@(";
break;
case UNTIL:
if(!sens_list_.empty()) {
out << "@(";
for(std::set<ExpName*>::iterator it = sens_list_.begin();
it != sens_list_.end(); ++it) {
if(it != sens_list_.begin())
out << ",";
(*it)->emit(out, ent, scope);
}
out << ");";
}
out << "wait(";
break;
}
errors += expr_->emit(out, ent, scope);
out << ");" << endl;
return errors;
}
void WaitStmt::write_to_stream(std::ostream&fd)
{
switch(type_) {
case ON:
fd << "wait on ";
break;
case UNTIL:
fd << "wait until ";
break;
}
expr_->write_to_stream(fd);
}