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.
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 };

View File

@ -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<SequentialStmt*>*statements_;

View File

@ -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<perm_string,Variable*>::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<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_) {
@ -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<InterfacePort*>::const_iterator cur = ports_->begin()
; cur != ports_->end() ; ++cur) {

View File

@ -21,6 +21,7 @@
# include "vsignal.h"
# include "expression.h"
# include "scope.h"
# include "vtype.h"
# include "std_types.h"
# include <iostream>
@ -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);
}

View File

@ -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);
};