diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index a5ca5d6ff..79a1e0ce2 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -425,6 +425,11 @@ int draw_function(ivl_scope_t scope, ivl_scope_t parent) remember_signal(sig, func->get_scope()); rename_signal(sig, signame); } + + // Non-blocking assignment not allowed in functions + func->get_scope()->set_allow_signal_assignment(false); + + draw_stmt(func, func->get_container(), ivl_scope_def(scope)); assert(func); ent->get_arch()->get_scope()->add_decl(func); diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 59166026d..c3bcaa183 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -116,6 +116,8 @@ static int draw_nbassign(vhdl_procedural *proc, stmt_container *container, return 1; } + assert(proc->get_scope()->allow_signal_assignment()); + ivl_lval_t lval = ivl_stmt_lval(stmt, 0); ivl_signal_t sig; if ((sig = ivl_lval_sig(lval))) { @@ -201,21 +203,27 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container, decl->set_initial(rhs); - // This signal may be used e.g. in a loop test so we need - // to make a variable as well - blocking_assign_to(proc, sig); - - // The signal may have been renamed by the above call - const std::string &renamed = get_renamed_signal(sig); + if (proc->get_scope()->allow_signal_assignment()) { + // This signal may be used e.g. in a loop test so we need + // to make a variable as well + blocking_assign_to(proc, sig); + + // The signal may have been renamed by the above call + const std::string &renamed = get_renamed_signal(sig); - vhdl_var_ref *lval_ref = new vhdl_var_ref(renamed.c_str(), NULL); - vhdl_var_ref *sig_ref = new vhdl_var_ref(signame.c_str(), NULL); - - vhdl_assign_stmt *assign = new vhdl_assign_stmt(lval_ref, sig_ref); - container->add_stmt(assign); + vhdl_var_ref *lval_ref = new vhdl_var_ref(renamed.c_str(), NULL); + vhdl_var_ref *sig_ref = new vhdl_var_ref(signame.c_str(), NULL); + + vhdl_assign_stmt *assign = new vhdl_assign_stmt(lval_ref, sig_ref); + container->add_stmt(assign); + } } else { - blocking_assign_to(proc, sig); + if (proc->get_scope()->allow_signal_assignment()) { + // Remember we need to write the variable back to the + // original signal + blocking_assign_to(proc, sig); + } // The signal may have been renamed by the above call const std::string &renamed = get_renamed_signal(sig); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 97fbc2753..87629a46f 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -26,7 +26,7 @@ #include vhdl_scope::vhdl_scope() - : parent_(NULL), init_(false) + : parent_(NULL), init_(false), sig_assign_(true) { } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 463a637b4..a356cb7b9 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -547,10 +547,13 @@ public: bool initializing() const { return init_; } void set_initializing(bool i) { init_ = i; } + + void set_allow_signal_assignment(bool b) { sig_assign_ = b; } + bool allow_signal_assignment() const { return sig_assign_; } private: decl_list_t decls_; vhdl_scope *parent_; - bool init_; + bool init_, sig_assign_; };