Generate `after' modifier instead of `wait' statements

This commit is contained in:
Nick Gasson 2008-06-12 11:24:43 +01:00
parent 645ee2003f
commit 8fe2211e2b
3 changed files with 45 additions and 13 deletions

View File

@ -171,7 +171,7 @@ static int draw_noop(vhdl_process *proc, stmt_container *container,
* assignment. * assignment.
*/ */
static int draw_nbassign(vhdl_process *proc, stmt_container *container, static int draw_nbassign(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt) ivl_statement_t stmt, vhdl_expr *after = NULL)
{ {
int nlvals = ivl_stmt_lvals(stmt); int nlvals = ivl_stmt_lvals(stmt);
if (nlvals != 1) { if (nlvals != 1) {
@ -195,7 +195,10 @@ static int draw_nbassign(vhdl_process *proc, stmt_container *container,
// The type here can be null as it is never actually needed // The type here can be null as it is never actually needed
vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL); vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL);
container->add_stmt(new vhdl_nbassign_stmt(lval_ref, rhs)); vhdl_nbassign_stmt *nbassign = new vhdl_nbassign_stmt(lval_ref, rhs);
if (after != NULL)
nbassign->set_after(after);
container->add_stmt(nbassign);
} }
else { else {
error("Only signals as lvals supported at the moment"); error("Only signals as lvals supported at the moment");
@ -221,16 +224,28 @@ static int draw_delay(vhdl_process *proc, stmt_container *container,
// VHDL wait statement compute the value from that. // VHDL wait statement compute the value from that.
// The other solution is to add them as parameters to // The other solution is to add them as parameters to
// the vhdl_process class // the vhdl_process class
vhdl_wait_stmt *wait = vhdl_expr *time = new vhdl_const_int(value);
new vhdl_wait_stmt(VHDL_WAIT_FOR_NS, new vhdl_const_int(value));
container->add_stmt(wait);
// Expand the sub-statement as well // If the sub-statement is an assignment then VHDL lets
// Often this would result in a useless `null' statement which // us put the delay after it, which is more compact and
// is caught here instead // idiomatic
ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt);
if (ivl_statement_type(sub_stmt) != IVL_ST_NOOP) ivl_statement_type_t type = ivl_statement_type(sub_stmt);
draw_stmt(proc, container, sub_stmt); if (type == IVL_ST_ASSIGN_NB) {
draw_nbassign(proc, container, sub_stmt, time);
}
else {
vhdl_wait_stmt *wait =
new vhdl_wait_stmt(VHDL_WAIT_FOR_NS, time);
container->add_stmt(wait);
// Expand the sub-statement as well
// Often this would result in a useless `null' statement which
// is caught here instead
if (ivl_statement_type(sub_stmt) != IVL_ST_NOOP)
draw_stmt(proc, container, sub_stmt);
}
return 0; return 0;
} }

View File

@ -484,11 +484,26 @@ void vhdl_fcall::emit(std::ofstream &of, int level) const
exprs_.emit(of, level); exprs_.emit(of, level);
} }
vhdl_nbassign_stmt::~vhdl_nbassign_stmt()
{
delete lhs_;
delete rhs_;
if (after_)
delete after_;
}
void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
{ {
lhs_->emit(of, level); lhs_->emit(of, level);
of << " <= "; of << " <= ";
rhs_->emit(of, level); rhs_->emit(of, level);
if (after_) {
of << " after ";
after_->emit(of, level);
of << " ns";
}
of << ";"; of << ";";
} }

View File

@ -226,12 +226,14 @@ private:
class vhdl_nbassign_stmt : public vhdl_seq_stmt { class vhdl_nbassign_stmt : public vhdl_seq_stmt {
public: public:
vhdl_nbassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) vhdl_nbassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs)
: lhs_(lhs), rhs_(rhs) {} : lhs_(lhs), rhs_(rhs), after_(NULL) {}
~vhdl_nbassign_stmt();
void set_after(vhdl_expr *after) { after_ = after; }
void emit(std::ofstream &of, int level) const; void emit(std::ofstream &of, int level) const;
private: private:
vhdl_var_ref *lhs_; vhdl_var_ref *lhs_;
vhdl_expr *rhs_; vhdl_expr *rhs_, *after_;
}; };
enum vhdl_wait_type_t { enum vhdl_wait_type_t {