vhdlpp: Check generics when searching through constants.
This commit is contained in:
parent
d3229b9068
commit
807ad8002d
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue