Merge pull request #95 from orsonmmz/automatic_rebased

vhdlpp: Specify lifetime for variables.
This commit is contained in:
Stephen Williams 2016-05-04 08:05:01 -07:00
commit a219df2f18
5 changed files with 35 additions and 18 deletions

View File

@ -67,6 +67,8 @@ class ScopeBase {
// type is returned, otherwise NULL. // type is returned, otherwise NULL.
const VTypeEnum* is_enum_name(perm_string name) const; 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 // Moves signals, variables and components from another scope to
// this one. After the transfer new_* maps are cleared in the source scope. // 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 }; enum transfer_type_t { SIGNALS = 1, VARIABLES = 2, COMPONENTS = 4, ALL = 0xffff };

View File

@ -49,12 +49,13 @@ class SubprogramBody : public LineInfo, public ScopeBase {
int emit(ostream&out, Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*ent, ScopeBase*scope);
// Emit body as it would show up in a package. // 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 write_to_stream(std::ostream&fd) const;
void dump(std::ostream&fd) const; void dump(std::ostream&fd) const;
const SubprogramHeader*header() const { return header_; } const SubprogramHeader*header() const { return header_; }
bool is_subprogram() const { return true; }
private: private:
std::list<SequentialStmt*>*statements_; std::list<SequentialStmt*>*statements_;

View File

@ -26,15 +26,27 @@
using namespace std; using namespace std;
int SubprogramBody::emit_package(ostream&fd) const int SubprogramBody::emit_package(ostream&fd)
{ {
int errors = 0; int errors = 0;
for (map<perm_string,Variable*>::const_iterator cur = new_variables_.begin() for (map<perm_string,Variable*>::const_iterator cur = new_variables_.begin()
; cur != new_variables_.end() ; ++cur) { ; cur != new_variables_.end() ; ++cur) {
// Enable reg_flag for variables // Enable reg_flag for variables
cur->second->count_ref_sequ(); cur->second->count_ref_sequ();
errors += cur->second->emit(fd, NULL, NULL); errors += cur->second->emit(fd, NULL, this, false);
}
// Emulate automatic functions (add explicit initial value assignments)
for (map<perm_string,Variable*>::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_) { if (statements_) {
@ -54,13 +66,13 @@ int SubprogramHeader::emit_package(ostream&fd) const
int errors = 0; int errors = 0;
if (return_type_) { if (return_type_) {
fd << "function "; fd << "function automatic ";
return_type_->emit_def(fd, empty_perm_string); return_type_->emit_def(fd, empty_perm_string);
} else { } else {
fd << "task"; fd << "task automatic";
} }
fd << " \\" << name_ << " ("; fd << " \\" << name_ << " (";
for (list<InterfacePort*>::const_iterator cur = ports_->begin() for (list<InterfacePort*>::const_iterator cur = ports_->begin()
; cur != ports_->end() ; ++cur) { ; cur != ports_->end() ; ++cur) {

View File

@ -21,6 +21,7 @@
# include "vsignal.h" # include "vsignal.h"
# include "expression.h" # include "expression.h"
# include "scope.h"
# include "vtype.h" # include "vtype.h"
# include "std_types.h" # include "std_types.h"
# include <iostream> # include <iostream>
@ -49,7 +50,7 @@ void SigVarBase::type_elaborate_(VType::decl_t&decl)
decl.type = type_; 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; int errors = 0;
@ -62,8 +63,8 @@ int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope)
decl.reg_flag = true; decl.reg_flag = true;
errors += decl.emit(out, peek_name()); errors += decl.emit(out, peek_name());
Expression*init_expr = peek_init_expr(); const Expression*init_expr = peek_init_expr();
if (init_expr) { if (initialize && init_expr) {
/* Emit initialization value for wires as a weak assignment */ /* Emit initialization value for wires as a weak assignment */
if(!decl.reg_flag && !type->type_match(&primitive_REAL)) if(!decl.reg_flag && !type->type_match(&primitive_REAL))
out << ";" << endl << "/*init*/ assign (weak1, weak0) " << peek_name(); out << ";" << endl << "/*init*/ assign (weak1, weak0) " << peek_name();
@ -75,17 +76,19 @@ int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope)
return errors; 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; int errors = 0;
out << (!scope->is_subprogram() ? "static " : "automatic ");
VType::decl_t decl; VType::decl_t decl;
type_elaborate_(decl); type_elaborate_(decl);
decl.reg_flag = true; decl.reg_flag = true;
errors += decl.emit(out, peek_name()); errors += decl.emit(out, peek_name());
Expression*init_expr = peek_init_expr(); const Expression*init_expr = peek_init_expr();
if (init_expr) { if (initialize && init_expr) {
out << " = "; out << " = ";
init_expr->emit(out, ent, scope); init_expr->emit(out, ent, scope);
} }

View File

@ -46,14 +46,13 @@ class SigVarBase : public LineInfo {
void elaborate(Entity*ent, ScopeBase*scope); void elaborate(Entity*ent, ScopeBase*scope);
perm_string peek_name() const { return name_; } perm_string peek_name() const { return name_; }
const Expression* peek_init_expr() const { return init_expr_; }
protected: protected:
unsigned peek_refcnt_sequ_() const { return refcnt_sequ_; } unsigned peek_refcnt_sequ_() const { return refcnt_sequ_; }
void type_elaborate_(VType::decl_t&decl); void type_elaborate_(VType::decl_t&decl);
Expression* peek_init_expr() const { return init_expr_; }
private: private:
perm_string name_; perm_string name_;
const VType*type_; const VType*type_;
@ -71,7 +70,7 @@ class Signal : public SigVarBase {
public: public:
Signal(perm_string name, const VType*type, Expression*init_expr); 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 { class Variable : public SigVarBase {
@ -79,7 +78,7 @@ class Variable : public SigVarBase {
public: public:
Variable(perm_string name, const VType*type, Expression*init_expr = NULL); 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); void write_to_stream(std::ostream&fd);
}; };