vhdlpp: Check generics when searching through constants.

This commit is contained in:
Maciej Suminski 2015-03-06 16:59:30 +01:00
parent d3229b9068
commit 807ad8002d
7 changed files with 72 additions and 11 deletions

View File

@ -28,7 +28,7 @@ using namespace std;
Architecture::Architecture(perm_string name, const ActiveScope&ref,
list<Architecture::Statement*>&s)
: Scope(ref), name_(name)
: Scope(ref), name_(name), cur_component_(NULL)
{
statements_.splice(statements_.end(), s);
}
@ -39,6 +39,34 @@ Architecture::~Architecture()
ScopeBase::cleanup();
}
bool Architecture::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const
{
if(Scope::find_constant(by_name, typ, exp))
return true;
// Check generics in components
if(cur_component_) {
std::map<perm_string,ComponentBase*>::const_iterator c = new_components_.find(cur_component_->component_name());
if(c == new_components_.end())
c = old_components_.find(cur_component_->component_name());
assert(c != old_components_.end());
ComponentBase*base = c->second;
const InterfacePort*generic = base->find_generic(by_name);
if(!generic)
return false; // apparently there is no such generic in the component
Expression*e = cur_component_->find_generic_map(by_name);
typ = generic->type;
exp = e ? e : generic->expr;
return true;
}
return false;
}
void Architecture::push_genvar_type(perm_string gname, const VType*gtype)
{
genvar_type_t tmp;
@ -191,6 +219,17 @@ ComponentInstantiation::~ComponentInstantiation()
}
}
Expression*ComponentInstantiation::find_generic_map(perm_string by_name) const
{
map<perm_string,Expression*>::const_iterator p = generic_map_.find(by_name);
if(p == generic_map_.end())
return NULL;
return p->second;
}
ProcessStatement::ProcessStatement(perm_string iname,
std::list<Expression*>*sensitivity_list,
std::list<SequentialStmt*>*statements_list)

View File

@ -25,7 +25,7 @@
# include <list>
# include <map>
class ComponentBase;
class ComponentInstantiation;
class Entity;
class Expression;
class ExpName;
@ -54,10 +54,6 @@ class Architecture : public Scope, public LineInfo {
virtual int elaborate(Entity*ent, Architecture*arc);
virtual int emit(ostream&out, Entity*ent, Architecture*arc);
virtual void dump(ostream&out, int indent = 0) const;
private:
private: // Not implemented
};
public:
@ -69,6 +65,10 @@ class Architecture : public Scope, public LineInfo {
perm_string get_name() const { return name_; }
// Sets the currently processed component (to be able to reach its parameters).
void set_cur_component(ComponentInstantiation*component) { cur_component_ = component; }
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
// Elaborate this architecture in the context of the given entity.
int elaborate(Entity*entity);
@ -110,6 +110,9 @@ class Architecture : public Scope, public LineInfo {
};
std::list<genvar_emit_t> genvar_emit_stack_;
// Currently processed component (or NULL if none).
ComponentInstantiation*cur_component_;
private: // Not implemented
};
@ -198,6 +201,12 @@ class ComponentInstantiation : public Architecture::Statement {
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
virtual void dump(ostream&out, int indent =0) const;
// Returns the expression that initalizes a generic (or NULL if not found).
Expression*find_generic_map(perm_string by_name) const;
inline perm_string instance_name() const { return iname_; }
inline perm_string component_name() const { return cname_; }
private:
perm_string iname_;
perm_string cname_;

View File

@ -92,6 +92,8 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
return 1;
}
arc->set_cur_component(this);
for (map<perm_string,Expression*>::const_iterator cur = generic_map_.begin()
; cur != generic_map_.end() ; ++cur) {
// check if generic from component instantiation
@ -133,6 +135,8 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
cur->second->elaborate_expr(ent, arc, iport->type);
}
arc->set_cur_component(NULL);
return errors;
}

View File

@ -148,6 +148,8 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
const char*comma = "";
int errors = 0;
arc->set_cur_component(this);
out << cname_;
if (! generic_map_.empty()) {
out << " #(";
@ -177,6 +179,8 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
}
out << ");" << endl;
arc->set_cur_component(NULL);
return errors;
}

View File

@ -273,6 +273,9 @@ int ExpName::elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lva
errors += 1;
}
const VType*dummy_type;
Expression*dummy_expr;
if (const InterfacePort*cur = ent->find_port(name_)) {
/* IEEE 1076-2008, p.80:
* For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER
@ -301,8 +304,11 @@ int ExpName::elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lva
} else if (ent->find_generic(name_)) {
/* OK */
} else if (scope->find_constant(name_, dummy_type, dummy_expr)) {
/* OK */
} else {
cerr << get_fileline() << ": error: No port or signal " << name_
cerr << get_fileline() << ": error: No port, signal or constant " << name_
<< " to be used as r-value." << endl;
errors += 1;
}

View File

@ -182,11 +182,10 @@ bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
return false;
}
if(!scope)
if (!scope)
return false;
bool rc = scope->find_constant(name_, type, exp);
if (rc == false)
if (!scope->find_constant(name_, type, exp))
return false;
return exp->evaluate(scope, val);

View File

@ -53,7 +53,7 @@ class ScopeBase {
virtual ~ScopeBase() =0;
const VType* find_type(perm_string by_name);
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
Signal* find_signal(perm_string by_name) const;
Variable* find_variable(perm_string by_name) const;
virtual const InterfacePort* find_param(perm_string by_name) const;