diff --git a/vhdlpp/scope.h b/vhdlpp/scope.h index 118dbb862..f92a74403 100644 --- a/vhdlpp/scope.h +++ b/vhdlpp/scope.h @@ -67,6 +67,8 @@ class ScopeBase { // type is returned, otherwise NULL. const VTypeEnum* is_enum_name(perm_string name) const; + virtual bool is_subprogram() const { return false; } + // Moves signals, variables and components from another scope to // this one. After the transfer new_* maps are cleared in the source scope. enum transfer_type_t { SIGNALS = 1, VARIABLES = 2, COMPONENTS = 4, ALL = 0xffff }; diff --git a/vhdlpp/subprogram.h b/vhdlpp/subprogram.h index 82ba804d1..d06f82461 100644 --- a/vhdlpp/subprogram.h +++ b/vhdlpp/subprogram.h @@ -49,12 +49,13 @@ class SubprogramBody : public LineInfo, public ScopeBase { int emit(ostream&out, Entity*ent, ScopeBase*scope); // Emit body as it would show up in a package. - int emit_package(std::ostream&fd) const; + int emit_package(std::ostream&fd); void write_to_stream(std::ostream&fd) const; void dump(std::ostream&fd) const; const SubprogramHeader*header() const { return header_; } + bool is_subprogram() const { return true; } private: std::list*statements_; diff --git a/vhdlpp/subprogram_emit.cc b/vhdlpp/subprogram_emit.cc index 2dab34a89..2d9e4e533 100644 --- a/vhdlpp/subprogram_emit.cc +++ b/vhdlpp/subprogram_emit.cc @@ -26,15 +26,27 @@ using namespace std; -int SubprogramBody::emit_package(ostream&fd) const +int SubprogramBody::emit_package(ostream&fd) { int errors = 0; for (map::const_iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { - // Enable reg_flag for variables - cur->second->count_ref_sequ(); - errors += cur->second->emit(fd, NULL, NULL); + // Enable reg_flag for variables + cur->second->count_ref_sequ(); + errors += cur->second->emit(fd, NULL, this, false); + } + + // Emulate automatic functions (add explicit initial value assignments) + for (map::const_iterator cur = new_variables_.begin() + ; cur != new_variables_.end() ; ++cur) { + Variable*var = cur->second; + + if(const Expression*init = var->peek_init_expr()) { + fd << cur->first << " = "; + init->emit(fd, NULL, this); + fd << "; // automatic function emulation" << endl; + } } if (statements_) { @@ -54,13 +66,13 @@ int SubprogramHeader::emit_package(ostream&fd) const int errors = 0; if (return_type_) { - fd << "function "; + fd << "function automatic "; return_type_->emit_def(fd, empty_perm_string); } else { - fd << "task"; + fd << "task automatic"; } - fd << " \\" << name_ << " ("; + fd << " \\" << name_ << " ("; for (list::const_iterator cur = ports_->begin() ; cur != ports_->end() ; ++cur) { diff --git a/vhdlpp/vsignal.cc b/vhdlpp/vsignal.cc index ab949d7e1..5d5eca4ff 100644 --- a/vhdlpp/vsignal.cc +++ b/vhdlpp/vsignal.cc @@ -21,6 +21,7 @@ # include "vsignal.h" # include "expression.h" +# include "scope.h" # include "vtype.h" # include "std_types.h" # include @@ -49,7 +50,7 @@ void SigVarBase::type_elaborate_(VType::decl_t&decl) decl.type = type_; } -int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope) +int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope, bool initialize) { int errors = 0; @@ -62,8 +63,8 @@ int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope) decl.reg_flag = true; errors += decl.emit(out, peek_name()); - Expression*init_expr = peek_init_expr(); - if (init_expr) { + const Expression*init_expr = peek_init_expr(); + if (initialize && init_expr) { /* Emit initialization value for wires as a weak assignment */ if(!decl.reg_flag && !type->type_match(&primitive_REAL)) out << ";" << endl << "/*init*/ assign (weak1, weak0) " << peek_name(); @@ -75,17 +76,19 @@ int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } -int Variable::emit(ostream&out, Entity*ent, ScopeBase*scope) +int Variable::emit(ostream&out, Entity*ent, ScopeBase*scope, bool initialize) { int errors = 0; + out << (!scope->is_subprogram() ? "static " : "automatic "); + VType::decl_t decl; type_elaborate_(decl); decl.reg_flag = true; errors += decl.emit(out, peek_name()); - Expression*init_expr = peek_init_expr(); - if (init_expr) { + const Expression*init_expr = peek_init_expr(); + if (initialize && init_expr) { out << " = "; init_expr->emit(out, ent, scope); } diff --git a/vhdlpp/vsignal.h b/vhdlpp/vsignal.h index 9beda6cef..27de1d778 100644 --- a/vhdlpp/vsignal.h +++ b/vhdlpp/vsignal.h @@ -46,14 +46,13 @@ class SigVarBase : public LineInfo { void elaborate(Entity*ent, ScopeBase*scope); perm_string peek_name() const { return name_; } + const Expression* peek_init_expr() const { return init_expr_; } protected: unsigned peek_refcnt_sequ_() const { return refcnt_sequ_; } void type_elaborate_(VType::decl_t&decl); - Expression* peek_init_expr() const { return init_expr_; } - private: perm_string name_; const VType*type_; @@ -71,7 +70,7 @@ class Signal : public SigVarBase { public: Signal(perm_string name, const VType*type, Expression*init_expr); - int emit(ostream&out, Entity*ent, ScopeBase*scope); + int emit(ostream&out, Entity*ent, ScopeBase*scope, bool initalize = true); }; class Variable : public SigVarBase { @@ -79,7 +78,7 @@ class Variable : public SigVarBase { public: Variable(perm_string name, const VType*type, Expression*init_expr = NULL); - int emit(ostream&out, Entity*ent, ScopeBase*scope); + int emit(ostream&out, Entity*ent, ScopeBase*scope, bool initialize = true); void write_to_stream(std::ostream&fd); };