diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index fe7ed4c48..15d214547 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -397,9 +397,11 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container, // Don't generate a zero-wait if this is the last statement in // the process - if (!is_last) + if (!is_last) { container->add_stmt (new vhdl_wait_stmt(VHDL_WAIT_FOR0)); + proc->added_wait_stmt(); + } } else make_assignment(proc, container, stmt, true); @@ -458,6 +460,11 @@ static int draw_delay(vhdl_procedural *proc, stmt_container *container, ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); vhdl_wait_stmt *wait = new vhdl_wait_stmt(VHDL_WAIT_FOR, time); + + // Remember that we needed a wait statement so if this is + // a process it cannot have a sensitivity list + proc->added_wait_stmt(); + container->add_stmt(wait); // Expand the sub-statement as well @@ -679,8 +686,8 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, // See if this can be implemented in a more idomatic way before we // fall back on the generic translation // TODO: put a flag here to enable this! - if (draw_synthesisable_wait(proc, container, stmt)) - return 0; + //if (draw_synthesisable_wait(proc, container, stmt)) + // return 0; vhdl_binop_expr *test = new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean()); @@ -695,7 +702,15 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, } if (combinatorial) { - vhdl_wait_stmt *wait = new vhdl_wait_stmt(VHDL_WAIT_ON); + // If the process has no wait statement in its body then + // add all the events to the sensitivity list, otherwise + // build a wait-on statement at the end of the process + + draw_stmt(proc, container, ivl_stmt_sub_stmt(stmt), true); + + vhdl_wait_stmt *wait = NULL; + if (proc->contains_wait_stmt()) + wait = new vhdl_wait_stmt(VHDL_WAIT_ON); for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); @@ -705,13 +720,16 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, ivl_nexus_t nexus = ivl_event_any(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); - wait->add_sensitivity(ref->get_name()); + if (wait) + wait->add_sensitivity(ref->get_name()); + else + proc->add_sensitivity(ref->get_name()); delete ref; } } - draw_stmt(proc, container, ivl_stmt_sub_stmt(stmt), true); - container->add_stmt(wait); + if (proc->contains_wait_stmt()) + container->add_stmt(wait); } else { for (int i = 0; i < nevents; i++) { diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 45c5687ee..bd0339fd6 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -724,13 +724,23 @@ private: */ class vhdl_procedural { public: + vhdl_procedural() : contains_wait_stmt_(false) {} virtual ~vhdl_procedural() {} virtual stmt_container *get_container() { return &stmts_; } virtual vhdl_scope *get_scope() { return &scope_; } + + void added_wait_stmt() { contains_wait_stmt_ = true; } + bool contains_wait_stmt() const { return contains_wait_stmt_; } protected: stmt_container stmts_; vhdl_scope scope_; + + // If this is true then the body contains a `wait' statement + // embedded in it somewhere + // If this is the case then we can't use a sensitvity list for + // the process + bool contains_wait_stmt_; };