diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 79a1e0ce2..5f03f20b4 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -393,38 +393,35 @@ int draw_function(ivl_scope_t scope, ivl_scope_t parent) const char *funcname = ivl_scope_tname(scope); - // This logic relies on the return value being the first port - vhdl_function *func = NULL; - int nports = ivl_scope_ports(scope); - for (int i = 0; i < nports; i++) { - ivl_signal_t sig = ivl_scope_port(scope, i); - std::string signame = make_safe_name(sig); - + // The return type is worked out from the output port + vhdl_function *func = new vhdl_function(funcname, NULL); + + int nsigs = ivl_scope_sigs(scope); + for (int i = 0; i < nsigs; i++) { + ivl_signal_t sig = ivl_scope_sig(scope, i); vhdl_type *sigtype = get_signal_type(sig); + + std::string signame = make_safe_name(sig); switch (ivl_signal_port(sig)) { case IVL_SIP_OUTPUT: - { - assert(func == NULL); - func = new vhdl_function(funcname, sigtype); - - // The magic variable Verilog_Result holds the return value - signame = "Verilog_Result"; - func->get_scope()->add_decl - (new vhdl_var_decl(signame.c_str(), new vhdl_type(*sigtype))); - } + // The magic variable Verilog_Result holds the return value + signame = "Verilog_Result"; + func->set_type(sigtype); + func->get_scope()->add_decl + (new vhdl_var_decl(signame.c_str(), new vhdl_type(*sigtype))); break; case IVL_SIP_INPUT: - assert(func); func->add_param(new vhdl_param_decl(signame.c_str(), sigtype)); break; default: assert(false); } - + 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); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index a356cb7b9..d650d2cd6 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -415,6 +415,7 @@ public: const std::string &get_name() const { return name_; } const vhdl_type *get_type() const; + void set_type(vhdl_type *t) { type_ = t; } void set_initial(vhdl_expr *initial); bool has_initial() const { return initial_ != NULL; } protected: