Merge pull request #95 from orsonmmz/automatic_rebased
vhdlpp: Specify lifetime for variables.
This commit is contained in:
commit
a219df2f18
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue