diff --git a/vhdlpp/architec_elaborate.cc b/vhdlpp/architec_elaborate.cc index b58bcc605..a3767ad95 100644 --- a/vhdlpp/architec_elaborate.cc +++ b/vhdlpp/architec_elaborate.cc @@ -54,10 +54,12 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc) return 1; } - map port_match; for (multimap::const_iterator cur = port_map_.begin() ; cur != port_map_.end() ; ++cur) { + /* check if a port from component instantiation + exists in the component declaration + */ const InterfacePort*iport = base->find_port(cur->first); if (iport == 0) { cerr << get_fileline() << ": error: No port " << cur->first @@ -68,9 +70,10 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc) ExpName* tmp; if (cur->second && (tmp = dynamic_cast(cur->second))) - errors += tmp->elaborate_rval(ent, arc); + errors += tmp->elaborate_rval(ent, arc, iport); /* It is possible for the port to be explicitly unconnected. In that case, the Expression will be nil */ + if (cur->second) cur->second->elaborate_expr(ent, arc, iport->type); } diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 57f06e9d3..d626501aa 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -21,6 +21,7 @@ # include "StringHeap.h" # include "LineInfo.h" +# include "entity.h" # include # include # include @@ -322,7 +323,7 @@ class ExpName : public Expression { public: // Base methods int elaborate_lval(Entity*ent, Architecture*arc, bool); - int elaborate_rval(Entity*ent, Architecture*arc); + int elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*); const VType* probe_type(Entity*ent, Architecture*arc) const; int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 84b8e16dd..048474cb8 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -71,13 +71,32 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ) return errors; } -int ExpName::elaborate_rval(Entity*ent, Architecture*arc) +int ExpName::elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*lval) { int errors = 0; if (const InterfacePort*cur = ent->find_port(name_)) { - /* OK */ - + /* IEEE 1076-2008, p.80: + * For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER + * For a formal port OUT, associated port should be OUT, INOUT or BUFFER + * For a formal port INOUT, associated prot should be OUT, INOUT or BUFFER + * For a formal port BUFFER, associated port should be OUT, INOUT or BUFFER + */ + switch(lval->mode) { + case PORT_OUT: + //case PORT_INOUT: + if (cur->mode == PORT_IN) { + cerr << get_fileline() << ": error: Connecting " + "formal output port " << lval->name << " to actual input port " + << name_ << "." << endl; + errors += 1; + } + break; + case PORT_IN: + case PORT_NONE: + default: + break; + } } else if (Signal* fs = arc->find_signal(name_)) { /* OK */