vhdlpp: Delayed assignment statements.

This commit is contained in:
Maciej Suminski 2016-01-21 10:52:18 +01:00
parent eeb5728e20
commit a884faa8c1
8 changed files with 79 additions and 4 deletions

View File

@ -132,16 +132,21 @@ int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
int errors = 0;
ivl_assert(*this, rval_.size() == 1);
Expression*rval = rval_.front();
const Expression*rval = rval_.front();
out << "// " << get_fileline() << endl;
out << "assign ";
if(const ExpDelay*delayed = dynamic_cast<const ExpDelay*>(rval)) {
out << "#(";
delayed->peek_delay()->emit(out, ent, arc);
out << ") ";
rval = delayed->peek_expr();
}
errors += lval_->emit(out, ent, arc);
out << " = ";
errors += rval->emit(out, ent, arc);
out << ";" << endl;
return errors;
}
@ -316,5 +321,4 @@ int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
out << "end" << endl;
return errors;
}

View File

@ -846,3 +846,14 @@ Expression*ExpRange::right()
ExpAttribute::RIGHT, NULL);
return right_;
}
ExpDelay::ExpDelay(Expression*expr, Expression*delay)
: expr_(expr), delay_(delay)
{
}
ExpDelay::~ExpDelay()
{
delete expr_;
delete delay_;
}

View File

@ -982,6 +982,27 @@ class ExpRange : public Expression {
bool range_reverse_;
};
// Helper class that wraps other expression to specify delay.
class ExpDelay : public Expression {
public:
ExpDelay(Expression*expr, Expression*delay);
~ExpDelay();
Expression*clone() const { return new ExpDelay(expr_->clone(), delay_->clone()); }
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
void write_to_stream(std::ostream&) const;
int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
void dump(ostream&out, int indent = 0) const;
const Expression*peek_expr() const { return expr_; }
const Expression*peek_delay() const { return delay_; }
private:
Expression*expr_;
Expression*delay_;
};
// Elaborates an expression used as an argument in a procedure/function call.
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope);

View File

@ -123,3 +123,11 @@ void ExpRange::dump(ostream&out, int indent) const
out << setw(indent) << "" << "Range ";
write_to_stream(out);
}
void ExpDelay::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Expression ";
expr_->write_to_stream(out);
out << " delayed by ";
delay_->write_to_stream(out);
}

View File

@ -1100,6 +1100,16 @@ int ExpRange::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
return errors;
}
int ExpDelay::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
{
int errors = 0;
errors += expr_->elaborate_expr(ent, scope, ltype);
errors += delay_->elaborate_expr(ent, scope, ltype);
return errors;
}
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope)
{

View File

@ -1091,3 +1091,15 @@ int ExpRange::emit(ostream&out, Entity*ent, ScopeBase*scope) const
return 0;
}
int ExpDelay::emit(ostream&out, Entity*ent, ScopeBase*scope) const
{
int errors = 0;
out << "#(";
errors += delay_->emit(out, ent, scope);
out << ") ";
errors += expr_->emit(out, ent, scope);
return errors;
}

View File

@ -334,3 +334,10 @@ void ExpRange::write_to_stream(ostream&fd) const
right_->write_to_stream(fd);
}
}
void ExpDelay::write_to_stream(ostream&out) const
{
expr_->write_to_stream(out);
out << " after ";
delay_->write_to_stream(out);
}

View File

@ -2882,6 +2882,8 @@ waveform_elements
waveform_element
: expression
{ $$ = $1; }
| expression K_after expression
{ $$ = new ExpDelay($1, $3); }
| K_null
{ $$ = 0; }
;